From 7bc33bb50393ef4a5412396cc05b2313630ee04b Mon Sep 17 00:00:00 2001 From: Shawn Xiao Date: Mon, 1 Sep 2014 13:03:15 +0800 Subject: [PATCH] ENGR00317558 gpu:5.0.11p1 gpu driver kernel part integration (cherry picked from commit a6f5349968e494d67f9da339dad433b528ce52fe) Conflict: drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c Revert "ENGR00317981: gpu-viv: use runtime pm for VDDPU management" and move the same change logic to file gc_hal_kernel_platform_imx6q14.c for following p1 framework change. Date: Jun 16, 2014 Signed-off-by: Loren Huang Signed-off-by: Shawn Xiao Acked-by: Shawn Guo --- drivers/mxc/gpu-viv/Kbuild | 22 +- drivers/mxc/gpu-viv/config | 2 +- .../hal/kernel/arch/gc_hal_kernel_context.c | 1 - .../hal/kernel/arch/gc_hal_kernel_context.h | 1 - .../hal/kernel/arch/gc_hal_kernel_hardware.c | 120 ++- .../hal/kernel/arch/gc_hal_kernel_hardware.h | 16 +- .../gc_hal_kernel_hardware_command_vg.c | 1 - .../gc_hal_kernel_hardware_command_vg.h | 1 - .../kernel/archvg/gc_hal_kernel_hardware_vg.c | 1 - .../kernel/archvg/gc_hal_kernel_hardware_vg.h | 1 - .../mxc/gpu-viv/hal/kernel/gc_hal_kernel.c | 798 ++++++++++++---- .../mxc/gpu-viv/hal/kernel/gc_hal_kernel.h | 137 ++- .../hal/kernel/gc_hal_kernel_command.c | 40 +- .../hal/kernel/gc_hal_kernel_command_vg.c | 88 +- .../mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c | 13 +- .../gpu-viv/hal/kernel/gc_hal_kernel_debug.c | 1 - .../gpu-viv/hal/kernel/gc_hal_kernel_event.c | 40 +- .../gpu-viv/hal/kernel/gc_hal_kernel_heap.c | 1 - .../hal/kernel/gc_hal_kernel_interrupt_vg.c | 1 - .../gpu-viv/hal/kernel/gc_hal_kernel_mmu.c | 2 - .../gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c | 1 - .../gpu-viv/hal/kernel/gc_hal_kernel_power.c | 1 - .../hal/kernel/gc_hal_kernel_precomp.h | 1 - .../hal/kernel/gc_hal_kernel_security.c | 212 ++++- .../mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c | 92 +- .../mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h | 1 - .../hal/kernel/gc_hal_kernel_video_memory.c | 77 +- drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h | 72 +- .../mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h | 313 ++++++- .../gpu-viv/hal/kernel/inc/gc_hal_driver.h | 26 + .../gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h | 1 - .../mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h | 1 - .../hal/kernel/inc/gc_hal_eglplatform.h | 3 +- .../hal/kernel/inc/gc_hal_eglplatform_type.h | 1 - .../gpu-viv/hal/kernel/inc/gc_hal_engine.h | 8 +- .../gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h | 3 +- .../mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h | 25 +- .../hal/kernel/inc/gc_hal_kernel_buffer.h | 1 - .../mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h | 1 - .../gpu-viv/hal/kernel/inc/gc_hal_options.h | 90 +- .../gpu-viv/hal/kernel/inc/gc_hal_profiler.h | 1 - .../gpu-viv/hal/kernel/inc/gc_hal_raster.h | 14 +- .../gpu-viv/hal/kernel/inc/gc_hal_rename.h | 1 - .../kernel/inc/gc_hal_security_interface.h | 137 +++ .../hal/kernel/inc/gc_hal_statistics.h | 1 - .../mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h | 2 +- .../gpu-viv/hal/kernel/inc/gc_hal_version.h | 5 +- .../mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h | 16 - .../os/linux/kernel/gc_hal_kernel_allocator.c | 21 +- .../os/linux/kernel/gc_hal_kernel_allocator.h | 8 - .../kernel/gc_hal_kernel_allocator_array.h | 1 - .../hal/os/linux/kernel/gc_hal_kernel_debug.h | 1 - .../os/linux/kernel/gc_hal_kernel_debugfs.c | 1 - .../os/linux/kernel/gc_hal_kernel_debugfs.h | 1 - .../os/linux/kernel/gc_hal_kernel_device.c | 212 +---- .../os/linux/kernel/gc_hal_kernel_device.h | 37 +- .../hal/os/linux/kernel/gc_hal_kernel_linux.c | 15 +- .../hal/os/linux/kernel/gc_hal_kernel_linux.h | 15 +- .../hal/os/linux/kernel/gc_hal_kernel_math.c | 1 - .../hal/os/linux/kernel/gc_hal_kernel_os.c | 671 ++++++++----- .../hal/os/linux/kernel/gc_hal_kernel_os.h | 1 - .../os/linux/kernel/gc_hal_kernel_platform.h | 263 ++++++ ..._kernel_driver.c => gc_hal_kernel_probe.c} | 576 ++++-------- .../kernel/gc_hal_kernel_security_channel.c | 7 +- .../hal/os/linux/kernel/gc_hal_kernel_sync.c | 1 - .../hal/os/linux/kernel/gc_hal_kernel_sync.h | 4 +- .../gc_hal_kernel_platform_imx6q14.c | 879 ++++++++++++++++++ 67 files changed, 3773 insertions(+), 1336 deletions(-) create mode 100644 drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h create mode 100644 drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h rename drivers/mxc/gpu-viv/hal/os/linux/kernel/{gc_hal_kernel_driver.c => gc_hal_kernel_probe.c} (74%) create mode 100644 drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild index 15da76a25d29..582d3d5ab3c8 100644 --- a/drivers/mxc/gpu-viv/Kbuild +++ b/drivers/mxc/gpu-viv/Kbuild @@ -39,13 +39,18 @@ CUSTOMER_ALLOCATOR_OBJS := EXTRA_CFLAGS += -Werror OBJS := $(OS_KERNEL_DIR)/gc_hal_kernel_device.o \ - $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o \ $(OS_KERNEL_DIR)/gc_hal_kernel_linux.o \ $(OS_KERNEL_DIR)/gc_hal_kernel_math.o \ $(OS_KERNEL_DIR)/gc_hal_kernel_os.o \ $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o \ $(OS_KERNEL_DIR)/gc_hal_kernel_allocator.o \ +ifneq ($(PLATFORM),) +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_probe.o +OBJS += $(OS_KERNEL_DIR)/platform/$(PLATFORM).o +else +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o +endif OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \ $(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \ @@ -71,9 +76,15 @@ OBJS +=\ endif ifneq ($(CONFIG_SYNC),) +EXTRA_CFLAGS += -Idrivers/staging/android + OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o endif +ifeq ($(SECURITY), 1) +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_security_channel.o \ + $(HAL_KERNEL_DIR)/gc_hal_kernel_security.o +endif ifneq ($(CUSTOMER_ALLOCATOR_OBJS),) OBJS += $(CUSTOMER_ALLOCATOR_OBJS) @@ -124,15 +135,9 @@ else EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=0 endif - EXTRA_CFLAGS += -DVIVANTE_PROFILER=1 EXTRA_CFLAGS += -DVIVANTE_PROFILER_CONTEXT=1 - -ifeq ($(ANDROID), 1) -EXTRA_CFLAGS += -DANDROID=1 -endif - ifeq ($(ENABLE_GPU_CLOCK_BY_DRIVER), 1) EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=1 else @@ -211,6 +216,9 @@ else EXTRA_CFLAGS += -DgcdFPGA_BUILD=0 endif +ifeq ($(SECURITY), 1) +EXTRA_CFLAGS += -DgcdSECURITY=1 +endif EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel diff --git a/drivers/mxc/gpu-viv/config b/drivers/mxc/gpu-viv/config index cd423d7764f8..3003051fd70a 100644 --- a/drivers/mxc/gpu-viv/config +++ b/drivers/mxc/gpu-viv/config @@ -33,5 +33,5 @@ USE_BANK_ALIGNMENT ?= 1 BANK_BIT_START ?= 13 BANK_BIT_END ?= 15 BANK_CHANNEL_BIT ?= 12 -ENABLE_GPU_CLOCK_BY_DRIVER ?= 1 +PLATFORM ?= freescale/gc_hal_kernel_platform_imx6q14 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 d0deb3b47918..4fa0c9647f30 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal.h" #include "gc_hal_kernel.h" #include "gc_hal_kernel_context.h" diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h index 9b9cda624eea..fe6cf5d66758 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_context_h_ #define __gc_hal_kernel_context_h_ 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 e7e7f7d1fa84..a565ca37641b 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal.h" #include "gc_hal_kernel.h" #if VIVANTE_PROFILER_CONTEXT @@ -64,9 +63,6 @@ typedef struct _gcsiDEBUG_REGISTERS } gcsiDEBUG_REGISTERS; -#ifdef LINUX -extern int gpu3DMinClock; -#endif /******************************************************************************\ ********************************* Support Code ********************************* \******************************************************************************/ @@ -141,7 +137,6 @@ _IdentifyHardware( 0x00020, (gctUINT32_PTR) &Identity->chipModel)); - if (((Identity->chipModel & 0xFF00) == 0x0400) && (Identity->chipModel != 0x0420) && (Identity->chipModel != 0x0428)) @@ -920,7 +915,6 @@ gckHARDWARE_Construct( gceSTATUS status; gckHARDWARE hardware = gcvNULL; gctUINT16 data = 0xff00; - gctUINT32 axi_ot; gctPOINTER pointer = gcvNULL; #if gcdMULTI_GPU_AFFINITY gctUINT32 control; @@ -969,10 +963,6 @@ gckHARDWARE_Construct( case gcv420: case gcv428: hardware->type = gcvHARDWARE_2D; - /*set outstanding limit*/ - gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot)); - axi_ot = (axi_ot & (~0xFF)) | 0x10; - gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot)); break; default: @@ -1061,6 +1051,7 @@ gckHARDWARE_Construct( hardware->clockState = gcvTRUE; hardware->powerState = gcvTRUE; hardware->lastWaitLink = ~0U; + hardware->lastEnd = ~0U; hardware->globalSemaphore = gcvNULL; #if gcdENABLE_FSCALE_VAL_ADJUST hardware->powerOnFscaleVal = 64; @@ -1105,6 +1096,8 @@ gckHARDWARE_Construct( hardware->endAfterFlushMmuCache = gcvFALSE; } + hardware->minFscaleValue = 1; + /* Return pointer to the gckHARDWARE object. */ *Hardware = hardware; @@ -1391,7 +1384,6 @@ gckHARDWARE_InitializeHardware( #endif } - if (Hardware->identity.chipModel == gcv4000 && ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222))) { @@ -1402,6 +1394,20 @@ gckHARDWARE_InitializeHardware( ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))))); } + if (Hardware->identity.chipModel == gcv1000 && + Hardware->identity.chipRevision == 0x5039) + { + gctUINT32 pulseEater; + + pulseEater = ((((gctUINT32) (0x01590880)) & ~(((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))); + + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0010C, + ((((gctUINT32) (pulseEater)) & ~(((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))))); + } + if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvSTATUS_FALSE) || (Hardware->identity.chipRevision < 0x5422) ) @@ -1419,7 +1425,6 @@ gckHARDWARE_InitializeHardware( regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))); } - if (_IsHardwareMatch(Hardware, gcv2000, 0x5108)) { gcmkONERROR( @@ -1537,14 +1542,6 @@ gckHARDWARE_InitializeHardware( Hardware->kernel->timeOut = 140 * 1000; } - /* Update GPU AXI cache atttribute. */ - gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00008, - 0x00002200)); - - - /*VIV: Disable RA HZ/EZ clock gating until the bug is resolved */ if (regPMC == 0) { gcmkONERROR( @@ -1571,6 +1568,19 @@ gckHARDWARE_InitializeHardware( regPMC)); } + if (_IsHardwareMatch(Hardware, gcv2000, 0x5108) + || _IsHardwareMatch(Hardware, gcv320, 0x5007) + || _IsHardwareMatch(Hardware, gcv880, 0x5106) + || _IsHardwareMatch(Hardware, gcv400, 0x4645) + ) + { + /* Update GPU AXI cache atttribute. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00008, + 0x00002200)); + } + #if gcdDEBUG_MODULE_CLOCK_GATING _ConfigureModuleLevelClockGating(Hardware); #endif @@ -2151,6 +2161,7 @@ gckHARDWARE_End( ) { gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gctUINT32 address; gceSTATUS status; gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu", @@ -2177,6 +2188,10 @@ gckHARDWARE_End( /* Make sure the CPU writes out the data to memory. */ gcmkONERROR( gckOS_MemoryBarrier(Hardware->os, Logical)); + + gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, gcvFALSE, &address)); + + Hardware->lastEnd = address; } if (Bytes != gcvNULL) @@ -2373,7 +2388,6 @@ gckHARDWARE_Event( gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); gcmkVERIFY_ARGUMENT(Event < 32); - #if gcdMULTI_GPU if (FromWhere == gcvKERNEL_COMMAND) FromWhere = gcvKERNEL_PIXEL; #endif @@ -3991,6 +4005,7 @@ gckHARDWARE_GetIdle( gceSTATUS status; gctUINT32 idle = 0; gctINT retry, poll, pollCount; + gctUINT32 address; gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait); @@ -4012,8 +4027,17 @@ gckHARDWARE_GetIdle( gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle)); + /* Read the current FE address. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00664, + &address)); + + /* See if we have to wait for FE idle. */ - if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) + && (address == Hardware->lastEnd + 8) + ) { /* FE is idle. */ break; @@ -5062,6 +5086,7 @@ gckHARDWARE_SetPowerManagementState( isrStarted = gcvTRUE; } +#if !gcdSECURITY /* Set NEW MMU. */ if (Hardware->mmuVersion != 0 && configMmu) { @@ -5075,6 +5100,7 @@ gckHARDWARE_SetPowerManagementState( gcvTRUE )); } +#endif } /* Get time until started. */ @@ -5421,19 +5447,25 @@ gckHARDWARE_GetFscaleValue( ) { *FscaleValue = Hardware->powerOnFscaleVal; -#ifdef LINUX - if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR)) - *MinFscaleValue = gpu3DMinClock; - else - *MinFscaleValue = 1; -#else - *MinFscaleValue = 1; -#endif + *MinFscaleValue = Hardware->minFscaleValue; *MaxFscaleValue = 64; return gcvSTATUS_OK; } +gceSTATUS +gckHARDWARE_SetMinFscaleValue( + IN gckHARDWARE Hardware, + IN gctUINT MinFscaleValue + ) +{ + if (MinFscaleValue >= 1 && MinFscaleValue <= 64) + { + Hardware->minFscaleValue = MinFscaleValue; + } + + return gcvSTATUS_OK; +} #endif #if gcdPOWEROFF_TIMEOUT @@ -5482,6 +5514,10 @@ gckHARDWARE_QueryIdle( gctBOOL isIdle3D1 = gcvFALSE; #endif +#if gcdINTERRUPT_STATISTIC + gctINT32 pendingInterrupt; +#endif + gcmkHEADER_ARG("Hardware=0x%x", Hardware); /* Verify the arguments. */ @@ -5531,6 +5567,10 @@ gckHARDWARE_QueryIdle( else { +#if gcdSECURITY + isIdle = gcvTRUE; + address = 0; +#else /* Read the current FE address. */ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, @@ -5554,6 +5594,7 @@ gckHARDWARE_QueryIdle( /* FE is not in WAIT/LINK yet. */ isIdle = gcvFALSE; } +#endif } #if gcdMULTI_GPU > 1 @@ -5601,6 +5642,19 @@ gckHARDWARE_QueryIdle( } +#if gcdINTERRUPT_STATISTIC + gcmkONERROR(gckOS_AtomGet( + Hardware->os, + Hardware->kernel->eventObj->interruptCount, + &pendingInterrupt + )); + + if (pendingInterrupt) + { + isIdle = gcvFALSE; + } +#endif + #if gcdMULTI_GPU > 1 if (Hardware->core == gcvCORE_MAJOR) { @@ -6913,6 +6967,12 @@ gckHARDWARE_IsFeatureAvailable( /* This feature doesn't apply for 2D cores. */ available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 14:14) & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1))))))) && ((((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) + { + available = gcvFALSE; + } break; case gcvFEATURE_ACE: 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 2fd731cb6886..58247d7c525f 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_hardware_h_ #define __gc_hal_kernel_hardware_h_ @@ -62,6 +61,7 @@ struct _gckHARDWARE gctUINT32 powerThread; gceCHIPPOWERSTATE chipPowerState; gctUINT32 lastWaitLink; + gctUINT32 lastEnd; gctBOOL clockState; gctBOOL powerState; gctPOINTER globalSemaphore; @@ -94,6 +94,8 @@ struct _gckHARDWARE gctBOOL gpuProfiler; gctBOOL endAfterFlushMmuCache; + + gctUINT32 minFscaleValue; }; gceSTATUS @@ -115,18 +117,6 @@ gckHARDWARE_GetFrameInfo( OUT gcsHAL_FRAME_INFO * FrameInfo ); -gceSTATUS -gckHARDWARE_SetFscaleValue( - IN gckHARDWARE Hardware, - IN gctUINT32 FscaleValue - ); -gceSTATUS -gckHARDWARE_GetFscaleValue( - IN gckHARDWARE Hardware, - IN gctUINT * FscaleValue, - IN gctUINT * MinFscaleValue, - IN gctUINT * MaxFscaleValue - ); #ifdef __cplusplus } #endif diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c index 049071d6c505..0013e63b9a53 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal.h" #include "gc_hal_kernel.h" diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h index ad4fecd5585f..22093a9655a8 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_hardware_command_vg_h_ #define __gc_hal_kernel_hardware_command_vg_h_ diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c index 07f582de3ad6..3cb47dd04b6f 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal.h" #include "gc_hal_kernel.h" #include "gc_hal_kernel_hardware_command_vg.h" diff --git a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h index 5845e5bd8bf9..ce54910545d7 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_hardware_vg_h_ #define __gc_hal_kernel_hardware_vg_h_ 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 396e8e68f127..b9703525df65 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #define _GC_OBJ_ZONE gcvZONE_KERNEL @@ -70,6 +69,9 @@ gctCONST_STRING _DispatchText[] = gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING), gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS), gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D), +#if VIVANTE_PROFILER_PERDRAW + gcvHAL_READ_PROFILER_REGISTER_SETTING, +#endif gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE), gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE), gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS), @@ -98,6 +100,13 @@ gctCONST_STRING _DispatchText[] = gcmDEFINE2TEXT(gcvHAL_GET_FSCALE_VALUE), gcmDEFINE2TEXT(gcvHAL_NAME_VIDEO_MEMORY), gcmDEFINE2TEXT(gcvHAL_IMPORT_VIDEO_MEMORY), + gcmDEFINE2TEXT(gcvHAL_QUERY_RESET_TIME_STAMP), + gcmDEFINE2TEXT(gcvHAL_READ_REGISTER_EX), + gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER_EX), + gcmDEFINE2TEXT(gcvHAL_SYNC_POINT), + gcmDEFINE2TEXT(gcvHAL_CREATE_NATIVE_FENCE), + gcmDEFINE2TEXT(gcvHAL_DESTROY_MMU), + gcmDEFINE2TEXT(gcvHAL_SHBUF), }; #endif @@ -330,11 +339,14 @@ gckKERNEL_Construct( /* Initialize virtual command buffer. */ /* TODO: Remove platform limitation after porting. */ #if (defined(LINUX) || defined(__QNXNTO__)) - kernel->virtualCommandBuffer = gcvFALSE; + kernel->virtualCommandBuffer = gcvTRUE; #else kernel->virtualCommandBuffer = gcvFALSE; #endif +#if gcdSECURITY + kernel->virtualCommandBuffer = gcvFALSE; +#endif /* Construct the gckCOMMAND object. */ gcmkONERROR( @@ -388,6 +400,10 @@ gckKERNEL_Construct( gcmkONERROR( gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock)); +#if gcdSECURITY + /* Connect to security service for this GPU. */ + gcmkONERROR(gckKERNEL_SecurityOpen(kernel, kernel->core, &kernel->securityChannel)); +#endif /* Construct a video memory mutex. */ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->vidmemMutex)); @@ -614,6 +630,10 @@ gckKERNEL_Destroy( gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline)); #endif +#if gcdSECURITY + gcmkVERIFY_OK(gckKERNEL_SecurityClose(Kernel->securityChannel)); +#endif + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->vidmemMutex)); /* Mark the gckKERNEL object as unknown. */ @@ -627,98 +647,6 @@ gckKERNEL_Destroy( return gcvSTATUS_OK; } -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT -#include -#include -#include -#include -#include - -extern struct task_struct *lowmem_deathpending; -static unsigned long lowmem_deathpending_timeout; - -static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel) -{ - struct task_struct *p; - struct task_struct *selected = NULL; - int tasksize; - int ret = -1; - int min_adj = 0; - int selected_tasksize = 0; - int selected_oom_adj; - /* - * If we already have a death outstanding, then - * bail out right away; indicating to vmscan - * that we have nothing further to offer on - * this pass. - * - */ - if (lowmem_deathpending && - time_before_eq(jiffies, lowmem_deathpending_timeout)) - return 0; - selected_oom_adj = min_adj; - - read_lock(&tasklist_lock); - for_each_process(p) { - struct mm_struct *mm; - struct signal_struct *sig; - gcuDATABASE_INFO info; - int oom_adj; - - task_lock(p); - mm = p->mm; - sig = p->signal; - if (!mm || !sig) { - task_unlock(p); - continue; - } - oom_adj = sig->oom_adj; - if (oom_adj < min_adj) { - task_unlock(p); - continue; - } - - tasksize = 0; - if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){ - tasksize += info.counters.bytes / PAGE_SIZE; - } - if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){ - tasksize += info.counters.bytes / PAGE_SIZE; - } - - task_unlock(p); - - if (tasksize <= 0) - continue; - - gckOS_Print(" pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize); - - if (selected) { - if (oom_adj < selected_oom_adj) - continue; - if (oom_adj == selected_oom_adj && - tasksize <= selected_tasksize) - continue; - } - selected = p; - selected_tasksize = tasksize; - selected_oom_adj = oom_adj; - } - if (selected) { - gckOS_Print(" send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); - lowmem_deathpending = selected; - lowmem_deathpending_timeout = jiffies + HZ; - force_sig(SIGKILL, selected); - ret = 0; - } - read_unlock(&tasklist_lock); - return ret; -} - -#endif - /******************************************************************************* ** ** _AllocateMemory @@ -749,6 +677,7 @@ gckKERNEL_AllocateLinearMemory( IN gctSIZE_T Bytes, IN gctUINT32 Alignment, IN gceSURF_TYPE Type, + IN gctUINT32 Flag, OUT gctUINT32 * Node ) { @@ -758,7 +687,7 @@ gckKERNEL_AllocateLinearMemory( gctINT loopCount; gcuVIDMEM_NODE_PTR node = gcvNULL; gctBOOL tileStatusInVirtual; - gctBOOL forceContiguous = gcvFALSE; + gctBOOL contiguous = gcvFALSE; gctBOOL cacheable = gcvFALSE; gctSIZE_T bytes = Bytes; gctUINT32 handle = 0; @@ -770,15 +699,20 @@ gckKERNEL_AllocateLinearMemory( gcmkVERIFY_ARGUMENT(Pool != gcvNULL); gcmkVERIFY_ARGUMENT(Bytes != 0); -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT -_AllocateMemory_Retry: -#endif + /* Get basic type. */ + Type &= 0xFF; + + /* Check flags. */ + contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS; + cacheable = Flag & gcvALLOC_FLAG_CACHEABLE; + +AllocateMemory: + /* Get initial pool. */ switch (pool = *Pool) { case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS: - forceContiguous = gcvTRUE; - /* fall through */ + contiguous = gcvTRUE; case gcvPOOL_DEFAULT: case gcvPOOL_LOCAL: pool = gcvPOOL_LOCAL_INTERNAL; @@ -798,7 +732,7 @@ _AllocateMemory_Retry: case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE: pool = gcvPOOL_CONTIGUOUS; loopCount = 1; - forceContiguous = gcvTRUE; + contiguous = gcvTRUE; cacheable = gcvTRUE; break; @@ -815,11 +749,8 @@ _AllocateMemory_Retry: gcmkONERROR( gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, gcvTRUE, &node)); - if(node) - { - bytes = node->Virtual.bytes; - node->Virtual.type = Type; - } + bytes = node->Virtual.bytes; + node->Virtual.type = Type; /* Success. */ break; @@ -829,7 +760,7 @@ _AllocateMemory_Retry: if (pool == gcvPOOL_CONTIGUOUS) { #if gcdCONTIGUOUS_SIZE_LIMIT - if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && forceContiguous == gcvFALSE) + if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && contiguous == gcvFALSE) { status = gcvSTATUS_OUT_OF_MEMORY; } @@ -840,57 +771,19 @@ _AllocateMemory_Retry: status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, cacheable, &node); } - if (gcmIS_SUCCESS(status) || forceContiguous == gcvTRUE) + if (gcmIS_SUCCESS(status)) { - if(node) - { - bytes = node->Virtual.bytes; - node->Virtual.type = Type; - } + bytes = node->Virtual.bytes; + node->Virtual.type = Type; /* Memory allocated. */ - if(node && forceContiguous == gcvTRUE) - { - gctUINT32 physAddr=0; - gctUINT32 baseAddress = 0; - - gckOS_LockPages(Kernel->os, - node->Virtual.physical, - node->Virtual.bytes, - gcvFALSE, - &node->Virtual.logical, - &node->Virtual.pageCount); - - /* Convert logical address into a physical address. */ - gckOS_GetPhysicalAddress(Kernel->os, node->Virtual.logical, &physAddr); - - gckOS_UnlockPages(Kernel->os, - node->Virtual.physical, - node->Virtual.bytes, - node->Virtual.logical); - - gckOS_GetBaseAddress(Kernel->os, &baseAddress); - - gcmkASSERT(physAddr >= baseAddress); - - /* Subtract baseAddress to get a GPU address used for programming. */ - physAddr -= baseAddress; - - if((physAddr & 0x80000000) || ((physAddr + Bytes) & 0x80000000)) - { - gckOS_Print("gpu virtual memory 0x%x cannot be allocated for external use !\n", physAddr); - - gckVIDMEM_Free(Kernel, node); - - node = gcvNULL; - } - } - break; } } else + /* gcvPOOL_SYSTEM can't be cacheable. */ + if (cacheable == gcvFALSE) { /* Get pointer to gckVIDMEM object for pool. */ status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory); @@ -957,6 +850,12 @@ _AllocateMemory_Retry: gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } + if (contiguous) + { + status = gcvSTATUS_OUT_OF_MEMORY; + break; + } + /* Advance to virtual memory. */ pool = gcvPOOL_VIRTUAL; } @@ -970,17 +869,18 @@ _AllocateMemory_Retry: if (node == gcvNULL) { -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT - if(forceContiguous == gcvTRUE) + if (contiguous) { - if(force_contiguous_lowmem_shrink(Kernel) == 0) + /* Broadcast OOM message. */ + status = gckOS_Broadcast(Kernel->os, Kernel->hardware, gcvBROADCAST_OUT_OF_MEMORY); + + if (gcmIS_SUCCESS(status)) { - /* Sleep 1 millisecond. */ - gckOS_Delay(gcvNULL, 1); - goto _AllocateMemory_Retry; + /* Get some memory. */ + gckOS_Delay(gcvNULL, 1); + goto AllocateMemory; } } -#endif /* Nothing allocated. */ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); @@ -996,7 +896,7 @@ _AllocateMemory_Retry: /* Encode surface type and pool to database type. */ type = gcvDB_VIDEO_MEMORY - | ((Type & 0xFF) << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) + | (Type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) | (pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT); /* Record in process db. */ @@ -1069,7 +969,7 @@ gckKERNEL_ReleaseVideoMemory( gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Handle, &nodeObject)); type = gcvDB_VIDEO_MEMORY - | ((nodeObject->type & 0xFF) << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) + | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT); gcmkONERROR( @@ -1148,7 +1048,8 @@ gckKERNEL_LockVideoMemory( gckVIDMEM_Lock(Kernel, node, Interface->u.LockVideoMemory.cacheable, - &Interface->u.LockVideoMemory.address)); + &Interface->u.LockVideoMemory.address, + &Interface->u.LockVideoMemory.physicalAddress)); locked = gcvTRUE; @@ -1390,7 +1291,9 @@ gckKERNEL_QueryDatabase( &Interface->u.Database.vidMemPool[i])); } +#if gcmIS_DEBUG(gcdDEBUG_TRACE) gckKERNEL_DumpVidMemUsage(Kernel, Interface->u.Database.processID); +#endif gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -1689,6 +1592,7 @@ gckKERNEL_Dispatch( Interface->u.AllocateLinearVideoMemory.bytes, Interface->u.AllocateLinearVideoMemory.alignment, Interface->u.AllocateLinearVideoMemory.type, + Interface->u.AllocateLinearVideoMemory.flag, &Interface->u.AllocateLinearVideoMemory.node)); break; @@ -2606,6 +2510,93 @@ gckKERNEL_Dispatch( break; #endif + case gcvHAL_SHBUF: + { + gctSHBUF shBuf; + gctPOINTER uData; + gctUINT32 bytes; + + switch (Interface->u.ShBuf.command) + { + case gcvSHBUF_CREATE: + bytes = Interface->u.ShBuf.bytes; + + /* Create. */ + gcmkONERROR(gckKERNEL_CreateShBuffer(Kernel, bytes, &shBuf)); + + Interface->u.ShBuf.id = gcmPTR_TO_UINT64(shBuf); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, + gcvDB_SHBUF, + shBuf, + gcvNULL, + 0)); + break; + + case gcvSHBUF_DESTROY: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + + /* Check db first to avoid illegal destroy in the process. */ + gcmkONERROR( + gckKERNEL_RemoveProcessDB(Kernel, + processID, + gcvDB_SHBUF, + shBuf)); + + gcmkONERROR(gckKERNEL_DestroyShBuffer(Kernel, shBuf)); + break; + + case gcvSHBUF_MAP: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + + /* Map for current process access. */ + gcmkONERROR(gckKERNEL_MapShBuffer(Kernel, shBuf)); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, + gcvDB_SHBUF, + shBuf, + gcvNULL, + 0)); + break; + + case gcvSHBUF_WRITE: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data); + bytes = Interface->u.ShBuf.bytes; + + /* Write. */ + gcmkONERROR( + gckKERNEL_WriteShBuffer(Kernel, shBuf, uData, bytes)); + break; + + case gcvSHBUF_READ: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data); + bytes = Interface->u.ShBuf.bytes; + + /* Read. */ + gcmkONERROR( + gckKERNEL_ReadShBuffer(Kernel, + shBuf, + uData, + bytes, + &bytes)); + + /* Return copied size. */ + Interface->u.ShBuf.bytes = bytes; + break; + + default: + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + break; + } + } + break; + default: /* Invalid command. */ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); @@ -3439,6 +3430,10 @@ gckKERNEL_Recovery( #else eventObj->pending = gcdEVENT_MASK; #endif +#endif + +#if gcdINTERRUPT_STATISTIC + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->interruptCount, 0)); #endif gcmkONERROR(gckEVENT_Notify(eventObj, 1)); @@ -4475,6 +4470,489 @@ gckKERNEL_SetRecovery( return gcvSTATUS_OK; } + +/******************************************************************************* +***** Shared Buffer ************************************************************ +*******************************************************************************/ + +/******************************************************************************* +** +** gckKERNEL_CreateShBuffer +** +** Create shared buffer. +** The shared buffer can be used across processes. Other process needs call +** gckKERNEL_MapShBuffer before use it. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctUINT32 Size +** Specify the shared buffer size. +** +** OUTPUT: +** +** gctSHBUF * ShBuf +** Pointer to hold return shared buffer handle. +*/ +gceSTATUS +gckKERNEL_CreateShBuffer( + IN gckKERNEL Kernel, + IN gctUINT32 Size, + OUT gctSHBUF * ShBuf + ) +{ + gceSTATUS status; + gcsSHBUF_PTR shBuf = gcvNULL; + + gcmkHEADER_ARG("Kernel=0x%X, Size=%u", Kernel, Size); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + + if (Size == 0) + { + /* Invalid size. */ + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + else if (Size > 1024) + { + /* Limite shared buffer size. */ + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } + + /* Create a shared buffer structure. */ + gcmkONERROR( + gckOS_Allocate(Kernel->os, + sizeof (gcsSHBUF), + (gctPOINTER *)&shBuf)); + + /* Initialize shared buffer. */ + shBuf->id = 0; + shBuf->reference = gcvNULL; + shBuf->size = Size; + shBuf->data = gcvNULL; + + /* Allocate integer id for this shared buffer. */ + gcmkONERROR( + gckKERNEL_AllocateIntegerId(Kernel->db->pointerDatabase, + shBuf, + &shBuf->id)); + + /* Allocate atom. */ + gcmkONERROR(gckOS_AtomConstruct(Kernel->os, &shBuf->reference)); + + /* Set default reference count to 1. */ + gcmkVERIFY_OK(gckOS_AtomSet(Kernel->os, shBuf->reference, 1)); + + /* Return integer id. */ + *ShBuf = (gctSHBUF)(gctUINTPTR_T)shBuf->id; + + gcmkFOOTER_ARG("*ShBuf=%u", shBuf->id); + return gcvSTATUS_OK; + +OnError: + /* Error roll back. */ + if (shBuf != gcvNULL) + { + if (shBuf->id != 0) + { + gcmkVERIFY_OK( + gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase, + shBuf->id)); + } + + gcmkOS_SAFE_FREE(Kernel->os, shBuf); + } + + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckKERNEL_DestroyShBuffer +** +** Destroy shared buffer. +** This will decrease reference of specified shared buffer and do actual +** destroy when no reference on it. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctSHBUF ShBuf +** Specify the shared buffer to be destroyed. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckKERNEL_DestroyShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf + ) +{ + gceSTATUS status; + gcsSHBUF_PTR shBuf; + gctINT32 oldValue = 0; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); + + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; + + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); + + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); + + /* Decrease the reference count. */ + gckOS_AtomDecrement(Kernel->os, shBuf->reference, &oldValue); + + if (oldValue == 1) + { + /* Free integer id. */ + gcmkVERIFY_OK( + gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase, + shBuf->id)); + + /* Free atom. */ + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, shBuf->reference)); + + if (shBuf->data) + { + gcmkOS_SAFE_FREE(Kernel->os, shBuf->data); + shBuf->data = gcvNULL; + } + + /* Free the shared buffer. */ + gcmkOS_SAFE_FREE(Kernel->os, shBuf); + } + + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + } + + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckKERNEL_MapShBuffer +** +** Map shared buffer into this process so that it can be used in this process. +** This will increase reference count on the specified shared buffer. +** Call gckKERNEL_DestroyShBuffer to dereference. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctSHBUF ShBuf +** Specify the shared buffer to be mapped. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckKERNEL_MapShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf + ) +{ + gceSTATUS status; + gcsSHBUF_PTR shBuf; + gctINT32 oldValue = 0; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); + + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; + + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); + + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); + + /* Increase the reference count. */ + gckOS_AtomIncrement(Kernel->os, shBuf->reference, &oldValue); + + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + } + + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckKERNEL_WriteShBuffer +** +** Write user data into shared buffer. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctSHBUF ShBuf +** Specify the shared buffer to be written to. +** +** gctPOINTER UserData +** User mode pointer to hold the source data. +** +** gctUINT32 ByteCount +** Specify number of bytes to write. If this is larger than +** shared buffer size, gcvSTATUS_INVALID_ARGUMENT is returned. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckKERNEL_WriteShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf, + IN gctPOINTER UserData, + IN gctUINT32 ByteCount + ) +{ + gceSTATUS status; + gcsSHBUF_PTR shBuf; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); + + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; + + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); + + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); + + if ((ByteCount > shBuf->size) || + (ByteCount == 0) || + (UserData == gcvNULL)) + { + /* Exceeds buffer max size or invalid. */ + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + if (shBuf->data == gcvNULL) + { + /* Allocate buffer data when first time write. */ + gcmkONERROR(gckOS_Allocate(Kernel->os, ByteCount, &shBuf->data)); + } + + /* Copy data from user. */ + gcmkONERROR( + gckOS_CopyFromUserData(Kernel->os, + shBuf->data, + UserData, + ByteCount)); + + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + } + + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckKERNEL_ReadShBuffer +** +** Read data from shared buffer and copy to user pointer. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctSHBUF ShBuf +** Specify the shared buffer to be read from. +** +** gctPOINTER UserData +** User mode pointer to save output data. +** +** gctUINT32 ByteCount +** Specify number of bytes to read. +** If this is larger than shared buffer size, only avaiable bytes are +** copied. If smaller, copy requested size. +** +** OUTPUT: +** +** gctUINT32 * BytesRead +** Pointer to hold how many bytes actually read from shared buffer. +*/ +gceSTATUS +gckKERNEL_ReadShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf, + IN gctPOINTER UserData, + IN gctUINT32 ByteCount, + OUT gctUINT32 * BytesRead + ) +{ + gceSTATUS status; + gcsSHBUF_PTR shBuf; + gctUINT32 bytes; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); + + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; + + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); + + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); + + if (shBuf->data == gcvNULL) + { + *BytesRead = 0; + + /* No data in shared buffer, skip copy. */ + status = gcvSTATUS_SKIP; + goto OnError; + } + else if (ByteCount == 0) + { + /* Invalid size to read. */ + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + /* Determine bytes to copy. */ + bytes = (ByteCount < shBuf->size) ? ByteCount : shBuf->size; + + /* Copy data to user. */ + gcmkONERROR( + gckOS_CopyToUserData(Kernel->os, + shBuf->data, + UserData, + bytes)); + + /* Return copied size. */ + *BytesRead = bytes; + + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + acquired = gcvFALSE; + + gcmkFOOTER_ARG("*BytesRead=%u", bytes); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + } + + gcmkFOOTER(); + return status; +} + + /******************************************************************************* ***** Test Code **************************************************************** *******************************************************************************/ diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h index bf35bfe11794..edf5c15c224e 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_h_ #define __gc_hal_kernel_h_ @@ -31,6 +30,9 @@ #include "gc_hal_kernel_vg.h" #endif +#if gcdSECURITY +#include "gc_hal_security_interface.h" +#endif #ifdef __cplusplus extern "C" { @@ -162,6 +164,7 @@ typedef enum _gceDATABASE_TYPE gcvDB_MAP_MEMORY, /* Map memory */ gcvDB_MAP_USER_MEMORY, /* Map user memory */ gcvDB_SYNC_POINT, /* Sync point. */ + gcvDB_SHBUF, /* Shared buffer. */ } gceDATABASE_TYPE; @@ -546,6 +549,10 @@ struct _gckKERNEL /* Level of dump information after stuck. */ gctUINT stuckDump; +#if gcdSECURITY + gctUINT32 securityChannel; +#endif + gctPOINTER vidmemMutex; }; @@ -862,7 +869,7 @@ typedef union _gcuVIDMEM_NODE /* Process ID owning this memory. */ gctUINT32 processID; -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG gctPOINTER kernelVirtual; #endif } @@ -885,6 +892,14 @@ typedef union _gcuVIDMEM_NODE /* do_mmap_pgoff address... mapped per-process. */ gctPOINTER logical; +#if gcdENABLE_VG + /* Physical address of this node, only meaningful when it is contiguous. */ + gctUINT32 physicalAddress; + + /* Kernel logical of this node. */ + gctPOINTER kernelVirtual; +#endif + /* Page table information. */ /* Used only when node is not contiguous */ gctSIZE_T pageCount; @@ -904,10 +919,6 @@ typedef union _gcuVIDMEM_NODE /* Surface type. */ gceSURF_TYPE type; -#if gcdENABLE_VG - gctPOINTER kernelVirtual; -#endif - } Virtual; } @@ -981,6 +992,23 @@ typedef struct _gcsVIDMEM_HANDLE } gcsVIDMEM_HANDLE; +typedef struct _gcsSHBUF * gcsSHBUF_PTR; +typedef struct _gcsSHBUF +{ + /* ID. */ + gctUINT32 id; + + /* Reference count. */ + gctPOINTER reference; + + /* Data size. */ + gctUINT32 size; + + /* Data. */ + gctPOINTER data; +} +gcsSHBUF; + gceSTATUS gckVIDMEM_HANDLE_Reference( IN gckKERNEL Kernel, @@ -1207,6 +1235,103 @@ gckHARDWARE_QueryIdle( OUT gctBOOL_PTR IsIdle ); +#if gcdSECURITY +gceSTATUS +gckKERNEL_SecurityOpen( + IN gckKERNEL Kernel, + IN gctUINT32 GPU, + OUT gctUINT32 *Channel + ); + +/* +** Close a security service channel +*/ +gceSTATUS +gckKERNEL_SecurityClose( + IN gctUINT32 Channel + ); + +/* +** Security service interface. +*/ +gceSTATUS +gckKERNEL_SecurityCallService( + IN gctUINT32 Channel, + IN OUT gcsTA_INTERFACE * Interface + ); + +gceSTATUS +gckKERNEL_SecurityStartCommand( + IN gckKERNEL Kernel + ); + +gceSTATUS +gckKERNEL_SecurityAllocateSecurityMemory( + IN gckKERNEL Kernel, + IN gctUINT32 Bytes, + OUT gctUINT32 * Handle + ); + +gceSTATUS +gckKERNEL_SecurityExecute( + IN gckKERNEL Kernel, + IN gctPOINTER Buffer, + IN gctUINT32 Bytes + ); + +gceSTATUS +gckKERNEL_SecurityMapMemory( + IN gckKERNEL Kernel, + IN gctUINT32 *PhysicalArray, + IN gctUINT32 PageCount, + OUT gctUINT32 * GPUAddress + ); + +gceSTATUS +gckKERNEL_SecurityUnmapMemory( + IN gckKERNEL Kernel, + IN gctUINT32 GPUAddress, + IN gctUINT32 PageCount + ); + +#endif + +gceSTATUS +gckKERNEL_CreateShBuffer( + IN gckKERNEL Kernel, + IN gctUINT32 Size, + OUT gctSHBUF * ShBuf + ); + +gceSTATUS +gckKERNEL_DestroyShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf + ); + +gceSTATUS +gckKERNEL_MapShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf + ); + +gceSTATUS +gckKERNEL_WriteShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf, + IN gctPOINTER UserData, + IN gctUINT32 ByteCount + ); + +gceSTATUS +gckKERNEL_ReadShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf, + IN gctPOINTER UserData, + IN gctUINT32 ByteCount, + OUT gctUINT32 * BytesRead + ); + /******************************************************************************\ ******************************* gckCONTEXT Object ******************************* 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 589df39f5bdb..22c603e35747 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #include "gc_hal_kernel_context.h" @@ -323,6 +322,9 @@ _FlushMMU( IN gckCOMMAND Command ) { +#if gcdSECURITY + return gcvSTATUS_OK; +#else gceSTATUS status; gctUINT32 oldValue; gckHARDWARE hardware = Command->kernel->hardware; @@ -405,6 +407,7 @@ _FlushMMU( return gcvSTATUS_OK; OnError: return status; +#endif } static void @@ -999,12 +1002,19 @@ gckCOMMAND_Start( Command->offset = waitLinkBytes; Command->newQueue = gcvFALSE; +#if gcdSECURITY + /* Start FE by calling security service. */ + gckKERNEL_SecurityStartCommand( + Command->kernel + ); +#else /* Enable command processor. */ gcmkONERROR(gckHARDWARE_Execute( hardware, Command->address, waitLinkBytes )); +#endif /* Command queue is running. */ Command->running = gcvTRUE; @@ -1086,6 +1096,11 @@ gckCOMMAND_Stop( hardware, Command->waitLogical, &Command->waitSize )); +#if gcdSECURITY + gcmkONERROR(gckKERNEL_SecurityExecute( + Command->kernel, Command->waitLogical, 8 + )); +#endif /* Update queue tail pointer. */ gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware, @@ -1681,10 +1696,6 @@ gckCOMMAND_Commit( /* Not using 2D. */ else { -#if !gcdCMD_NO_2D_CONTEXT - /* Mark 2D as dirty. */ - Context->dirty2D = gcvTRUE; -#endif /* Store the current context buffer. */ Context->dirtyBuffer = contextBuffer; @@ -1850,6 +1861,14 @@ gckCOMMAND_Commit( contextDumpBytes = entryBytes; #endif +#if gcdSECURITY + /* Commit context buffer to trust zone. */ + gckKERNEL_SecurityExecute( + Command->kernel, + entryLogical, + entryBytes - 8 + ); +#endif } /* Same context. */ @@ -2172,6 +2191,7 @@ gckCOMMAND_Commit( /* Generate a LINK from the end of the command buffer being scheduled back to the kernel command queue. */ +#if !gcdSECURITY gcmkONERROR(gckHARDWARE_Link( hardware, commandBufferLink, @@ -2179,6 +2199,7 @@ gckCOMMAND_Commit( exitBytes, &linkBytes )); +#endif #ifdef __QNXNTO__ gcmkONERROR(gckOS_UnmapUserPointer( @@ -2202,6 +2223,14 @@ gckCOMMAND_Commit( )); #endif +#if gcdSECURITY + /* Submit command buffer to trust zone. */ + gckKERNEL_SecurityExecute( + Command->kernel, + commandBufferLogical + offset, + commandBufferSize - offset - 8 + ); +#else /* Generate a LINK from the previous WAIT/LINK command sequence to the entry determined above (either the context or the command buffer). This LINK replaces the WAIT instruction from the previous WAIT/LINK @@ -2214,6 +2243,7 @@ gckCOMMAND_Commit( entryBytes, &Command->waitSize )); +#endif #if gcdNONPAGED_MEMORY_CACHEABLE /* Flush the cache for the link. */ diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c index 68471b9cb632..7186ce761671 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #if gcdENABLE_VG @@ -647,7 +646,7 @@ _RemoveRecordFromProcesDB( freeVideoMemory->node = gcmALL_TO_UINT32(nodeObject); type = gcvDB_VIDEO_MEMORY - | ((nodeObject->type & 0xFF) << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) + | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT); /* Remove record from process db. */ @@ -958,78 +957,41 @@ _HardwareToKernel( gceSTATUS status; gckVIDMEM memory; gctUINT32 offset; -#if gcdDYNAMIC_MAP_RESERVED_MEMORY gctUINT32 nodePhysical; -#endif + gctPOINTER *logical; + gctSIZE_T bytes; status = gcvSTATUS_OK; - /**************************** Video Memory ********************************/ - if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + memory = Node->VidMem.memory; + + if (memory->object.type == gcvOBJ_VIDMEM) { - /* Assume a non-virtual node and get the pool manager object. */ - memory = Node->VidMem.memory; - -#if gcdDYNAMIC_MAP_RESERVED_MEMORY nodePhysical = memory->baseAddress - + Node->VidMem.offset + + (gctUINT32)Node->VidMem.offset + Node->VidMem.alignment; - - if (Node->VidMem.kernelVirtual == gcvNULL) - { - status = gckOS_MapPhysical(Os, - nodePhysical, - Node->VidMem.bytes, - (gctPOINTER *)&Node->VidMem.kernelVirtual); - - if (gcmkIS_ERROR(status)) - { - return status; - } - } - - offset = Address - nodePhysical; - *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset); -#else - /* Determine the header offset within the pool it is allocated in. */ - offset = Address - memory->baseAddress; - - /* Translate the offset into the kernel side pointer. */ - status = gckOS_GetKernelLogicalEx( - Os, - gcvCORE_VG, - offset, - KernelPointer - ); -#endif + bytes = Node->VidMem.bytes; + logical = &Node->VidMem.kernelVirtual; } - /*************************** Virtual Memory *******************************/ else { - status = gckOS_GetPhysicalAddress(Os, - Node->Virtual.logical, - &nodePhysical); - + nodePhysical = Node->Virtual.physicalAddress; + bytes = Node->Virtual.bytes; + logical = &Node->Virtual.kernelVirtual; + } + + if (*logical == gcvNULL) + { + status = gckOS_MapPhysical(Os, nodePhysical, bytes, logical); + if (gcmkIS_ERROR(status)) { return status; } + } - if (Node->Virtual.kernelVirtual== gcvNULL) - { - status = gckOS_MapPhysical(Os, - nodePhysical, - Node->Virtual.bytes, - (gctPOINTER *)&Node->Virtual.kernelVirtual); - - if (gcmkIS_ERROR(status)) - { - return status; - } - } + offset = Address - nodePhysical; + *KernelPointer = (gctPOINTER)((gctUINT8_PTR)(*logical) + offset); - offset = Address - nodePhysical; - *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->Virtual.kernelVirtual + offset); - } /* Return status. */ return status; } @@ -1113,7 +1075,7 @@ _AllocateLinear( do { - gctINT32 i; + gctINT32 i; gctPOINTER pointer = gcvNULL; gcuVIDMEM_NODE_PTR node = gcvNULL; @@ -1152,7 +1114,7 @@ _AllocateLinear( * Node = node; * Address = address; * Logical = node->Virtual.logical; - + gcmkPRINT("Allocate success\n"); /* Success. */ return gcvSTATUS_OK; } @@ -3587,10 +3549,10 @@ gckVGCOMMAND_Commit( break; } - gcmkERR_BREAK(_FlushMMU(Command)); - do { + gcmkERR_BREAK(_FlushMMU(Command)); + /* Assign a context ID if not yet assigned. */ if (Context->id == 0) { 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 382f78c80feb..fd00b0c96fd3 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #define _GC_OBJ_ZONE gcvZONE_DATABASE @@ -1432,6 +1431,16 @@ gckKERNEL_DestroyProcessDB( break; #endif + case gcvDB_SHBUF: + /* Free shared buffer. */ + status = gckKERNEL_DestroyShBuffer(Kernel, + (gctSHBUF) record->data); + + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, + "DB: SHBUF %u (status=%d)", + (gctUINT32)(gctUINTPTR_T) record->data, status); + break; + default: gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE, "DB: Correcupted record=0x%08x type=%d", @@ -1779,10 +1788,10 @@ gckKERNEL_DumpVidMemUsage( IN gctINT32 ProcessID ) { - gctUINT32 i = 0; gceSTATUS status; gcsDATABASE_PTR database; gcsDATABASE_COUNTERS * counter; + gctUINT32 i = 0; static gctCONST_STRING surfaceTypes[] = { "UNKNOWN", 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 c6d690efa4c1..780d7e318ccb 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #include 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 7adadb36efa0..e7b157cda5a6 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #include "gc_hal_kernel_buffer.h" @@ -619,7 +618,7 @@ OnError: #if gcdINTERRUPT_STATISTIC if (eventObj->interruptCount) { - gcmkVERIFY_OK(gckOS_AtomDestroy(os, &eventObj->interruptCount)); + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->interruptCount)); } #endif gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj)); @@ -738,7 +737,7 @@ gckEVENT_Destroy( #endif #if gcdINTERRUPT_STATISTIC - gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, &Event->interruptCount)); + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->interruptCount)); #endif /* Mark the gckEVENT object as unknown. */ @@ -1236,7 +1235,6 @@ gckEVENT_AddList( break; } - /* Release the mutex. */ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex)); @@ -1694,9 +1692,12 @@ gckEVENT_Submit( #endif #if gcdINTERRUPT_STATISTIC - gctUINT32 oldValue; + gctINT32 oldValue; #endif +#if gcdSECURITY + gctPOINTER reservedBuffer; +#endif gctUINT32 flushBytes; gctUINT32 executeBytes; @@ -1811,6 +1812,9 @@ gckEVENT_Submit( /* Reserve space in the command queue. */ gcmkONERROR(gckCOMMAND_Reserve(command, bytes, &buffer, &bytes)); +#if gcdSECURITY + reservedBuffer = buffer; +#endif #if gcdMULTI_GPU gcmkONERROR(gckHARDWARE_ChipEnable( @@ -1855,8 +1859,16 @@ gckEVENT_Submit( )); #endif +#if gcdSECURITY + gckKERNEL_SecurityExecute( + Event->kernel, + reservedBuffer, + executeBytes + ); +#else /* Execute the hardware event. */ gcmkONERROR(gckCOMMAND_Execute(command, executeBytes)); +#endif #endif } @@ -2274,7 +2286,7 @@ gckEVENT_Interrupt( #if gcdINTERRUPT_STATISTIC { gctINT j = 0; - gctUINT32 oldValue; + gctINT32 oldValue; for (j = 0; j < gcmCOUNTOF(Event->queues); j++) { @@ -3413,7 +3425,8 @@ gckEVENT_Dump( gcsEVENT_PTR record = gcvNULL; gctINT i; #if gcdINTERRUPT_STATISTIC - gctUINT32 pendingInterrupt; + gctINT32 pendingInterrupt; + gctUINT32 intrAcknowledge; #endif gcmkHEADER_ARG("Event=0x%x", Event); @@ -3422,7 +3435,6 @@ gckEVENT_Dump( gcmkPRINT("*** EVENT STATE DUMP ***\n"); gcmkPRINT("**************************\n"); - gcmkPRINT(" Unsumbitted Event:"); while(queueHead) { @@ -3463,6 +3475,18 @@ gckEVENT_Dump( #if gcdINTERRUPT_STATISTIC gckOS_AtomGet(Event->os, Event->interruptCount, &pendingInterrupt); gcmkPRINT(" Number of Pending Interrupt: %d", pendingInterrupt); + + if (Event->kernel->recovery == 0) + { + gckOS_ReadRegisterEx( + Event->os, + Event->kernel->core, + 0x10, + &intrAcknowledge + ); + + gcmkPRINT(" INTR_ACKNOWLEDGE=0x%x", intrAcknowledge); + } #endif gcmkFOOTER_NO(); diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c index 4c25f395bddd..be0a60eb6da9 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c @@ -19,7 +19,6 @@ *****************************************************************************/ - /** ** @file ** gckHEAP object for kernel HAL layer. The heap implemented here is an arena- diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c index b2088fccda95..5716223b9807 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #if gcdENABLE_VG 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 8721c0b70976..fa9b9ada93d1 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #define _GC_OBJ_ZONE gcvZONE_MMU @@ -47,7 +46,6 @@ gceMMU_TYPE; # define gcdMMU_CLEAR_VALUE 0x00000ABC #endif -/*VIV: Start GPU address for gcvSURF_VERTEX. */ #define gcdVERTEX_START (128 << 10) typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR; diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c index 3909edda4b56..58c33b1b301d 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #if gcdENABLE_VG diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c index 1062f87c8997..b060310a435b 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #define _GC_OBJ_ZONE gcvZONE_POWER diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h index d5e0242fdfb9..9ea3d53626b4 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_precomp_h_ #define __gc_hal_kernel_precomp_h_ diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c index f9caa17e32d8..54e5ce39f44c 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" @@ -27,3 +26,214 @@ #define _GC_OBJ_ZONE gcvZONE_KERNEL +#if gcdSECURITY + +/* +** Open a security service channel. +*/ +gceSTATUS +gckKERNEL_SecurityOpen( + IN gckKERNEL Kernel, + IN gctUINT32 GPU, + OUT gctUINT32 *Channel + ) +{ + gceSTATUS status; + + gcmkONERROR(gckOS_OpenSecurityChannel(Kernel->os, Kernel->core, Channel)); + gcmkONERROR(gckOS_InitSecurityChannel(*Channel)); + + return gcvSTATUS_OK; + +OnError: + return status; +} + +/* +** Close a security service channel +*/ +gceSTATUS +gckKERNEL_SecurityClose( + IN gctUINT32 Channel + ) +{ + return gcvSTATUS_OK; +} + +/* +** Security service interface. +*/ +gceSTATUS +gckKERNEL_SecurityCallService( + IN gctUINT32 Channel, + IN OUT gcsTA_INTERFACE * Interface +) +{ + gceSTATUS status; + gcmkHEADER(); + + gcmkVERIFY_ARGUMENT(Interface != gcvNULL); + + gckOS_CallSecurityService(Channel, Interface); + + status = Interface->result; + + gcmkONERROR(status); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_SecurityStartCommand( + IN gckKERNEL Kernel + ) +{ + gceSTATUS status; + gcsTA_INTERFACE iface; + + gcmkHEADER(); + + iface.command = KERNEL_START_COMMAND; + iface.u.StartCommand.gpu = Kernel->core; + + gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface)); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_SecurityAllocateSecurityMemory( + IN gckKERNEL Kernel, + IN gctUINT32 Bytes, + OUT gctUINT32 * Handle + ) +{ + gceSTATUS status; + gcsTA_INTERFACE iface; + + gcmkHEADER(); + + iface.command = KERNEL_ALLOCATE_SECRUE_MEMORY; + iface.u.AllocateSecurityMemory.bytes = Bytes; + + gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface)); + + *Handle = iface.u.AllocateSecurityMemory.memory_handle; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_SecurityExecute( + IN gckKERNEL Kernel, + IN gctPOINTER Buffer, + IN gctUINT32 Bytes + ) +{ + gceSTATUS status; + gcsTA_INTERFACE iface; + + gcmkHEADER(); + + iface.command = KERNEL_EXECUTE; + iface.u.Execute.command_buffer = (gctUINT32 *)Buffer; + iface.u.Execute.gpu = Kernel->core; + iface.u.Execute.command_buffer_length = Bytes; + +#if defined(LINUX) + gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os, Buffer, + (gctUINT32 *)&iface.u.Execute.command_buffer)); +#endif + + gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface)); + + /* Update queue tail pointer. */ + gcmkONERROR(gckHARDWARE_UpdateQueueTail( + Kernel->hardware, 0, 0 + )); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_SecurityMapMemory( + IN gckKERNEL Kernel, + IN gctUINT32 *PhysicalArray, + IN gctUINT32 PageCount, + OUT gctUINT32 * GPUAddress + ) +{ + gceSTATUS status; + gcsTA_INTERFACE iface; + + gcmkHEADER(); + + iface.command = KERNEL_MAP_MEMORY; + +#if defined(LINUX) + gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os, PhysicalArray, + (gctUINT32 *)&iface.u.MapMemory.physicals)); +#endif + + iface.u.MapMemory.pageCount = PageCount; + + gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface)); + + *GPUAddress = iface.u.MapMemory.gpuAddress; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_SecurityUnmapMemory( + IN gckKERNEL Kernel, + IN gctUINT32 GPUAddress, + IN gctUINT32 PageCount + ) +{ + gceSTATUS status; + gcsTA_INTERFACE iface; + + gcmkHEADER(); + + iface.command = KERNEL_UNMAP_MEMORY; + + iface.u.UnmapMemory.gpuAddress = GPUAddress; + iface.u.UnmapMemory.pageCount = PageCount; + + gcmkONERROR(gckKERNEL_SecurityCallService(Kernel->securityChannel, &iface)); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +#endif diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c index 9377d2d825dd..c5494e02df1e 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #if gcdENABLE_VG @@ -377,6 +376,7 @@ gceSTATUS gckVGKERNEL_Dispatch( kernelInterface->u.AllocateLinearVideoMemory.bytes, kernelInterface->u.AllocateLinearVideoMemory.alignment, kernelInterface->u.AllocateLinearVideoMemory.type, + kernelInterface->u.AllocateLinearVideoMemory.flag, &kernelInterface->u.AllocateLinearVideoMemory.node )); @@ -545,6 +545,96 @@ gceSTATUS gckVGKERNEL_Dispatch( Interface->u.NameVideoMemory.handle, &Interface->u.NameVideoMemory.name)); break; + + case gcvHAL_DATABASE: + gcmkONERROR(gckKERNEL_QueryDatabase(Kernel, processID, Interface)); + break; + case gcvHAL_SHBUF: + { + gctSHBUF shBuf; + gctPOINTER uData; + gctUINT32 bytes; + + switch (Interface->u.ShBuf.command) + { + case gcvSHBUF_CREATE: + bytes = Interface->u.ShBuf.bytes; + + /* Create. */ + gcmkONERROR(gckKERNEL_CreateShBuffer(Kernel, bytes, &shBuf)); + + Interface->u.ShBuf.id = gcmPTR_TO_UINT64(shBuf); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, + gcvDB_SHBUF, + shBuf, + gcvNULL, + 0)); + break; + + case gcvSHBUF_DESTROY: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + + /* Check db first to avoid illegal destroy in the process. */ + gcmkONERROR( + gckKERNEL_RemoveProcessDB(Kernel, + processID, + gcvDB_SHBUF, + shBuf)); + + gcmkONERROR(gckKERNEL_DestroyShBuffer(Kernel, shBuf)); + break; + + case gcvSHBUF_MAP: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + + /* Map for current process access. */ + gcmkONERROR(gckKERNEL_MapShBuffer(Kernel, shBuf)); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, + gcvDB_SHBUF, + shBuf, + gcvNULL, + 0)); + break; + + case gcvSHBUF_WRITE: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data); + bytes = Interface->u.ShBuf.bytes; + + /* Write. */ + gcmkONERROR( + gckKERNEL_WriteShBuffer(Kernel, shBuf, uData, bytes)); + break; + + case gcvSHBUF_READ: + shBuf = gcmUINT64_TO_PTR(Interface->u.ShBuf.id); + uData = gcmUINT64_TO_PTR(Interface->u.ShBuf.data); + bytes = Interface->u.ShBuf.bytes; + + /* Read. */ + gcmkONERROR( + gckKERNEL_ReadShBuffer(Kernel, + shBuf, + uData, + bytes, + &bytes)); + + /* Return copied size. */ + Interface->u.ShBuf.bytes = bytes; + break; + + default: + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + break; + } + } + break; default: /* Invalid command. */ status = gcvSTATUS_INVALID_ARGUMENT; diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h index 70e45103fba2..8bdeb3896f22 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_vg_h_ #define __gc_hal_kernel_vg_h_ 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 7e81b3063e57..35e9fc21451c 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_precomp.h" #define _GC_OBJ_ZONE gcvZONE_VIDMEM @@ -242,10 +241,10 @@ gckVIDMEM_ConstructVirtual( node->Virtual.contiguous = Contiguous; node->Virtual.logical = gcvNULL; node->Virtual.cacheable = cacheable; - #if gcdENABLE_VG - node->Virtual.kernelVirtual = 0; + node->Virtual.kernelVirtual = gcvNULL; #endif + for (i = 0; i < gcdMAX_GPU_COUNT; i++) { node->Virtual.lockeds[i] = 0; @@ -484,7 +483,7 @@ gckVIDMEM_Construct( node->VidMem.logical = gcvNULL; #endif -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG node->VidMem.kernelVirtual = gcvNULL; #endif @@ -997,7 +996,7 @@ gckVIDMEM_AllocateLinear( /* Adjust the number of free bytes. */ Memory->freeBytes -= node->VidMem.bytes; -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG node->VidMem.kernelVirtual = gcvNULL; #endif @@ -1101,7 +1100,7 @@ gckVIDMEM_Free( ) #endif { -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG if (Node->VidMem.kernelVirtual) { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, @@ -1443,13 +1442,18 @@ _DestroyGPUMap( ** ** gctUINT32 * Address ** Pointer to a variable that will hold the hardware specific address. +** +** gctUINT32 * PhysicalAddress +** Pointer to a variable that will hold the bus address of a contiguous +** video node. */ gceSTATUS gckVIDMEM_Lock( IN gckKERNEL Kernel, IN gcuVIDMEM_NODE_PTR Node, IN gctBOOL Cacheable, - OUT gctUINT32 * Address + OUT gctUINT32 * Address, + OUT gctUINT64 * PhysicalAddress ) { gceSTATUS status; @@ -1460,6 +1464,7 @@ gckVIDMEM_Lock( gctBOOL needMapping = gcvFALSE; #endif gctUINT32 baseAddress; + gctUINT32 physicalAddress; gcmkHEADER_ARG("Node=0x%x", Node); @@ -1499,6 +1504,8 @@ gckVIDMEM_Lock( + offset + Node->VidMem.alignment; + physicalAddress = *Address; + /* Get hardware specific address. */ #if gcdENABLE_VG if (Kernel->vg == gcvNULL) @@ -1513,6 +1520,12 @@ gckVIDMEM_Lock( } } + gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical( + Kernel->os, + *Address, + Address + )); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Locked node 0x%x (%d) @ 0x%08X", Node, @@ -1544,6 +1557,16 @@ gckVIDMEM_Lock( &Node->Virtual.logical, &Node->Virtual.pageCount)); + gcmkONERROR(gckOS_GetPhysicalAddress( + os, + Node->Virtual.logical, + &physicalAddress + )); + +#if gcdENABLE_VG + Node->Virtual.physicalAddress = physicalAddress; +#endif + #if !gcdPROCESS_ADDRESS_SPACE /* Increment the lock count. */ if (Node->Virtual.lockeds[Kernel->core] ++ == 0) @@ -1576,6 +1599,32 @@ gckVIDMEM_Lock( } else { +#if gcdSECURITY + gctPHYS_ADDR physicalArrayPhysical; + gctPOINTER physicalArrayLogical; + + gcmkONERROR(gckOS_AllocatePageArray( + os, + Node->Virtual.physical, + Node->Virtual.pageCount, + &physicalArrayLogical, + &physicalArrayPhysical + )); + + gcmkONERROR(gckKERNEL_SecurityMapMemory( + Kernel, + physicalArrayLogical, + Node->Virtual.pageCount, + &Node->Virtual.addresses[Kernel->core] + )); + + gcmkONERROR(gckOS_FreeNonPagedMemory( + os, + 1, + physicalArrayPhysical, + physicalArrayLogical + )); +#else #if gcdENABLE_VG if (Kernel->vg != gcvNULL) { @@ -1618,6 +1667,7 @@ gckVIDMEM_Lock( { gcmkONERROR(gckMMU_Flush(Kernel->mmu, Node->Virtual.type)); } +#endif } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Mapped virtual node 0x%x to 0x%08X", @@ -1631,6 +1681,8 @@ gckVIDMEM_Lock( } + *PhysicalAddress = (gctUINT64)physicalAddress; + /* Release the mutex. */ gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidmemMutex)); @@ -1794,6 +1846,16 @@ gckVIDMEM_Unlock( /* See if we can unlock the resources. */ if (Node->Virtual.lockeds[Kernel->core] == 0) { +#if gcdSECURITY + if (Node->Virtual.addresses[Kernel->core] > 0x80000000) + { + gcmkONERROR(gckKERNEL_SecurityUnmapMemory( + Kernel, + Node->Virtual.addresses[Kernel->core], + Node->Virtual.pageCount + )); + } +#else /* Free the page table. */ if (Node->Virtual.pageTables[Kernel->core] != gcvNULL) { @@ -1817,6 +1879,7 @@ gckVIDMEM_Unlock( Node->Virtual.pageTables[Kernel->core] = gcvNULL; Node->Virtual.lockKernels[Kernel->core] = gcvNULL; } +#endif } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, 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 83e350ee3bb7..02d00140f81e 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_h_ #define __gc_hal_h_ @@ -33,6 +32,9 @@ #include "gc_hal_statistics.h" #endif +#if gcdSECURITY +#include "gc_hal_security_interface.h" +#endif #ifdef __cplusplus extern "C" { @@ -1066,6 +1068,39 @@ gckOS_GetThreadID( OUT gctUINT32_PTR ThreadID ); +#if gcdSECURITY +gceSTATUS +gckOS_OpenSecurityChannel( + IN gckOS Os, + IN gceCORE Core, + OUT gctUINT32 *Channel + ); + +gceSTATUS +gckOS_CloseSecurityChannel( + IN gctUINT32 Channel + ); + +gceSTATUS +gckOS_CallSecurityService( + IN gctUINT32 Channel, + IN gcsTA_INTERFACE * Interface + ); + +gceSTATUS +gckOS_InitSecurityChannel( + OUT gctUINT32 Channel + ); + +gceSTATUS +gckOS_AllocatePageArray( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T PageCount, + OUT gctPOINTER * PageArrayLogical, + OUT gctPHYS_ADDR * PageArrayPhysical + ); +#endif /******************************************************************************\ ********************************** Signal Object ********************************* @@ -1280,6 +1315,20 @@ gckOS_CacheInvalidate( gctSIZE_T Bytes ); +gceSTATUS +gckOS_CPUPhysicalToGPUPhysical( + IN gckOS Os, + IN gctUINT32 CPUPhysical, + IN gctUINT32_PTR GPUPhysical + ); + +gceSTATUS +gckOS_GPUPhysicalToCPUPhysical( + IN gckOS Os, + IN gctUINT32 GPUPhysical, + IN gctUINT32_PTR CPUPhysical + ); + /******************************************************************************\ ** Debug Support */ @@ -1334,6 +1383,9 @@ typedef enum _gceBROADCAST /* AXI bus error. */ gcvBROADCAST_AXI_BUS_ERROR, + + /* Out of memory. */ + gcvBROADCAST_OUT_OF_MEMORY, } gceBROADCAST; @@ -1607,7 +1659,8 @@ gckVIDMEM_Lock( IN gckKERNEL Kernel, IN gcuVIDMEM_NODE_PTR Node, IN gctBOOL Cacheable, - OUT gctUINT32 * Address + OUT gctUINT32 * Address, + OUT gctUINT64 * PhysicalAddress ); /* Unlock memory. */ @@ -1695,6 +1748,14 @@ gckKERNEL_Dispatch( IN OUT struct _gcsHAL_INTERFACE * Interface ); +/* Query Database requirements. */ +gceSTATUS + gckKERNEL_QueryDatabase( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN OUT gcsHAL_INTERFACE * Interface + ); + /* Query the video memory. */ gceSTATUS gckKERNEL_QueryVideoMemory( @@ -1718,6 +1779,7 @@ gckKERNEL_AllocateLinearMemory( IN gctSIZE_T Bytes, IN gctUINT32 Alignment, IN gceSURF_TYPE Type, + IN gctUINT32 Flag, OUT gctUINT32 * Node ); @@ -2186,6 +2248,12 @@ gckHARDWARE_GetFscaleValue( IN gctUINT * MinFscaleValue, IN gctUINT * MaxFscaleValue ); + +gceSTATUS +gckHARDWARE_SetMinFscaleValue( + IN gckHARDWARE Hardware, + IN gctUINT MinFscaleValue + ); #endif #if gcdPOWEROFF_TIMEOUT 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 ffeac7e40b44..58857221c531 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 @@ -43,6 +43,7 @@ typedef struct gcsATOM * gcsATOM_PTR; #ifndef VIVANTE_NO_3D typedef struct _gco3D * gco3D; typedef struct _gcoCL * gcoCL; +typedef struct _gcsFAST_FLUSH * gcsFAST_FLUSH_PTR; #endif typedef struct _gcoSURF * gcoSURF; @@ -149,6 +150,7 @@ typedef enum _gcePATCH_ID gcePATCH_GLOFTKRHM, gcvPATCH_OCLCTS, gcvPATCH_A8HP, + gcvPATCH_A8CN, gcvPATCH_WISTONESG, gcvPATCH_SPEEDRACE, gcvPATCH_FSBHAWAIIF, @@ -160,6 +162,11 @@ typedef enum _gcePATCH_ID gcvPATCH_RIPTIDEGP2, gcvPATCH_OESCTS, gcvPATCH_GANGSTAR, + gcvPATCH_WHRKYZIXOVAN, + gcvPATCH_NAMESGAS, + gcvPATCH_AFTERBURNER, + gcvPATCH_UIMARK, + gcvPATCH_FM_OES_PLAYER, gcvPATCH_COUNT } gcePATCH_ID; @@ -619,7 +626,6 @@ gcoHAL_IsFeatureAvailable( IN gceFEATURE Feature ); - gceSTATUS gcoHAL_IsSwwaNeeded( IN gcoHAL Hal, @@ -688,6 +694,25 @@ gcoHAL_ScheduleUnmapMemory( IN gctPOINTER Logical ); +/* Allocate video memory. */ +gceSTATUS +gcoOS_AllocateVideoMemory( + IN gcoOS Os, + IN gctBOOL InUserSpace, + IN gctBOOL InCacheable, + IN OUT gctSIZE_T * Bytes, + OUT gctUINT32 * Physical, + OUT gctPOINTER * Logical, + OUT gctPOINTER * Handle + ); + +/* Free video memory. */ +gceSTATUS +gcoOS_FreeVideoMemory( + IN gcoOS Os, + IN gctPOINTER Handle + ); + /* Map user memory. */ gceSTATUS gcoHAL_MapUserMemory( @@ -905,6 +930,47 @@ gcoHAL_QueryChipFeature( IN gceFEATURE Feature); #endif + +/*----------------------------------------------------------------------------*/ +/*----- Shared Buffer --------------------------------------------------------*/ + +/* Create shared buffer. */ +gceSTATUS +gcoHAL_CreateShBuffer( + IN gctUINT32 Size, + OUT gctSHBUF * ShBuf + ); + +/* Destroy shared buffer. */ +gceSTATUS +gcoHAL_DestroyShBuffer( + IN gctSHBUF ShBuf + ); + +/* Map shared buffer to current process. */ +gceSTATUS +gcoHAL_MapShBuffer( + IN gctSHBUF ShBuf + ); + +/* Write user data to shared buffer. */ +gceSTATUS +gcoHAL_WriteShBuffer( + IN gctSHBUF ShBuf, + IN gctCONST_POINTER Data, + IN gctUINT32 ByteCount + ); + +/* Read user data from shared buffer. */ +gceSTATUS +gcoHAL_ReadShBuffer( + IN gctSHBUF ShBuf, + IN gctPOINTER Data, + IN gctUINT32 BytesCount, + OUT gctUINT32 * BytesRead + ); + + /******************************************************************************\ ********************************** gcoOS Object ********************************* \******************************************************************************/ @@ -1040,36 +1106,6 @@ gcoOS_FreeContiguous( IN gctSIZE_T Bytes ); -/* Allocate video memory. */ -gceSTATUS -gcoOS_AllocateVideoMemory( - IN gcoOS Os, - IN gctBOOL InUserSpace, - IN gctBOOL InCacheable, - IN OUT gctSIZE_T * Bytes, - OUT gctUINT32 * Physical, - OUT gctPOINTER * Logical, - OUT gctPOINTER * Handle - ); - -/* Free video memory. */ -gceSTATUS -gcoOS_FreeVideoMemory( - IN gcoOS Os, - IN gctPOINTER Handle - ); - - -#if gcdENABLE_BUFFER_ALIGNMENT -gceSTATUS -gcoSURF_GetBankOffsetBytes( - IN gcoSURF Surfce, - IN gceSURF_TYPE Type, - IN gctUINT32 Stride, - IN gctUINT32_PTR Bytes - ); -#endif - /* Map user memory. */ gceSTATUS gcoOS_MapUserMemory( @@ -1787,6 +1823,11 @@ gcoOS_MemoryBarrier( IN gctPOINTER Logical ); +gceSTATUS +gcoOS_CPUPhysicalToGPUPhysical( + IN gctUINT32 CPUPhysical, + OUT gctUINT32_PTR GPUPhysical + ); /*----------------------------------------------------------------------------*/ /*----- Profile --------------------------------------------------------------*/ @@ -2262,20 +2303,6 @@ gcoSURF_SetRotation( IN gceSURF_ROTATION Rotation ); -/* Set surface pre-rotation angle. */ -gceSTATUS -gcoSURF_SetPreRotation( - IN gcoSURF Surface, - IN gceSURF_ROTATION Rotation - ); - -/* Get pre-rotation angle. */ -gceSTATUS -gcoSURF_GetPreRotation( - IN gcoSURF Surface, - IN gceSURF_ROTATION *Rotation - ); - gceSTATUS gcoSURF_IsValid( IN gcoSURF Surface @@ -2307,6 +2334,13 @@ gcoSURF_DisableTileStatus( IN gcoSURF Surface, IN gctBOOL Decompress ); + +/* Flush tile status cache for the specified surface. */ +gceSTATUS +gcoSURF_FlushTileStatus( + IN gcoSURF Surface, + IN gctBOOL Decompress + ); #endif /* VIVANTE_NO_3D */ /* Get surface size. */ @@ -2606,6 +2640,47 @@ gcoSURF_ResetSurWH( IN gceSURF_FORMAT fmt ); +/* Update surface timestamp. */ +gceSTATUS +gcoSURF_UpdateTimeStamp( + IN gcoSURF Surface + ); + +/* Query surface current timestamp. */ +gceSTATUS +gcoSURF_QueryTimeStamp( + IN gcoSURF Surface, + OUT gctUINT64 * TimeStamp + ); + +/* + * Allocate shared buffer for this surface, so that + * surface states can be shared across processes. + */ +gceSTATUS +gcoSURF_AllocShBuffer( + IN gcoSURF Surface, + OUT gctSHBUF * ShBuf + ); + +/* Bind shared buffer to this surface */ +gceSTATUS +gcoSURF_BindShBuffer( + IN gcoSURF Surface, + IN gctSHBUF ShBuf + ); + +/* Push surface shared states to shared buffer. */ +gceSTATUS +gcoSURF_PushSharedInfo( + IN gcoSURF Surface + ); + +/* Pop shared states from shared buffer. */ +gceSTATUS +gcoSURF_PopSharedInfo( + IN gcoSURF Surface + ); /******************************************************************************\ ********************************* gcoDUMP Object ******************************** @@ -4703,7 +4778,7 @@ struct _gcoOS_SymbolsList #define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \ { \ gcmONERROR(gcoBUFFER_Reserve( \ - Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \ + Hardware->buffer, ReserveSize, gcvTRUE, gcvCOMMAND_3D, &CommandBuffer \ )); \ \ Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \ @@ -4765,7 +4840,7 @@ struct _gcoOS_SymbolsList *Memory++ = __temp_data32__; \ \ gcoHARDWARE_UpdateDelta( \ - StateDelta, FixedPoint, Address, 0, __temp_data32__ \ + StateDelta, Address, 0, __temp_data32__ \ ); \ \ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ @@ -4785,7 +4860,7 @@ struct _gcoOS_SymbolsList *Memory++ = __temp_data32__; \ \ gcoHARDWARE_UpdateDelta( \ - StateDelta, FixedPoint, Address, Mask, __temp_data32__ \ + StateDelta, Address, Mask, __temp_data32__ \ ); \ \ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ @@ -4967,7 +5042,7 @@ struct _gcoOS_SymbolsList *Memory++ = __temp_data32__; \ \ gcoHARDWARE_UpdateDelta( \ - StateDelta, FixedPoint, Address, 0, __temp_data32__ \ + StateDelta, Address, 0, __temp_data32__ \ ); \ \ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ @@ -4985,7 +5060,7 @@ struct _gcoOS_SymbolsList *Memory++ = __temp_data32__; \ \ gcoHARDWARE_UpdateDelta( \ - StateDelta, FixedPoint, Address, Mask, __temp_data32__ \ + StateDelta, Address, Mask, __temp_data32__ \ ); \ \ gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ @@ -5071,6 +5146,144 @@ struct _gcoOS_SymbolsList \ } +#define gcmSETSTATEDATA_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + +#define gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + +#define gcmSETSINGLESTATE_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATA_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data); \ + gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \ +} + +#define gcmSETSINGLESTATEWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data); \ + gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \ +} + +#define gcmSETSTATEDATA_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ + \ + gcmSAFECASTSIZET(__temp_data32__, Data); \ + \ + *Memory++ = __temp_data32__; \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + +#define gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + +#define gcmSETSINGLESTATE_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATA_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data); \ + gcmENDSTATEBATCH(CommandBuffer, Memory); \ +} + +#define gcmSETSINGLESTATEWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data); \ + gcmENDSTATEBATCH(CommandBuffer, Memory); \ +} + +#define gcmDEFINESTATEBUFFER_NEW_FAST(CommandBuffer, Memory) \ + gcmDEFINESECUREUSER() \ + gcmDEFINELOADSTATEBASE() \ + gcsTEMPCMDBUF CommandBuffer = gcvNULL; \ + gctUINT32_PTR Memory; + +#define gcmDEFINESTATEBUFFER_FAST(CommandBuffer, Memory, ReserveSize) \ + gcmDEFINESECUREUSER() \ + gctSIZE_T ReserveSize; \ + gcoCMDBUF CommandBuffer; \ + gctUINT32_PTR Memory; + +#define gcmBEGINSTATEBUFFER_FAST(Hardware, CommandBuffer, Memory, ReserveSize) \ +{ \ + gcmONERROR(gcoBUFFER_Reserve( \ + Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \ + )); \ + \ + Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \ + \ + gcmBEGINSECUREUSER(); \ +} + +#define gcmBEGINSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \ +{ \ + if (OutSide) \ + {\ + Memory = (gctUINT32_PTR)*OutSide; \ + }\ + else \ + {\ + gcmONERROR(gcoBUFFER_StartTEMPCMDBUF( \ + Hardware->buffer, &CommandBuffer \ + ));\ + \ + Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \ + \ + }\ + \ + gcmBEGINSECUREUSER(); \ + gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\ +} /******************************************************************************* ** ** gcmCONFIGUREUNIFORMS 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 9cc9626e3b06..78bd8d277d34 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 @@ -180,6 +180,10 @@ typedef enum _gceHAL_COMMAND_CODES /* Destory MMU. */ gcvHAL_DESTROY_MMU, + + /* Shared buffer. */ + gcvHAL_SHBUF, + } gceHAL_COMMAND_CODES; @@ -400,6 +404,9 @@ typedef struct _gcsHAL_INTERFACE /* Type of allocation. */ IN gceSURF_TYPE type; + /* Flag of allocation. */ + IN gctUINT32 flag; + /* Memory pool to allocate from. */ IN OUT gcePOOL pool; @@ -467,6 +474,9 @@ typedef struct _gcsHAL_INTERFACE /* Mapped logical address. */ OUT gctUINT64 memory; + + /* Bus address of a contiguous video node. */ + OUT gctUINT64 physicalAddress; } LockVideoMemory; @@ -1075,6 +1085,22 @@ typedef struct _gcsHAL_INTERFACE IN gctUINT64 mmu; } DestroyMmu; + + struct _gcsHAL_SHBUF + { + gceSHBUF_COMMAND_CODES command; + + /* Shared buffer. */ + IN OUT gctUINT64 id; + + /* User data to be shared. */ + IN gctUINT64 data; + + /* Data size. */ + IN OUT gctUINT32 bytes; + } + ShBuf; + } u; } diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h index 7a7e8b5f4caf..d4e4b3eb67c7 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_driver_vg_h_ #define __gc_hal_driver_vg_h_ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h index 4b5a628c64e9..3f5dfac53012 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_dump_h_ #define __gc_hal_dump_h_ 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 87dc707854cf..690c957a8c66 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 @@ -111,7 +111,7 @@ typedef struct _gcsWL_EGL_WINDOW_INFO struct wl_egl_window { - gcsWL_EGL_DISPLAY *display; + gcsWL_EGL_DISPLAY* display; gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS]; gcsWL_EGL_WINDOW_INFO info; gctUINT current; @@ -661,3 +661,4 @@ gcoOS_DrawSurface( #endif #endif /* __gc_hal_eglplatform_h_ */ + diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h index aac4bdffdf63..10da3af527de 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_eglplatform_type_h_ #define __gc_hal_eglplatform_type_h_ 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 cc9fef78ad83..0934e02d9d67 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_engine_h_ #define __gc_hal_engine_h_ @@ -1275,6 +1274,13 @@ gco3D_DrawIndexedPrimitivesOffset( IN gctSIZE_T PrimitiveCount ); +/* Draw a element from pattern */ +gceSTATUS +gco3D_DrawPattern( + IN gco3D Engine, + IN gcsFAST_FLUSH_PTR FastFlushInfo + ); + /* Enable or disable anti-aliasing. */ gceSTATUS gco3D_SetAntiAlias( diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h index f081ea9598df..950bbc799b68 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_engine_vg_h_ #define __gc_hal_engine_vg_h_ @@ -796,6 +795,8 @@ gcoVG_DrawPath( IN gctFLOAT Scale, IN gctFLOAT Bias, #if gcdMOVG + IN gctUINT32 Width, + IN gctUINT32 Height, IN gctFLOAT *Bounds, #endif IN gctBOOL SoftwareTesselation 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 9c2bce6462b0..1de132150fd4 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_enum_h_ #define __gc_hal_enum_h_ @@ -340,6 +339,8 @@ typedef enum _gceSURF_TYPE gcvSURF_CREATE_AS_TEXTURE = 0x4000, /* create it as a texture */ + gcvSURF_PROTECTED_CONTENT = 0x8000, /* create it as content protected */ + gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE | gcvSURF_LINEAR, @@ -427,6 +428,8 @@ typedef enum _gceSURF_FLAG gcvSURF_FLAG_CONTENT_UPDATED = 0x2, /* content is y inverted */ gcvSURF_FLAG_CONTENT_YINVERTED = 0x4, + /* content is protected */ + gcvSURF_FLAG_CONTENT_PROTECTED = 0x8, } gceSURF_FLAG; @@ -1197,6 +1200,17 @@ typedef enum _gceSYNC_POINT_COMMAND_CODES } gceSYNC_POINT_COMMAND_CODES; +/* Shared buffer command codes. */ +typedef enum _gceSHBUF_COMMAND_CODES +{ + gcvSHBUF_CREATE, + gcvSHBUF_DESTROY, + gcvSHBUF_MAP, + gcvSHBUF_WRITE, + gcvSHBUF_READ, +} +gceSHBUF_COMMAND_CODES; + /* Event locations. */ typedef enum _gceKERNEL_WHERE { @@ -1471,11 +1485,20 @@ typedef enum _gceHAL_ARG_VERSION gceHAL_ARG_VERSION; +#define gcvALLOC_FLAG_NONE (0) +#define gcvALLOC_FLAG_CONTIGUOUS (1 << 0) +#define gcvALLOC_FLAG_CACHEABLE (1 << 1) +#define gcvALLOC_FLAG_SECURITY (1 << 2) + /* GL_VIV internal usage */ #ifndef GL_MAP_BUFFER_OBJ_VIV #define GL_MAP_BUFFER_OBJ_VIV 0x10000 #endif +/* Command buffer usage. */ +#define gcvCOMMAND_2D (1 << 0) +#define gcvCOMMAND_3D (1 << 1) + /******************************************************************************\ ****************************** Object Declarations ***************************** \******************************************************************************/ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h index e6454ec7412e..84283421f1dd 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_buffer_h_ #define __gc_hal_kernel_buffer_h_ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h index c4de7ca53f02..6258527d9a2d 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h @@ -19,7 +19,6 @@ *****************************************************************************/ - /* ** Include file for the local memory management. */ 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 bf2b8173efa8..a40ec70c910f 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 @@ -478,7 +478,6 @@ # define gcdPOWER_SUSPEND_WHEN_IDLE 1 #endif - #ifndef gcdFPGA_BUILD # define gcdFPGA_BUILD 0 #endif @@ -550,7 +549,7 @@ gcdENABLE_BANK_ALIGNMENT When enabled, video memory is allocated bank aligned. The vendor can modify - _GetSurfaceBankAlignment() and gcoSURF_GetBankOffsetBytes() to define how + _GetSurfaceBankAlignment() and _GetBankOffsetBytes() to define how different types of allocations are bank and channel aligned. When disabled (default), no bank alignment is done. */ @@ -652,22 +651,11 @@ #endif /* - gcdDYNAMIC_MAP_RESERVED_MEMORY - - When gcvPOOL_SYSTEM is constructed from RESERVED memory, - driver can map the whole reserved memory to kernel space - at the beginning, or just map a piece of memory when need - to access. - - Notice: - - It's only for the 2D openVG. For other cores, there is - _NO_ need to map reserved memory to kernel. - - It's meaningless when memory is allocated by - gckOS_AllocateContiguous, in that case, memory is always - mapped by system when allocated. + gcdDISABLE_CORES_2D3D + disable the 2D3D cores for 2D openVG */ -#ifndef gcdDYNAMIC_MAP_RESERVED_MEMORY -# define gcdDYNAMIC_MAP_RESERVED_MEMORY 1 +#ifndef gcdDISABLE_CORES_2D3D +# define gcdDISABLE_CORES_2D3D 0 #endif /* @@ -970,6 +958,16 @@ # define gcdENABLE_RENDER_INTO_WINDOW 1 #endif +/* + gcdENABLE_RENDER_INTO_WINDOW_WITH_FC + + Enable Direct-rendering (ie, No-Resolve) with tile status. + This is expremental and in development stage. +*/ +#ifndef gcdENABLE_RENDER_INTO_WINDOW_WITH_FC +# define gcdENABLE_RENDER_INTO_WINDOW_WITH_FC 0 +#endif + /* gcdENABLE_BLIT_BUFFER_PRESERVE @@ -979,7 +977,7 @@ to current buffer. */ #ifndef gcdENABLE_BLIT_BUFFER_PRESERVE -# define gcdENABLE_BLIT_BUFFER_PRESERVE 0 +# define gcdENABLE_BLIT_BUFFER_PRESERVE 1 #endif /* @@ -1003,20 +1001,25 @@ # define gcdANDROID_NATIVE_FENCE_SYNC 0 #endif - /* - gcdPRE_ROTATION + gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC - Enable pre-rotation for client side to avoid rotation when composition. - Android only for now. + Enable implicit android native buffer sync. + + For non-HW_RENDER buffer, CPU (or other hardware) and GPU can access + the buffer at the same time. This is to add implicit synchronization + between CPU (or the hardware) and GPU. - 0: disabled. - 1: pre-rotation by Vertex Shader. - 2: pre-rotation by Pixel Engine (need hardware support). - 3: pre-rotation by 3DBlit hardware (need hardware support). + Eventually, please do not use implicit native buffer sync, but use + "fence sync" or "android native fence sync" instead in libgui, which + can be enabled in frameworks/native/libs/gui/Android.mk. This kind + of synchronization should be done by app but not driver itself. + + Please disable this option when either "fence sync" or + "android native fence sync" is enabled. */ -#ifndef gcdPRE_ROTATION -# define gcdPRE_ROTATION 0 +#ifndef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC +# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 1 #endif /* @@ -1108,6 +1111,11 @@ # undef gcdENABLE_TS_DOUBLE_BUFFER # define gcdENABLE_TS_DOUBLE_BUFFER 0 # endif +#else +#if gcdMOVG +# undef gcdENABLE_TS_DOUBLE_BUFFER +# define gcdENABLE_TS_DOUBLE_BUFFER 0 +#endif #endif /* gcdINTERRUPT_STATISTIC @@ -1116,8 +1124,12 @@ */ #ifndef gcdINTERRUPT_STATISTIC +#if defined(LINUX) +# define gcdINTERRUPT_STATISTIC 1 +#else # define gcdINTERRUPT_STATISTIC 0 #endif +#endif /* gcdYINVERTED_RENDERING @@ -1160,13 +1172,7 @@ Expremental, under test. */ #ifndef gcdPARTIAL_FAST_CLEAR -# define gcdPARTIAL_FAST_CLEAR 0 -#endif - -/* Force disable bank alignment when partial fast clear enabled. */ -#if gcdPARTIAL_FAST_CLEAR -# undef gcdENABLE_BANK_ALIGNMENT -# define gcdENABLE_BANK_ALIGNMENT 0 +# define gcdPARTIAL_FAST_CLEAR 1 #endif /* @@ -1178,7 +1184,21 @@ # define gcdREMOVE_SURF_ORIENTATION 0 #endif +/* + gcdPATTERN_FAST_PATH + For pattern match +*/ +#ifndef gcdPATTERN_FAST_PATH +# define gcdPATTERN_FAST_PATH 1 +#endif +/* + gcdUSE_INPUT_DEVICE + disable input devices usage under fb mode to support fb+vdk multi-process +*/ +#ifndef gcdUSE_INPUT_DEVICE +# define gcdUSE_INPUT_DEVICE 1 +#endif #define LINUX_CMA_FSL 1 #define DYNAMIC_MEMORY_RECORD 1 diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h index 73cd53929ec7..d3428ee0e743 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_profiler_h_ #define __gc_hal_profiler_h_ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h index 2998016cc0df..8462385d3384 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_raster_h_ #define __gc_hal_raster_h_ @@ -222,6 +221,19 @@ gcoSURF_SetDither( IN gcoSURF Surface, IN gctBOOL Dither ); + +gceSTATUS +gcoSURF_Set2DSource( + gcoSURF Surface, + gceSURF_ROTATION Rotation + ); + +gceSTATUS +gcoSURF_Set2DTarget( + gcoSURF Surface, + gceSURF_ROTATION Rotation + ); + /******************************************************************************\ ********************************** gco2D Object ********************************* \******************************************************************************/ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h index 8244b4ecd1c1..745a1044c0d2 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_rename_h_ #define __gc_hal_rename_h_ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h new file mode 100644 index 000000000000..cb86d767c60a --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h @@ -0,0 +1,137 @@ +/**************************************************************************** +* +* 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. +* +*****************************************************************************/ + + +#ifndef _GC_HAL_SECURITY_INTERFACE_H_ +#define _GC_HAL_SECURITY_INTERFACE_H_ +/*! + @brief Command codes between kernel module and TrustZone + @discussion + Critical services must be done in TrustZone to avoid sensitive content leak. Most of kernel module is kept in non-Secure os to minimize + code in TrustZone. + */ +typedef enum kernel_packet_command { + KERNEL_START_COMMAND, + KERNEL_SUBMIT, + KERNEL_MAP_MEMORY, /* */ + KERNEL_UNMAP_MEMORY, + KERNEL_ALLOCATE_SECRUE_MEMORY, /*! Security memory management. */ + KERNEL_FREE_SECURE_MEMORY, + KERNEL_EXECUTE, /* Execute a command buffer. */ +} kernel_packet_command_t; + +/*! + @brief gckCOMMAND Object requests TrustZone to start FE. + @discussion + DMA enabled register can only be written in TrustZone to avoid GPU from jumping to a hacked code. + Kernel module need use these command to ask TrustZone start command parser. + */ +struct kernel_start_command { + kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */ + gctUINT8 gpu; /*! Which GPU. */ +}; + +/*! + @brief gckCOMMAND Object requests TrustZone to submit command buffer. + @discussion + Code in trustzone will check content of command buffer after copying command buffer to TrustZone. + */ +struct kernel_submit { + kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */ + gctUINT8 gpu; /*! Which GPU. */ + gctUINT8 kernel_command; /*! Whether it is a kernel command. */ + gctUINT32 command_buffer_handle; /*! Handle to command buffer. */ + gctUINT32 offset; /* Offset in command buffer. */ + gctUINT32 * command_buffer; /*! Content of command buffer need to be submit. */ + gctUINT32 command_buffer_length; /*! Length of command buffer. */ +}; + + +/*! + @brief gckVIDMEM Object requests TrustZone to allocate security memory. + @discussion + Allocate a buffer from security GPU memory. + */ +struct kernel_allocate_security_memory { + kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */ + gctUINT32 bytes; /*! Requested bytes. */ + gctUINT32 memory_handle; /*! Handle of allocated memory. */ +}; + +/*! + @brief gckVIDMEM Object requests TrustZone to allocate security memory. + @discussion + Free a video memory buffer from security GPU memory. + */ +struct kernel_free_security_memory { + kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */ + gctUINT32 memory_handle; /*! Handle of allocated memory. */ +}; + +struct kernel_execute { + kernel_packet_command_t command; /*! The command (always needs to be the first entry in a structure). */ + gctUINT8 gpu; /*! Which GPU. */ + gctUINT8 kernel_command; /*! Whether it is a kernel command. */ + gctUINT32 * command_buffer; /*! Content of command buffer need to be submit. */ + gctUINT32 command_buffer_length; /*! Length of command buffer. */ +}; + +typedef struct kernel_map_scatter_gather { + gctUINT32 bytes; + gctUINT32 physical; + struct kernel_map_scatter_gather *next; +} +kernel_map_scatter_gather_t; + +struct kernel_map_memory { + kernel_packet_command_t command; + kernel_map_scatter_gather_t *scatter; + gctUINT32 *physicals; + gctUINT32 pageCount; + gctUINT32 gpuAddress; +}; + +struct kernel_unmap_memory { + gctUINT32 gpuAddress; + gctUINT32 pageCount; +}; + +typedef struct _gcsTA_INTERFACE { + kernel_packet_command_t command; + union { + struct kernel_submit Submit; + struct kernel_start_command StartCommand; + struct kernel_allocate_security_memory AllocateSecurityMemory; + struct kernel_execute Execute; + struct kernel_map_memory MapMemory; + struct kernel_unmap_memory UnmapMemory; + } u; + gceSTATUS result; +} gcsTA_INTERFACE; + +enum { + gcvTA_COMMAND_INIT, + gcvTA_COMMAND_DISPATCH, + + gcvTA_CALLBACK_ALLOC_SECURE_MEM, + gcvTA_CALLBACK_FREE_SECURE_MEM, +}; + +#endif diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h index ea0063d659c0..07b8e725f29a 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_statistics_h_ #define __gc_hal_statistics_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 fa9a125eaf15..4fa42ef0c5b0 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_types_h_ #define __gc_hal_types_h_ @@ -216,6 +215,7 @@ typedef void * gctSIGNAL; typedef void * gctWINDOW; typedef void * gctIMAGE; typedef void * gctSYNC_POINT; +typedef void * gctSHBUF; typedef void * gctSEMAPHORE; 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 93c11ef35b3e..c21b41d5fa07 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_version_h_ #define __gc_hal_version_h_ @@ -29,9 +28,9 @@ #define gcvVERSION_PATCH 11 -#define gcvVERSION_BUILD 17486 +#define gcvVERSION_BUILD 19959 -#define gcvVERSION_STRING "5.0.11.17486" +#define gcvVERSION_STRING "5.0.11.p1.19959" #define gcvVERSION_DATE __DATE__ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h index c6044de8aefe..11b84995d3f7 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_vg_h_ #define __gc_hal_vg_h_ @@ -368,21 +367,6 @@ gckKERNEL_QueryCommandBuffer( OUT gcsCOMMAND_BUFFER_INFO_PTR Information ); -#if gcdDYNAMIC_MAP_RESERVED_MEMORY -gceSTATUS -gckOS_MapReservedMemoryToKernel( - IN gckOS Os, - IN gctUINT32 Physical, - IN gctINT Bytes, - IN OUT gctPOINTER *Virtual - ); - -gceSTATUS -gckOS_UnmapReservedMemoryFromKernel( - IN gctPOINTER Virtual - ); -#endif - /******************************************************************************\ ******************************* gckVGHARDWARE Object ****************************** \******************************************************************************/ diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c index e5bfeaa8ea7a..9a29e73ca485 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_linux.h" #include "gc_hal_kernel_allocator.h" #include @@ -30,6 +29,7 @@ #include #include "gc_hal_kernel_allocator_array.h" +#include "gc_hal_kernel_platform.h" #define _GC_OBJ_ZONE gcvZONE_OS @@ -394,6 +394,8 @@ _DefaultMapUser( unsigned long start; unsigned long pfn; gctINT i; + gckOS os = Allocator->os; + gcsPLATFORM * platform = os->device->platform; PLINUX_MDL mdl = Mdl; PLINUX_MDL_MAP mdlMap = MdlMap; @@ -465,6 +467,11 @@ _DefaultMapUser( + if (platform && platform->ops->adjustProt) + { + platform->ops->adjustProt(mdlMap->vma); + } + addr = mdl->addr; /* Now map all the vmalloc pages to this user address. */ @@ -557,14 +564,7 @@ _DefaultMapKernel( OUT gctPOINTER *Logical ) { - if (Mdl->contiguous && Mdl->addr) - { - /*for the memory allocated from DMA, there is no contiguousPages, - but the kernel virtual address is already got*/ - *Logical = Mdl->addr; - } - else - *Logical = _CreateKernelVirtualMapping(Mdl); + *Logical = _CreateKernelVirtualMapping(Mdl); return gcvSTATUS_OK; } @@ -575,8 +575,7 @@ _DefaultUnmapKernel( IN gctPOINTER Logical ) { - if (!Mdl->addr) - _DestoryKernelVirtualMapping(Logical); + _DestoryKernelVirtualMapping(Logical); return gcvSTATUS_OK; } diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h index b81e4e7e6e76..f0bf974fe47c 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h @@ -19,19 +19,11 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_allocator_h_ #define __gc_hal_kernel_allocator_h_ #include -#define gcvALLOC_FLAG_CONTIGUOUS (1 << 0) -#define gcvALLOC_FLAG_CACHEABLE (1 << 1) - -/* -* Defines -*/ - typedef struct _gcsALLOCATOR * gckALLOCATOR; typedef struct _gcsALLOCATOR_OPERATIONS diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator_array.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator_array.h index 2e3259ffdf22..0cd5579b9c5d 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator_array.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator_array.h @@ -19,7 +19,6 @@ *****************************************************************************/ - extern gceSTATUS _DefaultAlloctorInit( IN gckOS Os, diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h index 69fec425b5a0..ef341d2625f2 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_debug_h_ #define __gc_hal_kernel_debug_h_ 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 665710129d60..c0d617144e14 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifdef MODULE #include #endif diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h index 1e18188f11d5..dbe4e8404c3c 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #include #ifndef __gc_hal_kernel_debugfs_h_ 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 671578d07588..b063c7565d66 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 @@ -19,16 +19,11 @@ *****************************************************************************/ - #include "gc_hal_kernel_linux.h" #include #include #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) -#include -#endif -#include #define _GC_OBJ_ZONE gcvZONE_DEVICE @@ -565,7 +560,6 @@ gckGALDEVICE_Construct( IN gctUINT32 PhysSize, IN gctINT Signal, IN gctUINT LogFileSize, - IN struct device *pdev, IN gctINT PowerManagement, IN gctINT GpuProfiler, IN gcsDEVICE_CONSTRUCT_ARGS * Args, @@ -612,6 +606,11 @@ gckGALDEVICE_Construct( PhysBaseAddr, PhysSize, Signal); #endif +#if gcdDISABLE_CORES_2D3D + IrqLine = -1; + IrqLine2D = -1; +#endif + /* Allocate device structure. */ device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN); @@ -624,6 +623,8 @@ gckGALDEVICE_Construct( device->dbgNode = gcvNULL; + device->platform = Args->platform; + if (gckDEBUGFS_CreateNode( device, LogFileSize, PARENT_FILE,DEBUG_FILE, &(device->dbgNode))) { @@ -639,89 +640,6 @@ gckGALDEVICE_Construct( gckDEBUGFS_SetCurrentNode(device->dbgNode); } -#ifdef CONFIG_PM - /*Init runtime pm for gpu*/ - pm_runtime_enable(pdev); - device->pmdev = pdev; -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - /*get gpu regulator*/ - device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu"); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - device->gpu_regulator = devm_regulator_get(pdev, "pu"); -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - if (IS_ERR(device->gpu_regulator)) { - gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): Failed to get gpu regulator %s/%s \n", - __FUNCTION__, __LINE__, - PARENT_FILE, DEBUG_FILE); - gcmkONERROR(gcvSTATUS_NOT_FOUND); - } -#endif -#endif - /*Initialize the clock structure*/ - if (IrqLine != -1) { - device->clk_3d_core = clk_get(pdev, "gpu3d_clk"); - if (!IS_ERR(device->clk_3d_core)) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - if (cpu_is_mx6q()) { - device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk"); - if (IS_ERR(device->clk_3d_shader)) { - IrqLine = -1; - clk_put(device->clk_3d_core); - device->clk_3d_core = NULL; - device->clk_3d_shader = NULL; - gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n"); - } - } -#else - device->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk"); - device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk"); - if (IS_ERR(device->clk_3d_shader)) { - IrqLine = -1; - clk_put(device->clk_3d_core); - device->clk_3d_core = NULL; - device->clk_3d_shader = NULL; - gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n"); - } -#endif - } else { - IrqLine = -1; - device->clk_3d_core = NULL; - gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n"); - } - } - if ((IrqLine2D != -1) || (IrqLineVG != -1)) { - device->clk_2d_core = clk_get(pdev, "gpu2d_clk"); - if (IS_ERR(device->clk_2d_core)) { - IrqLine2D = -1; - IrqLineVG = -1; - device->clk_2d_core = NULL; - gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n"); - } else { - if (IrqLine2D != -1) { - device->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk"); - if (IS_ERR(device->clk_2d_axi)) { - device->clk_2d_axi = NULL; - IrqLine2D = -1; - gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n"); - } - } - if (IrqLineVG != -1) { - device->clk_vg_axi = clk_get(pdev, "openvg_axi_clk"); - if (IS_ERR(device->clk_vg_axi)) { - IrqLineVG = -1; - device->clk_vg_axi = NULL; - gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n"); - } - } - } - } - - #if gcdMULTI_GPU if (IrqLine3D0 != -1) { @@ -905,6 +823,12 @@ gckGALDEVICE_Construct( device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement )); +#if gcdENABLE_FSCALE_VAL_ADJUST + gcmkONERROR(gckHARDWARE_SetMinFscaleValue( + device->kernels[gcvCORE_MAJOR]->hardware, Args->gpu3DMinClock + )); +#endif + gcmkONERROR(gckHARDWARE_SetGpuProfiler( device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler )); @@ -958,6 +882,12 @@ gckGALDEVICE_Construct( device->kernels[gcvCORE_OCL]->hardware, FastClear, Compression )); +#if gcdENABLE_FSCALE_VAL_ADJUST + gcmkONERROR(gckHARDWARE_SetMinFscaleValue( + device->kernels[gcvCORE_OCL]->hardware, Args->gpu3DMinClock + )); +#endif + gcmkONERROR(gckHARDWARE_SetPowerManagement( device->kernels[gcvCORE_OCL]->hardware, PowerManagement )); @@ -1025,6 +955,12 @@ gckGALDEVICE_Construct( device->kernels[gcvCORE_2D]->hardware, PowerManagement )); +#if gcdENABLE_FSCALE_VAL_ADJUST + gcmkONERROR(gckHARDWARE_SetMinFscaleValue( + device->kernels[gcvCORE_2D]->hardware, 1 + )); +#endif + gcmkVERIFY_OK(gckKERNEL_SetRecovery( device->kernels[gcvCORE_2D], Args->recovery, Args->stuckDump )); @@ -1320,45 +1256,27 @@ gckGALDEVICE_Construct( } else { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) - mem_region = request_mem_region( - ContiguousBase, ContiguousSize, "galcore managed memory" - ); - - if (mem_region == gcvNULL) + if (Args->contiguousRequested == gcvFALSE) { - gcmkTRACE_ZONE( - gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): Failed to claim %ld bytes @ 0x%08X\n", - __FUNCTION__, __LINE__, - ContiguousSize, ContiguousBase + mem_region = request_mem_region( + ContiguousBase, ContiguousSize, "galcore managed memory" ); - gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); - } -#endif - - device->requestedContiguousBase = ContiguousBase; - device->requestedContiguousSize = ContiguousSize; - -#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG - if (gcmIS_CORE_PRESENT(device, gcvCORE_VG)) - { - device->contiguousBase -#if gcdPAGED_MEMORY_CACHEABLE - = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize); -#else - = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize); -#endif - if (device->contiguousBase == gcvNULL) + if (mem_region == gcvNULL) { - device->contiguousVidMem = gcvNULL; - device->contiguousSize = 0; + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Failed to claim %ld bytes @ 0x%08X\n", + __FUNCTION__, __LINE__, + ContiguousSize, ContiguousBase + ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } } -#endif + + device->requestedContiguousBase = ContiguousBase; + device->requestedContiguousSize = ContiguousSize; device->contiguousPhysical = gcvNULL; device->contiguousPhysicalName = 0; @@ -1498,17 +1416,7 @@ gckGALDEVICE_Destroy( if (Device->contiguousBase != gcvNULL) { - if (Device->contiguousMapped) - { -#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG - if (Device->contiguousBase) - { - /* Unmap the contiguous memory. */ - iounmap(Device->contiguousBase); - } -#endif - } - else + if (Device->contiguousMapped == gcvFALSE) { gcmkONERROR(_FreeMemory( Device, @@ -1521,7 +1429,7 @@ gckGALDEVICE_Destroy( Device->contiguousPhysical = gcvNULL; } - if (Device->requestedContiguousBase != 0) + if ((Device->contiguousRequested == gcvFALSE) && (Device->requestedContiguousBase != 0)) { release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize); Device->requestedContiguousBase = 0; @@ -1588,46 +1496,6 @@ gckGALDEVICE_Destroy( } } - /*Disable clock*/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - if (Device->clk_3d_axi) { - clk_put(Device->clk_3d_axi); - Device->clk_3d_axi = NULL; - } -#endif - if (Device->clk_3d_core) { - clk_put(Device->clk_3d_core); - Device->clk_3d_core = NULL; - } - if (Device->clk_3d_shader) { - clk_put(Device->clk_3d_shader); - Device->clk_3d_shader = NULL; - } - if (Device->clk_2d_core) { - clk_put(Device->clk_2d_core); - Device->clk_2d_core = NULL; - } - if (Device->clk_2d_axi) { - clk_put(Device->clk_2d_axi); - Device->clk_2d_axi = NULL; - } - if (Device->clk_vg_axi) { - clk_put(Device->clk_vg_axi); - Device->clk_vg_axi = NULL; - } - -#ifdef CONFIG_PM - if(Device->pmdev) - pm_runtime_disable(Device->pmdev); -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - if (Device->gpu_regulator) { - regulator_put(Device->gpu_regulator); - Device->gpu_regulator = NULL; - } -#endif - /* Destroy the gckOS object. */ if (Device->os != gcvNULL) { 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 70ac2db84039..2a7bf0d2b5bd 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_device_h_ #define __gc_hal_kernel_device_h_ @@ -27,21 +26,14 @@ ******************************* gckGALDEVICE Structure ******************************* \******************************************************************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) -struct contiguous_mem_pool { - struct dma_attrs attrs; - dma_addr_t phys; - void *virt; - size_t size; -}; -#endif - typedef struct _gckGALDEVICE { /* Objects. */ gckOS os; gckKERNEL kernels[gcdMAX_GPU_COUNT]; + gcsPLATFORM* platform; + /* Attributes. */ gctSIZE_T internalSize; gctPHYS_ADDR internalPhysical; @@ -77,6 +69,7 @@ typedef struct _gckGALDEVICE gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT]; gctUINT32 requestedContiguousBase; gctSIZE_T requestedContiguousSize; + gctUINT32 contiguousRequested; /* IRQ management. */ #if gcdMULTI_GPU @@ -111,25 +104,6 @@ typedef struct _gckGALDEVICE /* Device Debug File System Entry in kernel. */ struct _gcsDEBUGFS_Node * dbgNode; - /* Clock management.*/ - struct clk *clk_3d_core; - struct clk *clk_3d_shader; - struct clk *clk_3d_axi; - struct clk *clk_2d_core; - struct clk *clk_2d_axi; - struct clk *clk_vg_axi; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - /*Power management.*/ - struct regulator *gpu_regulator; -#endif - /*Run time pm*/ - struct device *pmdev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - struct contiguous_mem_pool *pool; - struct reset_control *rstc[gcdMAX_GPU_COUNT]; -#endif - #if DYNAMIC_MEMORY_RECORD gctSIZE_T cachedsize; gctSIZE_T nonpagedmemorysize; @@ -158,6 +132,10 @@ typedef struct _gcsDEVICE_CONSTRUCT_ARGS { gctBOOL recovery; gctUINT stuckDump; + gctUINT gpu3DMinClock; + + gctBOOL contiguousRequested; + gcsPLATFORM* platform; } gcsDEVICE_CONSTRUCT_ARGS; @@ -229,7 +207,6 @@ gceSTATUS gckGALDEVICE_Construct( IN gctUINT32 PhysSize, IN gctINT Signal, IN gctUINT LogFileSize, - IN struct device *pdev, IN gctINT PowerManagement, IN gctINT GpuProfiler, IN gcsDEVICE_CONSTRUCT_ARGS * Args, diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c index 2e7fd157d609..344f05827a86 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_linux.h" #define _GC_OBJ_ZONE gcvZONE_KERNEL @@ -265,6 +264,7 @@ gckKERNEL_MapVideoMemoryEx( gctUINT32 base = 0; gceSTATUS status; gctPOINTER logical = gcvNULL; + gctUINT32 baseAddress; gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x", Kernel, InUserSpace, Address); @@ -334,16 +334,23 @@ gckKERNEL_MapVideoMemoryEx( else #endif { - gctUINT32 baseAddress = 0; + gctUINT32 systemBaseAddress = 0; if (Kernel->hardware->mmuVersion == 0) { - gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress)); + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &systemBaseAddress)); } + gcmkVERIFY_OK( + gckOS_CPUPhysicalToGPUPhysical( + Kernel->os, + device->contiguousVidMem->baseAddress - systemBaseAddress, + &baseAddress + )); + gcmkVERIFY_OK( gckHARDWARE_SplitMemory(Kernel->hardware, - device->contiguousVidMem->baseAddress - baseAddress, + baseAddress, &pool, &base)); } 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 37141eac8a1a..88fbf7da5f2c 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_linux_h_ #define __gc_hal_kernel_linux_h_ @@ -47,7 +46,6 @@ #include #if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) -#include #include #endif @@ -55,10 +53,12 @@ #include "gc_hal.h" #include "gc_hal_driver.h" #include "gc_hal_kernel.h" +#include "gc_hal_kernel_platform.h" #include "gc_hal_kernel_device.h" #include "gc_hal_kernel_os.h" #include "gc_hal_kernel_debugfs.h" + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) #define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) @@ -105,7 +105,7 @@ #define gcdNOWARN 0 #endif -#define gcdUSE_NON_PAGED_MEMORY_CACHE 10 +#define gcdUSE_NON_PAGED_MEMORY_CACHE 0 /******************************************************************************\ ********************************** Structures ********************************** @@ -213,6 +213,15 @@ struct _gckOS atomic_t allocateCount; struct list_head allocatorList; + + /* Lock for register access check. */ + struct mutex registerAccessLocks[gcdMAX_GPU_COUNT]; + + /* External power states. */ + gctBOOL powerStates[gcdMAX_GPU_COUNT]; + + /* External clock states. */ + gctBOOL clockStates[gcdMAX_GPU_COUNT]; }; typedef struct _gcsSIGNAL * gcsSIGNAL_PTR; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c index 49b8da49838b..326ec2841883 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_linux.h" gctINT 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 c1df1aa302bd..bb9dd57ab1a3 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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_linux.h" #include @@ -28,22 +27,12 @@ #include #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) -#include -#endif #include #include #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23) #include #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) -#include -static inline void imx_gpc_power_up_pu(bool flag) {} -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) -#include -#endif #include -#include #if gcdANDROID_NATIVE_FENCE_SYNC #include @@ -54,16 +43,6 @@ static inline void imx_gpc_power_up_pu(bool flag) {} #include "gc_hal_kernel_allocator.h" -/******************************************************************************* -***** Version Signature *******************************************************/ - -#ifdef ANDROID -const char * _PLATFORM = "\n\0$PLATFORM$Android$\n"; -#else -const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n"; -#endif - - #define MEMORY_LOCK(os) \ gcmkVERIFY_OK(gckOS_AcquireMutex( \ (os), \ @@ -744,6 +723,73 @@ OnError: #endif #endif +gctBOOL +_AllowAccess( + IN gckOS Os, + IN gceCORE Core, + IN gctUINT32 Address + ) +{ + gctUINT32 data; + + /* Check external clock state. */ + if (Os->clockStates[Core] == gcvFALSE) + { + gcmkPRINT("[galcore]: %s(%d) External clock off", __FUNCTION__, __LINE__); + return gcvFALSE; + } + + /* Check internal clock state. */ + if (Address == 0) + { + return gcvTRUE; + } + +#if gcdMULTI_GPU + if (Core == gcvCORE_MAJOR) + { + data = readl((gctUINT8 *)Os->device->registerBases[gcvCORE_3D_0_ID] + 0x0); + } + else +#endif + { + data = readl((gctUINT8 *)Os->device->registerBases[Core] + 0x0); + } + + if ((data & 0x3) == 0x3) + { + gcmkPRINT("[galcore]: %s(%d) Internal clock off", __FUNCTION__, __LINE__); + return gcvFALSE; + } + + return gcvTRUE; +} + +static gceSTATUS +_ShrinkMemory( + IN gckOS Os + ) +{ + gcsPLATFORM * platform; + + gcmkHEADER_ARG("Os=0x%X", Os); + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + + platform = Os->device->platform; + + if (platform && platform->ops->shrinkMemory) + { + platform->ops->shrinkMemory(platform); + } + else + { + gcmkFOOTER_NO(); + return gcvSTATUS_NOT_SUPPORTED; + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} /******************************************************************************* ** @@ -769,6 +815,7 @@ gckOS_Construct( { gckOS os; gceSTATUS status; + gctINT i; gcmkHEADER_ARG("Context=0x%X", Context); @@ -863,6 +910,11 @@ gckOS_Construct( SetPageReserved(os->paddingPage); } + for (i = 0; i < gcdMAX_GPU_COUNT; i++) + { + mutex_init(&os->registerAccessLocks[i]); + } + gckOS_ImportAllocators(os); /* Return pointer to the gckOS object. */ @@ -2128,7 +2180,9 @@ gckOS_AllocateNonPagedMemory( gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } #else +#if !gcdSECURITY mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot); +#endif mdlMap->vma->vm_flags |= gcdVM_FLAGS; mdlMap->vma->vm_pgoff = 0; @@ -2156,7 +2210,11 @@ gckOS_AllocateNonPagedMemory( } else { +#if gcdSECURITY + *Logical = (gctPOINTER)mdl->kaddr; +#else *Logical = (gctPOINTER)mdl->addr; +#endif } /* @@ -2389,6 +2447,13 @@ gckOS_ReadRegisterEx( #endif gcmkVERIFY_ARGUMENT(Data != gcvNULL); + if (!in_interrupt()) + { + mutex_lock(&Os->registerAccessLocks[Core]); + } + + BUG_ON(!_AllowAccess(Os, Core, Address)); + #if gcdMULTI_GPU if (Core == gcvCORE_MAJOR) { @@ -2400,6 +2465,11 @@ gckOS_ReadRegisterEx( *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address); } + if (!in_interrupt()) + { + mutex_unlock(&Os->registerAccessLocks[Core]); + } + /* Success. */ gcmkFOOTER_ARG("*Data=0x%08x", *Data); return gcvSTATUS_OK; @@ -2475,6 +2545,13 @@ gckOS_WriteRegisterEx( gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]); #endif + if (!in_interrupt()) + { + mutex_lock(&Os->registerAccessLocks[Core]); + } + + BUG_ON(!_AllowAccess(Os, Core, Address)); + #if gcdMULTI_GPU if (Core == gcvCORE_MAJOR) { @@ -2489,6 +2566,11 @@ gckOS_WriteRegisterEx( writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address); } + if (!in_interrupt()) + { + mutex_unlock(&Os->registerAccessLocks[Core]); + } + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -2598,6 +2680,8 @@ gckOS_GetPhysicalAddress( gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address)); } + gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, *Address, Address)); + /* Success. */ gcmkFOOTER_ARG("*Address=0x%08x", *Address); return gcvSTATUS_OK; @@ -2735,7 +2819,11 @@ _ConvertLogical2Physical( PLINUX_MDL_MAP map; gcsUSER_MAPPING_PTR userMap; +#if gcdSECURITY + base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->kaddr; +#else base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->addr; +#endif /* Check for the logical address match. */ if ((base != gcvNULL) @@ -2989,60 +3077,81 @@ gckOS_MapPhysical( break; } } - else if(mdl->u.contiguousPages) - { - /*allocation from paged memory*/ - gctUINT32 phys= page_to_phys(mdl->u.contiguousPages); - if ((physical >= phys ) - && (physical < phys + mdl->numPages * PAGE_SIZE) - ) - { - /*allocation from paged memory*/ - if(!mdl->addr) - mdl->addr = _CreateKernelVirtualMapping(mdl); - *Logical = mdl->addr + (physical -phys); - break; - } - } mdl = mdl->next; } + MEMORY_UNLOCK(Os); + if (mdl == gcvNULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - struct contiguous_mem_pool *pool = Os->device->pool; + struct page * page = pfn_to_page(physical >> PAGE_SHIFT); - if (Physical >= pool->phys && Physical < pool->phys + pool->size) - logical = (gctPOINTER)(Physical - pool->phys + pool->virt); - else - logical = gcvNULL; -#else - /* Map memory as cached memory. */ - request_mem_region(physical, Bytes, "MapRegion"); - logical = (gctPOINTER) ioremap_nocache(physical, Bytes); -#endif + if (pfn_valid(page_to_pfn(page))) + { + gctUINT32 offset = physical & ~PAGE_MASK; + struct page ** pages; + gctUINT numPages; + gctINT i; + + numPages = GetPageCount(PAGE_ALIGN(offset + Bytes), 0); + + pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN); + + if (!pages) + { + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; + } + + for (i = 0; i < numPages; i++) + { + pages[i] = nth_page(page, i); + } + + logical = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL)); + + kfree(pages); - if (logical == gcvNULL) + if (logical == gcvNULL) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): Failed to vmap", + __FUNCTION__, __LINE__ + ); + + /* Out of resources. */ + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES); + return gcvSTATUS_OUT_OF_RESOURCES; + } + + logical += offset; + } + else { - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): Failed to map physical address 0x%08x", - __FUNCTION__, __LINE__, Physical - ); + /* Map memory as cached memory. */ + request_mem_region(physical, Bytes, "MapRegion"); + logical = (gctPOINTER) ioremap_nocache(physical, Bytes); - MEMORY_UNLOCK(Os); + if (logical == gcvNULL) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): Failed to ioremap", + __FUNCTION__, __LINE__ + ); - /* Out of resources. */ - gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES); - return gcvSTATUS_OUT_OF_RESOURCES; + /* Out of resources. */ + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES); + return gcvSTATUS_OUT_OF_RESOURCES; + } } /* Return pointer to mapped memory. */ *Logical = logical; } - MEMORY_UNLOCK(Os); /* Success. */ gcmkFOOTER_ARG("*Logical=0x%X", *Logical); @@ -3097,14 +3206,6 @@ gckOS_UnmapPhysical( if (Logical >= (gctPOINTER)mdl->addr && Logical < (gctPOINTER)((gctSTRING)mdl->addr + mdl->numPages * PAGE_SIZE)) { - /*allocation from paged memory*/ - if(mdl->u.contiguousPages) - { - char * addr= mdl->addr; - /*reset mdl->addr*/ - mdl->addr = gcvNULL; - _DestoryKernelVirtualMapping(addr); - } break; } } @@ -3112,11 +3213,10 @@ gckOS_UnmapPhysical( mdl = mdl->next; } - if (mdl == gcvNULL) { /* Unmap the memory. */ - iounmap(Logical); + vunmap((void *)((unsigned long)Logical & PAGE_MASK)); } MEMORY_UNLOCK(Os); @@ -4457,6 +4557,8 @@ gckOS_MapPagesEx( phys = page_to_phys(nth_page(mdl->u.contiguousPages, offset)); } + gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys)); + #if gcdENABLE_VG if (Core == gcvCORE_VG) { @@ -5433,6 +5535,9 @@ OnError: *Address = physical - Os->device->baseAddress; *Info = info; + gcmkVERIFY_OK( + gckOS_CPUPhysicalToGPUPhysical(Os, *Address, Address)); + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x", *Info, *Address); @@ -5476,6 +5581,51 @@ OnError: info->extraPage = 1; } +#if gcdSECURITY + { + gctPHYS_ADDR physicalArrayPhysical; + gctPOINTER physicalArrayLogical; + gctUINT32_PTR logical; + gctSIZE_T bytes = pageCount * gcmSIZEOF(gctUINT32); + pageTable = gcvNULL; + + gcmkONERROR(gckOS_AllocateNonPagedMemory( + Os, + gcvFALSE, + &bytes, + &physicalArrayPhysical, + &physicalArrayLogical + )); + + logical = physicalArrayLogical; + + /* Fill the page table. */ + for (i = 0; i < pageCount; i++) + { + gctUINT32 phys; + phys = page_to_phys(pages[i]); + + logical[i] = phys; + } + j = 0; + + + gcmkONERROR(gckKERNEL_SecurityMapMemory( + Os->device->kernels[Core], + physicalArrayLogical, + pageCount, + &address + )); + + gcmkONERROR(gckOS_FreeNonPagedMemory( + Os, + 1, + physicalArrayPhysical, + physicalArrayLogical + )); + } + +#else #if gcdENABLE_VG if (Core == gcvCORE_VG) { @@ -5517,6 +5667,9 @@ OnError: #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, @@ -5562,6 +5715,7 @@ OnError: gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu, gcvSURF_TYPE_UNKNOWN)); #endif } +#endif info->address = address; /* Save pointer to page table. */ @@ -5778,13 +5932,29 @@ OnError: MEMORY_MAP_LOCK(Os); +#if !gcdSECURITY gcmkASSERT(info->pageTable != gcvNULL); +#endif if (info->extraPage) { pageCount += 1; } +#if gcdSECURITY + if (info->address > 0x80000000) + { + gckKERNEL_SecurityUnmapMemory( + Os->device->kernels[Core], + info->address, + pageCount + ); + } + else + { + gcmkPRINT("Wrong address %s(%d) %x", __FUNCTION__, __LINE__, info->address); + } +#else #if gcdENABLE_VG if (Core == gcvCORE_VG) { @@ -5811,6 +5981,7 @@ OnError: )); #endif } +#endif if (info->extraPage) { @@ -6403,6 +6574,24 @@ gckOS_Broadcast( gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware)); gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel)); break; + + case gcvBROADCAST_OUT_OF_MEMORY: + gcmkTRACE_N(gcvLEVEL_INFO, 0, "gcvBROADCAST_OUT_OF_MEMORY\n"); + + status = _ShrinkMemory(Os); + + if (status == gcvSTATUS_NOT_SUPPORTED) + { + goto OnError; + } + + gcmkONERROR(status); + + break; + + default: + /* Skip unimplemented broadcast. */ + break; } /* Success. */ @@ -6813,177 +7002,54 @@ gckOS_SetGPUPower( IN gctBOOL Power ) { - struct clk *clk_3dcore = Os->device->clk_3d_core; - struct clk *clk_3dshader = Os->device->clk_3d_shader; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - struct clk *clk_3d_axi = Os->device->clk_3d_axi; -#endif - struct clk *clk_2dcore = Os->device->clk_2d_core; - struct clk *clk_2d_axi = Os->device->clk_2d_axi; - struct clk *clk_vg_axi = Os->device->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) - int ret; -#endif -#endif + gcsPLATFORM * platform; - gctBOOL oldClockState = gcvFALSE; - gctBOOL oldPowerState = gcvFALSE; + gctBOOL powerChange = gcvFALSE; + gctBOOL clockChange = gcvFALSE; gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power); + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + + platform = Os->device->platform; - if (Os->device->kernels[Core] != NULL) + powerChange = (Power != Os->powerStates[Core]); + + clockChange = (Clock != Os->clockStates[Core]); + + if (powerChange && (Power == gcvTRUE)) { -#if gcdENABLE_VG - if (Core == gcvCORE_VG) + if (platform && platform->ops->setPower) { - oldClockState = Os->device->kernels[Core]->vg->hardware->clockState; - oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState; + gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power)); } - else - { -#endif - oldClockState = Os->device->kernels[Core]->hardware->clockState; - oldPowerState = Os->device->kernels[Core]->hardware->powerState; -#if gcdENABLE_VG - } -#endif + + Os->powerStates[Core] = Power; } - if((Power == gcvTRUE) && (oldPowerState == gcvFALSE)) - { -#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) - if(!IS_ERR(Os->device->gpu_regulator)) { - ret = regulator_enable(Os->device->gpu_regulator); - if (ret != 0) - gckOS_Print("%s(%d): fail to enable pu regulator %d!\n", - __FUNCTION__, __LINE__, ret); - } -#else - imx_gpc_power_up_pu(true); -#endif -#endif -#ifdef CONFIG_PM - pm_runtime_get_sync(Os->device->pmdev); -#endif - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - if (Clock == gcvTRUE) { - if (oldClockState == gcvFALSE) { - switch (Core) { - case gcvCORE_MAJOR: - clk_enable(clk_3dcore); - if (cpu_is_mx6q()) - clk_enable(clk_3dshader); - break; - case gcvCORE_2D: - clk_enable(clk_2dcore); - clk_enable(clk_2d_axi); - break; - case gcvCORE_VG: - clk_enable(clk_2dcore); - clk_enable(clk_vg_axi); - break; - default: - break; - } - } - } else { - if (oldClockState == gcvTRUE) { - switch (Core) { - case gcvCORE_MAJOR: - if (cpu_is_mx6q()) - clk_disable(clk_3dshader); - clk_disable(clk_3dcore); - break; - case gcvCORE_2D: - clk_disable(clk_2dcore); - clk_disable(clk_2d_axi); - break; - case gcvCORE_VG: - clk_disable(clk_2dcore); - clk_disable(clk_vg_axi); - break; - default: - break; - } + if (clockChange) + { + mutex_lock(&Os->registerAccessLocks[Core]); + + if (platform && platform->ops->setClock) + { + gcmkVERIFY_OK(platform->ops->setClock(platform, Core, Clock)); } + + Os->clockStates[Core] = Clock; + + mutex_unlock(&Os->registerAccessLocks[Core]); } -#else - if (Clock == gcvTRUE) { - if (oldClockState == gcvFALSE) { - switch (Core) { - case gcvCORE_MAJOR: - clk_prepare(clk_3dcore); - clk_enable(clk_3dcore); - clk_prepare(clk_3dshader); - clk_enable(clk_3dshader); - clk_prepare(clk_3d_axi); - clk_enable(clk_3d_axi); - break; - case gcvCORE_2D: - clk_prepare(clk_2dcore); - clk_enable(clk_2dcore); - clk_prepare(clk_2d_axi); - clk_enable(clk_2d_axi); - break; - case gcvCORE_VG: - clk_prepare(clk_2dcore); - clk_enable(clk_2dcore); - clk_prepare(clk_vg_axi); - clk_enable(clk_vg_axi); - break; - default: - break; - } - } - } else { - if (oldClockState == gcvTRUE) { - switch (Core) { - case gcvCORE_MAJOR: - clk_disable(clk_3dshader); - clk_unprepare(clk_3dshader); - clk_disable(clk_3dcore); - clk_unprepare(clk_3dcore); - clk_disable(clk_3d_axi); - clk_unprepare(clk_3d_axi); - break; - case gcvCORE_2D: - clk_disable(clk_2dcore); - clk_unprepare(clk_2dcore); - clk_disable(clk_2d_axi); - clk_unprepare(clk_2d_axi); - break; - case gcvCORE_VG: - clk_disable(clk_2dcore); - clk_unprepare(clk_2dcore); - clk_disable(clk_vg_axi); - clk_unprepare(clk_vg_axi); - break; - default: - break; - } + + if (powerChange && (Power == gcvFALSE)) + { + if (platform && platform->ops->setPower) + { + gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power)); } + + Os->powerStates[Core] = Power; } -#endif - if((Power == gcvFALSE) && (oldPowerState == gcvTRUE)) - { -#ifdef CONFIG_PM - pm_runtime_put_sync(Os->device->pmdev); -#endif -#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) - if(!IS_ERR(Os->device->gpu_regulator)) - regulator_disable(Os->device->gpu_regulator); -#else - imx_gpc_power_up_pu(false); -#endif -#endif - } - /* TODO: Put your code here. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; } @@ -7012,41 +7078,21 @@ gckOS_ResetGPU( IN gceCORE Core ) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) -#define SRC_SCR_OFFSET 0 -#define BP_SRC_SCR_GPU3D_RST 1 -#define BP_SRC_SCR_GPU2D_RST 4 - void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR); - gctUINT32 bit_offset,val; + gceSTATUS status = gcvSTATUS_NOT_SUPPORTED; + gcsPLATFORM * platform; gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core); + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); - if(Core == gcvCORE_MAJOR) { - bit_offset = BP_SRC_SCR_GPU3D_RST; - } else if((Core == gcvCORE_VG) - ||(Core == gcvCORE_2D)) { - bit_offset = BP_SRC_SCR_GPU2D_RST; - } else { - return gcvSTATUS_INVALID_CONFIG; - } - val = __raw_readl(src_base + SRC_SCR_OFFSET); - val &= ~(1 << (bit_offset)); - val |= (1 << (bit_offset)); - __raw_writel(val, src_base + SRC_SCR_OFFSET); + platform = Os->device->platform; - while ((__raw_readl(src_base + SRC_SCR_OFFSET) & - (1 << (bit_offset))) != 0) { + if (platform && platform->ops->reset) + { + status = platform->ops->reset(platform, Core); } gcmkFOOTER_NO(); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - struct reset_control *rstc = Os->device->rstc[Core]; - if (rstc) - reset_control_reset(rstc); -#else - imx_src_reset_gpu((int)Core); -#endif - return gcvSTATUS_OK; + return status; } /******************************************************************************* @@ -8861,4 +8907,123 @@ OnError: } #endif +#if gcdSECURITY +gceSTATUS +gckOS_AllocatePageArray( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T PageCount, + OUT gctPOINTER * PageArrayLogical, + OUT gctPHYS_ADDR * PageArrayPhysical + ) +{ + gceSTATUS status = gcvSTATUS_OK; + PLINUX_MDL mdl; + gctUINT32* table; + gctUINT32 offset; + gctSIZE_T bytes; + + gcmkHEADER_ARG("Os=0x%X Physical=0x%X PageCount=%u", + Os, Physical, PageCount); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Physical != gcvNULL); + gcmkVERIFY_ARGUMENT(PageCount > 0); + + bytes = PageCount * gcmSIZEOF(gctUINT32); + gcmkONERROR(gckOS_AllocateNonPagedMemory( + Os, + gcvFALSE, + &bytes, + PageArrayPhysical, + PageArrayLogical + )); + + table = *PageArrayLogical; + + /* Convert pointer to MDL. */ + mdl = (PLINUX_MDL)Physical; + + /* Get all the physical addresses and store them in the page table. */ + + offset = 0; + PageCount = PageCount / (PAGE_SIZE / 4096); + + /* Try to get the user pages so DMA can happen. */ + while (PageCount-- > 0) + { + unsigned long phys = ~0; + + if (mdl->pagedMem && !mdl->contiguous) + { + phys = _NonContiguousToPhys(mdl->u.nonContiguousPages, offset); + } + else + { + if (!mdl->pagedMem) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): we should not get this call for Non Paged Memory!", + __FUNCTION__, __LINE__ + ); + } + + phys = page_to_phys(nth_page(mdl->u.contiguousPages, offset)); + } + + table[offset] = phys; + + offset += 1; + } + +OnError: + + /* Return the status. */ + gcmkFOOTER(); + return status; +} +#endif + +gceSTATUS +gckOS_CPUPhysicalToGPUPhysical( + IN gckOS Os, + IN gctUINT32 CPUPhysical, + IN gctUINT32_PTR GPUPhysical + ) +{ + gcsPLATFORM * platform; + gcmkHEADER_ARG("CPUPhysical=0x%X", CPUPhysical); + + platform = Os->device->platform; + + if (platform && platform->ops->getGPUPhysical) + { + gcmkVERIFY_OK( + platform->ops->getGPUPhysical(platform, CPUPhysical, GPUPhysical)); + } + else + { + *GPUPhysical = CPUPhysical; + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +gceSTATUS +gckOS_GPUPhysicalToCPUPhysical( + IN gckOS Os, + IN gctUINT32 GPUPhysical, + IN gctUINT32_PTR CPUPhysical + ) +{ + gcmkHEADER_ARG("GPUPhysical=0x%X", GPUPhysical); + + *CPUPhysical = GPUPhysical; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h index 2eb428f55d17..4bee13ab6daf 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h @@ -19,7 +19,6 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_os_h_ #define __gc_hal_kernel_os_h_ 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 new file mode 100644 index 000000000000..e2c4c8a7230a --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h @@ -0,0 +1,263 @@ +/**************************************************************************** +* +* 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. +* +*****************************************************************************/ + + +#ifndef _gc_hal_kernel_platform_h_ +#define _gc_hal_kernel_platform_h_ +#include + +typedef struct _gcsMODULE_PARAMETERS +{ +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + gctINT irqLine3D0; + gctUINT registerMemBase3D0; + gctUINT registerMemSize3D0; + gctINT irqLine3D1; + gctUINT registerMemBase3D1; + gctUINT registerMemSize3D1; +#else + gctINT irqLine; + gctUINT registerMemBase; + gctUINT registerMemSize; +#endif + gctINT irqLine2D; + gctUINT registerMemBase2D; + gctUINT registerMemSize2D; + gctINT irqLineVG; + gctUINT registerMemBaseVG; + gctUINT registerMemSizeVG; + gctUINT contiguousSize; + gctUINT contiguousBase; + gctUINT contiguousRequested; + gctUINT bankSize; + gctINT fastClear; + gctINT compression; + gctINT powerManagement; + gctINT gpuProfiler; + gctINT signal; + gctUINT baseAddress; + gctUINT physSize; + gctUINT logFileSize; + gctUINT recovery; + gctUINT stuckDump; + gctUINT showArgs; + +} +gcsMODULE_PARAMETERS; + +typedef struct _gcsPLATFORM * gckPLATFORM; + +typedef struct _gcsPLATFORM_OPERATIONS +{ + /******************************************************************************* + ** + ** needAddDevice + ** + ** Determine whether platform_device is created by initialization code. + ** If platform_device is created by BSP, return gcvFLASE here. + */ + gctBOOL + (*needAddDevice)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** adjustParam + ** + ** Override content of arguments, if a argument is not changed here, it will + ** keep as default value or value set by insmod command line. + */ + gceSTATUS + (*adjustParam)( + IN gckPLATFORM Platform, + OUT gcsMODULE_PARAMETERS *Args + ); + + /******************************************************************************* + ** + ** adjustDriver + ** + ** Override content of platform_driver which will be registered. + */ + gceSTATUS + (*adjustDriver)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** getPower + ** + ** Prepare power and clock operation. + */ + gceSTATUS + (*getPower)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** putPower + ** + ** Finish power and clock operation. + */ + gceSTATUS + (*putPower)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** allocPriv + ** + ** Construct platform private data. + */ + gceSTATUS + (*allocPriv)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** freePriv + ** + ** free platform private data. + */ + gceSTATUS + (*freePriv)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** setPower + ** + ** Set power state of specified GPU. + ** + ** INPUT: + ** + ** gceCORE GPU + ** GPU neeed to config. + ** + ** gceBOOL Enable + ** Enable or disable power. + */ + gceSTATUS + (*setPower)( + IN gckPLATFORM Platform, + IN gceCORE GPU, + IN gctBOOL Enable + ); + + /******************************************************************************* + ** + ** setPower + ** + ** Set clock state of specified GPU. + ** + ** INPUT: + ** + ** gceCORE GPU + ** GPU neeed to config. + ** + ** gceBOOL Enable + ** Enable or disable clock. + */ + gceSTATUS + (*setClock)( + IN gckPLATFORM Platform, + IN gceCORE GPU, + IN gctBOOL Enable + ); + + /******************************************************************************* + ** + ** reset + ** + ** Reset GPU outside. + ** + ** INPUT: + ** + ** gceCORE GPU + ** GPU neeed to reset. + */ + gceSTATUS + (*reset)( + IN gckPLATFORM Platform, + IN gceCORE GPU + ); + + /******************************************************************************* + ** + ** getGPUPhysical + ** + ** Convert CPU physical address to GPU physical address if they are + ** different. + */ + gceSTATUS + (*getGPUPhysical)( + IN gckPLATFORM Platform, + IN gctUINT32 CPUPhysical, + OUT gctUINT32_PTR GPUPhysical + ); + + /******************************************************************************* + ** + ** adjustProt + ** + ** Adjust Prot, it's for Cache on gc5000(0x5434) and gc3000(0x5435). + */ + gceSTATUS + (*adjustProt)( + IN struct vm_area_struct * vma + ); + + + /******************************************************************************* + ** + ** shrinkMemory + ** + ** Do something to collect memory, eg, act as oom killer. + */ + gceSTATUS + (*shrinkMemory)( + IN gckPLATFORM Platform + ); +} +gcsPLATFORM_OPERATIONS; + +typedef struct _gcsPLATFORM +{ + struct platform_device* device; + struct platform_driver* driver; + + gcsPLATFORM_OPERATIONS* ops; + + void* priv; +} +gcsPLATFORM; + +void +gckPLATFORM_QueryOperations( + IN gcsPLATFORM_OPERATIONS ** Operations + ); + +#endif diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c similarity index 74% rename from drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c rename to drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c index 1b0da4ffcbd0..db9a15a5e39e 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_probe.c @@ -19,11 +19,9 @@ *****************************************************************************/ - #include #include -#include #include "gc_hal_kernel_linux.h" #include "gc_hal_driver.h" @@ -37,67 +35,16 @@ #endif -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT -# include -# include -# include -# include -# include -# include - -struct task_struct *lowmem_deathpending; - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data); - -static struct notifier_block task_nb = { - .notifier_call = task_notify_func, -}; - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data) -{ - struct task_struct *task = data; - - if (task == lowmem_deathpending) - lowmem_deathpending = NULL; - - return NOTIFY_OK; -} -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) -#include -#else -#include -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) -#include -#else -#include -#include -#endif -#endif /* Zone used for header/footer. */ #define _GC_OBJ_ZONE gcvZONE_DRIVER -#if gcdENABLE_FSCALE_VAL_ADJUST -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) -#include -#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a); -#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a); -#else -extern int register_thermal_notifier(struct notifier_block *nb); -extern int unregister_thermal_notifier(struct notifier_block *nb); -#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a); -#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a); -#endif -#endif - MODULE_DESCRIPTION("Vivante Graphics Driver"); MODULE_LICENSE("GPL"); static struct class* gpuClass; +static gcsPLATFORM platform; + static gckGALDEVICE galDevice; static uint major = 199; @@ -150,11 +97,7 @@ module_param(registerMemBaseVG, ulong, 0644); static ulong registerMemSizeVG = 2 << 10; module_param(registerMemSizeVG, ulong, 0644); -#if gcdENABLE_FSCALE_VAL_ADJUST -static ulong contiguousSize = 128 << 20; -#else static ulong contiguousSize = 4 << 20; -#endif module_param(contiguousSize, ulong, 0644); static ulong contiguousBase = 0; @@ -199,13 +142,10 @@ MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle, static int showArgs = 0; module_param(showArgs, int, 0644); -int gpu3DMinClock = 0; +static int gpu3DMinClock = 1; module_param(gpu3DMinClock, int, 0644); -#if ENABLE_GPU_CLOCK_BY_DRIVER - unsigned long coreClock = 156000000; - module_param(coreClock, ulong, 0644); -#endif +static int contiguousRequested = 0; static int drv_open( struct inode* inode, @@ -372,7 +312,39 @@ static ssize_t show_idletime(struct device_driver *dev, char *buf) static DRIVER_ATTR(idletime, S_IRUGO | S_IWUSR, show_idletime, gcvNULL); - +void +_UpdateModuleParam( + gcsMODULE_PARAMETERS *Param + ) +{ +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY +#else + irqLine = Param->irqLine ; + registerMemBase = Param->registerMemBase; + registerMemSize = Param->registerMemSize; +#endif + irqLine2D = Param->irqLine2D ; + registerMemBase2D = Param->registerMemBase2D; + registerMemSize2D = Param->registerMemSize2D; + irqLineVG = Param->irqLineVG; + registerMemBaseVG = Param->registerMemBaseVG; + registerMemSizeVG = Param->registerMemSizeVG; + contiguousSize = Param->contiguousSize; + contiguousBase = Param->contiguousBase; + bankSize = Param->bankSize; + fastClear = Param->fastClear; + compression = Param->compression; + powerManagement = Param->powerManagement; + gpuProfiler = Param->gpuProfiler; + signal = Param->signal; + baseAddress = Param->baseAddress; + physSize = Param->physSize; + logFileSize = Param->logFileSize; + recovery = Param->recovery; + stuckDump = Param->stuckDump; + showArgs = Param->showArgs; + contiguousRequested = Param->contiguousRequested; +} void gckOS_DumpParam( @@ -423,36 +395,9 @@ gckOS_DumpParam( printk(" logFileSize = %d KB \n", logFileSize); printk(" recovery = %d\n", recovery); printk(" stuckDump = %d\n", stuckDump); -#if ENABLE_GPU_CLOCK_BY_DRIVER - printk(" coreClock = %lu\n", coreClock); -#endif printk(" gpuProfiler = %d\n", gpuProfiler); } -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT -static size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m); -static struct reserved_memory_account viv_gpu_resmem_handler = { - .name = "viv_gpu", - .get_page_used_by_process = viv_gpu_resmem_query, -}; - -size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m) -{ - gcuDATABASE_INFO info; - unsigned int processid = p->pid; - gckKERNEL gpukernel = m->data; - - /* ignore error happens in this api. */ - if (gckKERNEL_QueryProcessDB(gpukernel, processid, false, gcvDB_VIDEO_MEMORY, &info) != gcvSTATUS_OK) - return 0; - - /* we return pages. */ - if (info.counters.bytes > 0) - return info.counters.bytes / PAGE_SIZE; - return 0; -} -#endif - int drv_open( struct inode* inode, struct file* filp @@ -603,7 +548,7 @@ int drv_release( gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } - if ((!device->contiguousMapped) && galDevice->contiguousSize) + if ((!device->contiguousMapped) && device->contiguousSize) { if (data->contiguousLogical != gcvNULL) { @@ -980,7 +925,7 @@ OnError: #if !USE_PLATFORM_DRIVER static int __init drv_init(void) #else -static int drv_init(struct device *pdev) +static int drv_init(void) #endif { int ret; @@ -990,68 +935,30 @@ static int drv_init(struct device *pdev) struct class* device_class = gcvNULL; gcsDEVICE_CONSTRUCT_ARGS args = { - .recovery = recovery, - .stuckDump = stuckDump, + .recovery = recovery, + .stuckDump = stuckDump, + .gpu3DMinClock = gpu3DMinClock, + .contiguousRequested = contiguousRequested, + .platform = &platform, }; gcmkHEADER(); -#if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) - { -# if 0 - struct clk * clk; - - clk = clk_get(NULL, "GCCLK"); - - if (IS_ERR(clk)) - { - gcmkTRACE_ZONE( - gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): clk get error: %d\n", - __FUNCTION__, __LINE__, - PTR_ERR(clk) - ); - - result = -ENODEV; - gcmkONERROR(gcvSTATUS_GENERIC_IO); - } - - /* - * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently. - * Use the 2X clock. - */ - if (clk_set_rate(clk, coreClock * 2)) - { - gcmkTRACE_ZONE( - gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): Failed to set core clock.\n", - __FUNCTION__, __LINE__ - ); - - result = -EAGAIN; - gcmkONERROR(gcvSTATUS_GENERIC_IO); - } - - clk_enable(clk); - -#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) - gc_pwr(1); -# endif -#endif - } -#endif - printk(KERN_INFO "Galcore version %d.%d.%d.%d\n", gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD); + /* when enable gpu profiler, we need to turn off gpu powerMangement */ - if(gpuProfiler) + if (gpuProfiler) + { powerManagement = 0; + } + if (showArgs) { gckOS_DumpParam(); } - if(logFileSize != 0) + if (logFileSize != 0) { gckDEBUGFS_Initialize(); } @@ -1074,7 +981,6 @@ static int drv_init(struct device *pdev) contiguousBase, contiguousSize, bankSize, fastClear, compression, baseAddress, physSize, signal, logFileSize, - pdev, powerManagement, gpuProfiler, &args, @@ -1090,10 +996,6 @@ static int drv_init(struct device *pdev) goto OnError; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - device->pool = dev_get_drvdata(pdev); -#endif - /* Start the GAL device. */ gcmkONERROR(gckGALDEVICE_Start(device)); @@ -1101,12 +1003,16 @@ static int drv_init(struct device *pdev) && (device->kernels[gcvCORE_MAJOR] != gcvNULL) && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0)) { - status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize); +#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, baseAddress, physSize); + status = gckMMU_Enable(device->kernels[gcvCORE_OCL]->mmu, gpuPhysical, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU: status=%d\n", status); #endif @@ -1114,23 +1020,16 @@ static int drv_init(struct device *pdev) if ((device->kernels[gcvCORE_2D] != gcvNULL) && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0)) { - status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize); + 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; } -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT - task_free_register(&task_nb); - viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR]; - register_reserved_memory_account(&viv_gpu_resmem_handler); -#endif - - - /* Register the character device. */ ret = register_chrdev(major, DEVICE_NAME, &driver_fops); @@ -1219,17 +1118,13 @@ static void drv_exit(void) { gcmkHEADER(); -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT - task_free_unregister(&task_nb); - unregister_reserved_memory_account(&viv_gpu_resmem_handler); -#endif - gcmkASSERT(gpuClass != gcvNULL); device_destroy(gpuClass, MKDEV(major, 0)); class_destroy(gpuClass); unregister_chrdev(major, DEVICE_NAME); + galDevice->contiguousRequested = contiguousRequested; gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice)); gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice)); @@ -1238,20 +1133,6 @@ static void drv_exit(void) gckDEBUGFS_Terminate(); } -#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) - { -# if 0 - struct clk * clk = NULL; - -#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) - gc_pwr(0); -#endif - clk = clk_get(NULL, "GCCLK"); - clk_disable(clk); -# endif - } -#endif - gcmkFOOTER_NO(); } @@ -1260,34 +1141,6 @@ static void drv_exit(void) module_exit(drv_exit); #else -#if gcdENABLE_FSCALE_VAL_ADJUST -static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event, - void *dummy) -{ - static gctUINT orgFscale, minFscale, maxFscale; - static gctBOOL bAlreadyTooHot = gcvFALSE; - gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware; - - if (event && !bAlreadyTooHot) { - gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale); - gckHARDWARE_SetFscaleValue(hardware, minFscale); - bAlreadyTooHot = gcvTRUE; - gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale); - } else if (!event && bAlreadyTooHot) { - gckHARDWARE_SetFscaleValue(hardware, orgFscale); - gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale); - bAlreadyTooHot = gcvFALSE; - } - return NOTIFY_OK; -} - -static struct notifier_block thermal_hot_pm_notifier = { - .notifier_call = thermal_hot_pm_notify, - }; -#endif - - - #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) static int gpu_probe(struct platform_device *pdev) #else @@ -1295,112 +1148,63 @@ static int __devinit gpu_probe(struct platform_device *pdev) #endif { int ret = -ENODEV; - struct resource* res; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - struct contiguous_mem_pool *pool; - struct reset_control *rstc; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - struct device_node *dn =pdev->dev.of_node; - const u32 *prop; + gcsMODULE_PARAMETERS moduleParam = { +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY #else - struct viv_gpu_platform_data *pdata; + .irqLine = irqLine, + .registerMemBase = registerMemBase, + .registerMemSize = registerMemSize, #endif + .irqLine2D = irqLine2D, + .registerMemBase2D = registerMemBase2D, + .registerMemSize2D = registerMemSize2D, + .irqLineVG = irqLineVG, + .registerMemBaseVG = registerMemBaseVG, + .registerMemSizeVG = registerMemSizeVG, + .contiguousSize = contiguousSize, + .contiguousBase = contiguousBase, + .bankSize = bankSize, + .fastClear = fastClear, + .compression = compression, + .powerManagement = powerManagement, + .gpuProfiler = gpuProfiler, + .signal = signal, + .baseAddress = baseAddress, + .physSize = physSize, + .logFileSize = logFileSize, + .recovery = recovery, + .stuckDump = stuckDump, + .showArgs = showArgs, + }; gcmkHEADER(); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr"); - if (res) - baseAddress = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d"); - if (res) - irqLine = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d"); - if (res) - { - registerMemBase = res->start; - registerMemSize = res->end - res->start + 1; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d"); - if (res) - irqLine2D = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d"); - if (res) - { - registerMemBase2D = res->start; - registerMemSize2D = res->end - res->start + 1; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg"); - if (res) - irqLineVG = res->start; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg"); - if (res) - { - registerMemBaseVG = res->start; - registerMemSizeVG = res->end - res->start + 1; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL); - if (!pool) - return -ENOMEM; - if(contiguousSize) - { - pool->size = contiguousSize; - init_dma_attrs(&pool->attrs); - dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs); - pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys, - GFP_KERNEL, &pool->attrs); - if (!pool->virt) { - dev_err(&pdev->dev, "Failed to allocate contiguous memory\n"); - return -ENOMEM; - } - contiguousBase = pool->phys; - } - dev_set_drvdata(&pdev->dev, pool); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - prop = of_get_property(dn, "contiguousbase", NULL); - if(prop) - contiguousBase = *prop; - of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize); -#else - pdata = pdev->dev.platform_data; - if (pdata) { - contiguousBase = pdata->reserved_mem_base; - contiguousSize = pdata->reserved_mem_size; - } -#endif - if (contiguousSize == 0) - gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n "); - ret = drv_init(&pdev->dev); + platform.device = pdev; - if (!ret) + if (platform.ops->getPower) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - rstc = devm_reset_control_get(&pdev->dev, "gpu3d"); - galDevice->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc; + if (gcmIS_ERROR(platform.ops->getPower(&platform))) + { + gcmkFOOTER_NO(); + return ret; + } + } - rstc = devm_reset_control_get(&pdev->dev, "gpu2d"); - galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc; + if (platform.ops->adjustParam) + { + /* Override default module param. */ + platform.ops->adjustParam(&platform, &moduleParam); + /* Update module param because drv_init() uses them directly. */ + _UpdateModuleParam(&moduleParam); + } - rstc = devm_reset_control_get(&pdev->dev, "gpuvg"); - galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc; -#endif + ret = drv_init(); + if (!ret) + { platform_set_drvdata(pdev, galDevice); -#if gcdENABLE_FSCALE_VAL_ADJUST - if (galDevice->kernels[gcvCORE_MAJOR]) - REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier); -#endif - ret = driver_create_file(pdev->dev.driver, &driver_attr_meminfo); if(ret) dev_err(&pdev->dev, "create meminfo attr failed (%d)\n", ret); @@ -1417,14 +1221,6 @@ static int __devinit gpu_probe(struct platform_device *pdev) return ret; } -#if gcdENABLE_FSCALE_VAL_ADJUST - UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier); -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys, - &pool->attrs); -#endif gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret); return ret; } @@ -1435,26 +1231,19 @@ static int gpu_remove(struct platform_device *pdev) static int __devexit gpu_remove(struct platform_device *pdev) #endif { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - gckGALDEVICE device = platform_get_drvdata(pdev); - struct contiguous_mem_pool *pool = device->pool; -#endif gcmkHEADER(); -#if gcdENABLE_FSCALE_VAL_ADJUST - if(galDevice->kernels[gcvCORE_MAJOR]) - UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier); -#endif driver_remove_file(pdev->dev.driver, &driver_attr_meminfo); driver_remove_file(pdev->dev.driver, &driver_attr_pid); driver_remove_file(pdev->dev.driver, &driver_attr_idletime); drv_exit(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - if(pool->size) - dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys, - &pool->attrs); -#endif + + if (platform.ops->putPower) + { + platform.ops->putPower(&platform); + } + gcmkFOOTER_NO(); return 0; } @@ -1503,6 +1292,7 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state) { status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF); } + if (gcmIS_ERROR(status)) { return -1; @@ -1566,14 +1356,14 @@ static int gpu_resume(struct platform_device *dev) default: statesStored = device->statesStored[i]; break; - } + } /* Restore states. */ #if gcdENABLE_VG if (i == gcvCORE_VG) { status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored); - } + } else #endif { @@ -1590,47 +1380,25 @@ static int gpu_resume(struct platform_device *dev) return 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) -static const struct of_device_id mxs_gpu_dt_ids[] = { - { .compatible = "fsl,imx6q-gpu", }, - {/* sentinel */} -}; -MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids); - #ifdef CONFIG_PM -static int gpu_runtime_suspend(struct device *dev) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7) - release_bus_freq(BUS_FREQ_HIGH); -#endif - return 0; -} - -static int gpu_runtime_resume(struct device *dev) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7) - request_bus_freq(BUS_FREQ_HIGH); -#endif - return 0; -} - +#ifdef CONFIG_PM_SLEEP static int gpu_system_suspend(struct device *dev) { - pm_message_t state={0}; - return gpu_suspend(to_platform_device(dev), state); + pm_message_t state={0}; + return gpu_suspend(to_platform_device(dev), state); } static int gpu_system_resume(struct device *dev) { - return gpu_resume(to_platform_device(dev)); + return gpu_resume(to_platform_device(dev)); } +#endif static const struct dev_pm_ops gpu_pm_ops = { - SET_RUNTIME_PM_OPS(gpu_runtime_suspend, gpu_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume) + SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume) }; #endif -#endif + static struct platform_driver gpu_driver = { .probe = gpu_probe, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) @@ -1644,72 +1412,65 @@ static struct platform_driver gpu_driver = { .driver = { .name = DEVICE_NAME, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - .of_match_table = mxs_gpu_dt_ids, #if CONFIG_PM - .pm = &gpu_pm_ops, -#endif + .pm = &gpu_pm_ops, #endif } }; -#if 0 -static struct resource gpu_resources[] = { - { - .name = "gpu_irq", - .flags = IORESOURCE_IRQ, - }, - { - .name = "gpu_base", - .flags = IORESOURCE_MEM, - }, - { - .name = "gpu_mem", - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device * gpu_device; -#endif - static int __init gpu_init(void) { int ret = 0; -#if 0 /*ndef CONFIG_DOVE_GPU*/ - gpu_resources[0].start = gpu_resources[0].end = irqLine; + memset(&platform, 0, sizeof(gcsPLATFORM)); - gpu_resources[1].start = registerMemBase; - gpu_resources[1].end = registerMemBase + registerMemSize - 1; + gckPLATFORM_QueryOperations(&platform.ops); - gpu_resources[2].start = contiguousBase; - gpu_resources[2].end = contiguousBase + contiguousSize - 1; - - /* Allocate device */ - gpu_device = platform_device_alloc(DEVICE_NAME, -1); - if (!gpu_device) + if (platform.ops == gcvNULL) { - printk(KERN_ERR "galcore: platform_device_alloc failed.\n"); - ret = -ENOMEM; + printk(KERN_ERR "galcore: No platform specific operations.\n"); + ret = -ENODEV; goto out; } - /* Insert resource */ - ret = platform_device_add_resources(gpu_device, gpu_resources, 3); - if (ret) + if (platform.ops->allocPriv) { - printk(KERN_ERR "galcore: platform_device_add_resources failed.\n"); - goto put_dev; + /* Allocate platform private data. */ + if (gcmIS_ERROR(platform.ops->allocPriv(&platform))) + { + ret = -ENOMEM; + goto out; + } } - /* Add device */ - ret = platform_device_add(gpu_device); - if (ret) + if (platform.ops->needAddDevice + && platform.ops->needAddDevice(&platform)) { - printk(KERN_ERR "galcore: platform_device_add failed.\n"); - goto put_dev; + /* Allocate device */ + platform.device = platform_device_alloc(DEVICE_NAME, -1); + if (!platform.device) + { + printk(KERN_ERR "galcore: platform_device_alloc failed.\n"); + ret = -ENOMEM; + goto out; + } + + /* Add device */ + ret = platform_device_add(platform.device); + if (ret) + { + printk(KERN_ERR "galcore: platform_device_add failed.\n"); + goto put_dev; + } + } + + platform.driver = &gpu_driver; + + if (platform.ops->adjustDriver) + { + /* Override default platform_driver struct. */ + platform.ops->adjustDriver(&platform); } -#endif ret = platform_driver_register(&gpu_driver); if (!ret) @@ -1717,11 +1478,9 @@ static int __init gpu_init(void) goto out; } -#if 0 /*ndef CONFIG_DOVE_GPU*/ - platform_device_del(gpu_device); + platform_device_del(platform.device); put_dev: - platform_device_put(gpu_device); -#endif + platform_device_put(platform.device); out: return ret; @@ -1729,10 +1488,19 @@ out: static void __exit gpu_exit(void) { + if (platform.ops->needAddDevice + && platform.ops->needAddDevice(&platform)) + { + platform_device_unregister(platform.device); + } + + if (platform.priv) + { + /* Free platform private data. */ + platform.ops->freePriv(&platform); + } + platform_driver_unregister(&gpu_driver); -#if 0 /*ndef CONFIG_DOVE_GPU*/ - platform_device_unregister(gpu_device); -#endif } module_init(gpu_init); diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c index 0c93cbe11edd..007a6948ca5f 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c @@ -19,7 +19,6 @@ *****************************************************************************/ - #include "gc_hal_kernel_linux.h" #include @@ -27,7 +26,8 @@ #define _GC_OBJ_ZONE gcvZONE_OS -#define GPU3D_UUID { 0x111111, 0x1111, 0x1111, { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } } +#define GPU3D_UUID { 0xcc9f80ea, 0xa836, 0x11e3, { 0x9b, 0x07, 0x78, 0x2b, 0xcb, 0x5c, 0xf3, 0xe3 } } + static const TEEC_UUID gpu3d_uuid = GPU3D_UUID; TEEC_Context teecContext; @@ -88,9 +88,10 @@ gpu3d_allocate_secure_mem( result = TEEC_RegisterSharedMemory( context, shm); + if (result != TEEC_SUCCESS) { - gpu_free_memory(handle); + gckOS_FreeIonMemory(Os, (gctPHYS_ADDR)handle); kfree(shm); return NULL; } 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 86511e78542b..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 @@ -19,7 +19,6 @@ *****************************************************************************/ - #include #include diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h index fa663ef6d5b7..8a69921801ae 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h @@ -19,13 +19,13 @@ *****************************************************************************/ - #ifndef __gc_hal_kernel_sync_h_ #define __gc_hal_kernel_sync_h_ #include -#include +/* sync.h is in drivers/staging/android/ for now. */ +#include #include #include 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 new file mode 100644 index 000000000000..a73c4405e693 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c @@ -0,0 +1,879 @@ +/**************************************************************************** +* +* 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_platform.h" +#include "gc_hal_kernel_device.h" +#include "gc_hal_driver.h" +#include + +#if USE_PLATFORM_DRIVER +# include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) +#include +#else +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) +#include +#else +#include +#include +#endif +#endif + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#include +#endif +#include + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#include +#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a); +#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a); +#else +extern int register_thermal_notifier(struct notifier_block *nb); +extern int unregister_thermal_notifier(struct notifier_block *nb); +#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a); +#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a); +#endif + +struct platform_device *pdevice; + +#ifdef CONFIG_GPU_LOW_MEMORY_KILLER +# include +# include +# include +# include + +struct task_struct *lowmem_deathpending; + +static int +task_notify_func(struct notifier_block *self, unsigned long val, void *data); + +static struct notifier_block task_nb = { + .notifier_call = task_notify_func, +}; + +static int +task_notify_func(struct notifier_block *self, unsigned long val, void *data) +{ + struct task_struct *task = data; + + if (task == lowmem_deathpending) + lowmem_deathpending = NULL; + + return NOTIFY_OK; +} + +extern struct task_struct *lowmem_deathpending; +static unsigned long lowmem_deathpending_timeout; + +static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel) +{ + struct task_struct *p; + struct task_struct *selected = NULL; + int tasksize; + int ret = -1; + int min_adj = 0; + int selected_tasksize = 0; + int selected_oom_adj; + /* + * If we already have a death outstanding, then + * bail out right away; indicating to vmscan + * that we have nothing further to offer on + * this pass. + * + */ + if (lowmem_deathpending && + time_before_eq(jiffies, lowmem_deathpending_timeout)) + return 0; + selected_oom_adj = min_adj; + + read_lock(&tasklist_lock); + for_each_process(p) { + struct mm_struct *mm; + struct signal_struct *sig; + gcuDATABASE_INFO info; + int oom_adj; + + task_lock(p); + mm = p->mm; + sig = p->signal; + if (!mm || !sig) { + task_unlock(p); + continue; + } + oom_adj = sig->oom_score_adj; + if (oom_adj < min_adj) { + task_unlock(p); + continue; + } + + tasksize = 0; + task_unlock(p); + read_unlock(&tasklist_lock); + + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){ + tasksize += info.counters.bytes / PAGE_SIZE; + } + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){ + tasksize += info.counters.bytes / PAGE_SIZE; + } + + read_lock(&tasklist_lock); + + if (tasksize <= 0) + continue; + + gckOS_Print(" pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize); + + if (selected) { + if (oom_adj < selected_oom_adj) + continue; + if (oom_adj == selected_oom_adj && + tasksize <= selected_tasksize) + continue; + } + selected = p; + selected_tasksize = tasksize; + selected_oom_adj = oom_adj; + } + if (selected) { + gckOS_Print(" send sigkill to %d (%s), adj %d, size %d\n", + selected->pid, selected->comm, + selected_oom_adj, selected_tasksize); + lowmem_deathpending = selected; + lowmem_deathpending_timeout = jiffies + HZ; + force_sig(SIGKILL, selected); + ret = 0; + } + read_unlock(&tasklist_lock); + return ret; +} + + +gceSTATUS +_ShrinkMemory( + IN gckPLATFORM Platform + ) +{ + struct platform_device *pdev; + gckGALDEVICE galDevice; + gckKERNEL kernel; + + pdev = Platform->device; + + galDevice = platform_get_drvdata(pdev); + + kernel = galDevice->kernels[gcvCORE_MAJOR]; + + 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 + { + gcmkPRINT("%s(%d) can't find kernel! ", __FUNCTION__, __LINE__); + } + + return gcvSTATUS_OK; +} +#endif + +#if gcdENABLE_FSCALE_VAL_ADJUST +static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event, + void *dummy) +{ + static gctUINT orgFscale, minFscale, maxFscale; + static gctBOOL bAlreadyTooHot = gcvFALSE; + gckHARDWARE hardware; + gckGALDEVICE galDevice; + + galDevice = platform_get_drvdata(pdevice); + if (!galDevice) + { + /* GPU is not ready, so it is meaningless to change GPU freq. */ + return NOTIFY_OK; + } + + if (!galDevice->kernels[gcvCORE_MAJOR]) + { + return NOTIFY_OK; + } + + hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware; + + if (!hardware) + { + return NOTIFY_OK; + } + + if (event && !bAlreadyTooHot) { + gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale); + gckHARDWARE_SetFscaleValue(hardware, minFscale); + bAlreadyTooHot = gcvTRUE; + gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale); + } else if (!event && bAlreadyTooHot) { + gckHARDWARE_SetFscaleValue(hardware, orgFscale); + gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale); + bAlreadyTooHot = gcvFALSE; + } + return NOTIFY_OK; +} + +static struct notifier_block thermal_hot_pm_notifier = { + .notifier_call = thermal_hot_pm_notify, + }; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +static const struct of_device_id mxs_gpu_dt_ids[] = { + { .compatible = "fsl,imx6q-gpu", }, + {/* sentinel */} +}; +MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids); +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +struct contiguous_mem_pool { + struct dma_attrs attrs; + dma_addr_t phys; + void *virt; + size_t size; +}; +#endif + +struct imx_priv { + /* Clock management.*/ + struct clk *clk_3d_core; + struct clk *clk_3d_shader; + struct clk *clk_3d_axi; + struct clk *clk_2d_core; + struct clk *clk_2d_axi; + struct clk *clk_vg_axi; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + /*Power management.*/ + struct regulator *gpu_regulator; +#endif + /*Run time pm*/ + struct device *pmdev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct contiguous_mem_pool *pool; + struct reset_control *rstc[gcdMAX_GPU_COUNT]; +#endif +}; + +static struct imx_priv imxPriv; + +gceSTATUS +gckPLATFORM_AdjustParam( + IN gckPLATFORM Platform, + OUT gcsMODULE_PARAMETERS *Args + ) +{ + struct resource* res; + struct platform_device* pdev = Platform->device; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct imx_priv *priv = Platform->priv; + + struct contiguous_mem_pool *pool; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + struct device_node *dn =pdev->dev.of_node; + const u32 *prop; +#else + struct viv_gpu_platform_data *pdata; +#endif + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr"); + if (res) + Args->baseAddress = res->start; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d"); + if (res) + Args->irqLine = res->start; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d"); + if (res) + { + Args->registerMemBase = res->start; + Args->registerMemSize = res->end - res->start + 1; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d"); + if (res) + Args->irqLine2D = res->start; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d"); + if (res) + { + Args->registerMemBase2D = res->start; + Args->registerMemSize2D = res->end - res->start + 1; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg"); + if (res) + Args->irqLineVG = res->start; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg"); + if (res) + { + Args->registerMemBaseVG = res->start; + Args->registerMemSizeVG = res->end - res->start + 1; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL); + if (!pool) + return gcvSTATUS_OUT_OF_MEMORY; + if(Args->contiguousSize) + { + if(Args->contiguousSize == 4 << 20) + /*Update the default setting*/ + Args->contiguousSize = pool->size = 128 * 1024 * 1024; + else + pool->size = Args->contiguousSize; + + init_dma_attrs(&pool->attrs); + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs); + pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys, + GFP_KERNEL, &pool->attrs); + if (!pool->virt) { + dev_err(&pdev->dev, "Failed to allocate contiguous memory\n"); + + devm_kfree(&pdev->dev, pool); + + return gcvSTATUS_OUT_OF_MEMORY; + } + Args->contiguousBase = pool->phys; + } + Args->contiguousRequested = gcvTRUE; + + priv->pool = pool; + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + prop = of_get_property(dn, "contiguousbase", NULL); + if(prop) + Args->contiguousBase = *prop; + of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize); +#else + pdata = pdev->dev.platform_data; + if (pdata) { + Args->contiguousBase = pdata->reserved_mem_base; + Args->contiguousSize = pdata->reserved_mem_size; + } +#endif + if (Args->contiguousSize == 0) + gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n "); + + + return gcvSTATUS_OK; +} + +gceSTATUS +_AllocPriv( + IN gckPLATFORM Platform + ) +{ + Platform->priv = &imxPriv; + +#ifdef CONFIG_GPU_LOW_MEMORY_KILLER + task_free_register(&task_nb); +#endif + + return gcvSTATUS_OK; +} + +gceSTATUS +_FreePriv( + IN gckPLATFORM Platform + ) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct imx_priv *priv = Platform->priv; + struct platform_device *pdev = Platform->device; + + struct contiguous_mem_pool *pool = priv->pool; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + if (pool && pool->size) + { + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys, + &pool->attrs); + + devm_kfree(&pdev->dev, pool); + priv->pool = NULL; + } +#endif + +#ifdef CONFIG_GPU_LOW_MEMORY_KILLER + task_free_unregister(&task_nb); +#endif + + return gcvSTATUS_OK; +} + +gceSTATUS +_GetPower( + IN gckPLATFORM Platform + ) +{ + struct device* pdev = &Platform->device->dev; + struct imx_priv *priv = Platform->priv; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct reset_control *rstc; +#endif + +#ifdef CONFIG_PM + /*Init runtime pm for gpu*/ + pm_runtime_enable(pdev); + priv->pmdev = pdev; +#endif + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + rstc = devm_reset_control_get(pdev, "gpu3d"); + priv->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc; + rstc = devm_reset_control_get(pdev, "gpu2d"); + priv->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc; + rstc = devm_reset_control_get(pdev, "gpuvg"); + priv->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + /*get gpu regulator*/ + priv->gpu_regulator = regulator_get(pdev, "cpu_vddgpu"); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + priv->gpu_regulator = devm_regulator_get(pdev, "pu"); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + if (IS_ERR(priv->gpu_regulator)) { + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Failed to get gpu regulator \n", + __FUNCTION__, __LINE__); + return gcvSTATUS_NOT_FOUND; + } +#endif +#endif + + /*Initialize the clock structure*/ + priv->clk_3d_core = clk_get(pdev, "gpu3d_clk"); + if (!IS_ERR(priv->clk_3d_core)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + if (cpu_is_mx6q()) { + priv->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk"); + if (IS_ERR(priv->clk_3d_shader)) { + clk_put(priv->clk_3d_core); + priv->clk_3d_core = NULL; + priv->clk_3d_shader = NULL; + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n"); + } + } +#else + priv->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk"); + priv->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk"); + if (IS_ERR(priv->clk_3d_shader)) { + clk_put(priv->clk_3d_core); + priv->clk_3d_core = NULL; + priv->clk_3d_shader = NULL; + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n"); + } +#endif + } else { + priv->clk_3d_core = NULL; + gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n"); + } + + priv->clk_2d_core = clk_get(pdev, "gpu2d_clk"); + if (IS_ERR(priv->clk_2d_core)) { + priv->clk_2d_core = NULL; + gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n"); + } else { + priv->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk"); + if (IS_ERR(priv->clk_2d_axi)) { + priv->clk_2d_axi = NULL; + gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n"); + } + + priv->clk_vg_axi = clk_get(pdev, "openvg_axi_clk"); + if (IS_ERR(priv->clk_vg_axi)) { + priv->clk_vg_axi = NULL; + gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n"); + } + } + + +#if gcdENABLE_FSCALE_VAL_ADJUST + pdevice = Platform->device; + REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier); +#endif + + return gcvSTATUS_OK; +} + +gceSTATUS +_PutPower( + IN gckPLATFORM Platform + ) +{ + struct imx_priv *priv = Platform->priv; + + /*Disable clock*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + if (priv->clk_3d_axi) { + clk_put(priv->clk_3d_axi); + priv->clk_3d_axi = NULL; + } +#endif + if (priv->clk_3d_core) { + clk_put(priv->clk_3d_core); + priv->clk_3d_core = NULL; + } + if (priv->clk_3d_shader) { + clk_put(priv->clk_3d_shader); + priv->clk_3d_shader = NULL; + } + if (priv->clk_2d_core) { + clk_put(priv->clk_2d_core); + priv->clk_2d_core = NULL; + } + if (priv->clk_2d_axi) { + clk_put(priv->clk_2d_axi); + priv->clk_2d_axi = NULL; + } + if (priv->clk_vg_axi) { + clk_put(priv->clk_vg_axi); + priv->clk_vg_axi = NULL; + } + +#ifdef CONFIG_PM + if(priv->pmdev) + pm_runtime_disable(priv->pmdev); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + if (priv->gpu_regulator) { + regulator_put(priv->gpu_regulator); + priv->gpu_regulator = NULL; + } +#endif + +#if gcdENABLE_FSCALE_VAL_ADJUST + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier); +#endif + + return gcvSTATUS_OK; +} + +gceSTATUS +_SetPower( + IN gckPLATFORM Platform, + IN gceCORE GPU, + IN gctBOOL Enable + ) +{ + struct imx_priv* priv = Platform->priv; +#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) + int ret; +#endif +#endif + + if (Enable) + { +#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) + if(!IS_ERR(priv->gpu_regulator)) { + ret = regulator_enable(priv->gpu_regulator); + if (ret != 0) + gckOS_Print("%s(%d): fail to enable pu regulator %d!\n", + __FUNCTION__, __LINE__, ret); + } +#else + imx_gpc_power_up_pu(true); +#endif +#endif + +#ifdef CONFIG_PM + pm_runtime_get_sync(priv->pmdev); +#endif + } + else + { +#ifdef CONFIG_PM + pm_runtime_put_sync(priv->pmdev); +#endif + +#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) + if(!IS_ERR(priv->gpu_regulator)) + regulator_disable(priv->gpu_regulator); +#else + imx_gpc_power_up_pu(false); +#endif +#endif + + } + + return gcvSTATUS_OK; +} + +gceSTATUS +_SetClock( + IN gckPLATFORM Platform, + IN gceCORE GPU, + IN gctBOOL Enable + ) +{ + struct imx_priv* priv = Platform->priv; + struct clk *clk_3dcore = priv->clk_3d_core; + struct clk *clk_3dshader = priv->clk_3d_shader; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + struct clk *clk_3d_axi = priv->clk_3d_axi; +#endif + struct clk *clk_2dcore = priv->clk_2d_core; + struct clk *clk_2d_axi = priv->clk_2d_axi; + struct clk *clk_vg_axi = priv->clk_vg_axi; + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + if (Enable) { + switch (GPU) { + case gcvCORE_MAJOR: + clk_enable(clk_3dcore); + if (cpu_is_mx6q()) + clk_enable(clk_3dshader); + break; + case gcvCORE_2D: + clk_enable(clk_2dcore); + clk_enable(clk_2d_axi); + break; + case gcvCORE_VG: + clk_enable(clk_2dcore); + clk_enable(clk_vg_axi); + break; + default: + break; + } + } else { + switch (GPU) { + case gcvCORE_MAJOR: + if (cpu_is_mx6q()) + clk_disable(clk_3dshader); + clk_disable(clk_3dcore); + break; + case gcvCORE_2D: + clk_disable(clk_2dcore); + clk_disable(clk_2d_axi); + break; + case gcvCORE_VG: + clk_disable(clk_2dcore); + clk_disable(clk_vg_axi); + break; + default: + break; + } + } +#else + if (Enable) { + switch (GPU) { + case gcvCORE_MAJOR: + clk_prepare(clk_3dcore); + clk_enable(clk_3dcore); + clk_prepare(clk_3dshader); + clk_enable(clk_3dshader); + clk_prepare(clk_3d_axi); + clk_enable(clk_3d_axi); + break; + case gcvCORE_2D: + clk_prepare(clk_2dcore); + clk_enable(clk_2dcore); + clk_prepare(clk_2d_axi); + clk_enable(clk_2d_axi); + break; + case gcvCORE_VG: + clk_prepare(clk_2dcore); + clk_enable(clk_2dcore); + clk_prepare(clk_vg_axi); + clk_enable(clk_vg_axi); + break; + default: + break; + } + } else { + switch (GPU) { + case gcvCORE_MAJOR: + clk_disable(clk_3dshader); + clk_unprepare(clk_3dshader); + clk_disable(clk_3dcore); + clk_unprepare(clk_3dcore); + clk_disable(clk_3d_axi); + clk_unprepare(clk_3d_axi); + break; + case gcvCORE_2D: + clk_disable(clk_2dcore); + clk_unprepare(clk_2dcore); + clk_disable(clk_2d_axi); + clk_unprepare(clk_2d_axi); + break; + case gcvCORE_VG: + clk_disable(clk_2dcore); + clk_unprepare(clk_2dcore); + clk_disable(clk_vg_axi); + clk_unprepare(clk_vg_axi); + break; + default: + break; + } + } +#endif + + return gcvSTATUS_OK; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +#ifdef CONFIG_PM +static int gpu_runtime_suspend(struct device *dev) +{ + release_bus_freq(BUS_FREQ_HIGH); + return 0; +} + +static int gpu_runtime_resume(struct device *dev) +{ + request_bus_freq(BUS_FREQ_HIGH); + return 0; +} + +static struct dev_pm_ops gpu_pm_ops; +#endif +#endif + +gceSTATUS +_AdjustDriver( + IN gckPLATFORM Platform + ) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + struct platform_driver * driver = Platform->driver; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + driver->driver.of_match_table = mxs_gpu_dt_ids; +#endif + + /* Override PM callbacks to add runtime PM callbacks. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + /* Fill local structure with original value. */ + memcpy(&gpu_pm_ops, driver->driver.pm, sizeof(struct dev_pm_ops)); + + /* Add runtime PM callback. */ +#ifdef CONFIG_PM_RUNTIME + gpu_pm_ops.runtime_suspend = gpu_runtime_suspend; + gpu_pm_ops.runtime_resume = gpu_runtime_resume; + gpu_pm_ops.runtime_idle = NULL; +#endif + + /* Replace callbacks. */ + driver->driver.pm = &gpu_pm_ops; +#endif + return gcvSTATUS_OK; +} + +gceSTATUS +_Reset( + IN gckPLATFORM Platform, + gceCORE GPU + ) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) +#define SRC_SCR_OFFSET 0 +#define BP_SRC_SCR_GPU3D_RST 1 +#define BP_SRC_SCR_GPU2D_RST 4 + void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR); + gctUINT32 bit_offset,val; + + if(GPU == gcvCORE_MAJOR) { + bit_offset = BP_SRC_SCR_GPU3D_RST; + } else if((GPU == gcvCORE_VG) + ||(GPU == gcvCORE_2D)) { + bit_offset = BP_SRC_SCR_GPU2D_RST; + } else { + return gcvSTATUS_INVALID_CONFIG; + } + val = __raw_readl(src_base + SRC_SCR_OFFSET); + val &= ~(1 << (bit_offset)); + val |= (1 << (bit_offset)); + __raw_writel(val, src_base + SRC_SCR_OFFSET); + + while ((__raw_readl(src_base + SRC_SCR_OFFSET) & + (1 << (bit_offset))) != 0) { + } + + return gcvSTATUS_NOT_SUPPORTED; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + struct imx_priv* priv = Platform->priv; + struct reset_control *rstc = priv->rstc[GPU]; + if (rstc) + reset_control_reset(rstc); +#else + imx_src_reset_gpu((int)GPU); +#endif + return gcvSTATUS_OK; +} + +gcsPLATFORM_OPERATIONS platformOperations = { + .adjustParam = gckPLATFORM_AdjustParam, + .allocPriv = _AllocPriv, + .freePriv = _FreePriv, + .getPower = _GetPower, + .putPower = _PutPower, + .setPower = _SetPower, + .setClock = _SetClock, + .adjustDriver = _AdjustDriver, + .reset = _Reset, +#ifdef CONFIG_GPU_LOW_MEMORY_KILLER + .shrinkMemory = _ShrinkMemory, +#endif +}; + +void +gckPLATFORM_QueryOperations( + IN gcsPLATFORM_OPERATIONS ** Operations + ) +{ + *Operations = &platformOperations; +} + -- 2.39.2