From: Lothar Waßmann Date: Tue, 3 Feb 2015 12:45:41 +0000 (+0100) Subject: gpu: vivante: Update driver from Freescale 3.10.53-1.1-ga BSP X-Git-Tag: KARO-TX6-2015-02-27~25 X-Git-Url: https://git.karo-electronics.de/?p=karo-tx-linux.git;a=commitdiff_plain;h=8361006f5e4bfb66a34d982d3e88d737312566f1 gpu: vivante: Update driver from Freescale 3.10.53-1.1-ga BSP --- diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild index 2b277d6f4ee7..c39444cdd1b9 100644 --- a/drivers/mxc/gpu-viv/Kbuild +++ b/drivers/mxc/gpu-viv/Kbuild @@ -1,6 +1,6 @@ ############################################################################## # -# Copyright (C) 2005 - 2013 by Vivante Corp. +# 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 @@ -24,26 +24,55 @@ # AQROOT := $(srctree)/drivers/mxc/gpu-viv -AQARCH := $(AQROOT)/arch/XAQ2 -AQVGARCH := $(AQROOT)/arch/GC350 include $(AQROOT)/config KERNEL_DIR ?= $(TOOL_DIR)/kernel OS_KERNEL_DIR := hal/os/linux/kernel -ARCH_KERNEL_DIR := arch/$(notdir $(AQARCH))/hal/kernel -ARCH_VG_KERNEL_DIR := arch/$(notdir $(AQVGARCH))/hal/kernel +ARCH_KERNEL_DIR := hal/kernel/arch +ARCH_VG_KERNEL_DIR := hal/kernel/archvg HAL_KERNEL_DIR := hal/kernel +# Check and include platform config. +ifneq ($(PLATFORM),) + +# Get platform config path. +PLATFORM_CONFIG ?= $(AQROOT)/$(OS_KERNEL_DIR)/platform/$(PLATFORM).config + +# Check whether it exists. +PLATFORM_CONFIG := $(wildcard $(PLATFORM_CONFIG)) + +# Include it if exists. +ifneq ($(PLATFORM_CONFIG),) +include $(PLATFORM_CONFIG) +endif + +endif + +MODULE_NAME ?= galcore +CUSTOMER_ALLOCATOR_OBJS ?= +ALLOCATOR_ARRAY_H_LOCATION ?= $(OS_KERNEL_DIR)/allocator/default/ + 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_debugfs.o \ + $(OS_KERNEL_DIR)/gc_hal_kernel_allocator.o \ + +ifneq ($(CONFIG_IOMMU_SUPPORT),) +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_iommu.o +endif + +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 \ @@ -58,6 +87,10 @@ OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \ OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \ $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o +ifeq ($(VIVANTE_ENABLE_3D), 1) +OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_recorder.o +endif + ifeq ($(VIVANTE_ENABLE_VG), 1) OBJS +=\ $(HAL_KERNEL_DIR)/gc_hal_kernel_vg.o\ @@ -69,9 +102,20 @@ 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) +endif + ifeq ($(KERNELRELEASE), ) .PHONY: all clean install @@ -93,12 +137,6 @@ else EXTRA_CFLAGS += -DLINUX -DDRIVER -ifeq ($(ENUM_WORKAROUND), 1) -EXTRA_CFLAGS += -DENUM_WORKAROUND=1 -else -EXTRA_CFLAGS += -DENUM_WORKAROUND=0 -endif - ifeq ($(FLAREON),1) EXTRA_CFLAGS += -DFLAREON endif @@ -123,15 +161,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 @@ -144,12 +176,6 @@ else EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=0 endif -ifeq ($(NO_USER_DIRECT_ACCESS_FROM_KERNEL), 1) -EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=1 -else -EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0 -endif - ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1) EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1 else @@ -174,26 +200,28 @@ else EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=0 endif -ifeq ($(SUPPORT_SWAP_RECTANGLE), 1) -EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=1 +ifeq ($(CONFIG_SMP), y) +EXTRA_CFLAGS += -DgcdSMP=1 else -EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=0 +EXTRA_CFLAGS += -DgcdSMP=0 endif -ifeq ($(VIVANTE_ENABLE_VG), 1) -EXTRA_CFLAGS += -DgcdENABLE_VG=1 +ifeq ($(VIVANTE_ENABLE_3D),0) +EXTRA_CFLAGS += -DgcdENABLE_3D=0 else -EXTRA_CFLAGS += -DgcdENABLE_VG=0 +EXTRA_CFLAGS += -DgcdENABLE_3D=1 endif -ifeq ($(CONFIG_SMP), y) -EXTRA_CFLAGS += -DgcdSMP=1 +ifeq ($(VIVANTE_ENABLE_2D),0) +EXTRA_CFLAGS += -DgcdENABLE_2D=0 else -EXTRA_CFLAGS += -DgcdSMP=0 +EXTRA_CFLAGS += -DgcdENABLE_2D=1 endif -ifeq ($(VIVANTE_NO_3D),1) -EXTRA_CFLAGS += -DVIVANTE_NO_3D +ifeq ($(VIVANTE_ENABLE_VG),0) +EXTRA_CFLAGS += -DgcdENABLE_VG=0 +else +EXTRA_CFLAGS += -DgcdENABLE_VG=1 endif ifeq ($(ENABLE_OUTER_CACHE_PATCH), 1) @@ -216,17 +244,25 @@ ifeq ($(USE_BANK_ALIGNMENT), 1) endif endif -ifneq ($(CONFIG_SYNC),) -EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=1 +ifeq ($(gcdFPGA_BUILD), 1) +EXTRA_CFLAGS += -DgcdFPGA_BUILD=1 +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 -EXTRA_CFLAGS += -I$(AQARCH)/hal/kernel +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/arch +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc EXTRA_CFLAGS += -I$(AQROOT)/hal/os/linux/kernel +EXTRA_CFLAGS += -I$(AQROOT)/$(ALLOCATOR_ARRAY_H_LOCATION) ifeq ($(VIVANTE_ENABLE_VG), 1) -EXTRA_CFLAGS += -I$(AQVGARCH)/hal/kernel +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/archvg endif obj-$(CONFIG_MXC_GPU_VIV) += galcore.o diff --git a/drivers/mxc/gpu-viv/config b/drivers/mxc/gpu-viv/config index cdd143e03e51..94841414a07a 100644 --- a/drivers/mxc/gpu-viv/config +++ b/drivers/mxc/gpu-viv/config @@ -1,6 +1,6 @@ ############################################################################## # -# Copyright (C) 2005 - 2013 by Vivante Corp. +# 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 @@ -21,18 +21,16 @@ ARCH_TYPE ?= arm SDK_DIR ?= $(AQROOT)/build/sdk -USE_3D_VG ?= 1 +VIVANTE_ENABLE_3D ?= 1 +VIVANTE_ENABLE_2D ?= 1 +VIVANTE_ENABLE_VG ?= 1 FORCE_ALL_VIDEO_MEMORY_CACHED ?= 0 NONPAGED_MEMORY_CACHEABLE ?= 0 NONPAGED_MEMORY_BUFFERABLE ?= 1 CACHE_FUNCTION_UNIMPLEMENTED ?= 0 -VIVANTE_ENABLE_VG ?= 1 -NO_USER_DIRECT_ACCESS_FROM_KERNEL ?= 1 -VIVANTE_NO_3D ?= 0 ENABLE_OUTER_CACHE_PATCH ?= 1 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/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c similarity index 60% rename from drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c rename to drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c index e277a21a6097..08644a7cf5e5 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -89,6 +89,15 @@ gcvFALSE, gcvTRUE \ ) +#define _STATE_COUNT_OFFSET_HINT(reg, offset, count) \ + _State(\ + Context, index, \ + (reg ## _Address >> 2) + offset, \ + reg ## _ResetValue, \ + count, \ + gcvFALSE, gcvTRUE \ + ) + #define _STATE_X(reg) \ _State(\ Context, index, \ @@ -98,6 +107,15 @@ gcvTRUE, gcvFALSE \ ) +#define _STATE_INIT_VALUE(reg, value) \ + _State(\ + Context, index, \ + reg ## _Address >> 2, \ + value, \ + reg ## _Count, \ + gcvFALSE, gcvFALSE \ + ) + #define _CLOSE_RANGE() \ _TerminateStateBlock(Context, index) @@ -122,15 +140,15 @@ #define gcdSTATE_MASK \ (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 | 0xC0FFEE & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))) -#if !defined(VIVANTE_NO_3D) -static gctSIZE_T +#if gcdENABLE_3D +static gctUINT32 _TerminateStateBlock( IN gckCONTEXT Context, - IN gctSIZE_T Index + IN gctUINT32 Index ) { gctUINT32_PTR buffer; - gctSIZE_T align; + gctUINT32 align; /* Determine if we need alignment. */ align = (Index & 1) ? 1 : 0; @@ -156,13 +174,37 @@ _TerminateStateBlock( #endif -static gctSIZE_T +#if (gcdENABLE_3D || gcdENABLE_2D) +static gctUINT32 _FlushPipe( IN gckCONTEXT Context, - IN gctSIZE_T Index, + IN gctUINT32 Index, IN gcePIPE_SELECT Pipe ) { + gctBOOL fcFlushStall; + gctUINT32 flushSlots; + gctBOOL iCacheInvalidate; + + fcFlushStall + = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_FC_FLUSH_STALL); + + iCacheInvalidate + = ((((gctUINT32) (Context->hardware->identity.chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))); + + flushSlots = 6; + + if (fcFlushStall) + { + /* Flush tile status cache. */ + flushSlots += 6; + } + + if (iCacheInvalidate) + { + flushSlots += 12; + } + if (Context->buffer != gcvNULL) { gctUINT32_PTR buffer; @@ -182,7 +224,7 @@ _FlushPipe( : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); /* Semaphore from FE to PE. */ *buffer++ @@ -198,20 +240,106 @@ _FlushPipe( *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); - *buffer + *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + if (fcFlushStall) + { + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + /* Semaphore from FE to PE. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /* Stall from FE to PE. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + } + + if (iCacheInvalidate) + { + /* Invalidate I$ after pipe is stalled */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0218) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x021A) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); + + /* Semaphore from FE to PE. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /* Stall from FE to PE. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + } } - /* Flushing 3D pipe takes 6 slots. */ - return 6; + /* Number of slots taken by flushing pipe. */ + return flushSlots; } +#endif -#if !defined(VIVANTE_NO_3D) -static gctSIZE_T +#if gcdENABLE_3D +static gctUINT32 _SemaphoreStall( IN gckCONTEXT Context, - IN gctSIZE_T Index + IN gctUINT32 Index ) { if (Context->buffer != gcvNULL) @@ -245,13 +373,16 @@ _SemaphoreStall( } #endif -static gctSIZE_T +#if (gcdENABLE_3D || gcdENABLE_2D) +static gctUINT32 _SwitchPipe( IN gckCONTEXT Context, - IN gctSIZE_T Index, + IN gctUINT32 Index, IN gcePIPE_SELECT Pipe ) { + gctUINT32 slots = 6; + if (Context->buffer != gcvNULL) { gctUINT32_PTR buffer; @@ -265,29 +396,51 @@ _SwitchPipe( | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - *buffer + *buffer++ = (Pipe == gcvPIPE_2D) ? 0x1 : 0x0; + + /* Semaphore from FE to PE. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /* Stall from FE to PE. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); } - return 2; + Context->pipeSelectBytes = slots * gcmSIZEOF(gctUINT32); + + return slots; } +#endif -#if !defined(VIVANTE_NO_3D) -static gctSIZE_T +#if gcdENABLE_3D +static gctUINT32 _State( IN gckCONTEXT Context, - IN gctSIZE_T Index, + IN gctUINT32 Index, IN gctUINT32 Address, IN gctUINT32 Value, - IN gctSIZE_T Size, + IN gctUINT32 Size, IN gctBOOL FixedPoint, IN gctBOOL Hinted ) { gctUINT32_PTR buffer; - gctSIZE_T align, i; + gctUINT32 align; + gctUINT32 i; /* Determine if we need alignment. */ align = (Index & 1) ? 1 : 0; @@ -335,13 +488,13 @@ _State( } /* Walk all the states. */ - for (i = 0; i < Size; i += 1) + for (i = 0; i < (gctUINT32)Size; i += 1) { /* Set state to uninitialized value. */ buffer[Index + 1 + i] = Value; /* Set index in state mapping table. */ - Context->map[Address + i].index = Index + 1 + i; + Context->map[Address + i].index = (gctUINT)Index + 1 + i; #if gcdSECURE_USER /* Save hint. */ @@ -354,8 +507,8 @@ _State( } /* Save information for this LoadState. */ - Context->lastIndex = Index; - Context->lastAddress = Address + Size; + Context->lastIndex = (gctUINT)Index; + Context->lastAddress = Address + (gctUINT32)Size; Context->lastSize = Size; Context->lastFixed = FixedPoint; @@ -371,13 +524,13 @@ _State( ((((gctUINT32) (buffer[Context->lastIndex])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Context->lastSize + Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); /* Walk all the states. */ - for (i = 0; i < Size; i += 1) + for (i = 0; i < (gctUINT32)Size; i += 1) { /* Set state to uninitialized value. */ buffer[Index + i] = Value; /* Set index in state mapping table. */ - Context->map[Address + i].index = Index + i; + Context->map[Address + i].index = (gctUINT)Index + i; #if gcdSECURE_USER /* Save hint. */ @@ -390,22 +543,22 @@ _State( } /* Update last address and size. */ - Context->lastAddress += Size; + Context->lastAddress += (gctUINT32)Size; Context->lastSize += Size; /* Return number of slots required. */ return Size; } -static gctSIZE_T +static gctUINT32 _StateMirror( IN gckCONTEXT Context, IN gctUINT32 Address, - IN gctSIZE_T Size, + IN gctUINT32 Size, IN gctUINT32 AddressMirror ) { - gctSIZE_T i; + gctUINT32 i; /* Process when buffer is set. */ if (Context->buffer != gcvNULL) @@ -424,19 +577,21 @@ _StateMirror( } #endif +#if (gcdENABLE_3D || gcdENABLE_2D) static gceSTATUS _InitializeContextBuffer( IN gckCONTEXT Context ) { gctUINT32_PTR buffer; - gctSIZE_T index; + gctUINT32 index; -#if !defined(VIVANTE_NO_3D) +#if gcdENABLE_3D + gctBOOL halti0, halti1, halti2, halti3; gctUINT i; - gctUINT vertexUniforms, fragmentUniforms; + gctUINT vertexUniforms, fragmentUniforms, vsConstBase, psConstBase, constMax; + gctBOOL unifiedUniform; gctUINT fe2vsCount; - gctBOOL halti0; #endif /* Reset the buffer index. */ @@ -455,20 +610,31 @@ _InitializeContextBuffer( /* Build 2D states. *******************************************************/ -#if !defined(VIVANTE_NO_3D) +#if gcdENABLE_3D /**************************************************************************/ /* Build 3D states. *******************************************************/ + halti0 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ); + halti1 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ); + halti2 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ); + halti3 = (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures5)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ); - /* Query shader support. */ - gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps( - Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL)); + /* Query how many uniforms can support for non-unified uniform mode. */ + {if (Context->hardware->identity.numConstants > 256){ unifiedUniform = gcvTRUE; vsConstBase = 0xC000; psConstBase = 0xC000; constMax = Context->hardware->identity.numConstants; vertexUniforms = 256; fragmentUniforms = constMax - vertexUniforms;}else if (Context->hardware->identity.numConstants == 256){ if (Context->hardware->identity.chipModel == gcv2000 && Context->hardware->identity.chipRevision == 0x5118) { unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 64; constMax = 320; } else { unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 256; fragmentUniforms = 256; constMax = 512; }}else{ unifiedUniform = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vertexUniforms = 168; fragmentUniforms = 64; constMax = 232;}}; - /* Store the 3D entry index. */ - Context->entryOffset3D = index * gcmSIZEOF(gctUINT32); +#if !gcdENABLE_UNIFIED_CONSTANT + if (Context->hardware->identity.numConstants > 256) + { + unifiedUniform = gcvTRUE; + } + else + { + unifiedUniform = gcvFALSE; + } +#endif - /* Flush 2D pipe. */ - index += _FlushPipe(Context, index, gcvPIPE_2D); + /* Store the 3D entry index. */ + Context->entryOffset3D = (gctUINT)index * gcmSIZEOF(gctUINT32); /* Switch to 3D pipe. */ index += _SwitchPipe(Context, index, gcvPIPE_3D); @@ -489,14 +655,15 @@ _InitializeContextBuffer( index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x03854 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); /* Front End states. */ - fe2vsCount = 12; - if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) )) - { - fe2vsCount = 16; - } + fe2vsCount = 12; + if (halti0) + { + fe2vsCount = 16; + } index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE); index += _CLOSE_RANGE(); @@ -506,6 +673,7 @@ _InitializeContextBuffer( index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE); index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE); @@ -514,22 +682,44 @@ _InitializeContextBuffer( index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE); + if (halti2) + { + index += _State(Context, index, 0x14600 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14640 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14680 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE); + } + + /* This register is programed by all chips, which program all DECODE_SELECT as VS + ** except SAMPLER_DECODE_SELECT. + */ + index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + + if (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))))) + { + /* I-Cache states. */ + index += _State(Context, index, 0x00868 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x0086C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x0304C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x01028 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + + if (halti3) + { + index += _State(Context, index, 0x00890 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE); + index += _State(Context, index, 0x0104C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE); + index += _CLOSE_RANGE(); + } + } + /* Vertex Shader states. */ - index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - if (Context->hardware->identity.instructionCount <= 256) - { - index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE); - } index += _CLOSE_RANGE(); - index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE); /* Primitive Assembly states. */ index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE); @@ -543,14 +733,20 @@ _InitializeContextBuffer( index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00A40 >> 2, 0x00000000, Context->hardware->identity.varyingsCount, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE); index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00A88 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); +#if gcdMULTI_GPU + index += _State(Context, index, 0x03A00 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x03A04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x03A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); +#endif /* Setup states. */ index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE); index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE); @@ -569,21 +765,22 @@ _InitializeContextBuffer( index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00E24 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00E20 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + + if (halti2) + { + index += _State(Context, index, 0x00E0C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + } /* Pixel Shader states. */ - index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE); - if (Context->hardware->identity.instructionCount <= 256) - { - index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE); - } + index += _State(Context, index, 0x01030 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _CLOSE_RANGE(); - index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE); /* Texture states. */ index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE); @@ -612,21 +809,38 @@ _InitializeContextBuffer( index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE); index += _CLOSE_RANGE(); - if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) )) + if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 22:22)) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) )) + { + /* + * Linear stride LODn will overwrite LOD0 on GC880,GC2000. + * And only LOD0 is valid for this register. + */ + gctUINT count = halti1 ? 14 : 1; + + for (i = 0; i < 12; i += 1) + { + index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, count, gcvFALSE, gcvFALSE); + } + } + + if (halti1) { gctUINT texBlockCount; + gctUINT gcregTXLogSizeResetValue; + + /* Enable the integer filter pipe for all texture samplers + so that the floating point filter clock will shut off until + we start using the floating point filter. + */ + gcregTXLogSizeResetValue = ((((gctUINT32) (0x00000000)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 29:29) - (0 ? 29:29) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 29:29) - (0 ? 29:29) + 1))))))) << (0 ? 29:29))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 29:29) - (0 ? 29:29) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 29:29) - (0 ? 29:29) + 1))))))) << (0 ? 29:29))); /* New texture block. */ index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x10100 >> 2, gcregTXLogSizeResetValue, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); - for (i = 0; i < 256 / 16; i += 1) - { - index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, 14, gcvFALSE, gcvFALSE); - } index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); @@ -638,21 +852,33 @@ _InitializeContextBuffer( index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE); } - if ((Context->hardware->identity.chipModel == gcv2000) - && (Context->hardware->identity.chipRevision == 0x5108)) - { - texBlockCount = 12; - } - else - { - texBlockCount = ((512) >> (4)); - } + texBlockCount = ((512) >> (4)); + for (i = 0; i < texBlockCount; i += 1) { index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE); } } + if (halti2) + { + index += _State(Context, index, 0x10700 >> 2, 0x00000F00, 32, gcvFALSE, gcvFALSE); + } + + if (halti3) + { + index += _State(Context, index, 0x10780 >> 2, 0x00030000, 32, gcvFALSE, gcvFALSE); + } + + /* ASTC */ + if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures4)) >> (0 ? 13:13)) & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))) )) + { + index += _State(Context, index, 0x10500 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x10580 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x10600 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x10680 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE); + } + /* YUV. */ index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); @@ -676,47 +902,117 @@ _InitializeContextBuffer( index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + + if (((((gctUINT32) (Context->hardware->identity.chipMinorFeatures3)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))))) + { + index += _State(Context, index, 0x00940 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00944 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00948 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x0094C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00950 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00954 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + } + index += _CLOSE_RANGE(); - if (Context->hardware->identity.instructionCount > 1024) - { - /* New Shader instruction memory. */ - index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - index += _CLOSE_RANGE(); - - for (i = 0; - i < Context->hardware->identity.instructionCount << 2; - i += 256 << 2 - ) - { - index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE); - index += _CLOSE_RANGE(); - } - } - else if (Context->hardware->identity.instructionCount > 256) - { - /* New Shader instruction memory. */ - index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); - index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE); - index += _CLOSE_RANGE(); - - /* VX instruction memory. */ - for (i = 0; - i < Context->hardware->identity.instructionCount << 2; - i += 256 << 2 - ) - { - index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE); - index += _CLOSE_RANGE(); - } - - _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2); - } + if (!halti3) + { + if (Context->hardware->identity.instructionCount > 1024) + { + /* New Shader instruction PC registers. */ + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + + for (i = 0; + i < Context->hardware->identity.instructionCount << 2; + i += 256 << 2 + ) + { + index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + } + } + else if (Context->hardware->identity.instructionCount > 256) + { + /* New Shader instruction PC registers. */ + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + + /* VX instruction memory. */ + for (i = 0; + i < Context->hardware->identity.instructionCount << 2; + i += 256 << 2 + ) + { + index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + } + + _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2); + } + else /* if (Context->hardware->identity.instructionCount <= 256) */ + { + /* old shader instruction PC registers */ + index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + + index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + + index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + } + } + /* I cache use the new instruction PC registers */ + else + { + /* New Shader instruction PC registers. */ + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + } + + if (unifiedUniform) + { + gctINT numConstants = Context->hardware->identity.numConstants; + + index += _State(Context, index, 0x01024 >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x00864 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + + for (i = 0; + numConstants > 0; + i += 256 << 2, + numConstants -= 256 + ) + { + if (numConstants >= 256) + { + index += _State(Context, index, (0x30000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE); + } + else + { + index += _State(Context, index, (0x30000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE); + } + index += _CLOSE_RANGE(); + } + } +#if gcdENABLE_UNIFIED_CONSTANT + else +#endif + { + index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE); + } /* Store the index of the "XD" entry. */ - Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32); + Context->entryOffsetXDFrom3D = (gctUINT)index * gcmSIZEOF(gctUINT32); /* Pixel Engine states. */ @@ -757,16 +1053,31 @@ _InitializeContextBuffer( else { index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); + } + + if (Context->hardware->identity.pixelPipes > 1 || halti0) + { + index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); + } + + for (i = 0; i < 3; i++) + { + index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); + } - for (i = 0; i < 2; i++) + if (halti2) + { + for (i = 0; i < 7; i++) { - index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); + index += _State(Context, index, (0x14800 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); } + index += _State(Context, index, 0x14900 >> 2, 0x00000000, 7, gcvFALSE, gcvFALSE); } - if (Context->hardware->identity.pixelPipes > 1 || halti0) + + if (halti3) { - index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); + index += _State(Context, index, 0x014BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); } /* Resolve states. */ @@ -783,7 +1094,7 @@ _InitializeContextBuffer( index += _State(Context, index, 0x016B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); index += _CLOSE_RANGE(); - if (Context->hardware->identity.pixelPipes > 1) + if ((Context->hardware->identity.pixelPipes > 1) || halti1) { index += _State(Context, index, (0x016C0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE); @@ -792,6 +1103,49 @@ _InitializeContextBuffer( index += _State(Context, index, 0x01700 >> 2, 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvFALSE); } +#if gcd3DBLIT + index += _State(Context, index, (0x14000 >> 2) + (0 << 1), 0x00000000, 2, gcvFALSE, gcvTRUE); + index += _State(Context, index, 0x14008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1400C >> 2, 0x0001C800, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14010 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE); + index += _State(Context, index, 0x14014 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, (0x14018 >> 2) + (0 << 1), 0x00000000, 2, gcvFALSE, gcvTRUE); + index += _State(Context, index, 0x14020 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE); + index += _State(Context, index, 0x14024 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14028 >> 2, 0x0001C800, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1402C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14030 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14034 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14038 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1403C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14040 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14044 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14048 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1404C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14050 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14058 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1405C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14054 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14100 >> 2, 0x00000000, 64, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14200 >> 2, 0x00000000, 64, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14064 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14068 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + + index += _State(Context, index, 0x1406C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14070 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14074 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14078 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1407C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14080 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14084 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14088 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x1408C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14090 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + + index += _State(Context, index, 0x14094 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x14098 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); +#endif + /* Tile status. */ index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE); @@ -810,8 +1164,34 @@ _InitializeContextBuffer( index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE); index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE); index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE); + + + if (halti2) + { + index += _State(Context, index, 0x01780 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE); + index += _State(Context, index, 0x016BC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE); + index += _State(Context, index, (0x017A0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE); + index += _State(Context, index, (0x017C0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvTRUE); + index += _State(Context, index, (0x017E0 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvTRUE); + index += _State(Context, index, (0x01A00 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE); + index += _State(Context, index, (0x01A20 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE); + index += _State(Context, index, (0x01A40 >> 2) + 1, 0x00000000, 7, gcvFALSE, gcvFALSE); + } + index += _CLOSE_RANGE(); + if(((((gctUINT32) (Context->hardware->identity.chipMinorFeatures4)) >> (0 ? 25:25) & ((gctUINT32) ((((1 ? 25:25) - (0 ? 25:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:25) - (0 ? 25:25) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 25:25) - (0 ? 25:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:25) - (0 ? 25:25) + 1)))))))) + { + index += _State(Context, index, 0x03860 >> 2, 0x6, 1, gcvFALSE, gcvFALSE); + index += _CLOSE_RANGE(); + } + + if (halti3) + { + index += _State(Context, index, 0x01A80 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE); + index += _CLOSE_RANGE(); + } + /* Semaphore/stall. */ index += _SemaphoreStall(Context, index); #endif @@ -819,7 +1199,7 @@ _InitializeContextBuffer( /**************************************************************************/ /* Link to another address. ***********************************************/ - Context->linkIndex3D = index; + Context->linkIndex3D = (gctUINT)index; if (buffer != gcvNULL) { @@ -841,7 +1221,7 @@ _InitializeContextBuffer( /* Pipe switch for the case where neither 2D nor 3D are used. *************/ /* Store the 3D entry index. */ - Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32); + Context->entryOffsetXDFrom2D = (gctUINT)index * gcmSIZEOF(gctUINT32); /* Flush 2D pipe. */ index += _FlushPipe(Context, index, gcvPIPE_2D); @@ -850,7 +1230,7 @@ _InitializeContextBuffer( index += _SwitchPipe(Context, index, gcvPIPE_3D); /* Store the location of the link. */ - Context->linkIndexXD = index; + Context->linkIndexXD = (gctUINT)index; if (buffer != gcvNULL) { @@ -874,6 +1254,7 @@ _InitializeContextBuffer( /* Success. */ return gcvSTATUS_OK; } +#endif static gceSTATUS _DestroyContext( @@ -914,24 +1295,26 @@ _DestroyContext( /* Free state delta map. */ if (buffer->logical != gcvNULL) { -#if gcdVIRTUAL_COMMAND_BUFFER - gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer( - Context->hardware->kernel->eventObj, - Context->totalSize, - buffer->physical, - buffer->logical, - gcvKERNEL_PIXEL - )); - -#else - gcmkONERROR(gckEVENT_FreeContiguousMemory( - Context->hardware->kernel->eventObj, - Context->totalSize, - buffer->physical, - buffer->logical, - gcvKERNEL_PIXEL - )); -#endif + if (Context->hardware->kernel->virtualCommandBuffer) + { + gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer( + Context->hardware->kernel->eventObj, + Context->totalSize, + buffer->physical, + buffer->logical, + gcvKERNEL_PIXEL + )); + } + else + { + gcmkONERROR(gckEVENT_FreeContiguousMemory( + Context->hardware->kernel->eventObj, + Context->totalSize, + buffer->physical, + buffer->logical, + gcvKERNEL_PIXEL + )); + } buffer->logical = gcvNULL; } @@ -951,10 +1334,27 @@ _DestroyContext( } #endif /* Free record array copy. */ +#if REMOVE_DUPLICATED_COPY_FROM_USER + if (Context->recordArrayMap != gcvNULL) + { + gcsRECORD_ARRAY_MAP_PTR map = Context->recordArrayMap; + + do + { + /* Free record array. */ + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, map->kData)); + map = map->next; + } + while (map != Context->recordArrayMap); + + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArrayMap)); + } +#else if (Context->recordArray != gcvNULL) { gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray)); } +#endif /* Free the state mapping. */ if (Context->map != gcvNULL) @@ -1001,6 +1401,7 @@ OnError: ** Pointer to a variable thet will receive the gckCONTEXT object ** pointer. */ +#if (gcdENABLE_3D || gcdENABLE_2D) gceSTATUS gckCONTEXT_Construct( IN gckOS Os, @@ -1011,9 +1412,10 @@ gckCONTEXT_Construct( { gceSTATUS status; gckCONTEXT context = gcvNULL; - gctSIZE_T allocationSize; + gctUINT32 allocationSize; gctUINT i; gctPOINTER pointer = gcvNULL; + gctUINT32 address; gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware); @@ -1044,7 +1446,7 @@ gckCONTEXT_Construct( context->hardware = Hardware; -#if defined(VIVANTE_NO_3D) +#if !gcdENABLE_3D context->entryPipe = gcvPIPE_2D; context->exitPipe = gcvPIPE_2D; #elif gcdCMD_NO_2D_CONTEXT @@ -1081,7 +1483,7 @@ gckCONTEXT_Construct( /* Compute the size of the record array. **********************************/ context->recordArraySize - = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount; + = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * (gctUINT)context->stateCount; if (context->stateCount > 0) @@ -1127,6 +1529,8 @@ gckCONTEXT_Construct( /* Allocate a context buffer. */ gcsCONTEXT_PTR buffer; + gctSIZE_T totalSize = context->totalSize; + /* Allocate the context buffer structure. */ gcmkONERROR(gckOS_Allocate( Os, @@ -1169,26 +1573,43 @@ gckCONTEXT_Construct( )); /* Create a new physical context buffer. */ -#if gcdVIRTUAL_COMMAND_BUFFER - gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer( - context->hardware->kernel, - gcvFALSE, - &context->totalSize, - &buffer->physical, - &pointer - )); + if (context->hardware->kernel->virtualCommandBuffer) + { + gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer( + context->hardware->kernel, + gcvFALSE, + &totalSize, + &buffer->physical, + &pointer + )); -#else - gcmkONERROR(gckOS_AllocateContiguous( - Os, - gcvFALSE, - &context->totalSize, - &buffer->physical, - &pointer - )); -#endif + gcmkONERROR(gckKERNEL_GetGPUAddress( + context->hardware->kernel, + pointer, + gcvFALSE, + &address + )); + } + else + { + gcmkONERROR(gckOS_AllocateContiguous( + Os, + gcvFALSE, + &totalSize, + &buffer->physical, + &pointer + )); + + gcmkONERROR(gckHARDWARE_ConvertLogical( + context->hardware, + pointer, + gcvFALSE, + &address + )); + } buffer->logical = pointer; + buffer->address = address; /* Set gckEVENT object pointer. */ buffer->eventObj = Hardware->kernel->eventObj; @@ -1207,16 +1628,16 @@ gckCONTEXT_Construct( if (context->linkIndexXD != 0) { gctPOINTER xdLink; - gctUINT8_PTR xdEntryLogical; - gctSIZE_T xdEntrySize; - gctSIZE_T linkBytes; + gctUINT32 xdEntryAddress; + gctUINT32 xdEntrySize; + gctUINT32 linkBytes; /* Determine LINK parameters. */ xdLink = &buffer->logical[context->linkIndexXD]; - xdEntryLogical - = (gctUINT8_PTR) buffer->logical + xdEntryAddress + = buffer->address + context->entryOffsetXDFrom3D; xdEntrySize @@ -1225,14 +1646,14 @@ gckCONTEXT_Construct( /* Query LINK size. */ gcmkONERROR(gckHARDWARE_Link( - Hardware, gcvNULL, gcvNULL, 0, &linkBytes + Hardware, gcvNULL, 0, 0, &linkBytes )); /* Generate a LINK. */ gcmkONERROR(gckHARDWARE_Link( Hardware, xdLink, - xdEntryLogical, + xdEntryAddress, xdEntrySize, &linkBytes )); @@ -1291,6 +1712,7 @@ OnError: gcmkFOOTER(); return status; } +#endif /******************************************************************************\ ** @@ -1355,7 +1777,7 @@ gckCONTEXT_Update( IN gcsSTATE_DELTA_PTR StateDelta ) { -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D gceSTATUS status = gcvSTATUS_OK; gcsSTATE_DELTA _stateDelta; gckKERNEL kernel; @@ -1367,6 +1789,9 @@ gckCONTEXT_Update( gcsSTATE_DELTA_PTR kDelta = gcvNULL; gcsSTATE_DELTA_RECORD_PTR record; gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL; +#if REMOVE_DUPLICATED_COPY_FROM_USER + gcsRECORD_ARRAY_MAP_PTR recordArrayMap = gcvNULL; +#endif gctUINT elementCount; gctUINT address; gctUINT32 mask; @@ -1393,6 +1818,36 @@ gckCONTEXT_Update( gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy)); /* Allocate the copy buffer for the user record array. */ +#if REMOVE_DUPLICATED_COPY_FROM_USER + if (needCopy && (Context->recordArrayMap == gcvNULL)) + { + /* Allocate enough maps. */ + gcmkONERROR(gckOS_Allocate( + Context->os, + gcmSIZEOF(gcsRECORD_ARRAY_MAP_PTR) * gcdCONTEXT_BUFFER_COUNT, + (gctPOINTER *) &Context->recordArrayMap + )); + + for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i++) + { + /* Next mapping id. */ + gctUINT n = (i + 1) % gcdCONTEXT_BUFFER_COUNT; + + recordArrayMap = &Context->recordArrayMap[i]; + + /* Allocate the buffer. */ + gcmkONERROR(gckOS_Allocate( + Context->os, + Context->recordArraySize, + (gctPOINTER *) &recordArrayMap->kData + )); + + /* Initialize fields. */ + recordArrayMap->key = 0; + recordArrayMap->next = &Context->recordArrayMap[n]; + } + } +#else if (needCopy && (Context->recordArray == gcvNULL)) { /* Allocate the buffer. */ @@ -1402,6 +1857,7 @@ gckCONTEXT_Update( (gctPOINTER *) &Context->recordArray )); } +#endif /* Get the current context buffer. */ buffer = Context->buffer; @@ -1417,10 +1873,10 @@ gckCONTEXT_Update( gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache)); #endif -#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D) +#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && gcdENABLE_3D /* Update current context token. */ buffer->logical[Context->map[0x0E14].index] - = gcmPTR2INT(Context); + = (gctUINT32)gcmPTR2INT32(Context); #endif /* Are there any pending deltas? */ @@ -1446,6 +1902,58 @@ gckCONTEXT_Update( (gctPOINTER *) &kDelta )); +#if REMOVE_DUPLICATED_COPY_FROM_USER + if (needCopy) + { + recordArray = gcvNULL; + recordArrayMap = Context->recordArrayMap; + + do + { + /* Check if recordArray is alreay opened. */ + if (recordArrayMap->key == kDelta->recordArray) + { + /* Found. */ + recordArray = recordArrayMap->kData; + break; + } + + recordArrayMap = recordArrayMap->next; + } + while (recordArrayMap != Context->recordArrayMap); + + if (recordArray == gcvNULL) + { + while (recordArrayMap->key != 0) + { + /* Found an empty slot. */ + recordArrayMap = recordArrayMap->next; + } + + /* Get access to the state records. */ + gcmkONERROR(gckOS_CopyFromUserData( + kernel->os, + recordArrayMap->kData, + gcmUINT64_TO_PTR(kDelta->recordArray), + Context->recordArraySize + )); + + /* Save user pointer as key. */ + recordArrayMap->key = kDelta->recordArray; + recordArray = recordArrayMap->kData; + } + } + else + { + /* Get access to the state records. */ + gcmkONERROR(gckOS_MapUserPointer( + kernel->os, + gcmUINT64_TO_PTR(kDelta->recordArray), + Context->recordArraySize, + (gctPOINTER *) &recordArray + )); + } +#else /* Get access to the state records. */ gcmkONERROR(gckKERNEL_OpenUserData( kernel, needCopy, @@ -1453,6 +1961,7 @@ gckCONTEXT_Update( gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize, (gctPOINTER *) &recordArray )); +#endif /* Merge all pending states. */ for (j = 0; j < kDelta->recordCount; j += 1) @@ -1487,22 +1996,6 @@ gckCONTEXT_Update( /* Skip the state if not mapped. */ if (index == 0) { -#if gcdDEBUG - if ((address != 0x0594) - && (address != 0x0E00) - && (address != 0x0E03) - ) - { -#endif - gcmkTRACE( - gcvLEVEL_ERROR, - "%s(%d): State 0x%04X is not mapped.\n", - __FUNCTION__, __LINE__, - address - ); -#if gcdDEBUG - } -#endif continue; } @@ -1561,6 +2054,28 @@ gckCONTEXT_Update( /* Get the next state delta. */ nDelta = gcmUINT64_TO_PTR(kDelta->next); +#if REMOVE_DUPLICATED_COPY_FROM_USER + if (needCopy) + { + if (kDelta->refCount == 0) + { + /* No other reference, reset the mapping. */ + recordArrayMap->key = 0; + } + } + else + { + /* Close access to the state records. */ + gcmkONERROR(gckOS_UnmapUserPointer( + kernel->os, + gcmUINT64_TO_PTR(kDelta->recordArray), + Context->recordArraySize, + (gctPOINTER *) recordArray + )); + + recordArray = gcvNULL; + } +#else /* Get access to the state records. */ gcmkONERROR(gckKERNEL_CloseUserData( kernel, needCopy, @@ -1568,6 +2083,7 @@ gckCONTEXT_Update( gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize, (gctPOINTER *) &recordArray )); +#endif /* Close access to the current state delta. */ gcmkONERROR(gckKERNEL_CloseUserData( @@ -1678,10 +2194,10 @@ gckCONTEXT_Update( /* Get the next context buffer. */ buffer = buffer->next; - if (buffer == gcvNULL) - { - gcmkONERROR(gcvSTATUS_NOT_FOUND); - } + if (buffer == gcvNULL) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } } while (Context->buffer != buffer); @@ -1707,15 +2223,15 @@ gckCONTEXT_Update( OnError: /* Get access to the state records. */ - if (kDelta != gcvNULL) - { + if (kDelta != gcvNULL) + { gcmkVERIFY_OK(gckKERNEL_CloseUserData( kernel, needCopy, gcvFALSE, gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize, (gctPOINTER *) &recordArray )); - } + } /* Close access to the current state delta. */ gcmkVERIFY_OK(gckKERNEL_CloseUserData( @@ -1733,3 +2249,69 @@ OnError: #endif } +gceSTATUS +gckCONTEXT_MapBuffer( + IN gckCONTEXT Context, + OUT gctUINT32 *Physicals, + OUT gctUINT64 *Logicals, + OUT gctUINT32 *Bytes + ) +{ + gceSTATUS status; + int i = 0; + gctSIZE_T pageCount; + gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer; + gckKERNEL kernel = Context->hardware->kernel; + gctPOINTER logical; + gctPHYS_ADDR physical; + + gcsCONTEXT_PTR buffer; + + gcmkHEADER(); + + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT); + + buffer = Context->buffer; + + for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i++) + { + if (kernel->virtualCommandBuffer) + { + commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)buffer->physical; + physical = commandBuffer->physical; + + gcmkONERROR(gckOS_CreateUserVirtualMapping( + kernel->os, + physical, + Context->totalSize, + &logical, + &pageCount)); + } + else + { + physical = buffer->physical; + + gcmkONERROR(gckOS_MapMemory( + kernel->os, + physical, + Context->totalSize, + &logical)); + } + + Physicals[i] = gcmPTR_TO_NAME(physical); + + Logicals[i] = gcmPTR_TO_UINT64(logical); + + buffer = buffer->next; + } + + *Bytes = (gctUINT)Context->totalSize; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h similarity index 83% rename from drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h rename to drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h index 5d2c7c77ee90..29e6a5321e0d 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -24,6 +24,9 @@ #include "gc_hal_kernel_buffer.h" +/* Exprimental optimization. */ +#define REMOVE_DUPLICATED_COPY_FROM_USER 1 + #ifdef __cplusplus extern "C" { #endif @@ -61,6 +64,9 @@ typedef struct _gcsCONTEXT /* Logical address of the context buffer. */ gctUINT32_PTR logical; + /* Hardware address of the context buffer. */ + gctUINT32 address; + /* Pointer to the LINK commands. */ gctPOINTER link2D; gctPOINTER link3D; @@ -76,6 +82,20 @@ typedef struct _gcsCONTEXT } gcsCONTEXT; +typedef struct _gcsRECORD_ARRAY_MAP * gcsRECORD_ARRAY_MAP_PTR; +struct _gcsRECORD_ARRAY_MAP +{ + /* User pointer key. */ + gctUINT64 key; + + /* Kernel memory buffer. */ + gcsSTATE_DELTA_RECORD_PTR kData; + + /* Next map. */ + gcsRECORD_ARRAY_MAP_PTR next; + +}; + /* gckCONTEXT structure that hold the current context. */ struct _gckCONTEXT { @@ -89,14 +109,14 @@ struct _gckCONTEXT gckHARDWARE hardware; /* Command buffer alignment. */ - gctSIZE_T alignment; - gctSIZE_T reservedHead; - gctSIZE_T reservedTail; + gctUINT32 alignment; + gctUINT32 reservedHead; + gctUINT32 reservedTail; /* Context buffer metrics. */ gctSIZE_T stateCount; - gctSIZE_T totalSize; - gctSIZE_T bufferSize; + gctUINT32 totalSize; + gctUINT32 bufferSize; gctUINT32 linkIndex2D; gctUINT32 linkIndex3D; gctUINT32 linkIndexXD; @@ -118,7 +138,11 @@ struct _gckCONTEXT /* A copy of the user record array. */ gctUINT recordArraySize; +#if REMOVE_DUPLICATED_COPY_FROM_USER + gcsRECORD_ARRAY_MAP_PTR recordArrayMap; +#else gcsSTATE_DELTA_RECORD_PTR recordArray; +#endif /* Requested pipe select for context. */ gcePIPE_SELECT entryPipe; @@ -130,6 +154,8 @@ struct _gckCONTEXT gctUINT32 lastIndex; gctBOOL lastFixed; + gctUINT32 pipeSelectBytes; + /* Hint array. */ #if gcdSECURE_USER gctBOOL_PTR hint; diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c similarity index 77% rename from drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c rename to drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c index e8ad2ea3e031..3a225a9a208d 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -25,8 +25,32 @@ #include "gc_hal_kernel_context.h" #endif +#define gcdDISABLE_FE_L2 1 + #define _GC_OBJ_ZONE gcvZONE_HARDWARE +#define gcmSEMAPHORESTALL(buffer) \ + do \ + { \ + /* Arm the PE-FE Semaphore. */ \ + *buffer++ \ + = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, 1) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, 0x0E02); \ + \ + *buffer++ \ + = gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END) \ + | gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE);\ + \ + /* STALL FE until PE is done flushing. */ \ + *buffer++ \ + = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \ + \ + *buffer++ \ + = gcmSETFIELDVALUE(0, STALL_STALL, SOURCE, FRONT_END) \ + | gcmSETFIELDVALUE(0, STALL_STALL, DESTINATION, PIXEL_ENGINE); \ + } while(0) + typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR; typedef struct _gcsiDEBUG_REGISTERS { @@ -39,10 +63,20 @@ typedef struct _gcsiDEBUG_REGISTERS } gcsiDEBUG_REGISTERS; -extern int gpu3DMinClock; /******************************************************************************\ ********************************* Support Code ********************************* \******************************************************************************/ +static gctBOOL +_IsHardwareMatch( + IN gckHARDWARE Hardware, + IN gctINT32 ChipModel, + IN gctUINT32 ChipRevision + ) +{ + return ((Hardware->identity.chipModel == ChipModel) && + (Hardware->identity.chipRevision == ChipRevision)); +} + static gceSTATUS _ResetGPU( IN gckHARDWARE Hardware, @@ -72,7 +106,9 @@ _IdentifyHardware( gctUINT32 numConstants = 0; gctUINT32 bufferSize = 0; gctUINT32 varyingsCount = 0; - gctBOOL useHZ; +#if gcdMULTI_GPU + gctUINT32 gpuCoreCount = 0; +#endif gcmkHEADER_ARG("Os=0x%x", Os); @@ -101,12 +137,9 @@ _IdentifyHardware( 0x00020, (gctUINT32_PTR) &Identity->chipModel)); - /* !!!! HACK ALERT !!!! */ - /* Because people change device IDs without letting software know - ** about it - here is the hack to make it all look the same. Only - ** for GC400 family. Next time - TELL ME!!! */ if (((Identity->chipModel & 0xFF00) == 0x0400) - && (Identity->chipModel != 0x0420)) + && (Identity->chipModel != 0x0420) + && (Identity->chipModel != 0x0428)) { Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400); } @@ -141,6 +174,11 @@ _IdentifyHardware( Identity->chipRevision = 0x1051; } } + + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, + 0x000A8, + &Identity->productID)); } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, @@ -162,7 +200,7 @@ _IdentifyHardware( 0x0001C, &Identity->chipFeatures)); -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D /* Disable fast clear on GC700. */ if (Identity->chipModel == gcv700) { @@ -181,6 +219,7 @@ _IdentifyHardware( Identity->chipMinorFeatures2 = 0; Identity->chipMinorFeatures3 = 0; Identity->chipMinorFeatures4 = 0; + Identity->chipMinorFeatures5 = 0; } else { @@ -213,20 +252,18 @@ _IdentifyHardware( 0x00088, &Identity->chipMinorFeatures3)); - /*The BG2 chip has no compression supertiled, and the bit of GCMinorFeature3BugFixes15 is n/a*/ - if(Identity->chipModel == gcv1000 && Identity->chipRevision == 0x5036) - { - Identity->chipMinorFeatures3 - = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); - Identity->chipMinorFeatures3 - = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))); - } /* Read chip minor featuress register #4. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00094, &Identity->chipMinorFeatures4)); + + /* Read chip minor featuress register #5. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, + 0x000A0, + &Identity->chipMinorFeatures5)); } else { @@ -235,6 +272,7 @@ _IdentifyHardware( Identity->chipMinorFeatures2 = 0; Identity->chipMinorFeatures3 = 0; Identity->chipMinorFeatures4 = 0; + Identity->chipMinorFeatures5 = 0; } } @@ -256,53 +294,17 @@ _IdentifyHardware( /* Exception for GC1000, revision 5035 & GC800, revision 4612 */ if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035) || (Identity->chipRevision == 0x5036) - || (Identity->chipRevision == 0x5037))) - || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612)) - || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647))) + || (Identity->chipRevision == 0x5037) + || (Identity->chipRevision == 0x5039) + || (Identity->chipRevision >= 0x5040))) + || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612)) + || ((Identity->chipModel == gcv600) && (Identity->chipRevision >= 0x4650)) + || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647)) + || ((Identity->chipModel == gcv400) && (Identity->chipRevision >= 0x4633))) { Identity->superTileMode = 1; } - if (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245) - { - useHZ = ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) - || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))); - } - else - { - useHZ = gcvFALSE; - } - - if (useHZ) - { - /* Disable EZ. */ - Identity->chipFeatures - = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))); - } - - /* Disable HZ when EZ is present for older chips. */ - else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))))) - { - /* Disable HIERARCHICAL_Z. */ - Identity->chipMinorFeatures - = ((((gctUINT32) (Identity->chipMinorFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))); - } - - /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/ - if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106)) - { - /* Disable rectangle primitive. */ - Identity->chipMinorFeatures2 - = ((((gctUINT32) (Identity->chipMinorFeatures2)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); - } - - if ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4605)) - { - /* Correct feature bit: RTL does not have such feature. */ - Identity->chipFeatures - = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))); - } - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipFeatures=0x%08X", Identity->chipFeatures); @@ -327,13 +329,17 @@ _IdentifyHardware( "Identity: chipMinorFeatures4=0x%08X", Identity->chipMinorFeatures4); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Identity: chipMinorFeatures5=0x%08X", + Identity->chipMinorFeatures5); + /*************************************************************************** ** Get chip specs. */ if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))))) { - gctUINT32 specs, specs2, specs3; + gctUINT32 specs, specs2, specs3, specs4; /* Read gcChipSpecs register. */ gcmkONERROR( @@ -342,7 +348,6 @@ _IdentifyHardware( &specs)); /* Extract the fields. */ - streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) ); registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) ); threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) ); shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) ); @@ -367,6 +372,39 @@ _IdentifyHardware( &specs3)); varyingsCount = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) ); +#if gcdMULTI_GPU + gpuCoreCount = (((((gctUINT32) (specs3)) >> (0 ? 2:0)) & ((gctUINT32) ((((1 ? 2:0) - (0 ? 2:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:0) - (0 ? 2:0) + 1)))))) ); +#endif + + /* Read gcChipSpecs4 register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, + 0x0009C, + &specs4)); + + + streamCount = (((((gctUINT32) (specs4)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) ); + if (streamCount == 0) + { + /* Extract stream count from older register. */ + streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) ); + } + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Identity: chipSpecs1=0x%08X", + specs); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Identity: chipSpecs2=0x%08X", + specs2); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Identity: chipSpecs3=0x%08X", + specs3); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Identity: chipSpecs4=0x%08X", + specs4); } /* Get the number of pixel pipes. */ @@ -456,11 +494,10 @@ _IdentifyHardware( { Identity->instructionCount = 512; } - } - - if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))))) - { - Identity->instructionCount = 512; + else if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))))) + { + Identity->instructionCount = 512; + } } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, @@ -487,9 +524,7 @@ _IdentifyHardware( if (varyingsCount != 0) { - /* Bug 4480. */ - /*Identity->varyingsCount = varyingsCount;*/ - Identity->varyingsCount = 12; + Identity->varyingsCount = varyingsCount; } else if (((((gctUINT32) (Identity->chipMinorFeatures1)) >> (0 ? 23:23) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))))) { @@ -501,14 +536,57 @@ _IdentifyHardware( } /* For some cores, it consumes two varying for position, so the max varying vectors should minus one. */ - if ((Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) || + if ((Identity->chipModel == gcv5000 && Identity->chipRevision == 0x5434) || + (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) || (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5208) || + (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245) || + (Identity->chipModel == gcv3000 && Identity->chipRevision == 0x5435) || + (Identity->chipModel == gcv2200 && Identity->chipRevision == 0x5244) || + (Identity->chipModel == gcv1500 && Identity->chipRevision == 0x5246) || ((Identity->chipModel == gcv2100 || Identity->chipModel == gcv2000) && Identity->chipRevision == 0x5108) || (Identity->chipModel == gcv880 && (Identity->chipRevision == 0x5107 || Identity->chipRevision == 0x5106))) { Identity->varyingsCount -= 1; } + Identity->chip2DControl = 0; + if (Identity->chipModel == gcv320) + { + gctUINT32 data; + + gcmkONERROR( + gckOS_ReadRegisterEx(Os, + Core, + 0x0002C, + &data)); + + if ((data != 33956864) && + ((Identity->chipRevision == 0x5007) || + (Identity->chipRevision == 0x5220))) + { + Identity->chip2DControl |= 0xFF & + (Identity->chipRevision == 0x5220 ? 8 : + (Identity->chipRevision == 0x5007 ? 12 : 0)); + } + + if (Identity->chipRevision == 0x5007) + { + /* Disable splitting rectangle. */ + Identity->chip2DControl |= 0x100; + + /* Enable 2D Flush. */ + Identity->chip2DControl |= 0x200; + } + } + +#if gcdMULTI_GPU +#if gcdMULTI_GPU > 1 + Identity->gpuCoreCount = gpuCoreCount + 1; +#else + Identity->gpuCoreCount = 1; +#endif +#endif + /* Success. */ gcmkFOOTER(); return gcvSTATUS_OK; @@ -519,6 +597,99 @@ OnError: return status; } +#define gcdDEBUG_MODULE_CLOCK_GATING 0 +#define gcdDISABLE_MODULE_CLOCK_GATING 0 +#define gcdDISABLE_FE_CLOCK_GATING 0 +#define gcdDISABLE_PE_CLOCK_GATING 0 +#define gcdDISABLE_SH_CLOCK_GATING 0 +#define gcdDISABLE_PA_CLOCK_GATING 0 +#define gcdDISABLE_SE_CLOCK_GATING 0 +#define gcdDISABLE_RA_CLOCK_GATING 0 +#define gcdDISABLE_RA_EZ_CLOCK_GATING 0 +#define gcdDISABLE_RA_HZ_CLOCK_GATING 0 +#define gcdDISABLE_TX_CLOCK_GATING 0 + +#if gcdDEBUG_MODULE_CLOCK_GATING +gceSTATUS +_ConfigureModuleLevelClockGating( + gckHARDWARE Hardware + ) +{ + gctUINT32 data; + + gcmkVERIFY_OK( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + &data)); + +#if gcdDISABLE_FE_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); +#endif + +#if gcdDISABLE_PE_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))); +#endif + +#if gcdDISABLE_SH_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))); +#endif + +#if gcdDISABLE_PA_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); +#endif + +#if gcdDISABLE_SE_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); +#endif + +#if gcdDISABLE_RA_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); +#endif + +#if gcdDISABLE_TX_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))); +#endif + +#if gcdDISABLE_RA_EZ_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))); +#endif + +#if gcdDISABLE_RA_HZ_CLOCK_GATING + data = ((((gctUINT32) (data)) & ~(((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))); +#endif + + gcmkVERIFY_OK( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + data)); + +#if gcdDISABLE_MODULE_CLOCK_GATING + gcmkVERIFY_OK( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00100, + &data)); + + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + + gcmkVERIFY_OK( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00100, + data)); +#endif + + return gcvSTATUS_OK; +} +#endif + #if gcdPOWEROFF_TIMEOUT void _PowerTimerFunction( @@ -689,7 +860,7 @@ _FlushCache( ) { gceSTATUS status; - gctSIZE_T bytes, requested; + gctUINT32 bytes, requested; gctPOINTER buffer; /* Get the size of the flush command. */ @@ -718,6 +889,22 @@ OnError: return status; } +gctBOOL +_IsGPUIdle( + IN gctUINT32 Idle + ) +{ + return (((((gctUINT32) (Idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) + && (((((gctUINT32) (Idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) + ; +} + /******************************************************************************\ ****************************** gckHARDWARE API code ***************************** \******************************************************************************/ @@ -752,8 +939,10 @@ gckHARDWARE_Construct( gceSTATUS status; gckHARDWARE hardware = gcvNULL; gctUINT16 data = 0xff00; - gctUINT32 axi_ot; gctPOINTER pointer = gcvNULL; +#if gcdMULTI_GPU_AFFINITY + gctUINT32 control; +#endif gcmkHEADER_ARG("Os=0x%x", Os); @@ -791,26 +980,32 @@ gckHARDWARE_Construct( hardware->type = gcvHARDWARE_VG; break; + case gcv200: case gcv300: case gcv320: + case gcv328: 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: +#if gcdMULTI_GPU_AFFINITY + hardware->type = (Core == gcvCORE_MAJOR) ? gcvHARDWARE_3D : gcvHARDWARE_OCL; +#else hardware->type = gcvHARDWARE_3D; - if(hardware->identity.chipModel == gcv880) +#endif + + if(hardware->identity.chipModel == gcv880 && hardware->identity.chipRevision == 0x5107) { /*set outstanding limit*/ + gctUINT32 axi_ot; gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot)); - axi_ot = (axi_ot & (~0xFF)) | 0x10; + axi_ot = (axi_ot & (~0xFF)) | 0x00010; gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot)); } + if ((((((gctUINT32) (hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )) { hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D); @@ -832,6 +1027,25 @@ gckHARDWARE_Construct( "_ResetGPU failed: status=%d\n", status); } +#if gcdMULTI_GPU + gcmkONERROR(gckOS_WriteRegisterEx(Os, + Core, + 0x0055C, +#if gcdDISABLE_FE_L2 + 0x00FFFFFF)); +#else + 0x00FFFF05)); +#endif + +#elif gcdMULTI_GPU_AFFINITY + control = ((((gctUINT32) (0x00FF0A05)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))); + + gcmkONERROR(gckOS_WriteRegisterEx(Os, + Core, + 0x0055C, + control)); +#endif + hardware->powerMutex = gcvNULL; hardware->mmuVersion @@ -861,6 +1075,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; @@ -881,6 +1096,7 @@ gckHARDWARE_Construct( #endif gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty)); + gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pendingEvent)); #if gcdLINK_QUEUE_SIZE hardware->linkQueue.front = 0; @@ -894,6 +1110,21 @@ gckHARDWARE_Construct( /* Disable profiler by default */ hardware->gpuProfiler = gcvFALSE; +#if defined(LINUX) || defined(__QNXNTO__) || defined(UNDERCE) + if (hardware->mmuVersion) + { + hardware->endAfterFlushMmuCache = gcvTRUE; + } + else +#endif + { + hardware->endAfterFlushMmuCache = gcvFALSE; + } + + gcmkONERROR(gckOS_QueryOption(Os, "mmu", (gctUINT32_PTR)&hardware->enableMMU)); + + hardware->minFscaleValue = 1; + /* Return pointer to the gckHARDWARE object. */ *Hardware = hardware; @@ -934,6 +1165,11 @@ OnError: gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty)); } + if (hardware->pendingEvent != gcvNULL) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pendingEvent)); + } + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware)); } @@ -983,6 +1219,15 @@ gckHARDWARE_Destroy( gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty)); + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pendingEvent)); + + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory( + Hardware->os, + Hardware->functionBytes, + Hardware->functionPhysical, + Hardware->functionLogical + )); + /* Mark the object as unknown. */ Hardware->object.type = gcvOBJ_UNKNOWN; @@ -1053,6 +1298,8 @@ gckHARDWARE_InitializeHardware( gctUINT32 baseAddress; gctUINT32 chipRev; gctUINT32 control; + gctUINT32 data; + gctUINT32 regPMC = 0; gcmkHEADER_ARG("Hardware=0x%x", Hardware); @@ -1128,10 +1375,7 @@ gckHARDWARE_InitializeHardware( 0x00424, baseAddress)); -#if !VIVANTE_PROFILER { - gctUINT32 data; - gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, Hardware->powerBaseAddress + @@ -1156,80 +1400,75 @@ gckHARDWARE_InitializeHardware( + 0x00100, data)); -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D /* Disable PE clock gating on revs < 5.0 when HZ is present without a ** bug fix. */ if ((Hardware->identity.chipRevision < 0x5000) + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HZ) && ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) - && ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) ) { - gcmkONERROR( - gckOS_ReadRegisterEx(Hardware->os, - Hardware->core, - Hardware->powerBaseAddress - + 0x00104, - &data)); + if (regPMC == 0) + { + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + ®PMC)); + } /* Disable PE clock gating. */ - data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))); - - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - Hardware->powerBaseAddress - + 0x00104, - data)); + regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))); } #endif } -#endif - /* Special workaround for this core - ** Make sure pulse eater kicks in only when SH is idle */ if (Hardware->identity.chipModel == gcv4000 && - Hardware->identity.chipRevision == 0x5208) + ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222))) { - gcmkONERROR( + gcmkONERROR( gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0010C, ((((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 ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvFALSE) - || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) && (Hardware->identity.chipRevision < 0x5422)) - ) + if (Hardware->identity.chipModel == gcv1000 && + (Hardware->identity.chipRevision == 0x5039 || + Hardware->identity.chipRevision == 0x5040)) { - gctUINT32 data; - - gcmkONERROR( - gckOS_ReadRegisterEx(Hardware->os, - Hardware->core, - Hardware->powerBaseAddress - + 0x00104, - &data)); - - - data = ((((gctUINT32) (data)) & ~(((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))); + 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, - Hardware->powerBaseAddress - + 0x00104, - data)); + 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))))); } - /* Special workaround for this core - ** Make sure FE and TX are on different buses */ - if ((Hardware->identity.chipModel == gcv2000) - && (Hardware->identity.chipRevision == 0x5108)) + if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvSTATUS_FALSE) + || (Hardware->identity.chipRevision < 0x5422) + ) { - gctUINT32 data; + if (regPMC == 0) + { + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + ®PMC)); + } + + 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( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, @@ -1247,58 +1486,64 @@ gckHARDWARE_InitializeHardware( data)); } - /* Test if MMU is initialized. */ - if ((Hardware->kernel != gcvNULL) - && (Hardware->kernel->mmu != gcvNULL) - ) + gcmkONERROR( + gckHARDWARE_SetMMU(Hardware, + Hardware->kernel->mmu->pageTableLogical)); + + if (Hardware->identity.chipModel >= gcv400 + && Hardware->identity.chipModel != gcv420) { - /* Reset MMU. */ - if (Hardware->mmuVersion == 0) + if (regPMC == 0) { - gcmkONERROR( - gckHARDWARE_SetMMU(Hardware, - Hardware->kernel->mmu->pageTableLogical)); + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + ®PMC)); } + + /* Disable PA clock gating. */ + regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); } - if (Hardware->identity.chipModel >= gcv400 - && Hardware->identity.chipModel != gcv420 - && (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 15:15) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) != gcvTRUE) - ) + /* Limit 2D outstanding request. */ + if (_IsHardwareMatch(Hardware, gcv880, 0x5107)) { - gctUINT32 data; + gctUINT32 axi_ot; + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot)); + axi_ot = (axi_ot & (~0xFF)) | 0x00010; + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot)); + } + + if (Hardware->identity.chip2DControl & 0xFF) + { + gctUINT32 data; gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, - Hardware->powerBaseAddress - + 0x00104, + 0x00414, &data)); - /* Disable PA clock gating. */ - data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.chip2DControl & 0xFF) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))); gcmkONERROR( gckOS_WriteRegisterEx(Hardware->os, Hardware->core, - Hardware->powerBaseAddress - + 0x00104, + 0x00414, data)); } -#if gcdHZ_L2_DISALBE - /* Disable HZ-L2. */ - if (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) == gcvTRUE || - ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) == gcvTRUE) + if (_IsHardwareMatch(Hardware, gcv1000, 0x5035)) { - gctUINT32 data; - gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &data)); + /* Disable HZ-L2. */ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))); gcmkONERROR( @@ -1307,51 +1552,88 @@ gckHARDWARE_InitializeHardware( 0x00414, data)); } -#endif - /* Limit 2D outstanding request. */ - if(Hardware->identity.chipModel == gcv880) + if (_IsHardwareMatch(Hardware, gcv4000, 0x5222)) { - gctUINT32 axi_ot; - gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot)); - axi_ot = (axi_ot & (~0xFF)) | 0x10; - gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot)); + if (regPMC == 0) + { + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + ®PMC)); + } + + /* Disable TX clock gating. */ + regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))); } - if ((Hardware->identity.chipModel == gcv320) - && ((Hardware->identity.chipRevision == 0x5007) - || (Hardware->identity.chipRevision == 0x5220))) + if (_IsHardwareMatch(Hardware, gcv880, 0x5106)) { - gctUINT32 data; + Hardware->kernel->timeOut = 140 * 1000; + } + if (regPMC == 0) + { gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, - 0x0002C, - &data)); - if (data != 33956864) - { - gcmkONERROR( - gckOS_ReadRegisterEx(Hardware->os, + Hardware->powerBaseAddress + + 0x00104, + ®PMC)); + } + + /* Disable RA HZ clock gating. */ + regPMC = ((((gctUINT32) (regPMC)) & ~(((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))); + + /* Disable RA EZ clock gating. */ + regPMC = ((((gctUINT32) (regPMC)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))); + + if (regPMC != 0) + { + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + 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 ((Hardware->identity.chipRevision > 0x5420) + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)) + { + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, - 0x00414, + 0x0010C, &data)); - data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.chipRevision == 0x5220 ? 8 : (Hardware->identity.chipRevision == 0x5007 ? 16 : 0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))); + /* Disable internal DFS. */ + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))); - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, - 0x00414, + 0x0010C, data)); - } } - /* Update GPU AXI cache atttribute. */ - gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00008, - 0x00002200)); +#if gcdDEBUG_MODULE_CLOCK_GATING + _ConfigureModuleLevelClockGating(Hardware); +#endif /* Success. */ gcmkFOOTER_NO(); @@ -1539,6 +1821,7 @@ gckHARDWARE_QueryChipIdentity( Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2; Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3; Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4; + Identity->chipMinorFeatures5 = Hardware->identity.chipMinorFeatures5; /* Return chip specs. */ Identity->streamCount = Hardware->identity.streamCount; @@ -1553,6 +1836,12 @@ gckHARDWARE_QueryChipIdentity( Identity->bufferSize = Hardware->identity.bufferSize; Identity->varyingsCount = Hardware->identity.varyingsCount; Identity->superTileMode = Hardware->identity.superTileMode; +#if gcdMULTI_GPU + Identity->gpuCoreCount = Hardware->identity.gpuCoreCount; +#endif + Identity->chip2DControl = Hardware->identity.chip2DControl; + + Identity->productID = Hardware->identity.productID; /* Success. */ gcmkFOOTER_NO(); @@ -1643,8 +1932,8 @@ gckHARDWARE_SplitMemory( ** gckHARDWARE Hardware ** Pointer to the gckHARDWARE object. ** -** gctPOINTER Logical -** Logical address of command buffer. +** gctUINT32 Address +** Hardware address of command buffer. ** ** gctSIZE_T Bytes ** Number of bytes for the prefetch unit (until after the first LINK). @@ -1656,40 +1945,18 @@ gckHARDWARE_SplitMemory( gceSTATUS gckHARDWARE_Execute( IN gckHARDWARE Hardware, - IN gctPOINTER Logical, -#ifdef __QNXNTO__ - IN gctPOINTER Physical, - IN gctBOOL PhysicalAddresses, -#endif + IN gctUINT32 Address, IN gctSIZE_T Bytes ) { gceSTATUS status; - gctUINT32 address = 0, control; + gctUINT32 control; - gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu", - Hardware, Logical, Bytes); + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Bytes=%lu", + Hardware, Address, Bytes); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); - gcmkVERIFY_ARGUMENT(Logical != gcvNULL); - -#ifdef __QNXNTO__ - if (PhysicalAddresses && (Hardware->mmuVersion == 0)) - { - /* Convert physical into hardware specific address. */ - gcmkONERROR( - gckHARDWARE_ConvertPhysical(Hardware, Physical, &address)); - } - else - { -#endif - /* Convert logical into hardware specific address. */ - gcmkONERROR( - gckHARDWARE_ConvertLogical(Hardware, Logical, &address)); -#ifdef __QNXNTO__ - } -#endif /* Enable all events. */ gcmkONERROR( @@ -1697,7 +1964,7 @@ gckHARDWARE_Execute( /* Write address register. */ gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address)); + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address)); /* Build control register. */ control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) @@ -1715,7 +1982,7 @@ gckHARDWARE_Execute( gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Started command buffer @ 0x%08x", - address); + Address); /* Success. */ gcmkFOOTER_NO(); @@ -1772,9 +2039,9 @@ gckHARDWARE_WaitLink( IN gckHARDWARE Hardware, IN gctPOINTER Logical, IN gctUINT32 Offset, - IN OUT gctSIZE_T * Bytes, + IN OUT gctUINT32 * Bytes, OUT gctUINT32 * WaitOffset, - OUT gctSIZE_T * WaitSize + OUT gctUINT32 * WaitSize ) { static const gctUINT waitCount = 200; @@ -1782,7 +2049,7 @@ gckHARDWARE_WaitLink( gceSTATUS status; gctUINT32 address; gctUINT32_PTR logical; - gctSIZE_T bytes; + gctUINT32 bytes; gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu", Hardware, Logical, Offset, gcmOPT_VALUE(Bytes)); @@ -1791,13 +2058,12 @@ gckHARDWARE_WaitLink( gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL)); - /* Compute number of bytes required. */ -#if gcd6000_SUPPORT - bytes = gcmALIGN(Offset + 96, 8) - Offset; +#if gcdMULTI_GPU && !gcdDISABLE_FE_L2 + bytes = gcmALIGN(Offset + 40, 8) - Offset; #else + /* Compute number of bytes required. */ bytes = gcmALIGN(Offset + 16, 8) - Offset; #endif - /* Cast the input pointer. */ logical = (gctUINT32_PTR) Logical; @@ -1811,7 +2077,7 @@ gckHARDWARE_WaitLink( } /* Convert logical into hardware specific address. */ - gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address)); + gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, gcvFALSE, &address)); /* Store the WAIT/LINK address. */ Hardware->lastWaitLink = address; @@ -1821,99 +2087,45 @@ gckHARDWARE_WaitLink( = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (waitCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); -#if gcd6000_SUPPORT - /* Send FE-PE sempahore token. */ - logical[2] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - - logical[3] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); +#if gcdMULTI_GPU && !gcdDISABLE_FE_L2 + logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | gcvCORE_3D_0_MASK; - /* Send FE-PE stall token. */ - logical[4] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + logical[3] = 0; - logical[5] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - - /*************************************************************/ - /* Enable chip ID 0. */ - logical[6] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | (1 << 0); - - /* Send semaphore from FE to ChipID 1. */ - logical[8] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - - logical[9] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); - - /* Send semaphore from FE to ChipID 1. */ - logical[10] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); - - logical[11] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); - - /*************************************************************/ - /* Enable chip ID 1. */ - logical[12] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | (1 << 1); - - /* Send semaphore from FE to ChipID 1. */ - logical[14] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + /* LoadState(AQFlush, 1), flush. */ + logical[4] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - logical[15] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); + logical[5] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); - /* Wait for semaphore from ChipID 0. */ - logical[16] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + logical[6] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | gcvCORE_3D_ALL_MASK; - logical[17] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); + logical[7] = 0; - /*************************************************************/ - /* Enable all chips. */ - logical[18] = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | (0xFFFF); + /* Append LINK(2, address). */ + logical[8] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - /* LoadState(AQFlush, 1), flush. */ - logical[20] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + logical[9] = address; - logical[21] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%08x: WAIT %u", address, waitCount + ); - /* Append LINK(2, address). */ - logical[22] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: FLUSH 0x%x", address + 8, logical[3]); - logical[23] = address; + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%08x: LINK 0x%08x, #%lu", + address + 16, address, bytes + ); #else + /* Append LINK(2, address). */ logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) @@ -1932,7 +2144,6 @@ gckHARDWARE_WaitLink( address + 8, address, bytes ); #endif - if (WaitOffset != gcvNULL) { /* Return the offset pointer to WAIT command. */ @@ -1942,7 +2153,11 @@ gckHARDWARE_WaitLink( if (WaitSize != gcvNULL) { /* Return number of bytes used by the WAIT command. */ +#if gcdMULTI_GPU && !gcdDISABLE_FE_L2 + *WaitSize = 32; +#else *WaitSize = 8; +#endif } } @@ -1994,10 +2209,11 @@ gceSTATUS gckHARDWARE_End( IN gckHARDWARE Hardware, IN gctPOINTER Logical, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gctUINT32 address; gceSTATUS status; gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu", @@ -2024,6 +2240,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) @@ -2042,43 +2262,20 @@ OnError: return status; } -/******************************************************************************* -** -** gckHARDWARE_Nop -** -** Append a NOP command at the specified location in the command queue. -** -** INPUT: -** -** gckHARDWARE Hardware -** Pointer to an gckHARDWARE object. -** -** gctPOINTER Logical -** Pointer to the current location inside the command queue to append -** NOP command at or gcvNULL just to query the size of the NOP command. -** -** gctSIZE_T * Bytes -** Pointer to the number of bytes available for the NOP command. If -** 'Logical' is gcvNULL, this argument will be ignored. -** -** OUTPUT: -** -** gctSIZE_T * Bytes -** Pointer to a variable that will receive the number of bytes required -** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned. -*/ +#if gcdMULTI_GPU gceSTATUS -gckHARDWARE_Nop( +gckHARDWARE_ChipEnable( IN gckHARDWARE Hardware, IN gctPOINTER Logical, + IN gceCORE_3D_MASK ChipEnable, IN OUT gctSIZE_T * Bytes ) { gctUINT32_PTR logical = (gctUINT32_PTR) Logical; gceSTATUS status; - gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu", - Hardware, Logical, gcmOPT_VALUE(Bytes)); + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x ChipEnable=0x%x *Bytes=%lu", + Hardware, Logical, ChipEnable, gcmOPT_VALUE(Bytes)); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); @@ -2092,15 +2289,16 @@ gckHARDWARE_Nop( gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); } - /* Append NOP. */ - logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + /* Append CHIPENABLE. */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ChipEnable; - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: CHIPENABLE 0x%x", Logical, ChipEnable); } if (Bytes != gcvNULL) { - /* Return number of bytes required by the NOP command. */ + /* Return number of bytes required by the CHIPENABLE command. */ *Bytes = 8; } @@ -2113,12 +2311,13 @@ OnError: gcmkFOOTER(); return status; } +#endif /******************************************************************************* ** -** gckHARDWARE_Wait +** gckHARDWARE_Nop ** -** Append a WAIT command at the specified location in the command queue. +** Append a NOP command at the specified location in the command queue. ** ** INPUT: ** @@ -2127,13 +2326,10 @@ OnError: ** ** gctPOINTER Logical ** Pointer to the current location inside the command queue to append -** WAIT command at or gcvNULL just to query the size of the WAIT command. -** -** gctUINT32 Count -** Number of cycles to wait. +** NOP command at or gcvNULL just to query the size of the NOP command. ** ** gctSIZE_T * Bytes -** Pointer to the number of bytes available for the WAIT command. If +** Pointer to the number of bytes available for the NOP command. If ** 'Logical' is gcvNULL, this argument will be ignored. ** ** OUTPUT: @@ -2143,26 +2339,22 @@ OnError: ** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned. */ gceSTATUS -gckHARDWARE_Wait( +gckHARDWARE_Nop( IN gckHARDWARE Hardware, IN gctPOINTER Logical, - IN gctUINT32 Count, IN OUT gctSIZE_T * Bytes ) { + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; gceSTATUS status; - gctUINT32_PTR logical; - gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu", - Hardware, Logical, Count, gcmOPT_VALUE(Bytes)); + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu", + Hardware, Logical, gcmOPT_VALUE(Bytes)); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); - /* Cast the input pointer. */ - logical = (gctUINT32_PTR) Logical; - if (Logical != gcvNULL) { if (*Bytes < 8) @@ -2171,30 +2363,15 @@ gckHARDWARE_Wait( gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); } - /* Append WAIT. */ - logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - -#if gcmIS_DEBUG(gcdDEBUG_TRACE) - { - gctUINT32 address; - - /* Convert logical into hardware specific address. */ - gcmkONERROR(gckHARDWARE_ConvertLogical( - Hardware, logical, &address - )); + /* Append NOP. */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_HARDWARE, - "0x%08x: WAIT %u", address, Count - ); - } -#endif + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical); } if (Bytes != gcvNULL) { - /* Return number of bytes required by the WAIT command. */ + /* Return number of bytes required by the NOP command. */ *Bytes = 8; } @@ -2247,7 +2424,7 @@ gckHARDWARE_Event( IN gctPOINTER Logical, IN gctUINT8 Event, IN gceKERNEL_WHERE FromWhere, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gctUINT size; @@ -2263,6 +2440,10 @@ gckHARDWARE_Event( gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); gcmkVERIFY_ARGUMENT(Event < 32); +#if gcdMULTI_GPU + if (FromWhere == gcvKERNEL_COMMAND) FromWhere = gcvKERNEL_PIXEL; +#endif + /* Determine the size of the command. */ size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL)) @@ -2328,6 +2509,13 @@ gckHARDWARE_Event( logical[6] = 0; logical[7] = 0; } + +#if gcdINTERRUPT_STATISTIC + if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues)) + { + gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event); + } +#endif } if (Bytes != gcvNULL) @@ -2381,7 +2569,7 @@ gckHARDWARE_PipeSelect( IN gckHARDWARE Hardware, IN gctPOINTER Logical, IN gcePIPE_SELECT Pipe, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gctUINT32_PTR logical = (gctUINT32_PTR) Logical; @@ -2490,8 +2678,8 @@ OnError: ** the LINK command at or gcvNULL just to query the size of the LINK ** command. ** -** gctPOINTER FetchAddress -** Logical address of destination of LINK. +** gctUINT32 FetchAddress +** Hardware address of destination of LINK. ** ** gctSIZE_T FetchSize ** Number of bytes in destination of LINK. @@ -2510,14 +2698,13 @@ gceSTATUS gckHARDWARE_Link( IN gckHARDWARE Hardware, IN gctPOINTER Logical, - IN gctPOINTER FetchAddress, - IN gctSIZE_T FetchSize, - IN OUT gctSIZE_T * Bytes + IN gctUINT32 FetchAddress, + IN gctUINT32 FetchSize, + IN OUT gctUINT32 * Bytes ) { gceSTATUS status; gctSIZE_T bytes; - gctUINT32 address; gctUINT32 link; gctUINT32_PTR logical = (gctUINT32_PTR) Logical; @@ -2538,19 +2725,15 @@ gckHARDWARE_Link( gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); } - /* Convert logical address to hardware address. */ - gcmkONERROR( - gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address)); - gcmkONERROR( - gckOS_WriteMemory(Hardware->os, logical + 1, address)); + gckOS_WriteMemory(Hardware->os, logical + 1, FetchAddress)); /* Make sure the address got written before the LINK command. */ gcmkONERROR( gckOS_MemoryBarrier(Hardware->os, logical + 1)); /* Compute number of 64-byte aligned bytes to fetch. */ - bytes = gcmALIGN(address + FetchSize, 64) - address; + bytes = gcmALIGN(FetchAddress + FetchSize, 64) - FetchAddress; /* Append LINK(bytes / 8), FetchAddress. */ link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) @@ -2563,10 +2746,24 @@ gckHARDWARE_Link( gcmkONERROR( gckOS_MemoryBarrier(Hardware->os, logical)); -#if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER - if (address >= 0x80000000) +#if gcdLINK_QUEUE_SIZE && !gcdPROCESS_ADDRESS_SPACE + if ((Hardware->kernel->virtualCommandBuffer) + && (Hardware->kernel->stuckDump > 2) + ) { - gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes); + gctBOOL in; + + gcmkVERIFY_OK(gckCOMMAND_AddressInKernelCommandBuffer( + Hardware->kernel->command, FetchAddress, &in)); + + if (in == gcvFALSE) + { + /* Record user command buffer and context buffer link + ** information for stuck dump. + **/ + gckLINKQUEUE_Enqueue( + &Hardware->linkQueue, FetchAddress, FetchAddress + (gctUINT)bytes); + } } #endif } @@ -2628,14 +2825,22 @@ gckHARDWARE_UpdateQueueTail( gckOS_MemoryBarrier(Hardware->os, Logical)); /* Notify gckKERNEL object of change. */ +#if gcdMULTI_GPU gcmkONERROR( gckKERNEL_Notify(Hardware->kernel, + 0, gcvNOTIFY_COMMAND_QUEUE, gcvFALSE)); +#else + gcmkONERROR( + gckKERNEL_Notify(Hardware->kernel, + gcvNOTIFY_COMMAND_QUEUE, + gcvFALSE)); +#endif if (status == gcvSTATUS_CHIP_NOT_READY) { - gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING); + gcmkONERROR(gcvSTATUS_DEVICE); } /* Success. */ @@ -2662,6 +2867,9 @@ OnError: ** gctPOINTER Logical ** Logical address to convert. ** +** gctBOOL InUserSpace +** gcvTRUE if the memory in user space. +** ** gctUINT32* Address ** Return hardware specific address. ** @@ -2673,6 +2881,7 @@ gceSTATUS gckHARDWARE_ConvertLogical( IN gckHARDWARE Hardware, IN gctPOINTER Logical, + IN gctBOOL InUserSpace, OUT gctUINT32 * Address ) { @@ -2680,94 +2889,28 @@ gckHARDWARE_ConvertLogical( gceSTATUS status; gctUINT32 baseAddress; - gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical); + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d", + Hardware, Logical, InUserSpace); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); gcmkVERIFY_ARGUMENT(Logical != gcvNULL); gcmkVERIFY_ARGUMENT(Address != gcvNULL); -#if gcdVIRTUAL_COMMAND_BUFFER - status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address); - - if (status == gcvSTATUS_INVALID_ADDRESS) -#endif + /* Convert logical address into a physical address. */ + if (InUserSpace) { - /* Convert logical address into a physical address. */ - gcmkONERROR( - gckOS_GetPhysicalAddress(Hardware->os, Logical, &address)); - - /* For old MMU, get GPU address according to baseAddress. */ - if (Hardware->mmuVersion == 0) - { - gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress)); - - /* Subtract base address to get a GPU address. */ - gcmkASSERT(address >= baseAddress); - address -= baseAddress; - } - - /* Return hardware specific address. */ - *Address = (Hardware->mmuVersion == 0) - ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) - : address; + gcmkONERROR(gckOS_UserLogicalToPhysical(Hardware->os, Logical, &address)); + } + else + { + gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &address)); } - - /* Success. */ - gcmkFOOTER_ARG("*Address=0x%08x", *Address); - return gcvSTATUS_OK; - -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; -} - -/******************************************************************************* -** -** gckHARDWARE_ConvertPhysical -** -** Convert a physical address into a hardware specific address. -** -** INPUT: -** -** gckHARDWARE Hardware -** Pointer to an gckHARDWARE object. -** -** gctPHYS_ADDR Physical -** Physical address to convert. -** -** gctUINT32* Address -** Return hardware specific address. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gckHARDWARE_ConvertPhysical( - IN gckHARDWARE Hardware, - IN gctPHYS_ADDR Physical, - OUT gctUINT32 * Address - ) -{ - gctUINT32 address; - gctUINT32 baseAddress; - - gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical); - - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); - gcmkVERIFY_ARGUMENT(Physical != gcvNULL); - gcmkVERIFY_ARGUMENT(Address != gcvNULL); - - address = gcmPTR2INT(Physical); /* For old MMU, get GPU address according to baseAddress. */ if (Hardware->mmuVersion == 0) { - gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress)); + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress)); /* Subtract base address to get a GPU address. */ gcmkASSERT(address >= baseAddress); @@ -2780,9 +2923,14 @@ gckHARDWARE_ConvertPhysical( | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) : address; - /* Return the status. */ + /* Success. */ gcmkFOOTER_ARG("*Address=0x%08x", *Address); return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; } /******************************************************************************* @@ -2810,11 +2958,14 @@ gckHARDWARE_ConvertPhysical( gceSTATUS gckHARDWARE_Interrupt( IN gckHARDWARE Hardware, +#if gcdMULTI_GPU + IN gctUINT CoreId, +#endif IN gctBOOL InterruptValid ) { gckEVENT eventObj; - gctUINT32 data; + gctUINT32 data = 0; gceSTATUS status; gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid); @@ -2829,11 +2980,31 @@ gckHARDWARE_Interrupt( if (InterruptValid) { /* Read AQIntrAcknowledge register. */ +#if gcdMULTI_GPU + if (Hardware->core == gcvCORE_MAJOR) + { + gcmkONERROR( + gckOS_ReadRegisterByCoreId(Hardware->os, + Hardware->core, + CoreId, + 0x00010, + &data)); + } + else + { + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00010, + &data)); + } +#else gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00010, &data)); +#endif if (data == 0) { @@ -2842,14 +3013,23 @@ gckHARDWARE_Interrupt( } else { + +#if gcdINTERRUPT_STATISTIC + gckOS_AtomClearMask(Hardware->pendingEvent, data); +#endif + /* Inform gckEVENT of the interrupt. */ - status = gckEVENT_Interrupt(eventObj, data); + status = gckEVENT_Interrupt(eventObj, +#if gcdMULTI_GPU + CoreId, +#endif + data); } } else { - /* Handle events. */ - status = gckEVENT_Notify(eventObj, 0); + /* Handle events. */ + status = gckEVENT_Notify(eventObj, 0); } OnError: @@ -2885,9 +3065,9 @@ OnError: gceSTATUS gckHARDWARE_QueryCommandBuffer( IN gckHARDWARE Hardware, - OUT gctSIZE_T * Alignment, - OUT gctSIZE_T * ReservedHead, - OUT gctSIZE_T * ReservedTail + OUT gctUINT32 * Alignment, + OUT gctUINT32 * ReservedHead, + OUT gctUINT32 * ReservedTail ) { gcmkHEADER_ARG("Hardware=0x%x", Hardware); @@ -2971,7 +3151,7 @@ gckHARDWARE_QuerySystemMemory( return gcvSTATUS_OK; } -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D /******************************************************************************* ** ** gckHARDWARE_QueryShaderCaps @@ -2992,61 +3172,47 @@ gckHARDWARE_QuerySystemMemory( ** Pointer to a variable receiving the number of uniforms in the ** fragment shader. ** -** gctUINT * Varyings -** Pointer to a variable receiving the maimum number of varyings. +** gctBOOL * UnifiedUnforms +** Pointer to a variable receiving whether the uniformas are unified. */ gceSTATUS gckHARDWARE_QueryShaderCaps( IN gckHARDWARE Hardware, OUT gctUINT * VertexUniforms, OUT gctUINT * FragmentUniforms, - OUT gctUINT * Varyings + OUT gctBOOL * UnifiedUnforms ) { + gctBOOL unifiedConst; gctUINT32 vsConstMax; gctUINT32 psConstMax; + gctUINT32 vsConstBase; + gctUINT32 psConstBase; + gctUINT32 ConstMax; gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x " - "FragmentUniforms=0x%x Varyings=0x%x", + "FragmentUniforms=0x%x UnifiedUnforms=0x%x", Hardware, VertexUniforms, - FragmentUniforms, Varyings); + FragmentUniforms, UnifiedUnforms); - if ((Hardware->identity.chipModel == gcv2000) - && (Hardware->identity.chipRevision == 0x5118)) - { - vsConstMax = 256; - psConstMax = 64; - } - else if (Hardware->identity.numConstants > 256) - { - vsConstMax = 256; - psConstMax = 256; - } - else if (Hardware->identity.numConstants == 256) - { - vsConstMax = 256; - psConstMax = 256; - } - else - { - vsConstMax = 168; - psConstMax = 64; - } + {if (Hardware->identity.numConstants > 256){ unifiedConst = gcvTRUE; vsConstBase = 0xC000; psConstBase = 0xC000; ConstMax = Hardware->identity.numConstants; vsConstMax = 256; psConstMax = ConstMax - vsConstMax;}else if (Hardware->identity.numConstants == 256){ if (Hardware->identity.chipModel == gcv2000 && Hardware->identity.chipRevision == 0x5118) { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 64; ConstMax = 320; } else { unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 256; psConstMax = 256; ConstMax = 512; }}else{ unifiedConst = gcvFALSE; vsConstBase = 0x1400; psConstBase = 0x1C00; vsConstMax = 168; psConstMax = 64; ConstMax = 232;}}; if (VertexUniforms != gcvNULL) { + /* Return the vs shader const count. */ *VertexUniforms = vsConstMax; } if (FragmentUniforms != gcvNULL) { + /* Return the ps shader const count. */ *FragmentUniforms = psConstMax; } - if (Varyings != gcvNULL) + if (UnifiedUnforms != gcvNULL) { - /* Return the shader varyings count. */ - *Varyings = Hardware->identity.varyingsCount; + /* Return whether the uniformas are unified. */ + *UnifiedUnforms = unifiedConst; } /* Success. */ @@ -3081,65 +3247,109 @@ gckHARDWARE_SetMMU( { gceSTATUS status; gctUINT32 address = 0; - gctUINT32 baseAddress; + gctUINT32 idle; + gctUINT32 timer = 0, delay = 1; gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); - gcmkVERIFY_ARGUMENT(Logical != gcvNULL); - /* Convert the logical address into an hardware address. */ - gcmkONERROR( - gckHARDWARE_ConvertLogical(Hardware, Logical, &address)); + if (Hardware->mmuVersion == 0) + { + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); - /* Also get the base address - we need a real physical address. */ - gcmkONERROR( - gckOS_GetBaseAddress(Hardware->os, &baseAddress)); + /* Convert the logical address into physical address. */ + gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &address)); - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "Setting page table to 0x%08X", - address + baseAddress); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Setting page table to 0x%08X", + address); - /* Write the AQMemoryFePageTable register. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00400, - address + baseAddress)); + /* Write the AQMemoryFePageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00400, + address)); - /* Write the AQMemoryRaPageTable register. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00410, - address + baseAddress)); + /* Write the AQMemoryRaPageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00410, + address)); - /* Write the AQMemoryTxPageTable register. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00404, - address + baseAddress)); + /* Write the AQMemoryTxPageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00404, + address)); - /* Write the AQMemoryPePageTable register. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00408, - address + baseAddress)); + /* Write the AQMemoryPePageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00408, + address)); - /* Write the AQMemoryPezPageTable register. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x0040C, - address + baseAddress)); + /* Write the AQMemoryPezPageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0040C, + address)); + } + else if (Hardware->enableMMU == gcvTRUE) + { + /* Execute prepared command sequence. */ + gcmkONERROR(gckHARDWARE_Execute( + Hardware, + Hardware->functions[gcvHARDWARE_FUNCTION_MMU].address, + Hardware->functions[gcvHARDWARE_FUNCTION_MMU].bytes + )); + + /* Wait until MMU configure finishes. */ + do + { + gckOS_Delay(Hardware->os, delay); + + gcmkONERROR(gckOS_ReadRegisterEx( + Hardware->os, + Hardware->core, + 0x00004, + &idle)); + + timer += delay; + delay *= 2; + +#if gcdGPU_TIMEOUT + if (timer >= Hardware->kernel->timeOut) + { + /* Even if hardware is not reset correctly, let software + ** continue to avoid software stuck. Software will timeout again + ** and try to recover GPU in next timeout. + */ + gcmkONERROR(gcvSTATUS_DEVICE); + } +#endif + } + while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )); + + /* Enable MMU. */ + gcmkONERROR(gckOS_WriteRegisterEx( + Hardware->os, + Hardware->core, + 0x0018C, + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (gcvTRUE) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + )); + } /* Return the status. */ gcmkFOOTER_NO(); - return status; + return gcvSTATUS_OK; OnError: /* Return the status. */ @@ -3170,8 +3380,7 @@ gckHARDWARE_FlushMMU( gceSTATUS status; gckCOMMAND command; gctUINT32_PTR buffer; - gctSIZE_T bufferSize; - gctBOOL commitEntered = gcvFALSE; + gctUINT32 bufferSize; gctPOINTER pointer = gcvNULL; gctUINT32 flushSize; gctUINT32 count; @@ -3185,10 +3394,6 @@ gckHARDWARE_FlushMMU( /* Verify the gckCOMMAND object pointer. */ command = Hardware->kernel->command; - /* Acquire the command queue. */ - gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE)); - commitEntered = gcvTRUE; - /* Flush the memory controller. */ if (Hardware->mmuVersion == 0) { @@ -3222,7 +3427,7 @@ gckHARDWARE_FlushMMU( buffer = (gctUINT32_PTR) pointer; - count = (bufferSize - flushSize + 7) >> 3; + count = ((gctUINT)bufferSize - flushSize + 7) >> 3; gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical)); @@ -3236,7 +3441,6 @@ gckHARDWARE_FlushMMU( = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); @@ -3304,80 +3508,60 @@ gckHARDWARE_FlushMMU( gcmkONERROR(gckCOMMAND_Execute(command, flushSize)); } - /* Release the command queue. */ - gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE)); - commitEntered = gcvFALSE; - /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: - if (commitEntered) - { - /* Release the command queue mutex. */ - gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command, - gcvFALSE)); - } /* Return the status. */ gcmkFOOTER(); return status; } -/******************************************************************************* -** -** gckHARDWARE_SetMMUv2 -** -** Set the page table base address. -** -** INPUT: -** -** gckHARDWARE Harwdare -** Pointer to an gckHARDWARE object. -** -** OUTPUT: -** -** Nothing. -*/ gceSTATUS -gckHARDWARE_SetMMUv2( +gckHARDWARE_SetMMUStates( IN gckHARDWARE Hardware, - IN gctBOOL Enable, IN gctPOINTER MtlbAddress, IN gceMMU_MODE Mode, IN gctPOINTER SafeAddress, - IN gctBOOL FromPower + IN gctPOINTER Logical, + IN OUT gctUINT32 * Bytes ) { gceSTATUS status; gctUINT32 config, address; - gckCOMMAND command; gctUINT32_PTR buffer; - gctSIZE_T bufferSize; - gctBOOL commitEntered = gcvFALSE; - gctPOINTER pointer = gcvNULL; - gctBOOL acquired = gcvFALSE; + gctBOOL ace; + gctUINT32 reserveBytes = 16 + 4 * 4; + gctBOOL config2D; - gctSIZE_T configSize; - gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable); + gcmkHEADER_ARG("Hardware=0x%x", Hardware); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Hardware->mmuVersion != 0); + + ace = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ACE); + + if (ace) + { + reserveBytes += 8; + } config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D) && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D); - configSize = 4 * 4; - if (config2D) { - configSize += + reserveBytes += /* Pipe Select. */ 4 * 4 /* Configure MMU States. */ - + 4 * 4; + + 4 * 4 + /* Semaphore stall */ + + 4 * 8; } /* Convert logical address into physical address. */ @@ -3392,166 +3576,395 @@ gckHARDWARE_SetMMUv2( gcmkONERROR(gcvSTATUS_NOT_ALIGNED); } - switch (Mode) + switch (Mode) + { + case gcvMMU_MODE_1K: + if (config & 0x3FF) + { + gcmkONERROR(gcvSTATUS_NOT_ALIGNED); + } + + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + break; + + case gcvMMU_MODE_4K: + if (config & 0xFFF) + { + gcmkONERROR(gcvSTATUS_NOT_ALIGNED); + } + + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + break; + + default: + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + if (Logical != gcvNULL) + { + buffer = Logical; + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = config; + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = address; + + if (ace) + { + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = 0; + } + + do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);; + + if (config2D) + { + /* LoadState(AQPipeSelect, 1), pipe. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = 0x1; + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = config; + + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = address; + + do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);; + + /* LoadState(AQPipeSelect, 1), pipe. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + *buffer++ = 0x0; + + do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);; + } + + } + + if (Bytes != gcvNULL) + { + *Bytes = reserveBytes; + } + + /* Return the status. */ + gcmkFOOTER_NO(); + return status; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +#if gcdPROCESS_ADDRESS_SPACE +/******************************************************************************* +** +** gckHARDWARE_ConfigMMU +** +** Append a MMU Configuration command sequence at the specified location in the command +** queue. That command sequence consists of mmu configuration, LINK and WAIT/LINK. +** LINK is fetched and paresed with new mmu configuration. +** +** If MMU Configuration is not changed between commit, change last WAIT/LINK to +** link to ENTRY. +** +** -+-----------+-----------+----------------------------------------- +** | WAIT/LINK | WAIT/LINK | +** -+-----------+-----------+----------------------------------------- +** | /|\ +** \|/ | +** +--------------------+ +** | ENTRY | ... | LINK | +** +--------------------+ +** +** If MMU Configuration is changed between commit, change last WAIT/LINK to +** link to MMU CONFIGURATION command sequence, and there are an EVNET and +** an END at the end of this command sequence, when interrupt handler +** receives this event, it will start FE at ENTRY to continue the command +** buffer execution. +** +** -+-----------+-------------------+---------+---------+-----------+-- +** | WAIT/LINK | MMU CONFIGURATION | EVENT | END | WAIT/LINK | +** -+-----------+-------------------+---------+---------+-----------+-- +** | /|\ /|\ +** +-------------+ | +** +--------------------+ +** | ENTRY | ... | LINK | +** +--------------------+ +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** command sequence at or gcvNULL just to query the size of the +** command sequence. +** +** gctPOINTER MtlbLogical +** Pointer to the current Master TLB. +** +** gctUINT32 Offset +** Offset into command buffer required for alignment. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the command +** sequence. If 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** by the command sequence. If 'Bytes' is gcvNULL, nothing will +** be returned. +** +** gctUINT32 * WaitLinkOffset +** Pointer to a variable that will receive the offset of the WAIT/LINK command +** from the specified logcial pointer. +** If 'WaitLinkOffset' is gcvNULL nothing will be returned. +** +** gctSIZE_T * WaitLinkBytes +** Pointer to a variable that will receive the number of bytes used by +** the WAIT command. +** If 'WaitLinkBytes' is gcvNULL nothing will be returned. +*/ +gceSTATUS +gckHARDWARE_ConfigMMU( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctPOINTER MtlbLogical, + IN gctUINT32 Offset, + IN OUT gctSIZE_T * Bytes, + OUT gctSIZE_T * WaitLinkOffset, + OUT gctSIZE_T * WaitLinkBytes + ) +{ + gceSTATUS status; + gctSIZE_T bytes, bytesAligned; + gctUINT32 config; + gctUINT32_PTR buffer = (gctUINT32_PTR) Logical; + gctUINT32 physical; + gctUINT32 event; + + gcmkHEADER_ARG("Hardware=0x%08X Logical=0x%08x MtlbLogical=0x%08X", + Hardware, Logical, MtlbLogical); + + bytes + /* Flush cache states. */ + = 18 * 4 + /* MMU configuration states. */ + + 6 * 4 + /* EVENT. */ + + 2 * 4 + /* END. */ + + 2 * 4 + /* WAIT/LINK. */ + + 4 * 4; + + /* Compute number of bytes required. */ + bytesAligned = gcmALIGN(Offset + bytes, 8) - Offset; + + if (buffer != gcvNULL) { - case gcvMMU_MODE_1K: - if (config & 0x3FF) + if (MtlbLogical == gcvNULL) { - gcmkONERROR(gcvSTATUS_NOT_ALIGNED); + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } - config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); - - break; + /* Get physical address of this command buffer segment. */ + gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, buffer, &physical)); - case gcvMMU_MODE_4K: - if (config & 0xFFF) - { - gcmkONERROR(gcvSTATUS_NOT_ALIGNED); - } + /* Get physical address of Master TLB. */ + gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, MtlbLogical, &config)); - config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); - break; + /* Flush cache. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - default: - gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); - } + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); - /* Verify the gckCOMMAND object pointer. */ - command = Hardware->kernel->command; + /* Flush tile status cache. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - /* Acquire the command queue. */ - gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower)); - commitEntered = gcvTRUE; + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); - gcmkONERROR(gckCOMMAND_Reserve( - command, configSize, &pointer, &bufferSize - )); + /* Arm the PE-FE Semaphore. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - buffer = pointer; + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - buffer[0] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + /* STALL FE until PE is done flushing. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); - buffer[1] = config; + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - buffer[2] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + /* LINK to next slot to flush FE FIFO. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - buffer[3] = address; + *buffer++ + = physical + 10 * gcmSIZEOF(gctUINT32); - if (config2D) - { - /* LoadState(AQPipeSelect, 1), pipe. */ - buffer[4] + /* Configure MMU. */ + *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - buffer[5] = 0x1; + *buffer++ + = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) & ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)))); - buffer[6] + /* Arm the PE-FE Semaphore. */ + *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - buffer[7] = config; + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - buffer[8] - = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + /* STALL FE until PE is done flushing. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); - buffer[9] = address; + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - /* LoadState(AQPipeSelect, 1), pipe. */ - buffer[10] + /* LINK to next slot to flush FE FIFO. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *buffer++ + = physical + 18 * 4; + + *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - buffer[11] = 0x0; - } - - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address); + *buffer++ + = config; - gcmkONERROR(gckCOMMAND_Execute(command, configSize)); + /* Arm the PE-FE Semaphore. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); - if (FromPower == gcvFALSE) - { - /* Acquire global semaphore to suspend power management until MMU - ** is enabled. And acquired it before gckCOMMAND_ExitCommit to - ** make sure GPU keeps ON. */ - gcmkONERROR( - gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore)); + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - acquired = gcvTRUE; - } + /* STALL FE until PE is done flushing. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); - /* Release the command queue. */ - gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower)); - commitEntered = gcvFALSE; + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "call gckCOMMAND_Stall to make sure the config is done.\n "); + /* Event 29. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - gcmkONERROR(gckCOMMAND_Stall(command, FromPower)); + event = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + event = ((((gctUINT32) (event)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (29) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))); - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "Enable MMU through GCREG_MMU_CONTROL."); + *buffer++ + = event; - /* Enable MMU. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x0018C, - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Enable) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))))); + /* Append END. */ + *buffer++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + } - if (FromPower == gcvFALSE) + if (Bytes != gcvNULL) { - /* Relase global semaphore. */ - gcmkVERIFY_OK( - gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore)); - - acquired = gcvFALSE; + *Bytes = bytesAligned; } - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "call gckCOMMAND_Stall to check MMU available.\n"); - - gcmkONERROR(gckCOMMAND_Stall(command, FromPower)); - - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "The MMU is available.\n"); - - /* Return the status. */ - gcmkFOOTER_NO(); - return status; - -OnError: - if (commitEntered) + if (WaitLinkOffset != gcvNULL) { - /* Release the command queue mutex. */ - gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command, - FromPower)); + *WaitLinkOffset = bytes - 4 * 4; } - if (acquired) + if (WaitLinkBytes != gcvNULL) { - gcmkVERIFY_OK( - gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore)); +#if gcdMULTI_GPU + *WaitLinkBytes = 40; +#else + *WaitLinkBytes = 4 * 4; +#endif } - /* Return the status. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: gcmkFOOTER(); return status; } +#endif /******************************************************************************* ** @@ -3608,6 +4021,7 @@ gckHARDWARE_GetIdle( gceSTATUS status; gctUINT32 idle = 0; gctINT retry, poll, pollCount; + gctUINT32 address; gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait); @@ -3629,8 +4043,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 (_IsGPUIdle(idle) + && (address == Hardware->lastEnd + 8) + ) { /* FE is idle. */ break; @@ -3638,7 +4061,7 @@ gckHARDWARE_GetIdle( } /* Check if we need to wait for FE and FE is busy. */ - if (Wait && !(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + if (Wait && !_IsGPUIdle(idle)) { /* Wait a little. */ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, @@ -3656,6 +4079,13 @@ gckHARDWARE_GetIdle( /* Return idle to caller. */ *Data = idle; +#if defined(EMULATOR) + /* Wait a little while until CModel FE gets END. + * END is supposed to be appended by caller. + */ + gckOS_Delay(gcvNULL, 100); +#endif + /* Success. */ gcmkFOOTER_ARG("*Data=0x%08x", *Data); return gcvSTATUS_OK; @@ -3672,15 +4102,17 @@ gckHARDWARE_Flush( IN gckHARDWARE Hardware, IN gceKERNEL_FLUSH Flush, IN gctPOINTER Logical, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gctUINT32 pipe; gctUINT32 flush = 0; + gctBOOL flushTileStatus; gctUINT32_PTR logical = (gctUINT32_PTR) Logical; gceSTATUS status; - gctBOOL fcFlushStall; - gctUINT32 reserveBytes = 8; + gctUINT32 reserveBytes + /* Semaphore/Stall */ + = 4 * gcmSIZEOF(gctUINT32); gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu", Hardware, Flush, Logical, gcmOPT_VALUE(Bytes)); @@ -3691,15 +4123,8 @@ gckHARDWARE_Flush( /* Get current pipe. */ pipe = Hardware->kernel->command->pipeSelect; - fcFlushStall - = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) - && (Flush == gcvFLUSH_ALL) - ; - - if (fcFlushStall) - { - reserveBytes += 8; - } + /* Flush tile status cache. */ + flushTileStatus = Flush & gcvFLUSH_TILE_STATUS; /* Flush 3D color cache. */ if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0)) @@ -3717,7 +4142,6 @@ gckHARDWARE_Flush( if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0)) { flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))); - flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); } /* Flush 2D cache. */ @@ -3726,8 +4150,27 @@ gckHARDWARE_Flush( flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))); } +#if gcdMULTI_GPU + /* Flush L2 cache. */ + if ((Flush & gcvFLUSH_L2) && (pipe == 0x0)) + { + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + } +#endif + + /* Determine reserve bytes. */ + if (flush) + { + reserveBytes += 2 * gcmSIZEOF(gctUINT32); + } + + if (flushTileStatus) + { + reserveBytes += 2 * gcmSIZEOF(gctUINT32); + } + /* See if there is a valid flush. */ - if (flush == 0) + if ((flush == 0) && (flushTileStatus == gcvFALSE)) { if (Bytes != gcvNULL) { @@ -3747,29 +4190,52 @@ gckHARDWARE_Flush( gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); } - /* Append LOAD_STATE to AQFlush. */ - logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + if (flush) + { + /* Append LOAD_STATE to AQFlush. */ + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - logical[1] = flush; + *logical++ + = flush; - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "0x%x: FLUSH 0x%x", logical, flush); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: FLUSH 0x%x", logical - 1, flush); + } - if (fcFlushStall) + if (flushTileStatus) { - logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) - | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); - - logical[3] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, - "0x%x: FLUSH 0x%x", logical + 3, logical[3]); + "0x%x: FLUSH TILE STATUS 0x%x", logical - 1, logical[-1]); } + /* Semaphore. */ + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /* Stall. */ + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + *logical++ + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x05 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); } if (Bytes != gcvNULL) @@ -3796,7 +4262,7 @@ gckHARDWARE_SetFastClear( IN gctINT Compression ) { -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D gctUINT32 debug; gceSTATUS status; @@ -3896,6 +4362,7 @@ _PowerEnum(gceCHIPPOWERSTATE State) gcmSTRING(gcvPOWER_SUSPEND_BROADCAST), gcmSTRING(gcvPOWER_OFF_BROADCAST), gcmSTRING(gcvPOWER_OFF_RECOVERY), + gcmSTRING(gcvPOWER_OFF_TIMEOUT), gcmSTRING(gcvPOWER_ON_AUTO) }; @@ -3934,7 +4401,7 @@ gckHARDWARE_SetPowerManagementState( gckOS os; gctUINT flag, clock; gctPOINTER buffer; - gctSIZE_T bytes, requested; + gctUINT32 bytes, requested; gctBOOL acquired = gcvFALSE; gctBOOL mutexAcquired = gcvFALSE; gctBOOL stall = gcvTRUE; @@ -4060,12 +4527,6 @@ gckHARDWARE_SetPowerManagementState( command = Hardware->kernel->command; gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); - if (Hardware->powerManagement == gcvFALSE) - { - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - } - /* Start profiler. */ gcmkPROFILE_INIT(freq, time); @@ -4136,6 +4597,14 @@ gckHARDWARE_SetPowerManagementState( break; } + if (Hardware->powerManagement == gcvFALSE + && State != gcvPOWER_ON + ) + { + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + /* Get current process and thread IDs. */ gcmkONERROR(gckOS_GetProcessID(&process)); gcmkONERROR(gckOS_GetThreadID(&thread)); @@ -4156,30 +4625,14 @@ gckHARDWARE_SetPowerManagementState( gcmkFOOTER_NO(); return gcvSTATUS_OK; } - else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND) + else if (State != gcvPOWER_ON) { /* Called from IST, ** so waiting here will cause deadlock, ** if lock holder call gckCOMMAND_Stall() */ - gcmkONERROR(gcvSTATUS_INVALID_REQUEST); - } -#if gcdPOWEROFF_TIMEOUT - else if(State == gcvPOWER_OFF && timeout == gcvTRUE) - { - /* - ** try to aqcuire the mutex with more milliseconds, - ** flush_delayed_work should be running with timeout, - ** so waiting here will cause deadlock */ - status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcdPOWEROFF_TIMEOUT); - - if (status == gcvSTATUS_TIMEOUT) - { - gckOS_Print("GPU Timer deadlock, exit by timeout!!!!\n"); - - gcmkONERROR(gcvSTATUS_INVALID_REQUEST); - } + status = gcvSTATUS_INVALID_REQUEST; + goto OnError; } -#endif else { /* Acquire the power mutex. */ @@ -4215,16 +4668,16 @@ gckHARDWARE_SetPowerManagementState( if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast) { -#if gcdPOWER_SUSNPEND_WHEN_IDLE - /* Do nothing */ +#if gcdPOWER_SUSPEND_WHEN_IDLE + /* Do nothing */ - /* Release the power mutex. */ + /* Release the power mutex. */ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex)); - gcmkFOOTER_NO(); + gcmkFOOTER_NO(); return gcvSTATUS_OK; #else - /* Clock should be on when switch power from off to suspend */ + /* Clock should be on when switch power from off to suspend */ clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | @@ -4481,7 +4934,11 @@ gckHARDWARE_SetPowerManagementState( commitEntered = gcvFALSE; /* Wait to finish all commands. */ +#if gcdMULTI_GPU + gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE, gcvCORE_3D_ALL_MASK)); +#else gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE)); +#endif } } @@ -4561,7 +5018,7 @@ gckHARDWARE_SetPowerManagementState( if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF)) { if (Hardware->identity.chipModel == gcv4000 - && Hardware->identity.chipRevision == 0x5208) + && ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222))) { clock &= ~2U; } @@ -4642,20 +5099,6 @@ gckHARDWARE_SetPowerManagementState( gcmkONERROR(Hardware->startIsr(Hardware->isrContext)); isrStarted = gcvTRUE; } - - /* Set NEW MMU. */ - if (Hardware->mmuVersion != 0 && configMmu) - { - gcmkONERROR( - gckHARDWARE_SetMMUv2( - Hardware, - gcvTRUE, - Hardware->kernel->mmu->mtlbLogical, - gcvMMU_MODE_4K, - (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE, - gcvTRUE - )); - } } /* Get time until started. */ @@ -4817,7 +5260,6 @@ gckHARDWARE_QueryPowerManagementState( ** gckHARDWARE_SetPowerManagement ** ** Configure GPU power management function. -** Only used in driver initialization stage. ** ** INPUT: ** @@ -4838,14 +5280,53 @@ gckHARDWARE_SetPowerManagement( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + if(!Hardware->powerManagementLock) + { + gcmkVERIFY_OK( + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE)); - Hardware->powerManagement = PowerManagement; + Hardware->powerManagement = PowerManagement; + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex)); + } /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; } +/******************************************************************************* +** +** gckHARDWARE_SetPowerManagementLock +** +** Disable dynamic GPU power management switch. +** Only used in driver initialization stage. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** gctBOOL Lock +** Power Mangement Lock State. +** +*/ +gceSTATUS +gckHARDWARE_SetPowerManagementLock( + IN gckHARDWARE Hardware, + IN gctBOOL Lock + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + Hardware->powerManagementLock = Lock; + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} /******************************************************************************* ** ** gckHARDWARE_SetGpuProfiler @@ -4873,6 +5354,29 @@ gckHARDWARE_SetGpuProfiler( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + if (GpuProfiler == gcvTRUE) + { + gctUINT32 data = 0; + + /* Need to disable clock gating when doing profiling. */ + gcmkVERIFY_OK( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00100, + &data)); + + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + + gcmkVERIFY_OK( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00100, + data)); + } + Hardware->gpuProfiler = GpuProfiler; /* Success. */ @@ -4903,7 +5407,7 @@ gckHARDWARE_SetFscaleValue( if (Hardware->chipPowerState == gcvPOWER_ON) { - gctUINT32 data; + gctUINT32 data; gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, @@ -4979,15 +5483,25 @@ gckHARDWARE_GetFscaleValue( ) { *FscaleValue = Hardware->powerOnFscaleVal; - if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR)) - *MinFscaleValue = gpu3DMinClock; - else - *MinFscaleValue = 1; + *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 @@ -5029,6 +5543,16 @@ gckHARDWARE_QueryIdle( { gceSTATUS status; gctUINT32 idle, address; + gctBOOL isIdle; +#if gcdMULTI_GPU > 1 + gctUINT32 idle3D1 = 0; + gctUINT32 address3D1; + gctBOOL isIdle3D1 = gcvFALSE; +#endif + +#if gcdINTERRUPT_STATISTIC + gctINT32 pendingInterrupt; +#endif gcmkHEADER_ARG("Hardware=0x%x", Hardware); @@ -5039,7 +5563,10 @@ gckHARDWARE_QueryIdle( /* We are idle when the power is not ON. */ if (Hardware->chipPowerState != gcvPOWER_ON) { - *IsIdle = gcvTRUE; + isIdle = gcvTRUE; +#if gcdMULTI_GPU > 1 + isIdle3D1 = gcvTRUE; +#endif } else @@ -5048,6 +5575,18 @@ gckHARDWARE_QueryIdle( gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle)); +#if gcdMULTI_GPU > 1 + if (Hardware->core == gcvCORE_MAJOR) + { + gcmkONERROR( + gckOS_ReadRegisterByCoreId(Hardware->os, + Hardware->core, + gcvCORE_3D_1_ID, + 0x00004, + &idle3D1)); + } +#endif + /* Pipe must be idle. */ if (((((((gctUINT32) (idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1) || ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1) @@ -5059,11 +5598,15 @@ gckHARDWARE_QueryIdle( ) { /* Something is busy. */ - *IsIdle = gcvFALSE; + isIdle = gcvFALSE; } else { +#if gcdSECURITY + isIdle = gcvTRUE; + address = 0; +#else /* Read the current FE address. */ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, @@ -5072,18 +5615,91 @@ gckHARDWARE_QueryIdle( /* Test if address is inside the last WAIT/LINK sequence. */ if ((address >= Hardware->lastWaitLink) +#if gcdMULTI_GPU + && (address <= Hardware->lastWaitLink + 40) +#else && (address <= Hardware->lastWaitLink + 16) +#endif ) { /* FE is in last WAIT/LINK and the pipe is idle. */ - *IsIdle = gcvTRUE; + isIdle = gcvTRUE; } else { /* FE is not in WAIT/LINK yet. */ - *IsIdle = gcvFALSE; + isIdle = gcvFALSE; + } +#endif + } + +#if gcdMULTI_GPU > 1 + if (Hardware->core == gcvCORE_MAJOR) + { + /* Pipe must be idle. */ + if (((((((gctUINT32) (idle3D1)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle3D1)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle3D1)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle3D1)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle3D1)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle3D1)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle3D1)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1) + ) + { + /* Something is busy. */ + isIdle3D1 = gcvFALSE; + } + + else + { + /* Read the current FE address. */ + gcmkONERROR(gckOS_ReadRegisterByCoreId(Hardware->os, + Hardware->core, + gcvCORE_3D_1_ID, + 0x00664, + &address3D1)); + + /* Test if address is inside the last WAIT/LINK sequence. */ + if ((address3D1 >= Hardware->lastWaitLink) + && (address3D1 <= Hardware->lastWaitLink + 40) + ) + { + /* FE is in last WAIT/LINK and the pipe is idle. */ + isIdle3D1 = gcvTRUE; + } + else + { + /* FE is not in WAIT/LINK yet. */ + isIdle3D1 = gcvFALSE; + } } } +#endif + + } + +#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) + { + *IsIdle = (isIdle & isIdle3D1); + } + else +#endif + { + *IsIdle = isIdle; } /* Success. */ @@ -5214,7 +5830,7 @@ OnError: gceSTATUS gckHARDWARE_QueryProfileRegisters( IN gckHARDWARE Hardware, - IN gctBOOL Reset, + IN gctBOOL Reset, OUT gcsPROFILER_COUNTERS * Counters ) { @@ -5244,7 +5860,7 @@ gckHARDWARE_QueryProfileRegisters( gcmkONERROR( gckOS_ReadRegisterEx(Hardware->os, - Hardware->core, + Hardware->core, 0x0007C, &profiler->gpuIdleCyclesCounter)); @@ -5262,14 +5878,14 @@ gckHARDWARE_QueryProfileRegisters( profiler->pe_pixel_count_drawn_by_color_pipe = 0; profiler->pe_pixel_count_drawn_by_depth_pipe = 0; - /* Walk through all avaiable pixel pipes. */ + /* Walk through all avaiable pixel pipes. */ for (i = 0; i < Hardware->identity.pixelPipes; ++i) { /* Select proper pipe. */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, - Hardware->core, - 0x00000, - ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))))); + Hardware->core, + 0x00000, + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))))); /* BW */ gcmkONERROR( @@ -5304,20 +5920,18 @@ gckHARDWARE_QueryProfileRegisters( 0x00000, clock)); - if(Reset){ - /* Reset counters. */ - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1)); - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0)); - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0)); - gcmkONERROR( - gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0)); - gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); + /* Reset counters. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1)); + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0)); + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0)); + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); - } /* SH */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); @@ -5336,9 +5950,9 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) -));} +)); /* PA */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); @@ -5353,18 +5967,18 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profile gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) -));} +)); /* SE */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) -));} +)); /* RA */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); @@ -5379,9 +5993,9 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profile gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) -));} +)); /* TX */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); @@ -5402,9 +6016,9 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profile gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) -));} +)); /* MC */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); @@ -5413,9 +6027,9 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profile gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) -));} +)); /* HI */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); @@ -5424,9 +6038,9 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profile gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled)); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled)); - if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) )); gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) -));} +)); /* Success. */ gcmkFOOTER_NO(); @@ -5439,6 +6053,7 @@ OnError: } #endif + #if VIVANTE_PROFILER_CONTEXT #define gcmkUPDATE_PROFILE_DATA(data) \ profilerHistroy->data += profiler->data @@ -5446,7 +6061,7 @@ OnError: gceSTATUS gckHARDWARE_QueryContextProfile( IN gckHARDWARE Hardware, - IN gctBOOL Reset, + IN gctBOOL Reset, IN gckCONTEXT Context, OUT gcsPROFILER_COUNTERS * Counters ) @@ -5470,13 +6085,10 @@ gckHARDWARE_QueryContextProfile( profiler, &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS) )); - if (Reset) - { - /* Reset counters. */ - gcmkVERIFY_OK(gckOS_ZeroMemory( - &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS) - )); - } + /* Reset counters. */ + gcmkVERIFY_OK(gckOS_ZeroMemory( + &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS) + )); gcmkVERIFY_OK(gckOS_ReleaseMutex( command->os, command->mutexContextSeq @@ -5492,6 +6104,21 @@ OnError: return status; } +static gctUINT32 +CalcDelta( + IN gctUINT32 new, + IN gctUINT32 old + ) +{ + if (new >= old) + { + return new - old; + } + else + { + return (gctUINT32)((gctUINT64)new + 0x100000000ll - old); + } +} gceSTATUS gckHARDWARE_UpdateContextProfile( @@ -5503,7 +6130,7 @@ gckHARDWARE_UpdateContextProfile( gcsPROFILER_COUNTERS * profiler = &Context->latestProfiler; gcsPROFILER_COUNTERS * profilerHistroy = &Context->histroyProfiler; gctUINT i, clock; - gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn; + gctUINT32 colorKilled = 0, colorDrawn = 0, depthKilled = 0, depthDrawn = 0; gctUINT32 totalRead, totalWrite; gceCHIPMODEL chipModel; gctUINT32 chipRevision; @@ -5607,8 +6234,6 @@ gckHARDWARE_UpdateContextProfile( clock)); - - /* Reset counters. */ gcmkONERROR( gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1)); @@ -5628,7 +6253,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->ps_inst_counter; - profiler->ps_inst_counter -= Context->prevPSInstCount; + profiler->ps_inst_counter = CalcDelta(temp, Context->prevPSInstCount); Context->prevPSInstCount = temp; } gcmkUPDATE_PROFILE_DATA(ps_inst_counter); @@ -5638,7 +6263,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->rendered_pixel_counter; - profiler->rendered_pixel_counter -= Context->prevPSPixelCount; + profiler->rendered_pixel_counter = CalcDelta(temp, Context->prevPSPixelCount); Context->prevPSPixelCount = temp; } gcmkUPDATE_PROFILE_DATA(rendered_pixel_counter); @@ -5648,7 +6273,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->vs_inst_counter; - profiler->vs_inst_counter -= Context->prevVSInstCount; + profiler->vs_inst_counter = CalcDelta(temp, Context->prevVSInstCount); Context->prevVSInstCount = temp; } gcmkUPDATE_PROFILE_DATA(vs_inst_counter); @@ -5658,7 +6283,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->rendered_vertice_counter; - profiler->rendered_vertice_counter -= Context->prevVSVertexCount; + profiler->rendered_vertice_counter = CalcDelta(temp, Context->prevVSVertexCount); Context->prevVSVertexCount = temp; } gcmkUPDATE_PROFILE_DATA(rendered_vertice_counter); @@ -5668,7 +6293,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->vtx_branch_inst_counter; - profiler->vtx_branch_inst_counter -= Context->prevVSBranchInstCount; + profiler->vtx_branch_inst_counter = CalcDelta(temp, Context->prevVSBranchInstCount); Context->prevVSBranchInstCount = temp; } gcmkUPDATE_PROFILE_DATA(vtx_branch_inst_counter); @@ -5678,7 +6303,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->vtx_texld_inst_counter; - profiler->vtx_texld_inst_counter -= Context->prevVSTexInstCount; + profiler->vtx_texld_inst_counter = CalcDelta(temp, Context->prevVSTexInstCount); Context->prevVSTexInstCount = temp; } gcmkUPDATE_PROFILE_DATA(vtx_texld_inst_counter); @@ -5688,7 +6313,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->pxl_branch_inst_counter; - profiler->pxl_branch_inst_counter -= Context->prevPSBranchInstCount; + profiler->pxl_branch_inst_counter = CalcDelta(temp, Context->prevPSBranchInstCount); Context->prevPSBranchInstCount = temp; } gcmkUPDATE_PROFILE_DATA(pxl_branch_inst_counter); @@ -5698,7 +6323,7 @@ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profile if (needResetShader) { temp = profiler->pxl_texld_inst_counter; - profiler->pxl_texld_inst_counter -= Context->prevPSTexInstCount; + profiler->pxl_texld_inst_counter = CalcDelta(temp, Context->prevPSTexInstCount); Context->prevPSTexInstCount = temp; } gcmkUPDATE_PROFILE_DATA(pxl_texld_inst_counter); @@ -5835,6 +6460,34 @@ OnError: } #endif + +#if VIVANTE_PROFILER_NEW +gceSTATUS +gckHARDWARE_InitProfiler( + IN gckHARDWARE Hardware + ) +{ + gceSTATUS status; + gctUINT32 control; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + &control)); + /* Enable debug register. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))))); + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} +#endif + static gceSTATUS _ResetGPU( IN gckHARDWARE Hardware, @@ -5927,6 +6580,22 @@ _ResetGPU( continue; } +#if gcdMULTI_GPU > 1 + if (Core == gcvCORE_MAJOR) + { + /* Read idle register. */ + gcmkONERROR(gckOS_ReadRegisterByCoreId(Os, + Core, + gcvCORE_3D_1_ID, + 0x00004, + &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)))))) ) == 0) + { + continue; + } + } +#endif /* Read reset register. */ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, @@ -5940,6 +6609,24 @@ _ResetGPU( continue; } +#if gcdMULTI_GPU > 1 + if (Core == gcvCORE_MAJOR) + { + /* Read reset register. */ + gcmkONERROR(gckOS_ReadRegisterByCoreId(Os, + Core, + gcvCORE_3D_1_ID, + 0x00000, + &control)); + + if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0) + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0) + ) + { + continue; + } + } +#endif /* GPU is idle. */ break; } @@ -5959,97 +6646,42 @@ gckHARDWARE_Reset( ) { gceSTATUS status; - gckCOMMAND command; - gctBOOL acquired = gcvFALSE; - gctBOOL mutexAcquired = gcvFALSE; - gctUINT32 process, thread; gcmkHEADER_ARG("Hardware=0x%x", Hardware); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL); - command = Hardware->kernel->command; - gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); - - if (Hardware->identity.chipRevision < 0x4600) - { - /* Not supported - we need the isolation bit. */ - gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); - } - - status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0); - if (status == gcvSTATUS_TIMEOUT) - { - gcmkONERROR(gckOS_GetProcessID(&process)); - gcmkONERROR(gckOS_GetThreadID(&thread)); - - if ((Hardware->powerProcess == process) - && (Hardware->powerThread == thread)) - { - /* No way to recovery from a error in power management. */ - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - } - } - else - { - mutexAcquired = gcvTRUE; - } - - if (Hardware->chipPowerState == gcvPOWER_ON) - { - /* Acquire the power management semaphore. */ - gcmkONERROR( - gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore)); - acquired = gcvTRUE; - } - - if ((Hardware->chipPowerState == gcvPOWER_ON) - || (Hardware->chipPowerState == gcvPOWER_IDLE) - ) - { - /* Stop the command processor. */ - gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE)); - } - - /* Stop isr, we will start it again when power on GPU. */ - if (Hardware->stopIsr) - { - gcmkONERROR(Hardware->stopIsr(Hardware->isrContext)); - } /* Hardware reset. */ status = gckOS_ResetGPU(Hardware->os, Hardware->core); if (gcmIS_ERROR(status)) { + if (Hardware->identity.chipRevision < 0x4600) + { + /* Not supported - we need the isolation bit. */ + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + /* Soft reset. */ gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core)); } - /* Force an OFF to ON power switch. */ - Hardware->chipPowerState = gcvPOWER_OFF; + /* Initialize hardware. */ + gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware)); - gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex)); - mutexAcquired = gcvFALSE; + /* Jump to address into which GPU should run if it doesn't stuck. */ + gcmkONERROR(gckHARDWARE_Execute(Hardware, Hardware->kernel->restoreAddress, 16)); + + gcmkPRINT("[galcore]: recovery done"); /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: - if (acquired) - { - /* Release the power management semaphore. */ - gcmkVERIFY_OK( - gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore)); - } - - if (mutexAcquired) - { - gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex); - } + gcmkPRINT("[galcore]: Hardware not reset successfully, give up"); /* Return the error. */ gcmkFOOTER(); @@ -6110,7 +6742,7 @@ gckHARDWARE_NeedBaseAddress( /* Make sure this is a load state. */ if (((((gctUINT32) (State)) >> (0 ? 31:27) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))))) { -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D /* Get the state address. */ switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) )) { @@ -6198,7 +6830,7 @@ gckHARDWARE_Compose( IN gctUINT8 EventID ) { -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D gceSTATUS status; gctUINT32_PTR triggerState; @@ -6227,7 +6859,7 @@ gckHARDWARE_Compose( /* Flush the cache for the wait/link. */ gcmkONERROR(gckOS_CacheClean( Hardware->os, ProcessID, gcvNULL, - Physical, Logical, Offset + Size + (gctUINT32)Physical, Logical, Offset + Size )); #endif @@ -6287,13 +6919,50 @@ gckHARDWARE_IsFeatureAvailable( );*/ available = gcvFALSE; break; + case gcvFEATURE_MC20: available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))); break; + + case gcvFEATURE_EARLY_Z: + available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))); + break; + + case gcvFEATURE_HZ: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))); + break; + + case gcvFEATURE_NEW_HZ: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))); + break; + + case gcvFEATURE_FAST_MSAA: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))); + break; + + case gcvFEATURE_SMALL_MSAA: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))); + break; + case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING: /* 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 || + Hardware->identity.chipRevision == 0x5040)) + { + available = gcvFALSE; + } + break; + + case gcvFEATURE_ACE: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))); + break; + + case gcvFEATURE_HALTI2: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))); break; case gcvFEATURE_PIPE_2D: @@ -6301,15 +6970,15 @@ gckHARDWARE_IsFeatureAvailable( break; case gcvFEATURE_PIPE_3D: -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D available = ((((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))))))); #else available = gcvFALSE; #endif break; - case gcvFEATURE_HALTI2: - available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))); + case gcvFEATURE_FC_FLUSH_STALL: + available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))); break; default: @@ -6318,8 +6987,8 @@ gckHARDWARE_IsFeatureAvailable( } /* Return result. */ - gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK); - return available ? gcvSTATUS_TRUE : gcvSTATUS_OK; + gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE); + return available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE; } /******************************************************************************* @@ -6342,10 +7011,15 @@ gckHARDWARE_DumpMMUException( IN gckHARDWARE Hardware ) { -#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT - gctUINT32 mmu, mmuStatus, address, i; -#if gcdDEBUG - gctUINT32 mtlb, stlb, offset; + gctUINT32 mmu = 0; + gctUINT32 mmuStatus = 0; + gctUINT32 address = 0; + gctUINT32 i = 0; + gctUINT32 mtlb = 0; + gctUINT32 stlb = 0; + gctUINT32 offset = 0; +#if gcdPROCESS_ADDRESS_SPACE + gcsDATABASE_PTR database; #endif gcmkHEADER_ARG("Hardware=0x%x", Hardware); @@ -6418,16 +7092,23 @@ gckHARDWARE_DumpMMUException( gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address); +#if gcdPROCESS_ADDRESS_SPACE + for (i = 0; i < gcmCOUNTOF(Hardware->kernel->db->db); ++i) + { + for (database = Hardware->kernel->db->db[i]; + database != gcvNULL; + database = database->next) + { + gcmkPRINT(" database [%d] :", database->processID); + gckMMU_DumpPageTableEntry(database->mmu, address); + } + } +#endif } - gcmkFOOTER_NO(); -#else - /* If clock could be off automatically, we can't read mmu debug - ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0 - ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */ - gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__); -#endif + gckHARDWARE_DumpGPUState(Hardware); + gcmkFOOTER_NO(); return gcvSTATUS_OK; } @@ -6507,16 +7188,16 @@ gckHARDWARE_DumpGPUState( }; gceSTATUS status; - gckKERNEL kernel; - gctUINT32 idle, axi; - gctUINT32 dmaAddress1, dmaAddress2; - gctUINT32 dmaState1, dmaState2; - gctUINT32 dmaLow, dmaHigh; - gctUINT32 cmdState, cmdDmaState, cmdFetState; - gctUINT32 dmaReqState, calState, veReqState; + gckKERNEL kernel = gcvNULL; + gctUINT32 idle = 0, axi = 0; + gctUINT32 dmaAddress1 = 0, dmaAddress2 = 0; + gctUINT32 dmaState1 = 0, dmaState2 = 0; + gctUINT32 dmaLow = 0, dmaHigh = 0; + gctUINT32 cmdState = 0, cmdDmaState = 0, cmdFetState = 0; + gctUINT32 dmaReqState = 0, calState = 0, veReqState = 0; gctUINT i; - gctUINT pipe, pixelPipes; - gctUINT32 control, oldControl; + gctUINT pipe = 0, pixelPipes = 0; + gctUINT32 control = 0, oldControl = 0; gckOS os = Hardware->os; gceCORE core = Hardware->core; @@ -6600,6 +7281,7 @@ gckHARDWARE_DumpGPUState( gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2); } } + gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow); gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh); gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2); @@ -6618,10 +7300,10 @@ gckHARDWARE_DumpGPUState( gcmkPRINT_N(4, " Debug registers of pipe[%d]:\n", pipe); /* Switch pipe. */ - gckOS_ReadRegisterEx(os, core, 0x0, &control); + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x0, &control)); control &= ~(0xF << 20); control |= (pipe << 20); - gckOS_WriteRegisterEx(os, core, 0x0, control); + gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, control)); for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1) { @@ -6653,7 +7335,7 @@ gckHARDWARE_DumpGPUState( } /* Restore control. */ - gckOS_WriteRegisterEx(os, core, 0x0, oldControl); + gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, oldControl)); /* dump stack. */ gckOS_DumpCallStack(os); @@ -6665,8 +7347,6 @@ OnError: return status; } - -#if gcdFRAME_DB static gceSTATUS gckHARDWARE_ReadPerformanceRegister( IN gckHARDWARE Hardware, @@ -6723,7 +7403,7 @@ gckHARDWARE_GetFrameInfo( gctUINT i, clock; gcsHAL_FRAME_INFO info; #if gcdFRAME_DB_RESET - gctUINT reset; + gctUINT reset; #endif gcmkHEADER_ARG("Hardware=0x%x", Hardware); @@ -7062,7 +7742,6 @@ OnError: gcmkFOOTER(); return status; } -#endif #if gcdDVFS #define READ_FROM_EATER1 0 @@ -7254,4 +7933,104 @@ OnError: } #endif +/******************************************************************************* +** +** gckHARDWARE_PrepareFunctions +** +** Generate command buffer snippets which will be used by gckHARDWARE, by which +** gckHARDWARE can manipulate GPU by FE command without using gckCOMMAND to avoid +** race condition and deadlock. +** +** Notice: +** 1. Each snippet can only be executed when GPU is idle. +** 2. Execution is triggered by AHB (0x658) +** 3. Each snippet followed by END so software can sync with GPU by checking GPU +** idle +** 4. It is transparent to gckCOMMAND command buffer. +** +** Existing Snippets: +** 1. MMU Configure +** For new MMU, after GPU is reset, FE execute this command sequence to enble MMU. +*/ +gceSTATUS +gckHARDWARE_PrepareFunctions( + gckHARDWARE Hardware + ) +{ + gceSTATUS status; + gckOS os; + gctUINT32 offset = 0; + gctUINT32 mmuBytes; + gctUINT32 endBytes; + gctUINT8_PTR logical; + + gcmkHEADER_ARG("%x", Hardware); + + os = Hardware->os; + + gcmkVERIFY_OK(gckOS_GetPageSize(os, &Hardware->functionBytes)); + + /* Allocate a command buffer. */ + gcmkONERROR(gckOS_AllocateNonPagedMemory( + os, + gcvFALSE, + &Hardware->functionBytes, + &Hardware->functionPhysical, + &Hardware->functionLogical + )); + + gcmkONERROR(gckOS_GetPhysicalAddress( + os, + Hardware->functionLogical, + &Hardware->functionAddress + )); + + if (Hardware->mmuVersion > 0) + { + /* MMU configure command sequence. */ + logical = (gctUINT8_PTR)Hardware->functionLogical + offset; + + Hardware->functions[gcvHARDWARE_FUNCTION_MMU].address + = Hardware->functionAddress + offset; + + gcmkONERROR(gckHARDWARE_SetMMUStates( + Hardware, + Hardware->kernel->mmu->mtlbLogical, + gcvMMU_MODE_4K, + (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE, + logical, + &mmuBytes + )); + + offset += mmuBytes; + + logical = (gctUINT8_PTR)Hardware->functionLogical + offset; + + gcmkONERROR(gckHARDWARE_End( + Hardware, + gcvNULL, + &endBytes + )); + + gcmkONERROR(gckHARDWARE_End( + Hardware, + logical, + &endBytes + )); + + offset += endBytes; + + Hardware->functions[gcvHARDWARE_FUNCTION_MMU].bytes = mmuBytes + endBytes; + } + + gcmkASSERT(offset < Hardware->functionBytes); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h similarity index 74% rename from drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h rename to drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h index 287ea600a2b3..2ffa1468b5e4 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -30,6 +30,25 @@ extern "C" { #endif +typedef enum { + gcvHARDWARE_FUNCTION_MMU, + gcvHARDWARE_FUNCTION_FLUSH, + + gcvHARDWARE_FUNCTION_NUM, +} +gceHARDWARE_FUNCTION; + + +typedef struct _gcsHARWARE_FUNCTION +{ + /* Entry of the function. */ + gctUINT32 address; + + /* Bytes of the function. */ + gctUINT32 bytes; +} +gcsHARDWARE_FUNCTION; + /* gckHARDWARE object. */ struct _gckHARDWARE { @@ -61,6 +80,7 @@ struct _gckHARDWARE gctUINT32 powerThread; gceCHIPPOWERSTATE chipPowerState; gctUINT32 lastWaitLink; + gctUINT32 lastEnd; gctBOOL clockState; gctBOOL powerState; gctPOINTER globalSemaphore; @@ -71,6 +91,11 @@ struct _gckHARDWARE gctUINT32 mmuVersion; + /* Whether use new MMU. It is meaningless + ** for old MMU since old MMU is always enabled. + */ + gctBOOL enableMMU; + /* Type */ gceHARDWARE_TYPE type; @@ -80,19 +105,32 @@ struct _gckHARDWARE gctPOINTER powerOffTimer; #endif - gctPOINTER pageTableDirty; - #if gcdENABLE_FSCALE_VAL_ADJUST - /* FSCALE_VAL when gcvPOWER_ON. */ gctUINT32 powerOnFscaleVal; #endif + gctPOINTER pageTableDirty; #if gcdLINK_QUEUE_SIZE struct _gckLINKQUEUE linkQueue; #endif gctBOOL powerManagement; + gctBOOL powerManagementLock; gctBOOL gpuProfiler; + + gctBOOL endAfterFlushMmuCache; + + gctUINT32 minFscaleValue; + + gctPOINTER pendingEvent; + + /* Function used by gckHARDWARE. */ + gctPHYS_ADDR functionPhysical; + gctPOINTER functionLogical; + gctUINT32 functionAddress; + gctSIZE_T functionBytes; + + gcsHARDWARE_FUNCTION functions[gcvHARDWARE_FUNCTION_NUM]; }; gceSTATUS @@ -114,20 +152,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/arch/gc_hal_kernel_recorder.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c new file mode 100644 index 000000000000..087fa8353ff1 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c @@ -0,0 +1,679 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2014 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + +#include "gc_hal.h" +#include "gc_hal_kernel.h" +#include "gc_hal_kernel_context.h" + +/* + * ----------------------- + * HARDWARE STATE RECORDER + * ----------------------- + * + * State mirror buffer is used to 'mirror' hardware states since hardware + * states can't be dumpped. It is a context buffer which stores 'global' + * context. + * + * For each commit, state recorder + * 1) Records context buffer (if there is) and command buffers in this commit. + * 2) Parse those buffers to estimate the state changed. + * 3) Stores result to a mirror buffer. + * + * == Commit 0 ==================================================================== + * + * Context Buffer 0 + * + * Command Buffer 0 + * + * Mirror Buffer 0 <- Context Buffer 0 + Command Buffer 0 + * + * == Commit 1 ==================================================================== + * + * Command Buffer 1 + * + * Mirror Buffer 1 <- Command buffer 1 + Mirror Buffer 0 + * + * == Commit 2 ==================================================================== + * + * Context Buffer 2 (optional) + * + * Command Buffer 2 + * + * Mirror Buffer 2 <- Command buffer 2 + Context Buffer 2 + Mirror Buffer 1 + * + * == Commit N ==================================================================== + * + * For Commit N, these buffers are needed to reproduce hardware's behavior in + * this commit. + * + * Mirror Buffer [N - 1] : State Mirror accumlated by past commits, + * which is used to restore hardware state. + * Context Buffer [N] : + * Command Buffer [N] : Command buffer executed by hardware in this commit. + * + * If sequence of states programming matters, hardware's behavior can't be reproduced, + * but the state values stored in mirror buffer are assuring. + */ + +/* Queue size. */ +#define gcdNUM_RECORDS 6 + +typedef struct _gcsPARSER_HANDLER * gckPARSER_HANDLER; + +typedef void +(*HandlerFunction)( + IN gckPARSER_HANDLER Handler, + IN gctUINT32 Addr, + IN gctUINT32 Data + ); + +typedef struct _gcsPARSER_HANDLER +{ + gctUINT32 type; + gctUINT32 cmd; + gctPOINTER private; + HandlerFunction function; +} +gcsPARSER_HANDLER; + +typedef struct _gcsPARSER * gckPARSER; +typedef struct _gcsPARSER +{ + gctUINT8_PTR currentCmdBufferAddr; + + /* Current command. */ + gctUINT32 lo; + gctUINT32 hi; + + gctUINT8 cmdOpcode; + gctUINT16 cmdAddr; + gctUINT32 cmdSize; + gctUINT32 cmdRectCount; + gctUINT8 skip; + gctUINT32 skipCount; + + gctBOOL allow; + + /* Callback used by parser to handle a command. */ + gckPARSER_HANDLER commandHandler; +} +gcsPARSER; + +typedef struct _gcsMIRROR +{ + gctUINT32_PTR logical[gcdNUM_RECORDS]; + gctUINT32 bytes; + gcsSTATE_MAP_PTR map; + gctUINT32 stateCount; +} +gcsMIRROR; + +typedef struct _gcsDELTA +{ + gctUINT64 commitStamp; + gctUINT32_PTR command; + gctUINT32 commandBytes; + gctUINT32_PTR context; + gctUINT32 contextBytes; +} +gcsDELTA; + +typedef struct _gcsRECORDER +{ + gckOS os; + gcsMIRROR mirror; + gcsDELTA deltas[gcdNUM_RECORDS]; + + /* Index of current record. */ + gctUINT index; + + /* Number of records. */ + gctUINT num; + + /* Plugin used by gckPARSER. */ + gcsPARSER_HANDLER recorderHandler; + gckPARSER parser; +} +gcsRECORDER; + + +/******************************************************************************\ +***************************** Command Buffer Parser **************************** +\******************************************************************************/ + +/* +** Command buffer parser checks command buffer in FE's view to make sure there +** is no format error. +** +** Parser provide a callback mechnisam, so plug-in can be added to implement +** other functions. +*/ + +static void +_HandleLoadState( + IN OUT gckPARSER Parser + ) +{ + gctUINT i; + gctUINT32_PTR data = (gctUINT32_PTR)Parser->currentCmdBufferAddr; + gctUINT32 cmdAddr = Parser->cmdAddr; + + if (Parser->commandHandler == gcvNULL + || Parser->commandHandler->cmd != 0x01 + ) + { + /* No handler for this command. */ + return; + } + + for (i = 0; i < Parser->cmdSize; i++) + { + Parser->commandHandler->function(Parser->commandHandler, cmdAddr, *data); + + /* Advance to next state. */ + cmdAddr++; + data++; + } +} + +static void +_GetCommand( + IN OUT gckPARSER Parser + ) +{ + gctUINT32 * buffer = (gctUINT32 *)Parser->currentCmdBufferAddr; + + gctUINT16 cmdRectCount; + gctUINT16 cmdDataCount; + + Parser->hi = buffer[0]; + Parser->lo = buffer[1]; + + Parser->cmdOpcode = (((((gctUINT32) (Parser->hi)) >> (0 ? 31:27)) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) ); + Parser->cmdRectCount = 1; + + switch (Parser->cmdOpcode) + { + case 0x01: + /* Extract count. */ + Parser->cmdSize = (((((gctUINT32) (Parser->hi)) >> (0 ? 25:16)) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1)))))) ); + if (Parser->cmdSize == 0) + { + /* 0 means 1024. */ + Parser->cmdSize = 1024; + } + Parser->skip = (Parser->cmdSize & 0x1) ? 0 : 1; + + /* Extract address. */ + Parser->cmdAddr = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ); + + Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 4; + Parser->skipCount = Parser->cmdSize + Parser->skip; + break; + + case 0x05: + Parser->cmdSize = 4; + Parser->skipCount = gcmALIGN(Parser->cmdSize, 2); + break; + + case 0x06: + Parser->cmdSize = 5; + Parser->skipCount = gcmALIGN(Parser->cmdSize, 2); + break; + + case 0x0C: + Parser->cmdSize = 3; + Parser->skipCount = gcmALIGN(Parser->cmdSize, 2); + break; + + case 0x09: + Parser->cmdSize = 2; + Parser->cmdAddr = 0x0F16; + Parser->skipCount = gcmALIGN(Parser->cmdSize, 2); + break; + + case 0x04: + Parser->cmdSize = 1; + Parser->cmdAddr = 0x0F06; + + cmdRectCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) ); + cmdDataCount = (((((gctUINT32) (Parser->hi)) >> (0 ? 26:16)) & ((gctUINT32) ((((1 ? 26:16) - (0 ? 26:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:16) - (0 ? 26:16) + 1)))))) ); + + Parser->skipCount = gcmALIGN(Parser->cmdSize, 2) + + cmdRectCount * 2 + + gcmALIGN(cmdDataCount, 2); + + Parser->cmdRectCount = cmdRectCount; + break; + + case 0x03: + Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8; + Parser->skipCount = 0; + break; + + case 0x02: + Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + 8; + Parser->skipCount = 0; + break; + + default: + /* Unknown command is a risk. */ + Parser->allow = gcvFALSE; + break; + } +} + +static void +_ParseCommand( + IN OUT gckPARSER Parser + ) +{ + switch(Parser->cmdOpcode) + { + case 0x01: + _HandleLoadState(Parser); + break; + case 0x05: + case 0x06: + case 0x0C: + break; + case 0x04: + break; + default: + break; + } + + /* Advance to next command. */ + Parser->currentCmdBufferAddr = Parser->currentCmdBufferAddr + + (Parser->skipCount << 2); +} + +gceSTATUS +gckPARSER_Parse( + IN gckPARSER Parser, + IN gctUINT8_PTR Buffer, + IN gctUINT32 Bytes + ) +{ + gckPARSER parser = Parser; + gctUINT8_PTR end = (gctUINT8_PTR)Buffer + Bytes; + + /* Initialize parser. */ + parser->currentCmdBufferAddr = (gctUINT8_PTR)Buffer; + parser->skip = 0; + parser->allow = gcvTRUE; + + /* Go through command buffer until reaching the end + ** or meeting an error. */ + do + { + _GetCommand(parser); + + _ParseCommand(parser); + } + while ((parser->currentCmdBufferAddr < end) && (parser->allow == gcvTRUE)); + + if (parser->allow == gcvFALSE) + { + /* Error detected. */ + return gcvSTATUS_NOT_SUPPORTED; + } + + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckPARSER_RegisterCommandHandler +** +** Register a command handler which will be called when parser get a command. +** +*/ +gceSTATUS +gckPARSER_RegisterCommandHandler( + IN gckPARSER Parser, + IN gckPARSER_HANDLER Handler + ) +{ + Parser->commandHandler = Handler; + + return gcvSTATUS_OK; +} + +gceSTATUS +gckPARSER_Construct( + IN gckOS Os, + IN gckPARSER_HANDLER Handler, + OUT gckPARSER * Parser + ) +{ + gceSTATUS status; + gckPARSER pointer; + + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsPARSER), (gctPOINTER *)&pointer)); + + /* Put it here temp, should have a more general plug-in mechnisam. */ + pointer->commandHandler = Handler; + + *Parser = pointer; + + return gcvSTATUS_OK; + +OnError: + return status; +} + +void +gckPARSER_Destroy( + IN gckOS Os, + IN gckPARSER Parser + ) +{ + gcmkOS_SAFE_FREE(Os, Parser); +} + +/******************************************************************************\ +**************************** Hardware States Recorder ************************** +\******************************************************************************/ + +static void +_RecodeState( + IN gckPARSER_HANDLER Handler, + IN gctUINT32 Addr, + IN gctUINT32 Data + ) +{ + gcmkVERIFY_OK(gckRECORDER_UpdateMirror(Handler->private, Addr, Data)); +} + +static gctUINT +_Previous( + IN gctUINT Index + ) +{ + if (Index == 0) + { + return gcdNUM_RECORDS - 1; + } + + return Index - 1; +} + +static gctUINT +_Next( + IN gctUINT Index + ) +{ + return (Index + 1) % gcdNUM_RECORDS; +} + +gceSTATUS +gckRECORDER_Construct( + IN gckOS Os, + IN gckHARDWARE Hardware, + OUT gckRECORDER * Recorder + ) +{ + gceSTATUS status; + gckCONTEXT context = gcvNULL; + gckRECORDER recorder = gcvNULL; + gctUINT32 mapSize; + gctUINT i; + gctBOOL virtualCommandBuffer = Hardware->kernel->virtualCommandBuffer; + + /* TODO: We only need context buffer and state map, it should be able to get without construct a + ** new context. + ** Now it is leaked, since we can't free it when command buffer is gone. + */ + + /* MMU is not ready now. */ + Hardware->kernel->virtualCommandBuffer = gcvFALSE; + + gcmkONERROR(gckCONTEXT_Construct(Os, Hardware, 0, &context)); + + /* Restore. */ + Hardware->kernel->virtualCommandBuffer = virtualCommandBuffer; + + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsRECORDER), (gctPOINTER *)&recorder)); + + gckOS_ZeroMemory(recorder, gcmSIZEOF(gcsRECORDER)); + + /* Copy state map. */ + recorder->mirror.stateCount = context->stateCount; + + mapSize = context->stateCount * gcmSIZEOF(gcsSTATE_MAP); + + gcmkONERROR(gckOS_Allocate(Os, mapSize, (gctPOINTER *)&recorder->mirror.map)); + + gckOS_MemCopy(recorder->mirror.map, context->map, mapSize); + + /* Copy context buffer. */ + recorder->mirror.bytes = context->totalSize; + + for (i = 0; i < gcdNUM_RECORDS; i++) + { + gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->mirror.logical[i])); + gckOS_MemCopy(recorder->mirror.logical[i], context->buffer->logical, context->totalSize); + } + + for (i = 0; i < gcdNUM_RECORDS; i++) + { + /* TODO : Optimize size. */ + gcmkONERROR(gckOS_Allocate(Os, gcdCMD_BUFFER_SIZE, (gctPOINTER *)&recorder->deltas[i].command)); + gcmkONERROR(gckOS_Allocate(Os, context->totalSize, (gctPOINTER *)&recorder->deltas[i].context)); + } + + recorder->index = 0; + recorder->num = 0; + + /* Initialize Parser plugin. */ + recorder->recorderHandler.cmd = 0x01; + recorder->recorderHandler.private = recorder; + recorder->recorderHandler.function = _RecodeState; + + gcmkONERROR(gckPARSER_Construct(Os, &recorder->recorderHandler, &recorder->parser)); + + recorder->os = Os; + + *Recorder = recorder; + + return gcvSTATUS_OK; + +OnError: + if (recorder) + { + gckRECORDER_Destory(Os, recorder); + } + + return status; +} + +gceSTATUS +gckRECORDER_Destory( + IN gckOS Os, + IN gckRECORDER Recorder + ) +{ + gctUINT i; + + if (Recorder->mirror.map) + { + gcmkOS_SAFE_FREE(Os, Recorder->mirror.map); + } + + for (i = 0; i < gcdNUM_RECORDS; i++) + { + if (Recorder->mirror.logical[i]) + { + gcmkOS_SAFE_FREE(Os, Recorder->mirror.logical[i]); + } + } + + for (i = 0; i < gcdNUM_RECORDS; i++) + { + if (Recorder->deltas[i].command) + { + gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].command); + } + + if (Recorder->deltas[i].context) + { + gcmkOS_SAFE_FREE(Os, Recorder->deltas[i].context); + } + } + + if (Recorder->parser) + { + gckPARSER_Destroy(Os, Recorder->parser); + } + + gcmkOS_SAFE_FREE(Os, Recorder); + + return gcvSTATUS_OK; +} + +gceSTATUS +gckRECORDER_UpdateMirror( + IN gckRECORDER Recorder, + IN gctUINT32 State, + IN gctUINT32 Data + ) +{ + gctUINT32 index; + gcsSTATE_MAP_PTR map = Recorder->mirror.map; + gctUINT32_PTR buffer = Recorder->mirror.logical[Recorder->index]; + + if (State >= Recorder->mirror.stateCount) + { + /* Ignore them just like HW does. */ + return gcvSTATUS_OK; + } + + index = map[State].index; + + if (index) + { + buffer[index] = Data; + } + + return gcvSTATUS_OK; +} + +void +gckRECORDER_AdvanceIndex( + IN gckRECORDER Recorder, + IN gctUINT64 CommitStamp + ) +{ + /* Get next record. */ + gctUINT next = (Recorder->index + 1) % gcdNUM_RECORDS; + + /* Record stamp of this commit. */ + Recorder->deltas[Recorder->index].commitStamp = CommitStamp; + + /* Mirror of next record is mirror of this record and delta in next record. */ + gckOS_MemCopy(Recorder->mirror.logical[next], + Recorder->mirror.logical[Recorder->index], Recorder->mirror.bytes); + + /* Advance to next record. */ + Recorder->index = next; + + Recorder->num = gcmMIN(Recorder->num + 1, gcdNUM_RECORDS - 1); + + + /* Reset delta. */ + Recorder->deltas[Recorder->index].commandBytes = 0; + Recorder->deltas[Recorder->index].contextBytes = 0; +} + +void +gckRECORDER_Record( + IN gckRECORDER Recorder, + IN gctUINT8_PTR CommandBuffer, + IN gctUINT32 CommandBytes, + IN gctUINT8_PTR ContextBuffer, + IN gctUINT32 ContextBytes + ) +{ + gcsDELTA * delta = &Recorder->deltas[Recorder->index]; + + if (CommandBytes != 0xFFFFFFFF) + { + gckPARSER_Parse(Recorder->parser, CommandBuffer, CommandBytes); + gckOS_MemCopy(delta->command, CommandBuffer, CommandBytes); + delta->commandBytes = CommandBytes; + } + + if (ContextBytes != 0xFFFFFFFF) + { + gckPARSER_Parse(Recorder->parser, ContextBuffer, ContextBytes); + gckOS_MemCopy(delta->context, ContextBuffer, ContextBytes); + delta->contextBytes = ContextBytes; + } +} + +void +gckRECORDER_Dump( + IN gckRECORDER Recorder + ) +{ + gctUINT last = Recorder->index; + gctUINT previous; + gctUINT i; + gcsMIRROR *mirror = &Recorder->mirror; + gcsDELTA *delta; + gckOS os = Recorder->os; + + for (i = 0; i < Recorder->num; i++) + { + last = _Previous(last); + } + + for (i = 0; i < Recorder->num; i++) + { + delta = &Recorder->deltas[last]; + + /* Dump record */ + gcmkPRINT("#[commit %llu]", delta->commitStamp); + + if (delta->commitStamp) + { + previous = _Previous(last); + + gcmkPRINT("#[mirror]"); + gckOS_DumpBuffer(os, mirror->logical[previous], mirror->bytes, gceDUMP_BUFFER_CONTEXT, gcvTRUE); + gcmkPRINT("@[kernel.execute]"); + } + + if (delta->contextBytes) + { + gckOS_DumpBuffer(os, delta->context, delta->contextBytes, gceDUMP_BUFFER_CONTEXT, gcvTRUE); + gcmkPRINT("@[kernel.execute]"); + } + + gckOS_DumpBuffer(os, delta->command, delta->commandBytes, gceDUMP_BUFFER_USER, gcvTRUE); + gcmkPRINT("@[kernel.execute]"); + + last = _Next(last); + } +} + + diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c similarity index 99% rename from drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c rename to drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c index cf40e3f6b764..0013e63b9a53 100644 --- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -176,8 +176,8 @@ gckVGCOMMAND_StateCommand( IN gctUINT32 Pipe, IN gctPOINTER Logical, IN gctUINT32 Address, - IN gctSIZE_T Count, - IN OUT gctSIZE_T * Bytes + IN gctUINT32 Count, + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x", @@ -277,7 +277,7 @@ gckVGCOMMAND_RestartCommand( IN gctPOINTER Logical, IN gctUINT32 FetchAddress, IN gctUINT FetchCount, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x", @@ -368,7 +368,7 @@ gckVGCOMMAND_FetchCommand( IN gctPOINTER Logical, IN gctUINT32 FetchAddress, IN gctUINT FetchCount, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x", @@ -470,7 +470,7 @@ gckVGCOMMAND_CallCommand( IN gctPOINTER Logical, IN gctUINT32 FetchAddress, IN gctUINT FetchCount, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x", @@ -542,7 +542,7 @@ gceSTATUS gckVGCOMMAND_ReturnCommand( IN gckVGCOMMAND Command, IN gctPOINTER Logical, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x", @@ -619,7 +619,7 @@ gckVGCOMMAND_EventCommand( IN gctPOINTER Logical, IN gceBLOCK Block, IN gctINT32 InterruptId, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x", @@ -857,7 +857,7 @@ gckVGCOMMAND_EndCommand( IN gckVGCOMMAND Command, IN gctPOINTER Logical, IN gctINT32 InterruptId, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ) { gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x", diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h similarity index 97% rename from drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h rename to drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h index aa767ee17356..22093a9655a8 100644 --- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -254,8 +254,8 @@ gckVGCOMMAND_StateCommand( IN gctUINT32 Pipe, IN gctPOINTER Logical, IN gctUINT32 Address, - IN gctSIZE_T Count, - IN OUT gctSIZE_T * Bytes + IN gctUINT32 Count, + IN OUT gctUINT32 * Bytes ); /* Form a RESTART command at the specified location in the command buffer. */ @@ -265,7 +265,7 @@ gckVGCOMMAND_RestartCommand( IN gctPOINTER Logical, IN gctUINT32 FetchAddress, IN gctUINT FetchCount, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Form a FETCH command at the specified location in the command buffer. */ @@ -275,7 +275,7 @@ gckVGCOMMAND_FetchCommand( IN gctPOINTER Logical, IN gctUINT32 FetchAddress, IN gctUINT FetchCount, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Form a CALL command at the specified location in the command buffer. */ @@ -285,7 +285,7 @@ gckVGCOMMAND_CallCommand( IN gctPOINTER Logical, IN gctUINT32 FetchAddress, IN gctUINT FetchCount, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Form a RETURN command at the specified location in the command buffer. */ @@ -293,7 +293,7 @@ gceSTATUS gckVGCOMMAND_ReturnCommand( IN gckVGCOMMAND Command, IN gctPOINTER Logical, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Form an EVENT command at the specified location in the command buffer. */ @@ -303,7 +303,7 @@ gckVGCOMMAND_EventCommand( IN gctPOINTER Logical, IN gceBLOCK Block, IN gctINT32 InterruptId, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Form an END command at the specified location in the command buffer. */ @@ -312,7 +312,7 @@ gckVGCOMMAND_EndCommand( IN gckVGCOMMAND Command, IN gctPOINTER Logical, IN gctINT32 InterruptId, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); #endif /* __gc_hal_kernel_hardware_command_h_ */ diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c similarity index 97% rename from drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c rename to drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c index a17d2fdb7747..3cb47dd04b6f 100644 --- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -310,9 +310,9 @@ gckVGHARDWARE_Construct( hardware->clockState = gcvTRUE; hardware->powerState = gcvTRUE; - hardware->powerOffTime = 0; #if gcdPOWEROFF_TIMEOUT - hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT; + hardware->powerOffTime = 0; + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT; gcmkVERIFY_OK(gckOS_CreateTimer(Os, _VGPowerTimerFunction, @@ -352,14 +352,16 @@ gckVGHARDWARE_Construct( while (gcvFALSE); #if gcdPOWEROFF_TIMEOUT - if (hardware->powerOffTimer != gcvNULL) - { - gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer)); - gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer)); - } + if (hardware->powerOffTimer != gcvNULL) + { + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer)); + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer)); + } #endif - if (hardware->pageTableDirty != gcvNULL) + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE)); + + if (hardware != gcvNULL && hardware->pageTableDirty != gcvNULL) { gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty)); } @@ -369,8 +371,6 @@ gckVGHARDWARE_Construct( gcmkVERIFY_OK(gckOS_Free(Os, hardware)); } - gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE)); - gcmkFOOTER(); /* Return the status. */ return status; @@ -889,7 +889,7 @@ gceSTATUS gckVGHARDWARE_Execute( IN gckVGHARDWARE Hardware, IN gctUINT32 Address, - IN gctSIZE_T Count + IN gctUINT32 Count ) { gceSTATUS status; @@ -1042,6 +1042,9 @@ gckVGHARDWARE_AlignToTile( ** gctPOINTER Logical ** Logical address to convert. ** +** gctBOOL InUserSpace +** gcvTRUE if the memory in user space. +** ** gctUINT32* Address ** Return hardware specific address. ** @@ -1053,14 +1056,15 @@ gceSTATUS gckVGHARDWARE_ConvertLogical( IN gckVGHARDWARE Hardware, IN gctPOINTER Logical, + IN gctBOOL InUserSpace, OUT gctUINT32 * Address ) { gctUINT32 address; gceSTATUS status; - gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x", - Hardware, Logical, Address); + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d Address=0x%x", + Hardware, Logical, InUserSpace, Address); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); @@ -1070,9 +1074,18 @@ gckVGHARDWARE_ConvertLogical( do { /* Convert logical address into a physical address. */ - gcmkERR_BREAK(gckOS_GetPhysicalAddress( - Hardware->os, Logical, &address - )); + if (InUserSpace) + { + gcmkERR_BREAK(gckOS_UserLogicalToPhysical( + Hardware->os, Logical, &address + )); + } + else + { + gcmkERR_BREAK(gckOS_GetPhysicalAddress( + Hardware->os, Logical, &address + )); + } /* Return hardware specific address. */ *Address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))); @@ -1174,32 +1187,33 @@ gceSTATUS gckVGHARDWARE_SetMMU( do { /* Convert the logical address into an hardware address. */ - gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) ); + gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, + gcvFALSE, &address)); /* Write the AQMemoryFePageTable register. */ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, 0x00400, - gcmkFIXADDRESS(address)) ); + gcmkFIXADDRESS(address))); /* Write the AQMemoryTxPageTable register. */ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, 0x00404, - gcmkFIXADDRESS(address)) ); + gcmkFIXADDRESS(address))); /* Write the AQMemoryPePageTable register. */ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, 0x00408, - gcmkFIXADDRESS(address)) ); + gcmkFIXADDRESS(address))); /* Write the AQMemoryPezPageTable register. */ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, 0x0040C, - gcmkFIXADDRESS(address)) ); + gcmkFIXADDRESS(address))); /* Write the AQMemoryRaPageTable register. */ gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG, 0x00410, - gcmkFIXADDRESS(address)) ); + gcmkFIXADDRESS(address))); } while (gcvFALSE); @@ -1436,7 +1450,7 @@ static gceSTATUS _CommandStall( gcmkERR_BREAK(gckOS_WaitSignal( command->os, command->powerStallSignal, - gcdGPU_TIMEOUT)); + command->kernel->kernel->timeOut)); } @@ -1800,17 +1814,10 @@ gckVGHARDWARE_SetPowerManagementState( acquired = gcvTRUE; } - if (flag & gcvPOWER_FLAG_STOP) - { - } /* Get time until stopped. */ gcmkPROFILE_QUERY(time, stopTime); - /* Only process this when hardware is enabled. */ - if (Hardware->clockState && Hardware->powerState) - { - } if (flag & gcvPOWER_FLAG_DELAY) { @@ -1824,7 +1831,10 @@ gckVGHARDWARE_SetPowerManagementState( if (flag & gcvPOWER_FLAG_INITIALIZE) { + + /* Initialize GPU here, replaced by InitializeHardware later */ gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical)); + gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(Hardware, -1)); /* Force the command queue to reload the next context. */ command->currentContext = 0; @@ -1854,9 +1864,6 @@ gckVGHARDWARE_SetPowerManagementState( /* Get time until off. */ gcmkPROFILE_QUERY(time, offTime); - if (flag & gcvPOWER_FLAG_START) - { - } /* Get time until started. */ gcmkPROFILE_QUERY(time, startTime); @@ -2023,6 +2030,7 @@ gckVGHARDWARE_SetPowerManagement( return gcvSTATUS_OK; } +#if gcdPOWEROFF_TIMEOUT gceSTATUS gckVGHARDWARE_SetPowerOffTimeout( IN gckVGHARDWARE Hardware, @@ -2051,6 +2059,7 @@ gckVGHARDWARE_QueryPowerOffTimeout( gcmkFOOTER_ARG("*Timeout=%d", *Timeout); return gcvSTATUS_OK; } +#endif gceSTATUS gckVGHARDWARE_QueryIdle( diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h similarity index 98% rename from drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h rename to drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h index 73d4594d7bc0..ce54910545d7 100644 --- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h +++ b/drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -61,7 +61,6 @@ struct _gckVGHARDWARE gctISRMANAGERFUNC stopIsr; gctPOINTER isrContext; gctPOINTER pageTableDirty; - #if gcdPOWEROFF_TIMEOUT gctUINT32 powerOffTime; gctUINT32 powerOffTimeout; 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 879d467e3620..b14708d307d4 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -50,7 +50,7 @@ gctCONST_STRING _DispatchText[] = gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY), gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY), gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY), - gcmDEFINE2TEXT(gcvHAL_FREE_VIDEO_MEMORY), + gcmDEFINE2TEXT(gcvHAL_RELEASE_VIDEO_MEMORY), gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY), gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY), gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY), @@ -68,10 +68,10 @@ gctCONST_STRING _DispatchText[] = gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING), gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING), gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS), + gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D), #if VIVANTE_PROFILER_PERDRAW - gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING), + gcvHAL_READ_PROFILER_REGISTER_SETTING, #endif - gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D), gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE), gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE), gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS), @@ -86,21 +86,196 @@ gctCONST_STRING _DispatchText[] = gcmDEFINE2TEXT(gcvHAL_VERSION), gcmDEFINE2TEXT(gcvHAL_CHIP_INFO), gcmDEFINE2TEXT(gcvHAL_ATTACH), - gcmDEFINE2TEXT(gcvHAL_DETACH) + gcmDEFINE2TEXT(gcvHAL_DETACH), + gcmDEFINE2TEXT(gcvHAL_COMPOSE), + gcmDEFINE2TEXT(gcvHAL_SET_TIMEOUT), + gcmDEFINE2TEXT(gcvHAL_GET_FRAME_INFO), + gcmDEFINE2TEXT(gcvHAL_QUERY_COMMAND_BUFFER), + gcmDEFINE2TEXT(gcvHAL_COMMIT_DONE), + gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_STATE), + gcmDEFINE2TEXT(gcvHAL_DUMP_EVENT), + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER), + gcmDEFINE2TEXT(gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER), + gcmDEFINE2TEXT(gcvHAL_SET_FSCALE_VALUE), + 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 -#if gcdENABLE_RECOVERY +#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC void -_ResetFinishFunction( +_MonitorTimerFunction( gctPOINTER Data ) { gckKERNEL kernel = (gckKERNEL)Data; + gctUINT32 pendingInterrupt; + gctBOOL reset = gcvFALSE; + gctUINT32 mask; + gctUINT32 advance = kernel->timeOut/2; + +#if gcdENABLE_VG + if (kernel->core == gcvCORE_VG) + { + return; + } +#endif + + if (kernel->monitorTimerStop) + { + /* Stop. */ + return; + } + + gckOS_AtomGet(kernel->os, kernel->eventObj->interruptCount, &pendingInterrupt); + + if (kernel->monitoring == gcvFALSE) + { + if (pendingInterrupt) + { + /* Begin to mointor GPU state. */ + kernel->monitoring = gcvTRUE; + + /* Record current state. */ + kernel->lastCommitStamp = kernel->eventObj->lastCommitStamp; + kernel->restoreAddress = kernel->hardware->lastWaitLink; + gcmkVERIFY_OK(gckOS_AtomGet( + kernel->os, + kernel->hardware->pendingEvent, + &kernel->restoreMask + )); + + /* Clear timeout. */ + kernel->timer = 0; + } + } + else + { + if (pendingInterrupt) + { + gcmkVERIFY_OK(gckOS_AtomGet( + kernel->os, + kernel->hardware->pendingEvent, + &mask + )); + + if (kernel->eventObj->lastCommitStamp == kernel->lastCommitStamp + && kernel->hardware->lastWaitLink == kernel->restoreAddress + && mask == kernel->restoreMask + ) + { + /* GPU state is not changed, accumlate timeout. */ + kernel->timer += advance; + + if (kernel->timer >= kernel->timeOut) + { + /* GPU stuck, trigger reset. */ + reset = gcvTRUE; + } + } + else + { + /* GPU state changed, cancel current timeout.*/ + kernel->monitoring = gcvFALSE; + } + } + else + { + /* GPU finish all jobs, cancel current timeout*/ + kernel->monitoring = gcvFALSE; + } + } + + if (reset) + { + gckKERNEL_Recovery(kernel); + + /* Work in this timeout is done. */ + kernel->monitoring = gcvFALSE; + } + + gcmkVERIFY_OK(gckOS_StartTimer(kernel->os, kernel->monitorTimer, advance)); +} +#endif + +#if gcdPROCESS_ADDRESS_SPACE +gceSTATUS +_MapCommandBuffer( + IN gckKERNEL Kernel + ) +{ + gceSTATUS status; + gctUINT32 i; + gctUINT32 physical; + gckMMU mmu; + + gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu)); + + for (i = 0; i < gcdCOMMAND_QUEUES; i++) + { + gcmkONERROR(gckOS_GetPhysicalAddress( + Kernel->os, + Kernel->command->queues[i].logical, + &physical + )); + + gcmkONERROR(gckMMU_FlatMapping(mmu, physical)); + } + + return gcvSTATUS_OK; + +OnError: + return status; +} +#endif + +void +_DumpDriverConfigure( + IN gckKERNEL Kernel + ) +{ + gcmkPRINT_N(0, "**************************\n"); + gcmkPRINT_N(0, "*** GPU DRV CONFIG ***\n"); + gcmkPRINT_N(0, "**************************\n"); - gckOS_AtomSet(kernel->os, kernel->resetAtom, 0); + gcmkPRINT("Galcore version %d.%d.%d.%d\n", + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD); + + gckOS_DumpParam(); } + +void +_DumpState( + IN gckKERNEL Kernel + ) +{ + /* Dump GPU Debug registers. */ + gcmkVERIFY_OK(gckHARDWARE_DumpGPUState(Kernel->hardware)); + + if (Kernel->virtualCommandBuffer) + { + gcmkVERIFY_OK(gckCOMMAND_DumpExecutingBuffer(Kernel->command)); + } + + /* Dump Pending event. */ + gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj)); + + /* Dump Process DB. */ + gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel)); + +#if gcdRECORD_COMMAND + /* Dump record. */ + gckRECORDER_Dump(Kernel->command->recorder); #endif +} /******************************************************************************* ** @@ -164,13 +339,13 @@ gckKERNEL_Construct( #if gcdDVFS kernel->dvfs = gcvNULL; #endif + kernel->monitorTimer = gcvNULL; /* Initialize the gckKERNEL object. */ kernel->object.type = gcvOBJ_KERNEL; kernel->os = Os; kernel->core = Core; - if (SharedDB == gcvNULL) { gcmkONERROR(gckOS_Allocate(Os, @@ -195,10 +370,16 @@ gckKERNEL_Construct( /* Construct a database mutex. */ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex)); - /* Construct a id-pointer database. */ + /* Construct a video memory name database. */ + gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->nameDatabase)); + + /* Construct a video memory name database mutex. */ + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->nameDatabaseMutex)); + + /* Construct a pointer name database. */ gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase)); - /* Construct a id-pointer database mutex. */ + /* Construct a pointer name database mutex. */ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex)); } else @@ -213,19 +394,9 @@ gckKERNEL_Construct( kernel->timers[i].stopTime = 0; } - kernel->timeOut = gcdGPU_TIMEOUT; - /* Save context. */ kernel->context = Context; -#if gcdVIRTUAL_COMMAND_BUFFER - kernel->virtualBufferHead = - kernel->virtualBufferTail = gcvNULL; - - gcmkONERROR( - gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock)); -#endif - /* Construct atom holding number of clients. */ kernel->atomClients = gcvNULL; gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients)); @@ -238,6 +409,8 @@ gckKERNEL_Construct( /* Construct the gckMMU object. */ gcmkONERROR( gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg)); + + kernel->timeOut = gcdGPU_TIMEOUT; } else #endif @@ -249,9 +422,22 @@ gckKERNEL_Construct( /* Set pointer to gckKERNEL object in gckHARDWARE object. */ kernel->hardware->kernel = kernel; - /* Initialize the hardware. */ - gcmkONERROR( - gckHARDWARE_InitializeHardware(kernel->hardware)); + kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D + ? gcdGPU_2D_TIMEOUT + : gcdGPU_TIMEOUT + ; + + /* Initialize virtual command buffer. */ + /* TODO: Remove platform limitation after porting. */ +#if (defined(LINUX) || defined(__QNXNTO__)) + kernel->virtualCommandBuffer = gcvTRUE; +#else + kernel->virtualCommandBuffer = gcvFALSE; +#endif + +#if gcdSECURITY + kernel->virtualCommandBuffer = gcvFALSE; +#endif /* Construct the gckCOMMAND object. */ gcmkONERROR( @@ -265,17 +451,13 @@ gckKERNEL_Construct( gcmkONERROR( gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu)); -#if gcdENABLE_RECOVERY - gcmkONERROR( - gckOS_AtomConstruct(Os, &kernel->resetAtom)); + gcmkVERIFY_OK(gckOS_GetTime(&kernel->resetTimeStamp)); - gcmkVERIFY_OK( - gckOS_CreateTimer(Os, - (gctTIMERFUNCTION)_ResetFinishFunction, - (gctPOINTER)kernel, - &kernel->resetFlagClearTimer)); - kernel->resetTimeStamp = 0; -#endif + gcmkONERROR(gckHARDWARE_PrepareFunctions(kernel->hardware)); + + /* Initialize the hardware. */ + gcmkONERROR( + gckHARDWARE_InitializeHardware(kernel->hardware)); #if gcdDVFS if (gckHARDWARE_IsFeatureAvailable(kernel->hardware, @@ -297,6 +479,42 @@ gckKERNEL_Construct( gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline)); #endif + kernel->recovery = gcvTRUE; + kernel->stuckDump = 1; + + kernel->virtualBufferHead = + kernel->virtualBufferTail = gcvNULL; + + 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 + +#if gcdGPU_TIMEOUT && gcdINTERRUPT_STATISTIC + if (kernel->timeOut) + { + gcmkVERIFY_OK(gckOS_CreateTimer( + Os, + (gctTIMERFUNCTION)_MonitorTimerFunction, + (gctPOINTER)kernel, + &kernel->monitorTimer + )); + + kernel->monitoring = gcvFALSE; + + kernel->monitorTimerStop = gcvFALSE; + + gcmkVERIFY_OK(gckOS_StartTimer( + Os, + kernel->monitorTimer, + 100 + )); + } +#endif + /* Return pointer to the gckKERNEL object. */ *Kernel = kernel; @@ -337,19 +555,6 @@ OnError: gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients)); } -#if gcdENABLE_RECOVERY - if (kernel->resetAtom != gcvNULL) - { - gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom)); - } - - if (kernel->resetFlagClearTimer) - { - gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer)); - gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->resetFlagClearTimer)); - } -#endif - if (kernel->dbCreated && kernel->db != gcvNULL) { if (kernel->db->dbMutex != gcvNULL) @@ -361,13 +566,11 @@ OnError: gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db)); } -#if gcdVIRTUAL_COMMAND_BUFFER if (kernel->virtualBufferLock != gcvNULL) { /* Destroy the virtual command buffer mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock)); } -#endif #if gcdDVFS if (kernel->dvfs) @@ -384,6 +587,12 @@ OnError: } #endif + if (kernel->monitorTimer) + { + gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->monitorTimer)); + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->monitorTimer)); + } + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel)); } @@ -442,11 +651,14 @@ gckKERNEL_Destroy( database = databaseNext) { databaseNext = database->next; + + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->counterMutex)); gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database)); } if (Kernel->db->lastDatabase != gcvNULL) { + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->lastDatabase->counterMutex)); gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase)); } @@ -460,12 +672,24 @@ gckKERNEL_Destroy( /* Destroy the database mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex)); + /* Destroy video memory name database. */ + gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->nameDatabase)); + + /* Destroy video memory name database mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->nameDatabaseMutex)); + /* Destroy id-pointer database. */ gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase)); /* Destroy id-pointer database mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + + /* Destroy the database. */ + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db)); + + /* Notify stuck timer to quit. */ + Kernel->monitorTimerStop = gcvTRUE; } #if gcdENABLE_VG @@ -487,24 +711,12 @@ gckKERNEL_Destroy( /* Destroy the gckHARDWARE object. */ gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware)); - -#if gcdENABLE_RECOVERY - gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom)); - - if (Kernel->resetFlagClearTimer) - { - gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer)); - gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->resetFlagClearTimer)); - } -#endif } /* Detsroy the client atom. */ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients)); -#if gcdVIRTUAL_COMMAND_BUFFER gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock)); -#endif #if gcdDVFS if (Kernel->dvfs) @@ -518,6 +730,16 @@ gckKERNEL_Destroy( gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline)); #endif +#if gcdSECURITY + gcmkVERIFY_OK(gckKERNEL_SecurityClose(Kernel->securityChannel)); +#endif + + if (Kernel->monitorTimer) + { + gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->monitorTimer)); + gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->monitorTimer)); + } + /* Mark the gckKERNEL object as unknown. */ Kernel->object.type = gcvOBJ_UNKNOWN; @@ -529,98 +751,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 @@ -643,14 +773,16 @@ static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel) ** Pointer to a gcsHAL_INTERFACE structure that receives any data to be ** returned. */ -static gceSTATUS -_AllocateMemory( +gceSTATUS +gckKERNEL_AllocateLinearMemory( IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, IN OUT gcePOOL * Pool, IN gctSIZE_T Bytes, - IN gctSIZE_T Alignment, + IN gctUINT32 Alignment, IN gceSURF_TYPE Type, - OUT gcuVIDMEM_NODE_PTR * Node + IN gctUINT32 Flag, + OUT gctUINT32 * Node ) { gcePOOL pool; @@ -659,7 +791,11 @@ _AllocateMemory( 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; + gceDATABASE_TYPE type; gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d", Kernel, *Pool, Bytes, Alignment, Type); @@ -667,14 +803,18 @@ _AllocateMemory( 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; case gcvPOOL_DEFAULT: case gcvPOOL_LOCAL: pool = gcvPOOL_LOCAL_INTERNAL; @@ -690,12 +830,6 @@ _AllocateMemory_Retry: loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS; break; - case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE: - pool = gcvPOOL_CONTIGUOUS; - loopCount = 1; - forceContiguous = gcvTRUE; - break; - default: loopCount = 1; break; @@ -707,7 +841,10 @@ _AllocateMemory_Retry: { /* Create a gcuVIDMEM_NODE for virtual memory. */ gcmkONERROR( - gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, &node)); + gckVIDMEM_ConstructVirtual(Kernel, Flag | gcvALLOC_FLAG_NON_CONTIGUOUS, Bytes, &node)); + + bytes = node->Virtual.bytes; + node->Virtual.type = Type; /* Success. */ break; @@ -717,7 +854,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; } @@ -725,88 +862,56 @@ _AllocateMemory_Retry: #endif { /* Create a gcuVIDMEM_NODE from contiguous memory. */ - status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, &node); + status = gckVIDMEM_ConstructVirtual( + Kernel, + Flag | gcvALLOC_FLAG_CONTIGUOUS, + Bytes, + &node); } - if (gcmIS_SUCCESS(status) || forceContiguous == gcvTRUE) + if (gcmIS_SUCCESS(status)) { - /* Memory allocated. */ - if(node && forceContiguous == gcvTRUE) - { - gctUINT32 physAddr=0; - gctUINT32 baseAddress = 0; - - gcmkONERROR( - gckOS_LockPages(Kernel->os, - node->Virtual.physical, - node->Virtual.bytes, - gcvFALSE, - &node->Virtual.logical, - &node->Virtual.pageCount)); - - /* Convert logical address into a physical address. */ - gcmkONERROR( - gckOS_GetPhysicalAddress(Kernel->os, - node->Virtual.logical, - &physAddr)); - - gcmkONERROR( - gckOS_UnlockPages(Kernel->os, - node->Virtual.physical, - node->Virtual.bytes, - node->Virtual.logical)); - - gcmkONERROR(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 in force contiguous request!\n", physAddr); - - gcmkONERROR(gckVIDMEM_Free(node)); - - node = gcvNULL; - } - } + bytes = node->Virtual.bytes; + node->Virtual.type = Type; + /* Memory allocated. */ break; } } else + /* gcvPOOL_SYSTEM can't be cacheable. */ + if (cacheable == gcvFALSE) { /* Get pointer to gckVIDMEM object for pool. */ -#if gcdUSE_VIDMEM_PER_PID - gctUINT32 pid; - gckOS_GetProcessID(&pid); - - status = gckKERNEL_GetVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory); - if (status == gcvSTATUS_NOT_FOUND) - { - /* Create VidMem pool for this process. */ - status = gckKERNEL_CreateVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory); - } -#else status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory); -#endif if (gcmIS_SUCCESS(status)) { /* Allocate memory. */ - status = gckVIDMEM_AllocateLinear(videoMemory, - Bytes, - Alignment, - Type, - &node); +#if defined(gcdLINEAR_SIZE_LIMIT) + /* 512 KB */ + if (Bytes > gcdLINEAR_SIZE_LIMIT) + { + status = gcvSTATUS_OUT_OF_MEMORY; + } + else +#endif + { + status = gckVIDMEM_AllocateLinear(Kernel, + videoMemory, + Bytes, + Alignment, + Type, + (*Pool == gcvPOOL_SYSTEM), + &node); + } if (gcmIS_SUCCESS(status)) { /* Memory allocated. */ node->VidMem.pool = pool; + bytes = node->VidMem.bytes; break; } } @@ -835,15 +940,29 @@ _AllocateMemory_Retry: else if (pool == gcvPOOL_CONTIGUOUS) { - tileStatusInVirtual = - gckHARDWARE_IsFeatureAvailable(Kernel->hardware, - gcvFEATURE_MC20); +#if gcdENABLE_VG + if (Kernel->vg) + { + tileStatusInVirtual = gcvFALSE; + } + else +#endif + { + tileStatusInVirtual = + gckHARDWARE_IsFeatureAvailable(Kernel->hardware, + gcvFEATURE_MC20); + } if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE) { gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } + if (contiguous) + { + break; + } + /* Advance to virtual memory. */ pool = gcvPOOL_VIRTUAL; } @@ -857,31 +976,68 @@ _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); } + /* Allocate handle for this video memory. */ + gcmkONERROR( + gckVIDMEM_NODE_Allocate(Kernel, node, Type, pool, &handle)); + /* Return node and pool used for allocation. */ - *Node = node; + *Node = handle; *Pool = pool; + /* Encode surface type and pool to database type. */ + type = gcvDB_VIDEO_MEMORY + | (Type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) + | (pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT); + + /* Record in process db. */ + gcmkONERROR( + gckKERNEL_AddProcessDB(Kernel, + ProcessID, + type, + gcmINT2PTR(handle), + gcvNULL, + bytes)); + /* Return status. */ gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node); return gcvSTATUS_OK; OnError: + if (handle) + { + /* Destroy handle allocated. */ + gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, handle)); + } + + if (node) + { + /* Free video memory allocated. */ + gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node)); + } + + /* For some case like chrome with webgl test, it needs too much memory so that it invokes oom_killer + * And the case is killed by oom_killer, the user wants not to see the crash and hope the case iteself handles the condition + * So the patch reports the out_of_memory to the case */ + if ( status == gcvSTATUS_OUT_OF_MEMORY && (Flag & gcvALLOC_FLAG_MEMLIMIT) ) + gcmkPRINT("The running case is out_of_memory"); + /* Return the status. */ gcmkFOOTER(); return status; @@ -889,514 +1045,789 @@ OnError: /******************************************************************************* ** -** gckKERNEL_Dispatch +** gckKERNEL_ReleaseVideoMemory ** -** Dispatch a command received from the user HAL layer. +** Release handle of a video memory. ** ** INPUT: ** ** gckKERNEL Kernel ** Pointer to an gckKERNEL object. ** -** gctBOOL FromUser -** whether the call is from the user space. +** gctUINT32 ProcessID +** ProcessID of current process. ** -** gcsHAL_INTERFACE * Interface -** Pointer to a gcsHAL_INTERFACE structure that defines the command to -** be dispatched. +** gctUINT32 Handle +** Handle of video memory. ** ** OUTPUT: ** -** gcsHAL_INTERFACE * Interface -** Pointer to a gcsHAL_INTERFACE structure that receives any data to be -** returned. +** Nothing. */ - gceSTATUS -gckKERNEL_Dispatch( +gckKERNEL_ReleaseVideoMemory( IN gckKERNEL Kernel, - IN gctBOOL FromUser, - IN OUT gcsHAL_INTERFACE * Interface + IN gctUINT32 ProcessID, + IN gctUINT32 Handle ) { - gceSTATUS status = gcvSTATUS_OK; - gctSIZE_T bytes; - gcuVIDMEM_NODE_PTR node; - gctBOOL locked = gcvFALSE; - gctPHYS_ADDR physical = gcvNULL; - gctPOINTER logical = gcvNULL; - gctPOINTER info = gcvNULL; - gckCONTEXT context = gcvNULL; - gctUINT32 address; - gctUINT32 processID; - gckKERNEL kernel = Kernel; -#if gcdSECURE_USER - gcskSECURE_CACHE_PTR cache; -#endif - gctBOOL asynchronous; - gctPOINTER paddr = gcvNULL; -#if !USE_NEW_LINUX_SIGNAL - gctSIGNAL signal; -#endif - gceSURF_TYPE type; + gceSTATUS status; + gckVIDMEM_NODE nodeObject; + gceDATABASE_TYPE type; - gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x", - Kernel, FromUser, Interface); + gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d Handle=%d", + Kernel, ProcessID, Handle); - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - gcmkVERIFY_ARGUMENT(Interface != gcvNULL); + gcmkONERROR( + gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Handle, &nodeObject)); -#if gcmIS_DEBUG(gcdDEBUG_TRACE) - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, - "Dispatching command %d (%s)", - Interface->command, _DispatchText[Interface->command]); -#endif -#if QNX_SINGLE_THREADED_DEBUGGING - gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE); -#endif + type = gcvDB_VIDEO_MEMORY + | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) + | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT); - /* Get the current process ID. */ - gcmkONERROR(gckOS_GetProcessID(&processID)); + gcmkONERROR( + gckKERNEL_RemoveProcessDB(Kernel, + ProcessID, + type, + gcmINT2PTR(Handle))); -#if gcdSECURE_USER - gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache)); -#endif + gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, Handle); - /* Dispatch on command. */ - switch (Interface->command) - { - case gcvHAL_GET_BASE_ADDRESS: - /* Get base address. */ - gcmkONERROR( - gckOS_GetBaseAddress(Kernel->os, - &Interface->u.GetBaseAddress.baseAddress)); - break; + gckVIDMEM_NODE_Dereference(Kernel, nodeObject); - case gcvHAL_QUERY_VIDEO_MEMORY: - /* Query video memory size. */ - gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface)); - break; + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - case gcvHAL_QUERY_CHIP_IDENTITY: - /* Query chip identity. */ - gcmkONERROR( - gckHARDWARE_QueryChipIdentity( - Kernel->hardware, - &Interface->u.QueryChipIdentity)); - break; +OnError: + gcmkFOOTER(); + return status; +} - case gcvHAL_MAP_MEMORY: - physical = gcmINT2PTR(Interface->u.MapMemory.physical); +/******************************************************************************* +** +** gckKERNEL_LockVideoMemory +** +** Lock a video memory node. It will generate a cpu virtual address used +** by software and a GPU address used by GPU. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gceCORE Core +** GPU to which video memory is locked. +** +** gcsHAL_INTERFACE * Interface +** Pointer to a gcsHAL_INTERFACE structure that defines the command to +** be dispatched. +** +** OUTPUT: +** +** gcsHAL_INTERFACE * Interface +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be +** returned. +*/ +gceSTATUS +gckKERNEL_LockVideoMemory( + IN gckKERNEL Kernel, + IN gceCORE Core, + IN gctUINT32 ProcessID, + IN gctBOOL FromUser, + IN OUT gcsHAL_INTERFACE * Interface + ) +{ + gceSTATUS status; + gckVIDMEM_NODE nodeObject = gcvNULL; + gcuVIDMEM_NODE_PTR node = gcvNULL; + gctBOOL locked = gcvFALSE; + gctBOOL asynchronous = gcvFALSE; +#ifndef __QNXNTO__ + gctPOINTER pointer = gcvNULL; +#endif - /* Map memory. */ - gcmkONERROR( - gckKERNEL_MapMemory(Kernel, - physical, - (gctSIZE_T) Interface->u.MapMemory.bytes, - &logical)); + gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d", + Kernel, ProcessID); - Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical); + gcmkONERROR( + gckVIDMEM_HANDLE_LookupAndReference(Kernel, + Interface->u.LockVideoMemory.node, + &nodeObject)); - gcmkVERIFY_OK( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_MAP_MEMORY, - logical, - physical, - (gctSIZE_T) Interface->u.MapMemory.bytes)); - break; + node = nodeObject->node; - case gcvHAL_UNMAP_MEMORY: - physical = gcmINT2PTR(Interface->u.UnmapMemory.physical); + Interface->u.LockVideoMemory.gid = 0; - /* Unmap memory. */ - gcmkONERROR( - gckKERNEL_UnmapMemory(Kernel, - physical, - (gctSIZE_T) Interface->u.UnmapMemory.bytes, - gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical))); - gcmkVERIFY_OK( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_MAP_MEMORY, - gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical))); - break; + /* Lock video memory. */ + gcmkONERROR( + gckVIDMEM_Lock(Kernel, + nodeObject, + Interface->u.LockVideoMemory.cacheable, + &Interface->u.LockVideoMemory.address, + &Interface->u.LockVideoMemory.gid, + &Interface->u.LockVideoMemory.physicalAddress)); - case gcvHAL_ALLOCATE_NON_PAGED_MEMORY: - bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes; + locked = gcvTRUE; - /* Allocate non-paged memory. */ + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + { + /* Map video memory address into user space. */ +#ifdef __QNXNTO__ + if (node->VidMem.logical == gcvNULL) + { + gcmkONERROR( + gckKERNEL_MapVideoMemory(Kernel, + FromUser, + Interface->u.LockVideoMemory.address, + ProcessID, + node->VidMem.bytes, + &node->VidMem.logical)); + } + gcmkASSERT(node->VidMem.logical != gcvNULL); + + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical); +#else gcmkONERROR( - gckOS_AllocateNonPagedMemory( - Kernel->os, - FromUser, - &bytes, - &physical, - &logical)); + gckKERNEL_MapVideoMemoryEx(Kernel, + Core, + FromUser, + Interface->u.LockVideoMemory.address, + &pointer)); - Interface->u.AllocateNonPagedMemory.bytes = bytes; - Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical); - Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical); + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(pointer); +#endif + } + else + { + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical); - gcmkVERIFY_OK( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_NON_PAGED, - logical, - gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical), - bytes)); + /* Success. */ + status = gcvSTATUS_OK; + } - break; +#if gcdPROCESS_ADDRESS_SPACE + gcmkONERROR(gckVIDMEM_Node_Lock( + Kernel, + nodeObject, + &Interface->u.LockVideoMemory.address + )); +#endif - case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER: -#if gcdVIRTUAL_COMMAND_BUFFER - bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes; - gcmkONERROR( - gckKERNEL_AllocateVirtualCommandBuffer( - Kernel, - FromUser, - &bytes, - &physical, - &logical)); +#if gcdSECURE_USER + /* Return logical address as physical address. */ + Interface->u.LockVideoMemory.address = + (gctUINT32)(Interface->u.LockVideoMemory.memory); +#endif + gcmkONERROR( + gckKERNEL_AddProcessDB(Kernel, + ProcessID, gcvDB_VIDEO_MEMORY_LOCKED, + gcmINT2PTR(Interface->u.LockVideoMemory.node), + gcvNULL, + 0)); - Interface->u.AllocateVirtualCommandBuffer.bytes = bytes; - Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical); - Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical); + gckVIDMEM_HANDLE_Reference( + Kernel, ProcessID, (gctUINT32)Interface->u.LockVideoMemory.node); - gcmkVERIFY_OK( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_COMMAND_BUFFER, - logical, - gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical), - bytes)); -#else - status = gcvSTATUS_NOT_SUPPORTED; -#endif - break; + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - case gcvHAL_FREE_NON_PAGED_MEMORY: - physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical); +OnError: + if (locked) + { + /* Roll back the lock. */ + gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel, + nodeObject, + gcvSURF_TYPE_UNKNOWN, + &asynchronous)); - /* Unmap user logical out of physical memory first. */ - gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os, - physical, - (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes, - gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + if (gcvTRUE == asynchronous) + { + /* Bottom Half */ + gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel, + nodeObject, + gcvSURF_TYPE_UNKNOWN, + gcvNULL)); + } + } - /* Free non-paged memory. */ - gcmkONERROR( - gckOS_FreeNonPagedMemory(Kernel->os, - (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes, - physical, - gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + if (nodeObject != gcvNULL) + { + gckVIDMEM_NODE_Dereference(Kernel, nodeObject); + } - gcmkVERIFY_OK( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_NON_PAGED, - gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + gcmkFOOTER(); + return status; +} -#if gcdSECURE_USER - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( - Kernel, - cache, - gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical), - Interface->u.FreeNonPagedMemory.bytes)); -#endif +/******************************************************************************* +** +** gckKERNEL_UnlockVideoMemory +** +** Unlock a video memory node. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctUINT32 ProcessID +** ProcessID of current process. +** +** gcsHAL_INTERFACE * Interface +** Pointer to a gcsHAL_INTERFACE structure that defines the command to +** be dispatched. +** +** OUTPUT: +** +** gcsHAL_INTERFACE * Interface +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be +** returned. +*/ +gceSTATUS +gckKERNEL_UnlockVideoMemory( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN OUT gcsHAL_INTERFACE * Interface + ) +{ + gceSTATUS status; + gckVIDMEM_NODE nodeObject; + gcuVIDMEM_NODE_PTR node; - gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical); + gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d", + Kernel, ProcessID); - break; + gcmkONERROR(gckVIDMEM_HANDLE_Lookup( + Kernel, + ProcessID, + (gctUINT32)Interface->u.UnlockVideoMemory.node, + &nodeObject)); - case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY: - bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes; + node = nodeObject->node; - /* Allocate contiguous memory. */ - gcmkONERROR(gckOS_AllocateContiguous( - Kernel->os, - FromUser, - &bytes, - &physical, - &logical)); + /* Unlock video memory. */ +#if gcdSECURE_USER + /* Save node information before it disappears. */ + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + { + logical = gcvNULL; + bytes = 0; + } + else + { + logical = node->Virtual.logical; + bytes = node->Virtual.bytes; + } +#endif - Interface->u.AllocateContiguousMemory.bytes = bytes; - Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical); - Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical); - - gcmkONERROR(gckHARDWARE_ConvertLogical( - Kernel->hardware, - gcmUINT64_TO_PTR(Interface->u.AllocateContiguousMemory.logical), - &Interface->u.AllocateContiguousMemory.address)); - - gcmkVERIFY_OK(gckKERNEL_AddProcessDB( - Kernel, - processID, gcvDB_CONTIGUOUS, - logical, - gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical), - bytes)); - - break; - - case gcvHAL_FREE_CONTIGUOUS_MEMORY: - physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical); - - /* Unmap user logical out of physical memory first. */ - gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os, - physical, - (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes, - gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical))); - - /* Free contiguous memory. */ - gcmkONERROR( - gckOS_FreeContiguous(Kernel->os, - physical, - gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical), - (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes)); - - gcmkVERIFY_OK( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_CONTIGUOUS, - gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + /* Unlock video memory. */ + gcmkONERROR(gckVIDMEM_Unlock( + Kernel, + nodeObject, + Interface->u.UnlockVideoMemory.type, + &Interface->u.UnlockVideoMemory.asynchroneous)); #if gcdSECURE_USER - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( - Kernel, - cache, - gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical), - Interface->u.FreeContiguousMemory.bytes)); + /* Flush the translation cache for virtual surfaces. */ + if (logical != gcvNULL) + { + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel, + cache, + logical, + bytes)); + } #endif - gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical); - - break; + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - case gcvHAL_ALLOCATE_VIDEO_MEMORY: +OnError: + gcmkFOOTER(); + return status; +} - gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); +gceSTATUS +gckKERNEL_QueryDatabase( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN OUT gcsHAL_INTERFACE * Interface + ) +{ + gceSTATUS status; + gctINT i; + gcuDATABASE_INFO tmp; - break; + gceDATABASE_TYPE type[3] = { + gcvDB_VIDEO_MEMORY | (gcvPOOL_SYSTEM << gcdDB_VIDEO_MEMORY_POOL_SHIFT), + gcvDB_VIDEO_MEMORY | (gcvPOOL_CONTIGUOUS << gcdDB_VIDEO_MEMORY_POOL_SHIFT), + gcvDB_VIDEO_MEMORY | (gcvPOOL_VIRTUAL << gcdDB_VIDEO_MEMORY_POOL_SHIFT), + }; - case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY: - type = Interface->u.AllocateLinearVideoMemory.type; + gcmkHEADER(); - /* Allocate memory. */ - gcmkONERROR( - _AllocateMemory(Kernel, - &Interface->u.AllocateLinearVideoMemory.pool, - Interface->u.AllocateLinearVideoMemory.bytes, - Interface->u.AllocateLinearVideoMemory.alignment, - Interface->u.AllocateLinearVideoMemory.type, - &node)); + /* Query video memory. */ + gcmkONERROR( + gckKERNEL_QueryProcessDB(Kernel, + Interface->u.Database.processID, + !Interface->u.Database.validProcessID, + gcvDB_VIDEO_MEMORY, + &Interface->u.Database.vidMem)); - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - bytes = node->VidMem.bytes; - node->VidMem.type = type; + /* Query non-paged memory. */ + gcmkONERROR( + gckKERNEL_QueryProcessDB(Kernel, + Interface->u.Database.processID, + !Interface->u.Database.validProcessID, + gcvDB_NON_PAGED, + &Interface->u.Database.nonPaged)); - gcmkONERROR( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_RESERVED, - node, - gcvNULL, - bytes)); - } - else - { - bytes = node->Virtual.bytes; - node->Virtual.type = type; + /* Query contiguous memory. */ + gcmkONERROR( + gckKERNEL_QueryProcessDB(Kernel, + Interface->u.Database.processID, + !Interface->u.Database.validProcessID, + gcvDB_CONTIGUOUS, + &Interface->u.Database.contiguous)); - if(node->Virtual.contiguous) - { - gcmkONERROR( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS, - node, - gcvNULL, - bytes)); - } - else - { - gcmkONERROR( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_VIRTUAL, - node, - gcvNULL, - bytes)); - } + /* Query GPU idle time. */ + gcmkONERROR( + gckKERNEL_QueryProcessDB(Kernel, + Interface->u.Database.processID, + !Interface->u.Database.validProcessID, + gcvDB_IDLE, + &Interface->u.Database.gpuIdle)); + for (i = 0; i < 3; i++) + { + /* Query each video memory pool. */ + gcmkONERROR( + gckKERNEL_QueryProcessDB(Kernel, + Interface->u.Database.processID, + !Interface->u.Database.validProcessID, + type[i], + &Interface->u.Database.vidMemPool[i])); + } - } + /* Query virtual command buffer pool. */ + gcmkONERROR( + gckKERNEL_QueryProcessDB(Kernel, + Interface->u.Database.processID, + !Interface->u.Database.validProcessID, + gcvDB_COMMAND_BUFFER, + &tmp)); - gcmkONERROR( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY, - node, - gcvNULL, - bytes)); + Interface->u.Database.vidMemPool[2].counters.bytes += tmp.counters.bytes; + Interface->u.Database.vidMemPool[2].counters.maxBytes += tmp.counters.maxBytes; + Interface->u.Database.vidMemPool[2].counters.totalBytes += tmp.counters.totalBytes; - /* Get the node. */ - Interface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node); - break; + Interface->u.Database.vidMem.counters.bytes += tmp.counters.bytes; + Interface->u.Database.vidMem.counters.maxBytes += tmp.counters.maxBytes; + Interface->u.Database.vidMem.counters.totalBytes += tmp.counters.totalBytes; - case gcvHAL_FREE_VIDEO_MEMORY: - node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node); -#ifdef __QNXNTO__ - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM - && node->VidMem.logical != gcvNULL) - { - gcmkONERROR( - gckKERNEL_UnmapVideoMemory(Kernel, - node->VidMem.logical, - processID, - node->VidMem.bytes)); - node->VidMem.logical = gcvNULL; - } +#if gcmIS_DEBUG(gcdDEBUG_TRACE) + gckKERNEL_DumpVidMemUsage(Kernel, Interface->u.Database.processID); #endif - /* Free video memory. */ - gcmkONERROR( - gckVIDMEM_Free(node)); - gcmkONERROR( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY, - node)); + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - gcmkONERROR( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_RESERVED, - node)); - } - else if(node->Virtual.contiguous) - { - gcmkONERROR( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS, - node)); - } - else - { - gcmkONERROR( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_VIRTUAL, - node)); - } +OnError: + gcmkFOOTER(); + return status; +} - break; +gceSTATUS +gckKERNEL_ConfigPowerManagement( + IN gckKERNEL Kernel, + IN OUT gcsHAL_INTERFACE * Interface +) +{ + gceSTATUS status; + gctBOOL enable = Interface->u.ConfigPowerManagement.enable; - case gcvHAL_LOCK_VIDEO_MEMORY: - node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node); + gcmkHEADER(); - /* Lock video memory. */ - gcmkONERROR( - gckVIDMEM_Lock(Kernel, - node, - Interface->u.LockVideoMemory.cacheable, - &Interface->u.LockVideoMemory.address)); + gcmkONERROR(gckHARDWARE_SetPowerManagement(Kernel->hardware, enable)); - locked = gcvTRUE; + if (enable == gcvTRUE) + { + gcmkONERROR( + gckHARDWARE_SetPowerManagementState(Kernel->hardware, gcvPOWER_ON)); + } - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - /* Map video memory address into user space. */ -#ifdef __QNXNTO__ - if (node->VidMem.logical == gcvNULL) - { - gcmkONERROR( - gckKERNEL_MapVideoMemory(Kernel, - FromUser, - Interface->u.LockVideoMemory.address, - processID, - node->VidMem.bytes, - &node->VidMem.logical)); - } - gcmkASSERT(node->VidMem.logical != gcvNULL); + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical); -#else - gcmkONERROR( - gckKERNEL_MapVideoMemory(Kernel, - FromUser, - Interface->u.LockVideoMemory.address, - &logical)); +OnError: + gcmkFOOTER(); + return status; +} - Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical); +/******************************************************************************* +** +** gckKERNEL_Dispatch +** +** Dispatch a command received from the user HAL layer. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctBOOL FromUser +** whether the call is from the user space. +** +** gcsHAL_INTERFACE * Interface +** Pointer to a gcsHAL_INTERFACE structure that defines the command to +** be dispatched. +** +** OUTPUT: +** +** gcsHAL_INTERFACE * Interface +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be +** returned. +*/ +gceSTATUS +gckKERNEL_Dispatch( + IN gckKERNEL Kernel, + IN gctBOOL FromUser, + IN OUT gcsHAL_INTERFACE * Interface + ) +{ + gceSTATUS status = gcvSTATUS_OK; + gctPHYS_ADDR physical = gcvNULL; + gctSIZE_T bytes; + gctPOINTER logical = gcvNULL; + gctPOINTER info = gcvNULL; +#if (gcdENABLE_3D || gcdENABLE_2D) + gckCONTEXT context = gcvNULL; #endif - } - else - { - Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical); - - /* Success. */ - status = gcvSTATUS_OK; - } - + gckKERNEL kernel = Kernel; + gctUINT32 address; + gctUINT32 processID; #if gcdSECURE_USER - /* Return logical address as physical address. */ - Interface->u.LockVideoMemory.address = - Interface->u.LockVideoMemory.memory; + gcskSECURE_CACHE_PTR cache; + gctPOINTER logical; #endif - gcmkONERROR( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_LOCKED, - node, - gcvNULL, - 0)); + gctUINT32 paddr = gcvINVALID_ADDRESS; +#if !USE_NEW_LINUX_SIGNAL + gctSIGNAL signal; +#endif + gckVIRTUAL_COMMAND_BUFFER_PTR buffer; - break; + gckVIDMEM_NODE nodeObject; + gctBOOL powerMutexAcquired = gcvFALSE; - case gcvHAL_UNLOCK_VIDEO_MEMORY: - /* Unlock video memory. */ - node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node); + gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x", + Kernel, FromUser, Interface); -#if gcdSECURE_USER - /* Save node information before it disappears. */ - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - logical = gcvNULL; - bytes = 0; - } - else - { - logical = node->Virtual.logical; - bytes = node->Virtual.bytes; - } + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Interface != gcvNULL); + +#if gcmIS_DEBUG(gcdDEBUG_TRACE) + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, + "Dispatching command %d (%s)", + Interface->command, _DispatchText[Interface->command]); +#endif +#if QNX_SINGLE_THREADED_DEBUGGING + gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE); #endif - /* Unlock video memory. */ - gcmkONERROR( - gckVIDMEM_Unlock(Kernel, - node, - Interface->u.UnlockVideoMemory.type, - &Interface->u.UnlockVideoMemory.asynchroneous)); + /* Get the current process ID. */ + gcmkONERROR(gckOS_GetProcessID(&processID)); #if gcdSECURE_USER - /* Flush the translation cache for virtual surfaces. */ - if (logical != gcvNULL) - { - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel, - cache, - logical, - bytes)); - } + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache)); #endif - if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE) - { - /* There isn't a event to unlock this node, remove record now */ - gcmkONERROR( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_LOCKED, - node)); - } - break; - case gcvHAL_EVENT_COMMIT: - /* Commit an event queue. */ - gcmkONERROR( - gckEVENT_Commit(Kernel->eventObj, - gcmUINT64_TO_PTR(Interface->u.Event.queue))); - break; + /* Dispatch on command. */ + switch (Interface->command) + { + case gcvHAL_GET_BASE_ADDRESS: + /* Get base address. */ + gcmkONERROR( + gckOS_GetBaseAddress(Kernel->os, + &Interface->u.GetBaseAddress.baseAddress)); + break; + + case gcvHAL_QUERY_VIDEO_MEMORY: + /* Query video memory size. */ + gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface)); + break; + + case gcvHAL_QUERY_CHIP_IDENTITY: + /* Query chip identity. */ + gcmkONERROR( + gckHARDWARE_QueryChipIdentity( + Kernel->hardware, + &Interface->u.QueryChipIdentity)); + break; + + case gcvHAL_MAP_MEMORY: + physical = gcmINT2PTR(Interface->u.MapMemory.physical); + + /* Map memory. */ + gcmkONERROR( + gckKERNEL_MapMemory(Kernel, + physical, + (gctSIZE_T) Interface->u.MapMemory.bytes, + &logical)); + + Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_MAP_MEMORY, + logical, + physical, + (gctSIZE_T) Interface->u.MapMemory.bytes)); + break; + + case gcvHAL_UNMAP_MEMORY: + physical = gcmINT2PTR(Interface->u.UnmapMemory.physical); + + gcmkVERIFY_OK( + gckKERNEL_RemoveProcessDB(Kernel, + processID, gcvDB_MAP_MEMORY, + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical))); + + /* Unmap memory. */ + gcmkONERROR( + gckKERNEL_UnmapMemory(Kernel, + physical, + (gctSIZE_T) Interface->u.UnmapMemory.bytes, + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical))); + break; + + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY: + bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes; + + /* Allocate non-paged memory. */ + gcmkONERROR( + gckOS_AllocateNonPagedMemory( + Kernel->os, + FromUser, + &bytes, + &physical, + &logical)); + + Interface->u.AllocateNonPagedMemory.bytes = bytes; + Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical); + Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_NON_PAGED, + logical, + gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical), + bytes)); + break; + + case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER: + bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes; + + gcmkONERROR( + gckKERNEL_AllocateVirtualCommandBuffer( + Kernel, + FromUser, + &bytes, + &physical, + &logical)); + + Interface->u.AllocateVirtualCommandBuffer.bytes = bytes; + Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical); + Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_COMMAND_BUFFER, + logical, + gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical), + bytes)); + break; + + case gcvHAL_FREE_NON_PAGED_MEMORY: + physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical); + + gcmkVERIFY_OK( + gckKERNEL_RemoveProcessDB(Kernel, + processID, gcvDB_NON_PAGED, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + + /* Unmap user logical out of physical memory first. */ + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os, + physical, + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + + /* Free non-paged memory. */ + gcmkONERROR( + gckOS_FreeNonPagedMemory(Kernel->os, + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes, + physical, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + +#if gcdSECURE_USER + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( + Kernel, + cache, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical), + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes)); +#endif + + gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical); + break; + + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY: + bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes; + + /* Allocate contiguous memory. */ + gcmkONERROR(gckOS_AllocateContiguous( + Kernel->os, + FromUser, + &bytes, + &physical, + &logical)); + + Interface->u.AllocateContiguousMemory.bytes = bytes; + Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical); + Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical); + + gcmkONERROR(gckHARDWARE_ConvertLogical( + Kernel->hardware, + logical, + gcvTRUE, + &Interface->u.AllocateContiguousMemory.address)); + + gcmkVERIFY_OK(gckKERNEL_AddProcessDB( + Kernel, + processID, gcvDB_CONTIGUOUS, + logical, + gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical), + bytes)); + break; + + case gcvHAL_FREE_CONTIGUOUS_MEMORY: + physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical); + + gcmkVERIFY_OK( + gckKERNEL_RemoveProcessDB(Kernel, + processID, gcvDB_CONTIGUOUS, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); + + /* Unmap user logical out of physical memory first. */ + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os, + physical, + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes, + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical))); + + /* Free contiguous memory. */ + gcmkONERROR( + gckOS_FreeContiguous(Kernel->os, + physical, + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical), + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes)); + +#if gcdSECURE_USER + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( + Kernel, + cache, + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical), + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes)); +#endif + + gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical); + break; + + case gcvHAL_ALLOCATE_VIDEO_MEMORY: + + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + + break; + + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY: + /* Allocate memory. */ + gcmkONERROR( + gckKERNEL_AllocateLinearMemory(Kernel, processID, + &Interface->u.AllocateLinearVideoMemory.pool, + Interface->u.AllocateLinearVideoMemory.bytes, + Interface->u.AllocateLinearVideoMemory.alignment, + Interface->u.AllocateLinearVideoMemory.type, + Interface->u.AllocateLinearVideoMemory.flag, + &Interface->u.AllocateLinearVideoMemory.node)); + break; + + case gcvHAL_RELEASE_VIDEO_MEMORY: + /* Release video memory. */ + gcmkONERROR(gckKERNEL_ReleaseVideoMemory( + Kernel, processID, + (gctUINT32)Interface->u.ReleaseVideoMemory.node + )); + break; + + case gcvHAL_LOCK_VIDEO_MEMORY: + /* Lock video memory. */ + gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, Kernel->core, processID, FromUser, Interface)); + break; + + case gcvHAL_UNLOCK_VIDEO_MEMORY: + /* Unlock video memory. */ + gcmkONERROR(gckKERNEL_UnlockVideoMemory(Kernel, processID, Interface)); + break; + + case gcvHAL_EVENT_COMMIT: + /* Commit an event queue. */ +#if gcdMULTI_GPU + if (Interface->u.Event.gpuMode == gcvMULTI_GPU_MODE_INDEPENDENT) + { + gcmkONERROR( + gckEVENT_Commit(Kernel->eventObj, + gcmUINT64_TO_PTR(Interface->u.Event.queue), + Interface->u.Event.chipEnable)); + } + else + { + gcmkONERROR( + gckEVENT_Commit(Kernel->eventObj, + gcmUINT64_TO_PTR(Interface->u.Event.queue), + gcvCORE_3D_ALL_MASK)); + } +#else + gcmkONERROR( + gckEVENT_Commit(Kernel->eventObj, + gcmUINT64_TO_PTR(Interface->u.Event.queue))); +#endif + break; case gcvHAL_COMMIT: /* Commit a command and context buffer. */ +#if gcdMULTI_GPU + if (Interface->u.Commit.gpuMode == gcvMULTI_GPU_MODE_INDEPENDENT) + { + gcmkONERROR( + gckCOMMAND_Commit(Kernel->command, + Interface->u.Commit.context ? + gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL, + gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer), + gcmUINT64_TO_PTR(Interface->u.Commit.delta), + gcmUINT64_TO_PTR(Interface->u.Commit.queue), + processID, + Interface->u.Commit.chipEnable)); + } + else + { + gcmkONERROR( + gckCOMMAND_Commit(Kernel->command, + Interface->u.Commit.context ? + gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL, + gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer), + gcmUINT64_TO_PTR(Interface->u.Commit.delta), + gcmUINT64_TO_PTR(Interface->u.Commit.queue), + processID, + gcvCORE_3D_ALL_MASK)); + } +#else gcmkONERROR( gckCOMMAND_Commit(Kernel->command, Interface->u.Commit.context ? @@ -1405,11 +1836,17 @@ gckKERNEL_Dispatch( gcmUINT64_TO_PTR(Interface->u.Commit.delta), gcmUINT64_TO_PTR(Interface->u.Commit.queue), processID)); +#endif + break; case gcvHAL_STALL: /* Stall the command queue. */ +#if gcdMULTI_GPU + gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE, gcvCORE_3D_ALL_MASK)); +#else gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE)); +#endif break; case gcvHAL_MAP_USER_MEMORY: @@ -1437,6 +1874,10 @@ gckKERNEL_Dispatch( address = Interface->u.UnmapUserMemory.address; info = gcmNAME_TO_PTR(Interface->u.UnmapUserMemory.info); + gcmkVERIFY_OK( + gckKERNEL_RemoveProcessDB(Kernel, + processID, gcvDB_MAP_USER_MEMORY, + gcmINT2PTR(Interface->u.UnmapUserMemory.info))); /* Unmap user memory. */ gcmkONERROR( gckOS_UnmapUserMemory(Kernel->os, @@ -1451,15 +1892,10 @@ gckKERNEL_Dispatch( Kernel, cache, gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory), - Interface->u.UnmapUserMemory.size)); + (gctSIZE_T) Interface->u.UnmapUserMemory.size)); #endif - gcmkVERIFY_OK( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_MAP_USER_MEMORY, - gcmINT2PTR(Interface->u.UnmapUserMemory.info))); gcmRELEASE_NAME(Interface->u.UnmapUserMemory.info); - break; #if !USE_NEW_LINUX_SIGNAL @@ -1483,15 +1919,15 @@ gckKERNEL_Dispatch( break; case gcvUSER_SIGNAL_DESTROY: - /* Destroy the signal. */ - gcmkONERROR( - gckOS_DestroyUserSignal(Kernel->os, - Interface->u.UserSignal.id)); - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( Kernel, processID, gcvDB_SIGNAL, gcmINT2PTR(Interface->u.UserSignal.id))); + + /* Destroy the signal. */ + gcmkONERROR( + gckOS_DestroyUserSignal(Kernel->os, + Interface->u.UserSignal.id)); break; case gcvUSER_SIGNAL_SIGNAL: @@ -1503,69 +1939,10 @@ gckKERNEL_Dispatch( break; case gcvUSER_SIGNAL_WAIT: -#if gcdGPU_TIMEOUT - if (Interface->u.UserSignal.wait == gcvINFINITE) - { - gckHARDWARE hardware; - gctUINT32 timer = 0; - - for(;;) - { - /* Wait on the signal. */ - status = gckOS_WaitUserSignal(Kernel->os, - Interface->u.UserSignal.id, - gcdGPU_ADVANCETIMER); - - if (status == gcvSTATUS_TIMEOUT) - { - gcmkONERROR( - gckOS_SignalQueryHardware(Kernel->os, - (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id, - &hardware)); - - if (hardware) - { - /* This signal is bound to a hardware, - ** so the timeout is limited by Kernel->timeOut. - */ - timer += gcdGPU_ADVANCETIMER; - } - - if (timer >= Kernel->timeOut) - { - gcmkONERROR( - gckOS_Broadcast(Kernel->os, - hardware, - gcvBROADCAST_GPU_STUCK)); - - timer = 0; - - /* If a few process try to reset GPU, only one - ** of them can do the real reset, other processes - ** still need to wait for this signal is triggered, - ** which menas reset is finished. - */ - continue; - } - } - else - { - /* Bail out on other error. */ - gcmkONERROR(status); - - /* Wait for signal successfully. */ - break; - } - } - } - else -#endif - { - /* Wait on the signal. */ - status = gckOS_WaitUserSignal(Kernel->os, - Interface->u.UserSignal.id, - Interface->u.UserSignal.wait); - } + /* Wait on the signal. */ + status = gckOS_WaitUserSignal(Kernel->os, + Interface->u.UserSignal.id, + Interface->u.UserSignal.wait); break; @@ -1585,15 +1962,15 @@ gckKERNEL_Dispatch( break; case gcvUSER_SIGNAL_UNMAP: - /* Destroy the signal. */ - gcmkONERROR( - gckOS_DestroyUserSignal(Kernel->os, - Interface->u.UserSignal.id)); - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( Kernel, processID, gcvDB_SIGNAL, gcmINT2PTR(Interface->u.UserSignal.id))); + + /* Destroy the signal. */ + gcmkONERROR( + gckOS_DestroyUserSignal(Kernel->os, + Interface->u.UserSignal.id)); break; default: @@ -1631,7 +2008,8 @@ gckKERNEL_Dispatch( { gceCHIPPOWERSTATE power; - gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE); + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE)); + powerMutexAcquired = gcvTRUE; gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware, &power)); if (power == gcvPOWER_ON) @@ -1650,6 +2028,7 @@ gckKERNEL_Dispatch( status = gcvSTATUS_CHIP_NOT_READY; } gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex)); + powerMutexAcquired = gcvFALSE; } #else /* No access from user land to read registers. */ @@ -1658,6 +2037,106 @@ gckKERNEL_Dispatch( #endif break; +#if gcdMULTI_GPU + case gcvHAL_READ_REGISTER_EX: +#if gcdREGISTER_ACCESS_FROM_USER + { + gceCHIPPOWERSTATE power; + gctUINT32 coreId = 0; + gctUINT32 coreSelect = Interface->u.ReadRegisterDataEx.coreSelect; + + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE); + powerMutexAcquired = gcvTRUE; + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware, + &power)); + if (power == gcvPOWER_ON) + { + for (; coreSelect != 0; coreSelect >>= 1, coreId++) + { + if (coreSelect & 1UL) + { + /* Read a register. */ + gcmkONERROR( + gckOS_ReadRegisterByCoreId( + Kernel->os, + Kernel->core, + coreId, + Interface->u.ReadRegisterDataEx.address, + &Interface->u.ReadRegisterDataEx.data[coreId])); + } + } + } + else + { + for (coreId = 0; coreId < gcdMULTI_GPU; coreId++) + { + /* Chip is in power-state. */ + Interface->u.ReadRegisterDataEx.data[coreId] = 0; + } + status = gcvSTATUS_CHIP_NOT_READY; + } + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex)); + powerMutexAcquired = gcvFALSE; + } +#else + gctUINT32 coreId; + + /* No access from user land to read registers. */ + for (coreId = 0; coreId < gcdMULTI_GPU; coreId++) + { + Interface->u.ReadRegisterDataEx.data[coreId] = 0; + } + + status = gcvSTATUS_NOT_SUPPORTED; +#endif + break; + + case gcvHAL_WRITE_REGISTER_EX: +#if gcdREGISTER_ACCESS_FROM_USER + { + gceCHIPPOWERSTATE power; + gctUINT32 coreId = 0; + gctUINT32 coreSelect = Interface->u.WriteRegisterDataEx.coreSelect; + + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE)); + powerMutexAcquired = gcvTRUE; + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware, + &power)); + if (power == gcvPOWER_ON) + { + for (; coreSelect != 0; coreSelect >>= 1, coreId++) + { + if (coreSelect & 1UL) + { + /* Write a register. */ + gcmkONERROR( + gckOS_WriteRegisterByCoreId( + Kernel->os, + Kernel->core, + coreId, + Interface->u.WriteRegisterDataEx.address, + Interface->u.WriteRegisterDataEx.data[coreId])); + } + } + } + else + { + /* Chip is in power-state. */ + for (coreId = 0; coreId < gcdMULTI_GPU; coreId++) + { + Interface->u.WriteRegisterDataEx.data[coreId] = 0; + } + status = gcvSTATUS_CHIP_NOT_READY; + } + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex)); + powerMutexAcquired = gcvFALSE; + } +#else + status = gcvSTATUS_NOT_SUPPORTED; +#endif + break; +#endif + case gcvHAL_WRITE_REGISTER: #if gcdREGISTER_ACCESS_FROM_USER { @@ -1730,11 +2209,18 @@ gckKERNEL_Dispatch( status = gcvSTATUS_OK; break; + case gcvHAL_SET_PROFILE_SETTING: #if VIVANTE_PROFILER /* Set profile setting */ if(Kernel->hardware->gpuProfiler) + { Kernel->profileEnable = Interface->u.SetProfileSetting.enable; +#if VIVANTE_PROFILER_NEW + if (Kernel->profileEnable) + gckHARDWARE_InitProfiler(Kernel->hardware); +#endif + } else { status = gcvSTATUS_NOT_SUPPORTED; @@ -1763,7 +2249,8 @@ gckKERNEL_Dispatch( case gcvHAL_RESET: /* Reset the hardware. */ - gckKERNEL_Recovery(Kernel); + gcmkONERROR( + gckHARDWARE_Reset(Kernel->hardware)); break; case gcvHAL_DEBUG: @@ -1795,58 +2282,57 @@ gckKERNEL_Dispatch( break; case gcvHAL_DUMP_GPU_STATE: - /* Dump GPU state */ { gceCHIPPOWERSTATE power; - gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware, - &power)); + + _DumpDriverConfigure(Kernel); + + gcmkONERROR(gckHARDWARE_QueryPowerManagementState( + Kernel->hardware, + &power + )); + if (power == gcvPOWER_ON) { Interface->u.ReadRegisterData.data = 1; - gcmkVERIFY_OK( - gckHARDWARE_DumpGPUState(Kernel->hardware)); -#if gcdVIRTUAL_COMMAND_BUFFER - gcmkVERIFY_OK( - gckCOMMAND_DumpExecutingBuffer(Kernel->command)); -#endif + + _DumpState(Kernel); } else { Interface->u.ReadRegisterData.data = 0; status = gcvSTATUS_CHIP_NOT_READY; + + gcmkPRINT("[galcore]: Can't dump state if GPU isn't POWER ON."); } } break; case gcvHAL_DUMP_EVENT: - /* Dump GPU event */ - gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj)); - - /* Dump Process DB. */ - gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel)); break; case gcvHAL_CACHE: - node = gcmUINT64_TO_PTR(Interface->u.Cache.node); - if (node == gcvNULL) - { - /* FIXME Surface wrap some memory which is not allocated by us, - ** So we don't have physical address to handle outer cache, ignore it*/ - status = gcvSTATUS_OK; - break; - } - else if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - /* Video memory has no physical handles. */ - physical = gcvNULL; - } - else + + logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical); + + if (Interface->u.Cache.node) { - /* Grab physical handle. */ - physical = node->Virtual.physical; + gcmkONERROR(gckVIDMEM_HANDLE_Lookup( + Kernel, + processID, + Interface->u.Cache.node, + &nodeObject)); + + if (nodeObject->node->VidMem.memory->object.type == gcvOBJ_VIDMEM + || nodeObject->node->Virtual.contiguous + ) + { + /* If memory is contiguous, get physical address. */ + gcmkONERROR(gckOS_GetPhysicalAddress( + Kernel->os, logical, (gctUINT32*)&paddr)); + } } - logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical); bytes = (gctSIZE_T) Interface->u.Cache.bytes; switch(Interface->u.Cache.operation) { @@ -1878,10 +2364,10 @@ gckKERNEL_Dispatch( bytes); break; - case gcvCACHE_MEMORY_BARRIER: - status = gckOS_MemoryBarrier(Kernel->os, - logical); - break; + case gcvCACHE_MEMORY_BARRIER: + status = gckOS_MemoryBarrier(Kernel->os, + logical); + break; default: status = gcvSTATUS_INVALID_ARGUMENT; break; @@ -1912,7 +2398,7 @@ gckKERNEL_Dispatch( /* Check truncation overflow. */ Interface->u.TimeStamp.timeDelta = (gctINT32) timeDelta; - /*bit0~bit30 is available*/ + /*bit0~bit30 is available*/ if (timeDelta>>31) { Interface->u.TimeStamp.timeDelta = 0; @@ -1924,64 +2410,7 @@ gckKERNEL_Dispatch( break; case gcvHAL_DATABASE: - /* Query video memory. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.Database.processID, - !Interface->u.Database.validProcessID, - gcvDB_VIDEO_MEMORY, - &Interface->u.Database.vidMem)); - - /* Query non-paged memory. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.Database.processID, - !Interface->u.Database.validProcessID, - gcvDB_NON_PAGED, - &Interface->u.Database.nonPaged)); - - /* Query contiguous memory. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.Database.processID, - !Interface->u.Database.validProcessID, - gcvDB_CONTIGUOUS, - &Interface->u.Database.contiguous)); - - /* Query GPU idle time. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.Database.processID, - !Interface->u.Database.validProcessID, - gcvDB_IDLE, - &Interface->u.Database.gpuIdle)); - break; - - case gcvHAL_VIDMEM_DATABASE: - /* Query reserved video memory. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.VidMemDatabase.processID, - !Interface->u.VidMemDatabase.validProcessID, - gcvDB_VIDEO_MEMORY_RESERVED, - &Interface->u.VidMemDatabase.vidMemResv)); - - /* Query contiguous video memory. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.VidMemDatabase.processID, - !Interface->u.VidMemDatabase.validProcessID, - gcvDB_VIDEO_MEMORY_CONTIGUOUS, - &Interface->u.VidMemDatabase.vidMemCont)); - - /* Query virtual video memory. */ - gcmkONERROR( - gckKERNEL_QueryProcessDB(Kernel, - Interface->u.VidMemDatabase.processID, - !Interface->u.VidMemDatabase.validProcessID, - gcvDB_VIDEO_MEMORY_VIRTUAL, - &Interface->u.VidMemDatabase.vidMemVirt)); - + gcmkONERROR(gckKERNEL_QueryDatabase(Kernel, processID, Interface)); break; case gcvHAL_VERSION: @@ -2003,6 +2432,7 @@ gckKERNEL_Dispatch( Interface->u.ChipInfo.types[0] = Kernel->hardware->type; break; +#if (gcdENABLE_3D || gcdENABLE_2D) case gcvHAL_ATTACH: /* Attach user process. */ gcmkONERROR( @@ -2014,6 +2444,15 @@ gckKERNEL_Dispatch( Interface->u.Attach.stateCount = bytes; Interface->u.Attach.context = gcmPTR_TO_NAME(context); + if (Interface->u.Attach.map == gcvTRUE) + { + gcmkVERIFY_OK( + gckCONTEXT_MapBuffer(context, + Interface->u.Attach.physicals, + Interface->u.Attach.logicals, + &Interface->u.Attach.bytes)); + } + gcmkVERIFY_OK( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_CONTEXT, @@ -2021,18 +2460,19 @@ gckKERNEL_Dispatch( gcvNULL, 0)); break; +#endif case gcvHAL_DETACH: - /* Detach user process. */ - gcmkONERROR( - gckCOMMAND_Detach(Kernel->command, - gcmNAME_TO_PTR(Interface->u.Detach.context))); - gcmkVERIFY_OK( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_CONTEXT, gcmINT2PTR(Interface->u.Detach.context))); + /* Detach user process. */ + gcmkONERROR( + gckCOMMAND_Detach(Kernel->command, + gcmNAME_TO_PTR(Interface->u.Detach.context))); + gcmRELEASE_NAME(Interface->u.Detach.context); break; @@ -2049,142 +2489,10 @@ gckKERNEL_Dispatch( gckKERNEL_SetTimeOut(Kernel, Interface->u.SetTimeOut.timeOut); break; -#if gcdFRAME_DB case gcvHAL_GET_FRAME_INFO: gcmkONERROR(gckHARDWARE_GetFrameInfo( - Kernel->hardware, - gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo))); - break; -#endif - - case gcvHAL_GET_SHARED_INFO: - if (Interface->u.GetSharedInfo.data == gcvNULL) - { - gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); - } - else - { - gctUINT32 pid = Interface->u.GetSharedInfo.pid; - gctUINT32 dataId = Interface->u.GetSharedInfo.dataId; - gctSIZE_T bytes = Interface->u.GetSharedInfo.bytes; - gctPOINTER data = Interface->u.GetSharedInfo.data; - gcsDATABASE_RECORD record; - - /* Find record. */ - gcmkONERROR( - gckKERNEL_FindProcessDB(Kernel, - pid, - 0, - gcvDB_SHARED_INFO, - gcmINT2PTR(dataId), - &record)); - - /* Check memory size. */ - if (bytes < record.bytes) - { - /* Insufficient memory to hold shared data. */ - gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); - } - - /* Copy to user. */ - status = gckOS_CopyToUserData(Kernel->os, - record.physical, - data, - record.bytes); - - /* - * Remove from process db. - * Every time when shared info is taken, the record is erased in - * kernel side. - */ - gcmkVERIFY_OK( - gckKERNEL_RemoveProcessDB(Kernel, - pid, - gcvDB_SHARED_INFO, - gcmINT2PTR(dataId))); - /* Free existed data. */ - gcmkVERIFY_OK( - gckOS_FreeMemory(Kernel->os, record.physical)); - } - break; - - case gcvHAL_SET_SHARED_INFO: - { - gctUINT32 dataId = Interface->u.SetSharedInfo.dataId; - gctPOINTER data = Interface->u.SetSharedInfo.data; - gctUINT32 bytes = Interface->u.SetSharedInfo.bytes; - gctPOINTER memory = gcvNULL; - gcsDATABASE_RECORD record; - - if (gcmIS_SUCCESS(gckKERNEL_FindProcessDB(Kernel, - processID, - 0, - gcvDB_SHARED_INFO, - gcmINT2PTR(dataId), - &record))) - { - /* Find a record with the same id. */ - if (bytes != record.bytes) - { - /* Remove from process db. */ - gcmkVERIFY_OK( - gckKERNEL_RemoveProcessDB(Kernel, - processID, - gcvDB_SHARED_INFO, - gcmINT2PTR(dataId))); - - /* Free existed data. */ - gcmkVERIFY_OK( - gckOS_FreeMemory(Kernel->os, record.physical)); - } - else - { - /* Re-use allocated memory. */ - memory = record.physical; - } - } - - if ((data == gcvNULL) || (bytes == 0)) - { - /* Nothing to record. */ - break; - } - - if (bytes > 1024) - { - /* Limite data size. */ - gcmkONERROR(gcvSTATUS_TOO_COMPLEX); - } - - if (memory == gcvNULL) - { - /* Allocate memory for holding shared data. */ - gcmkONERROR( - gckOS_AllocateMemory(Kernel->os, bytes, &memory)); - - /* Add to process db. */ - status = gckKERNEL_AddProcessDB(Kernel, - processID, - gcvDB_SHARED_INFO, - gcmINT2PTR(dataId), - memory, - bytes); - - if (gcmIS_ERROR(status)) - { - /* Failed to add process db. Free allocated memory. */ - gcmkVERIFY_OK(gckOS_FreeMemory(Kernel->os, memory)); - break; - } - } - - /* Copy shared data to kernel memory. */ - gcmkONERROR( - gckOS_CopyFromUserData(Kernel->os, - memory, - data, - bytes)); - } + Kernel->hardware, + gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo))); break; case gcvHAL_SET_FSCALE_VALUE: @@ -2206,30 +2514,81 @@ gckKERNEL_Dispatch( #endif break; - case gcvHAL_QUERY_RESET_TIME_STAMP: -#if gcdENABLE_RECOVERY - Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp; -#else - Interface->u.QueryResetTimeStamp.timeStamp = 0; -#endif + case gcvHAL_NAME_VIDEO_MEMORY: + gcmkONERROR(gckVIDMEM_NODE_Name(Kernel, + Interface->u.NameVideoMemory.handle, + &Interface->u.NameVideoMemory.name)); break; -#if gcdANDROID_NATIVE_FENCE_SYNC - case gcvHAL_SYNC_POINT: - { - gctSYNC_POINT syncPoint; + case gcvHAL_IMPORT_VIDEO_MEMORY: + gcmkONERROR(gckVIDMEM_NODE_Import(Kernel, + Interface->u.ImportVideoMemory.name, + &Interface->u.ImportVideoMemory.handle)); - switch (Interface->u.SyncPoint.command) - { - case gcvSYNC_POINT_CREATE: - gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint)); + gcmkONERROR( + gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_VIDEO_MEMORY, + gcmINT2PTR(Interface->u.ImportVideoMemory.handle), + gcvNULL, + 0)); + break; - Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint); + case gcvHAL_GET_VIDEO_MEMORY_FD: + gcmkONERROR(gckVIDMEM_NODE_GetFd( + Kernel, + Interface->u.GetVideoMemoryFd.handle, + &Interface->u.GetVideoMemoryFd.fd + )); - gcmkVERIFY_OK( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_SYNC_POINT, - syncPoint, + /* No need to add it to processDB because OS will release all fds when + ** process quits. + */ + break; + + case gcvHAL_QUERY_RESET_TIME_STAMP: + Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp; + break; + + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER: + buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical); + + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( + Kernel, + processID, + gcvDB_COMMAND_BUFFER, + gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical))); + + gcmkONERROR(gckOS_DestroyUserVirtualMapping( + Kernel->os, + buffer->physical, + (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes, + gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical))); + + gcmkONERROR(gckKERNEL_DestroyVirtualCommandBuffer( + Kernel, + (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes, + (gctPHYS_ADDR)buffer, + gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical))); + + gcmRELEASE_NAME(Interface->u.FreeVirtualCommandBuffer.physical); + break; + +#if gcdANDROID_NATIVE_FENCE_SYNC + case gcvHAL_SYNC_POINT: + { + gctSYNC_POINT syncPoint; + + switch (Interface->u.SyncPoint.command) + { + case gcvSYNC_POINT_CREATE: + gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint)); + + Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint); + + gcmkVERIFY_OK( + gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_SYNC_POINT, + syncPoint, gcvNULL, 0)); break; @@ -2269,6 +2628,97 @@ 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; + + case gcvHAL_CONFIG_POWER_MANAGEMENT: + gcmkONERROR(gckKERNEL_ConfigPowerManagement(Kernel, Interface)); + break; + default: /* Invalid command. */ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); @@ -2278,33 +2728,15 @@ OnError: /* Save status. */ Interface->status = status; - if (gcmIS_ERROR(status)) - { - if (locked) - { - /* Roll back the lock. */ - gcmkVERIFY_OK( - gckVIDMEM_Unlock(Kernel, - gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node), - gcvSURF_TYPE_UNKNOWN, - &asynchronous)); - - if (gcvTRUE == asynchronous) - { - /* Bottom Half */ - gcmkVERIFY_OK( - gckVIDMEM_Unlock(Kernel, - gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node), - gcvSURF_TYPE_UNKNOWN, - gcvNULL)); - } - } - } - #if QNX_SINGLE_THREADED_DEBUGGING gckOS_ReleaseMutex(Kernel->os, Kernel->debugMutex); #endif + if (powerMutexAcquired == gcvTRUE) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex)); + } + /* Return the status. */ gcmkFOOTER(); return status; @@ -2417,6 +2849,11 @@ gckKERNEL_AttachProcessEx( /* Create the process database. */ gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID)); } + +#if gcdPROCESS_ADDRESS_SPACE + /* Map kernel command buffer in the process's own MMU. */ + gcmkONERROR(_MapCommandBuffer(Kernel)); +#endif } else { @@ -2433,7 +2870,11 @@ gckKERNEL_AttachProcessEx( if (Kernel->vg == gcvNULL) #endif { +#if gcdMULTI_GPU + status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE, gcvCORE_3D_ALL_MASK); +#else status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE); +#endif if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer) { @@ -2661,7 +3102,7 @@ gckKERNEL_MapLogicalToPhysical( #elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH { gctINT i; - gctUINT32 data = gcmPTR2INT(*Data); + gctUINT32 data = gcmPTR2INT32(*Data); gctUINT32 key, index; gcskLOGICAL_CACHE_PTR hash; @@ -2712,56 +3153,593 @@ gckKERNEL_MapLogicalToPhysical( *Data, key); } - /* Insert the slot at the head of the hash list. */ - slot->nextHash = hash->nextHash; - if (slot->nextHash != gcvNULL) + /* Insert the slot at the head of the hash list. */ + slot->nextHash = hash->nextHash; + if (slot->nextHash != gcvNULL) + { + slot->nextHash->prevHash = slot; + } + slot->prevHash = hash; + hash->nextHash = slot; + } + + /* Move slot to head of list. */ + if (slot != Cache->cache[0].next) + { + /* Unlink. */ + slot->prev->next = slot->next; + slot->next->prev = slot->prev; + + /* Move to head of chain. */ + slot->prev = &Cache->cache[0]; + slot->next = Cache->cache[0].next; + slot->prev->next = slot; + slot->next->prev = slot; + } + } +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE + { + gctUINT32 index = (gcmPTR2INT32(*Data) % gcdSECURE_CACHE_SLOTS) + 1; + + /* Get cache slot. */ + slot = &Cache->cache[index]; + + /* Check for cache miss. */ + if (slot->logical != *Data) + { + /* Initialize the cache line. */ + slot->logical = *Data; + + /* Map the logical address to a DMA address. */ + gcmkONERROR( + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma)); + } + } +#endif + + /* Return DMA address. */ + *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0)); + + /* Success. */ + gcmkFOOTER_ARG("*Data=0x%08x", *Data); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_FlushTranslationCache( + IN gckKERNEL Kernel, + IN gcskSECURE_CACHE_PTR Cache, + IN gctPOINTER Logical, + IN gctSIZE_T Bytes + ) +{ + gctINT i; + gcskLOGICAL_CACHE_PTR slot; + gctUINT8_PTR ptr; + + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu", + Kernel, Cache, Logical, Bytes); + + /* Do we need to flush the entire cache? */ + if (Logical == gcvNULL) + { + /* Clear all cache slots. */ + for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i) + { + Cache->cache[i].logical = gcvNULL; + +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH + Cache->cache[i].nextHash = gcvNULL; + Cache->cache[i].prevHash = gcvNULL; +#endif +} + +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH + /* Zero the hash table. */ + for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i) + { + Cache->hash[i].nextHash = gcvNULL; + } +#endif + + /* Reset the cache functionality. */ + Cache->cacheIndex = gcvNULL; + Cache->cacheFree = 1; + Cache->cacheStamp = 0; + } + + else + { + gctUINT8_PTR low = (gctUINT8_PTR) Logical; + gctUINT8_PTR high = low + Bytes; + +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU + gcskLOGICAL_CACHE_PTR next; + + /* Walk all used cache slots. */ + for (i = 1, slot = Cache->cache[0].next; + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL); + ++i, slot = next + ) + { + /* Save pointer to next slot. */ + next = slot->next; + + /* Test if this slot falls within the range to flush. */ + ptr = (gctUINT8_PTR) slot->logical; + if ((ptr >= low) && (ptr < high)) + { + /* Unlink slot. */ + slot->prev->next = slot->next; + slot->next->prev = slot->prev; + + /* Append slot to tail of cache. */ + slot->prev = Cache->cache[0].prev; + slot->next = &Cache->cache[0]; + slot->prev->next = slot; + slot->next->prev = slot; + + /* Mark slot as empty. */ + slot->logical = gcvNULL; + } + } + +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR + gcskLOGICAL_CACHE_PTR next; + + for (i = 1, slot = Cache->cache[0].next; + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL); + ++i, slot = next) + { + /* Save pointer to next slot. */ + next = slot->next; + + /* Test if this slot falls within the range to flush. */ + ptr = (gctUINT8_PTR) slot->logical; + if ((ptr >= low) && (ptr < high)) + { + /* Test if this slot is the current slot. */ + if (slot == Cache->cacheIndex) + { + /* Move to next or previous slot. */ + Cache->cacheIndex = (slot->next->logical != gcvNULL) + ? slot->next + : (slot->prev->logical != gcvNULL) + ? slot->prev + : gcvNULL; + } + + /* Unlink slot from cache. */ + slot->prev->next = slot->next; + slot->next->prev = slot->prev; + + /* Insert slot to head of cache. */ + slot->prev = &Cache->cache[0]; + slot->next = Cache->cache[0].next; + slot->prev->next = slot; + slot->next->prev = slot; + + /* Mark slot as empty. */ + slot->logical = gcvNULL; + slot->stamp = 0; + } + } + +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH + gctINT j; + gcskLOGICAL_CACHE_PTR hash, next; + + /* Walk all hash tables. */ + for (i = 0, hash = Cache->hash; + i < gcmCOUNTOF(Cache->hash); + ++i, ++hash) + { + /* Walk all slots in the hash. */ + for (j = 0, slot = hash->nextHash; + (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL); + ++j, slot = next) + { + /* Save pointer to next slot. */ + next = slot->next; + + /* Test if this slot falls within the range to flush. */ + ptr = (gctUINT8_PTR) slot->logical; + if ((ptr >= low) && (ptr < high)) + { + /* Unlink slot from hash table. */ + if (slot->prevHash == hash) + { + hash->nextHash = slot->nextHash; + } + else + { + slot->prevHash->nextHash = slot->nextHash; + } + + if (slot->nextHash != gcvNULL) + { + slot->nextHash->prevHash = slot->prevHash; + } + + /* Unlink slot from cache. */ + slot->prev->next = slot->next; + slot->next->prev = slot->prev; + + /* Append slot to tail of cache. */ + slot->prev = Cache->cache[0].prev; + slot->next = &Cache->cache[0]; + slot->prev->next = slot; + slot->next->prev = slot; + + /* Mark slot as empty. */ + slot->logical = gcvNULL; + slot->prevHash = gcvNULL; + slot->nextHash = gcvNULL; + } + } + } + +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE + gctUINT32 index; + + /* Loop while inside the range. */ + for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i) + { + /* Get index into cache for this range. */ + index = (gcmPTR2INT32(low) % gcdSECURE_CACHE_SLOTS) + 1; + slot = &Cache->cache[index]; + + /* Test if this slot falls within the range to flush. */ + ptr = (gctUINT8_PTR) slot->logical; + if ((ptr >= low) && (ptr < high)) + { + /* Remove entry from cache. */ + slot->logical = gcvNULL; + } + + /* Next block. */ + low += gcdSECURE_CACHE_SLOTS; + } +#endif + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} +#endif + +/******************************************************************************* +** +** gckKERNEL_Recovery +** +** Try to recover the GPU from a fatal error. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckKERNEL_Recovery( + IN gckKERNEL Kernel + ) +{ + gceSTATUS status; + gckEVENT eventObj; + gckHARDWARE hardware; +#if gcdSECURE_USER + gctUINT32 processID; + gcskSECURE_CACHE_PTR cache; +#endif + gctUINT32 mask = 0; + gckCOMMAND command; + gckENTRYDATA data; + gctUINT32 i = 0, count = 0; +#if gcdINTERRUPT_STATISTIC + gctINT32 oldValue; +#endif + + gcmkHEADER_ARG("Kernel=0x%x", Kernel); + + /* Validate the arguemnts. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + + /* Grab gckEVENT object. */ + eventObj = Kernel->eventObj; + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT); + + /* Grab gckHARDWARE object. */ + hardware = Kernel->hardware; + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE); + + /* Grab gckCOMMAND object. */ + command = Kernel->command; + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); + +#if gcdSECURE_USER + /* Flush the secure mapping cache. */ + gcmkONERROR(gckOS_GetProcessID(&processID)); + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache)); + gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0)); +#endif + + if (Kernel->stuckDump == gcdSTUCK_DUMP_MINIMAL) + { + gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core); + } + else + { + _DumpDriverConfigure(Kernel); + _DumpState(Kernel); + } + + if (Kernel->recovery == gcvFALSE) + { + gcmkPRINT("[galcore]: Stop driver to keep scene."); + + for (;;) + { + gckOS_Delay(Kernel->os, 10000); + } + } + + /* Clear queue. */ + do + { + status = gckENTRYQUEUE_Dequeue(&command->queue, &data); + } + while (status == gcvSTATUS_OK); + + /* Issuing a soft reset for the GPU. */ + gcmkONERROR(gckHARDWARE_Reset(hardware)); + + mask = Kernel->restoreMask; + + for (i = 0; i < 32; i++) + { + if (mask & (1 << i)) + { + count++; + } + } + + /* Handle all outstanding events now. */ +#if gcdSMP +#if gcdMULTI_GPU + if (Kernel->core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending3D[i], mask)); + } + } + else + { + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask)); + } +#else + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask)); +#endif +#else +#if gcdMULTI_GPU + if (Kernel->core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + eventObj->pending3D[i] = mask; + } + } + else + { + eventObj->pending = mask; + } +#else + eventObj->pending = mask; +#endif +#endif + +#if gcdINTERRUPT_STATISTIC + while (count--) + { + gcmkONERROR(gckOS_AtomDecrement( + Kernel->os, + eventObj->interruptCount, + &oldValue + )); + } + + gckOS_AtomClearMask(Kernel->hardware->pendingEvent, mask); +#endif + + gcmkONERROR(gckEVENT_Notify(eventObj, 1)); + + gcmkVERIFY_OK(gckOS_GetTime(&Kernel->resetTimeStamp)); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckKERNEL_OpenUserData +** +** Get access to the user data. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctBOOL NeedCopy +** The flag indicating whether or not the data should be copied. +** +** gctPOINTER StaticStorage +** Pointer to the kernel storage where the data is to be copied if +** NeedCopy is gcvTRUE. +** +** gctPOINTER UserPointer +** User pointer to the data. +** +** gctSIZE_T Size +** Size of the data. +** +** OUTPUT: +** +** gctPOINTER * KernelPointer +** Pointer to the kernel pointer that will be pointing to the data. +*/ +gceSTATUS +gckKERNEL_OpenUserData( + IN gckKERNEL Kernel, + IN gctBOOL NeedCopy, + IN gctPOINTER StaticStorage, + IN gctPOINTER UserPointer, + IN gctSIZE_T Size, + OUT gctPOINTER * KernelPointer + ) +{ + gceSTATUS status; + + gcmkHEADER_ARG( + "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X " + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X", + Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer + ); + + /* Validate the arguemnts. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL)); + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL); + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL); + gcmkVERIFY_ARGUMENT(Size > 0); + + if (NeedCopy) + { + /* Copy the user data to the static storage. */ + gcmkONERROR(gckOS_CopyFromUserData( + Kernel->os, StaticStorage, UserPointer, Size + )); + + /* Set the kernel pointer. */ + * KernelPointer = StaticStorage; + } + else + { + gctPOINTER pointer = gcvNULL; + + /* Map the user pointer. */ + gcmkONERROR(gckOS_MapUserPointer( + Kernel->os, UserPointer, Size, &pointer + )); + + /* Set the kernel pointer. */ + * KernelPointer = pointer; + } + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckKERNEL_CloseUserData +** +** Release resources associated with the user data connection opened by +** gckKERNEL_OpenUserData. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctBOOL NeedCopy +** The flag indicating whether or not the data should be copied. +** +** gctBOOL FlushData +** If gcvTRUE, the data is written back to the user. +** +** gctPOINTER UserPointer +** User pointer to the data. +** +** gctSIZE_T Size +** Size of the data. +** +** OUTPUT: +** +** gctPOINTER * KernelPointer +** Kernel pointer to the data. +*/ +gceSTATUS +gckKERNEL_CloseUserData( + IN gckKERNEL Kernel, + IN gctBOOL NeedCopy, + IN gctBOOL FlushData, + IN gctPOINTER UserPointer, + IN gctSIZE_T Size, + OUT gctPOINTER * KernelPointer + ) +{ + gceSTATUS status = gcvSTATUS_OK; + gctPOINTER pointer; + + gcmkHEADER_ARG( + "Kernel=0x%08X NeedCopy=%d FlushData=%d " + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X", + Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer + ); + + /* Validate the arguemnts. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL); + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL); + gcmkVERIFY_ARGUMENT(Size > 0); + + /* Get a shortcut to the kernel pointer. */ + pointer = * KernelPointer; + + if (pointer != gcvNULL) + { + if (NeedCopy) + { + if (FlushData) { - slot->nextHash->prevHash = slot; + gcmkONERROR(gckOS_CopyToUserData( + Kernel->os, * KernelPointer, UserPointer, Size + )); } - slot->prevHash = hash; - hash->nextHash = slot; } - - /* Move slot to head of list. */ - if (slot != Cache->cache[0].next) + else { - /* Unlink. */ - slot->prev->next = slot->next; - slot->next->prev = slot->prev; - - /* Move to head of chain. */ - slot->prev = &Cache->cache[0]; - slot->next = Cache->cache[0].next; - slot->prev->next = slot; - slot->next->prev = slot; + /* Unmap record from kernel memory. */ + gcmkONERROR(gckOS_UnmapUserPointer( + Kernel->os, + UserPointer, + Size, + * KernelPointer + )); } - } -#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE - { - gctUINT32 index = (gcmPTR2INT(*Data) % gcdSECURE_CACHE_SLOTS) + 1; - - /* Get cache slot. */ - slot = &Cache->cache[index]; - - /* Check for cache miss. */ - if (slot->logical != *Data) - { - /* Initialize the cache line. */ - slot->logical = *Data; - /* Map the logical address to a DMA address. */ - gcmkONERROR( - gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma)); - } + /* Reset the kernel pointer. */ + * KernelPointer = gcvNULL; } -#endif - - /* Return DMA address. */ - *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0)); - - /* Success. */ - gcmkFOOTER_ARG("*Data=0x%08x", *Data); - return gcvSTATUS_OK; OnError: /* Return the status. */ @@ -2769,1065 +3747,1063 @@ OnError: return status; } -gceSTATUS -gckKERNEL_FlushTranslationCache( +void +gckKERNEL_SetTimeOut( IN gckKERNEL Kernel, - IN gcskSECURE_CACHE_PTR Cache, - IN gctPOINTER Logical, - IN gctSIZE_T Bytes + IN gctUINT32 timeOut ) { - gctINT i; - gcskLOGICAL_CACHE_PTR slot; - gctUINT8_PTR ptr; - - gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu", - Kernel, Cache, Logical, Bytes); - - /* Do we need to flush the entire cache? */ - if (Logical == gcvNULL) - { - /* Clear all cache slots. */ - for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i) - { - Cache->cache[i].logical = gcvNULL; - -#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH - Cache->cache[i].nextHash = gcvNULL; - Cache->cache[i].prevHash = gcvNULL; + gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut); +#if gcdGPU_TIMEOUT + Kernel->timeOut = timeOut; #endif + gcmkFOOTER_NO(); } -#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH - /* Zero the hash table. */ - for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i) - { - Cache->hash[i].nextHash = gcvNULL; - } -#endif - - /* Reset the cache functionality. */ - Cache->cacheIndex = gcvNULL; - Cache->cacheFree = 1; - Cache->cacheStamp = 0; - } - - else - { - gctUINT8_PTR low = (gctUINT8_PTR) Logical; - gctUINT8_PTR high = low + Bytes; +gceSTATUS +gckKERNEL_AllocateVirtualCommandBuffer( + IN gckKERNEL Kernel, + IN gctBOOL InUserSpace, + IN OUT gctSIZE_T * Bytes, + OUT gctPHYS_ADDR * Physical, + OUT gctPOINTER * Logical + ) +{ + gckOS os = Kernel->os; + gceSTATUS status; + gctPOINTER logical = gcvNULL; + gctSIZE_T pageCount; + gctSIZE_T bytes = *Bytes; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer = gcvNULL; + gckMMU mmu; + gctUINT32 flag = gcvALLOC_FLAG_NON_CONTIGUOUS; -#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU - gcskLOGICAL_CACHE_PTR next; + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu", + os, InUserSpace, gcmOPT_VALUE(Bytes)); - /* Walk all used cache slots. */ - for (i = 1, slot = Cache->cache[0].next; - (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL); - ++i, slot = next - ) - { - /* Save pointer to next slot. */ - next = slot->next; + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL); + gcmkVERIFY_ARGUMENT(*Bytes > 0); + gcmkVERIFY_ARGUMENT(Physical != gcvNULL); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); - /* Test if this slot falls within the range to flush. */ - ptr = (gctUINT8_PTR) slot->logical; - if ((ptr >= low) && (ptr < high)) - { - /* Unlink slot. */ - slot->prev->next = slot->next; - slot->next->prev = slot->prev; + gcmkONERROR(gckOS_Allocate(os, + sizeof(gckVIRTUAL_COMMAND_BUFFER), + (gctPOINTER)&buffer)); - /* Append slot to tail of cache. */ - slot->prev = Cache->cache[0].prev; - slot->next = &Cache->cache[0]; - slot->prev->next = slot; - slot->next->prev = slot; + gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER))); - /* Mark slot as empty. */ - slot->logical = gcvNULL; - } - } + buffer->bytes = bytes; -#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR - gcskLOGICAL_CACHE_PTR next; + gcmkONERROR(gckOS_AllocatePagedMemoryEx(os, + flag, + bytes, + gcvNULL, + &buffer->physical)); - for (i = 1, slot = Cache->cache[0].next; - (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL); - ++i, slot = next) - { - /* Save pointer to next slot. */ - next = slot->next; + if (InUserSpace) + { + gcmkONERROR(gckOS_CreateUserVirtualMapping(os, + buffer->physical, + bytes, + &logical, + &pageCount)); - /* Test if this slot falls within the range to flush. */ - ptr = (gctUINT8_PTR) slot->logical; - if ((ptr >= low) && (ptr < high)) - { - /* Test if this slot is the current slot. */ - if (slot == Cache->cacheIndex) - { - /* Move to next or previous slot. */ - Cache->cacheIndex = (slot->next->logical != gcvNULL) - ? slot->next - : (slot->prev->logical != gcvNULL) - ? slot->prev - : gcvNULL; - } + *Logical = + buffer->userLogical = logical; + } + else + { + gcmkONERROR(gckOS_CreateKernelVirtualMapping(os, + buffer->physical, + bytes, + &logical, + &pageCount)); - /* Unlink slot from cache. */ - slot->prev->next = slot->next; - slot->next->prev = slot->prev; + *Logical = + buffer->kernelLogical = logical; + } - /* Insert slot to head of cache. */ - slot->prev = &Cache->cache[0]; - slot->next = Cache->cache[0].next; - slot->prev->next = slot; - slot->next->prev = slot; + buffer->pageCount = pageCount; + buffer->kernel = Kernel; - /* Mark slot as empty. */ - slot->logical = gcvNULL; - slot->stamp = 0; - } - } + gcmkONERROR(gckOS_GetProcessID(&buffer->pid)); -#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH - gctINT j; - gcskLOGICAL_CACHE_PTR hash, next; +#if gcdPROCESS_ADDRESS_SPACE + gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu)); + buffer->mmu = mmu; +#else + mmu = Kernel->mmu; +#endif - /* Walk all hash tables. */ - for (i = 0, hash = Cache->hash; - i < gcmCOUNTOF(Cache->hash); - ++i, ++hash) - { - /* Walk all slots in the hash. */ - for (j = 0, slot = hash->nextHash; - (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL); - ++j, slot = next) - { - /* Save pointer to next slot. */ - next = slot->next; + gcmkONERROR(gckMMU_AllocatePages(mmu, + pageCount, + &buffer->pageTable, + &buffer->gpuAddress)); - /* Test if this slot falls within the range to flush. */ - ptr = (gctUINT8_PTR) slot->logical; - if ((ptr >= low) && (ptr < high)) - { - /* Unlink slot from hash table. */ - if (slot->prevHash == hash) - { - hash->nextHash = slot->nextHash; - } - else - { - slot->prevHash->nextHash = slot->nextHash; - } - if (slot->nextHash != gcvNULL) - { - slot->nextHash->prevHash = slot->prevHash; - } + gcmkONERROR(gckOS_MapPagesEx(os, + Kernel->core, + buffer->physical, + pageCount, + buffer->gpuAddress, + buffer->pageTable)); - /* Unlink slot from cache. */ - slot->prev->next = slot->next; - slot->next->prev = slot->prev; + gcmkONERROR(gckMMU_Flush(mmu, gcvSURF_INDEX)); - /* Append slot to tail of cache. */ - slot->prev = Cache->cache[0].prev; - slot->next = &Cache->cache[0]; - slot->prev->next = slot; - slot->next->prev = slot; + *Physical = buffer; - /* Mark slot as empty. */ - slot->logical = gcvNULL; - slot->prevHash = gcvNULL; - slot->nextHash = gcvNULL; - } - } - } + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, + "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x", + buffer->gpuAddress, buffer->pageCount, + buffer->kernelLogical, buffer->userLogical); -#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE - gctUINT32 index; + gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE)); - /* Loop while inside the range. */ - for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i) - { - /* Get index into cache for this range. */ - index = (gcmPTR2INT(low) % gcdSECURE_CACHE_SLOTS) + 1; - slot = &Cache->cache[index]; + if (Kernel->virtualBufferHead == gcvNULL) + { + Kernel->virtualBufferHead = + Kernel->virtualBufferTail = buffer; + } + else + { + buffer->prev = Kernel->virtualBufferTail; + Kernel->virtualBufferTail->next = buffer; + Kernel->virtualBufferTail = buffer; + } - /* Test if this slot falls within the range to flush. */ - ptr = (gctUINT8_PTR) slot->logical; - if ((ptr >= low) && (ptr < high)) - { - /* Remove entry from cache. */ - slot->logical = gcvNULL; - } + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock)); - /* Next block. */ - low += gcdSECURE_CACHE_SLOTS; - } + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (buffer->gpuAddress) + { +#if gcdPROCESS_ADDRESS_SPACE + gcmkVERIFY_OK( + gckMMU_FreePages(mmu, buffer->pageTable, buffer->pageCount)); +#else + gcmkVERIFY_OK( + gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount)); #endif } - /* Success. */ - gcmkFOOTER_NO(); - return gcvSTATUS_OK; + if (buffer->userLogical) + { + gcmkVERIFY_OK( + gckOS_DestroyUserVirtualMapping(os, + buffer->physical, + bytes, + buffer->userLogical)); + } + + if (buffer->kernelLogical) + { + gcmkVERIFY_OK( + gckOS_DestroyKernelVirtualMapping(os, + buffer->physical, + bytes, + buffer->kernelLogical)); + } + + if (buffer->physical) + { + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes)); + } + + gcmkVERIFY_OK(gckOS_Free(os, buffer)); + + /* Return the status. */ + gcmkFOOTER(); + return status; } -#endif -/******************************************************************************* -** -** gckKERNEL_Recovery -** -** Try to recover the GPU from a fatal error. -** -** INPUT: -** -** gckKERNEL Kernel -** Pointer to an gckKERNEL object. -** -** OUTPUT: -** -** Nothing. -*/ gceSTATUS -gckKERNEL_Recovery( - IN gckKERNEL Kernel +gckKERNEL_DestroyVirtualCommandBuffer( + IN gckKERNEL Kernel, + IN gctSIZE_T Bytes, + IN gctPHYS_ADDR Physical, + IN gctPOINTER Logical ) { -#if gcdENABLE_RECOVERY -#define gcdEVENT_MASK 0x3FFFFFFF - gceSTATUS status; - gckEVENT eventObj; - gckHARDWARE hardware; -#if gcdSECURE_USER - gctUINT32 processID; - gcskSECURE_CACHE_PTR cache; -#endif - gctUINT32 oldValue; - gcmkHEADER_ARG("Kernel=0x%x", Kernel); - - /* Validate the arguemnts. */ - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - - /* Grab gckEVENT object. */ - eventObj = Kernel->eventObj; - gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT); - - /* Grab gckHARDWARE object. */ - hardware = Kernel->hardware; - gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE); + gckOS os; + gckKERNEL kernel; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical; -#if gcdSECURE_USER - /* Flush the secure mapping cache. */ - gcmkONERROR(gckOS_GetProcessID(&processID)); - gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache)); - gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0)); -#endif + gcmkHEADER(); + gcmkVERIFY_ARGUMENT(buffer != gcvNULL); - gcmkONERROR( - gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue)); + kernel = buffer->kernel; + os = kernel->os; - if (oldValue) + if (!buffer->userLogical) { - /* Some one else will recovery GPU. */ - return gcvSTATUS_OK; + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(os, + buffer->physical, + Bytes, + Logical)); } - gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core); - - /* Start a timer to clear reset flag, before timer is expired, - ** other recovery request is ignored. */ +#if !gcdPROCESS_ADDRESS_SPACE gcmkVERIFY_OK( - gckOS_StartTimer(Kernel->os, - Kernel->resetFlagClearTimer, - gcdGPU_TIMEOUT - 500)); + gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount)); +#endif + gcmkVERIFY_OK(gckOS_UnmapPages(os, buffer->pageCount, buffer->gpuAddress)); - /* Try issuing a soft reset for the GPU. */ - status = gckHARDWARE_Reset(hardware); - if (status == gcvSTATUS_NOT_SUPPORTED) + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes)); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE)); + + if (buffer == kernel->virtualBufferHead) { - /* Switch to OFF power. The next submit should return the GPU to ON - ** state. */ - gcmkONERROR( - gckHARDWARE_SetPowerManagementState(hardware, - gcvPOWER_OFF_RECOVERY)); + if ((kernel->virtualBufferHead = buffer->next) == gcvNULL) + { + kernel->virtualBufferTail = gcvNULL; + } } else { - /* Bail out on reset error. */ - gcmkONERROR(status); - } + buffer->prev->next = buffer->next; - /* Handle all outstanding events now. */ -#if gcdSMP - gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK)); -#else - eventObj->pending = gcdEVENT_MASK; -#endif - gcmkONERROR(gckEVENT_Notify(eventObj, 1)); + if (buffer == kernel->virtualBufferTail) + { + kernel->virtualBufferTail = buffer->prev; + } + else + { + buffer->next->prev = buffer->prev; + } + } - /* Again in case more events got submitted. */ -#if gcdSMP - gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK)); -#else - eventObj->pending = gcdEVENT_MASK; -#endif - gcmkONERROR(gckEVENT_Notify(eventObj, 2)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock)); - Kernel->resetTimeStamp++; + gcmkVERIFY_OK(gckOS_Free(os, buffer)); - /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; - -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; -#else - return gcvSTATUS_OK; -#endif } -/******************************************************************************* -** -** gckKERNEL_OpenUserData -** -** Get access to the user data. -** -** INPUT: -** -** gckKERNEL Kernel -** Pointer to an gckKERNEL object. -** -** gctBOOL NeedCopy -** The flag indicating whether or not the data should be copied. -** -** gctPOINTER StaticStorage -** Pointer to the kernel storage where the data is to be copied if -** NeedCopy is gcvTRUE. -** -** gctPOINTER UserPointer -** User pointer to the data. -** -** gctSIZE_T Size -** Size of the data. -** -** OUTPUT: -** -** gctPOINTER * KernelPointer -** Pointer to the kernel pointer that will be pointing to the data. -*/ gceSTATUS -gckKERNEL_OpenUserData( +gckKERNEL_GetGPUAddress( + IN gckKERNEL Kernel, + IN gctPOINTER Logical, + IN gctBOOL InUserSpace, + OUT gctUINT32 * Address + ) +{ + gceSTATUS status; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer; + gctPOINTER start; + gctUINT32 pid; + + gcmkHEADER_ARG("Logical = %x InUserSpace=%d.", Logical, InUserSpace); + + gcmkVERIFY_OK(gckOS_GetProcessID(&pid)); + + status = gcvSTATUS_INVALID_ADDRESS; + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE)); + + /* Walk all command buffer. */ + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next) + { + if (InUserSpace) + { + start = buffer->userLogical; + } + else + { + start = buffer->kernelLogical; + } + + if (start == gcvNULL) + { + continue; + } + + if (Logical >= start + && (Logical < (gctPOINTER)((gctUINT8_PTR)start + buffer->pageCount * 4096)) + && pid == buffer->pid + ) + { + * Address = buffer->gpuAddress + (gctUINT32)((gctUINT8_PTR)Logical - (gctUINT8_PTR)start); + status = gcvSTATUS_OK; + break; + } + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock)); + + gcmkFOOTER_NO(); + return status; +} + +gceSTATUS +gckKERNEL_QueryGPUAddress( IN gckKERNEL Kernel, - IN gctBOOL NeedCopy, - IN gctPOINTER StaticStorage, - IN gctPOINTER UserPointer, - IN gctSIZE_T Size, - OUT gctPOINTER * KernelPointer + IN gctUINT32 GpuAddress, + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer ) { - gceSTATUS status; - - gcmkHEADER_ARG( - "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X " - "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X", - Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer - ); + gckVIRTUAL_COMMAND_BUFFER_PTR buffer; + gctUINT32 start; + gceSTATUS status = gcvSTATUS_NOT_SUPPORTED; - /* Validate the arguemnts. */ - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL)); - gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL); - gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL); - gcmkVERIFY_ARGUMENT(Size > 0); + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE)); - if (NeedCopy) + /* Walk all command buffers. */ + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next) { - /* Copy the user data to the static storage. */ - gcmkONERROR(gckOS_CopyFromUserData( - Kernel->os, StaticStorage, UserPointer, Size - )); + start = (gctUINT32)buffer->gpuAddress; - /* Set the kernel pointer. */ - * KernelPointer = StaticStorage; + if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096)) + { + /* Find a range matched. */ + *Buffer = buffer; + status = gcvSTATUS_OK; + break; + } } - else - { - gctPOINTER pointer = gcvNULL; - - /* Map the user pointer. */ - gcmkONERROR(gckOS_MapUserPointer( - Kernel->os, UserPointer, Size, &pointer - )); - /* Set the kernel pointer. */ - * KernelPointer = pointer; - } + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock)); -OnError: - /* Return the status. */ - gcmkFOOTER(); return status; } -/******************************************************************************* -** -** gckKERNEL_CloseUserData -** -** Release resources associated with the user data connection opened by -** gckKERNEL_OpenUserData. -** -** INPUT: -** -** gckKERNEL Kernel -** Pointer to an gckKERNEL object. -** -** gctBOOL NeedCopy -** The flag indicating whether or not the data should be copied. -** -** gctBOOL FlushData -** If gcvTRUE, the data is written back to the user. -** -** gctPOINTER UserPointer -** User pointer to the data. -** -** gctSIZE_T Size -** Size of the data. -** -** OUTPUT: -** -** gctPOINTER * KernelPointer -** Kernel pointer to the data. -*/ -gceSTATUS -gckKERNEL_CloseUserData( - IN gckKERNEL Kernel, - IN gctBOOL NeedCopy, - IN gctBOOL FlushData, - IN gctPOINTER UserPointer, - IN gctSIZE_T Size, - OUT gctPOINTER * KernelPointer +#if gcdLINK_QUEUE_SIZE +static void +gckLINKQUEUE_Dequeue( + IN gckLINKQUEUE LinkQueue ) { - gceSTATUS status = gcvSTATUS_OK; - gctPOINTER pointer; + gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE); - gcmkHEADER_ARG( - "Kernel=0x%08X NeedCopy=%d FlushData=%d " - "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X", - Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer - ); + LinkQueue->count--; + LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE; +} - /* Validate the arguemnts. */ - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL); - gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL); - gcmkVERIFY_ARGUMENT(Size > 0); +void +gckLINKQUEUE_Enqueue( + IN gckLINKQUEUE LinkQueue, + IN gctUINT32 start, + IN gctUINT32 end + ) +{ + if (LinkQueue->count == gcdLINK_QUEUE_SIZE) + { + gckLINKQUEUE_Dequeue(LinkQueue); + } - /* Get a shortcut to the kernel pointer. */ - pointer = * KernelPointer; + gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE); - if (pointer != gcvNULL) - { - if (NeedCopy) - { - if (FlushData) - { - gcmkONERROR(gckOS_CopyToUserData( - Kernel->os, * KernelPointer, UserPointer, Size - )); - } - } - else - { - /* Unmap record from kernel memory. */ - gcmkONERROR(gckOS_UnmapUserPointer( - Kernel->os, - UserPointer, - Size, - * KernelPointer - )); - } + LinkQueue->count++; - /* Reset the kernel pointer. */ - * KernelPointer = gcvNULL; - } + LinkQueue->data[LinkQueue->rear].start = start; + LinkQueue->data[LinkQueue->rear].end = end; -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; + gcmkVERIFY_OK( + gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid)); + + LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE; } void -gckKERNEL_SetTimeOut( - IN gckKERNEL Kernel, - IN gctUINT32 timeOut +gckLINKQUEUE_GetData( + IN gckLINKQUEUE LinkQueue, + IN gctUINT32 Index, + OUT gckLINKDATA * Data ) { - gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut); -#if gcdGPU_TIMEOUT - Kernel->timeOut = timeOut; -#endif - gcmkFOOTER_NO(); + gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE); + + *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE]; } +#endif -#if gcdVIRTUAL_COMMAND_BUFFER +/* +* gckENTRYQUEUE_Enqueue is called with Command->mutexQueue acquired. +*/ gceSTATUS -gckKERNEL_AllocateVirtualCommandBuffer( +gckENTRYQUEUE_Enqueue( IN gckKERNEL Kernel, - IN gctBOOL InUserSpace, - IN OUT gctSIZE_T * Bytes, - OUT gctPHYS_ADDR * Physical, - OUT gctPOINTER * Logical + IN gckENTRYQUEUE Queue, + IN gctUINT32 physical, + IN gctUINT32 bytes ) { - gckOS os = Kernel->os; - gceSTATUS status; - gctPOINTER logical; - gctSIZE_T pageCount; - gctSIZE_T bytes = *Bytes; - gckVIRTUAL_COMMAND_BUFFER_PTR buffer; - - gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu", - os, InUserSpace, gcmOPT_VALUE(Bytes)); + gctUINT32 next = (Queue->rear + 1) % gcdENTRY_QUEUE_SIZE; - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(os, gcvOBJ_OS); - gcmkVERIFY_ARGUMENT(Bytes != gcvNULL); - gcmkVERIFY_ARGUMENT(*Bytes > 0); - gcmkVERIFY_ARGUMENT(Physical != gcvNULL); - gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + if (next == Queue->front) + { + /* Queue is full. */ + return gcvSTATUS_INVALID_REQUEST; + } - gcmkONERROR(gckOS_Allocate(os, - sizeof(gckVIRTUAL_COMMAND_BUFFER), - (gctPOINTER)&buffer)); + /* Copy data. */ + Queue->data[Queue->rear].physical = physical; + Queue->data[Queue->rear].bytes = bytes; - gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER))); + gcmkVERIFY_OK(gckOS_MemoryBarrier(Kernel->os, &Queue->rear)); - gcmkONERROR(gckOS_AllocatePagedMemoryEx(os, - gcvFALSE, - bytes, - &buffer->physical)); + /* Update rear. */ + Queue->rear = next; - if (InUserSpace) - { - gcmkONERROR(gckOS_LockPages(os, - buffer->physical, - bytes, - gcvFALSE, - &logical, - &pageCount)); + return gcvSTATUS_OK; +} - *Logical = - buffer->userLogical = logical; - } - else +gceSTATUS +gckENTRYQUEUE_Dequeue( + IN gckENTRYQUEUE Queue, + OUT gckENTRYDATA * Data + ) +{ + if (Queue->front == Queue->rear) { - gcmkONERROR( - gckOS_CreateKernelVirtualMapping(buffer->physical, - &pageCount, - &logical)); - *Logical = - buffer->kernelLogical = logical; + /* Queue is empty. */ + return gcvSTATUS_INVALID_REQUEST; } - buffer->pageCount = pageCount; - buffer->kernel = Kernel; + /* Copy data. */ + *Data = &Queue->data[Queue->front]; + + /* Update front. */ + Queue->front = (Queue->front + 1) % gcdENTRY_QUEUE_SIZE; + + return gcvSTATUS_OK; +} + +/******************************************************************************\ +*************************** Pointer - ID translation *************************** +\******************************************************************************/ +#define gcdID_TABLE_LENGTH 1024 +typedef struct _gcsINTEGERDB * gckINTEGERDB; +typedef struct _gcsINTEGERDB +{ + gckOS os; + gctPOINTER* table; + gctPOINTER mutex; + gctUINT32 tableLen; + gctUINT32 currentID; + gctUINT32 unused; +} +gcsINTEGERDB; + +gceSTATUS +gckKERNEL_CreateIntegerDatabase( + IN gckKERNEL Kernel, + OUT gctPOINTER * Database + ) +{ + gceSTATUS status; + gckINTEGERDB database = gcvNULL; - gcmkONERROR(gckOS_GetProcessID(&buffer->pid)); + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database); - gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu, - pageCount, - &buffer->pageTable, - &buffer->gpuAddress)); + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Database != gcvNULL); - gcmkONERROR(gckOS_MapPagesEx(os, - Kernel->core, - buffer->physical, - pageCount, - buffer->pageTable)); + /* Allocate a database. */ + gcmkONERROR(gckOS_Allocate( + Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database)); - gcmkONERROR(gckMMU_Flush(Kernel->mmu)); + gcmkONERROR(gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB))); - *Physical = buffer; + /* Allocate a pointer table. */ + gcmkONERROR(gckOS_Allocate( + Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table)); - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, - "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x", - buffer->gpuAddress, buffer->pageCount, - buffer->kernelLogical, buffer->userLogical); + gcmkONERROR(gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH)); - gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE)); + /* Allocate a database mutex. */ + gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex)); - if (Kernel->virtualBufferHead == gcvNULL) - { - Kernel->virtualBufferHead = - Kernel->virtualBufferTail = buffer; - } - else - { - buffer->prev = Kernel->virtualBufferTail; - Kernel->virtualBufferTail->next = buffer; - Kernel->virtualBufferTail = buffer; - } + /* Initialize. */ + database->currentID = 0; + database->unused = gcdID_TABLE_LENGTH; + database->os = Kernel->os; + database->tableLen = gcdID_TABLE_LENGTH; - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock)); + *Database = database; - gcmkFOOTER_NO(); + gcmkFOOTER_ARG("*Database=0x%08X", *Database); return gcvSTATUS_OK; OnError: - if (buffer->gpuAddress) - { - gcmkVERIFY_OK( - gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount)); - } - - if (buffer->userLogical) - { - gcmkVERIFY_OK( - gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical)); - } - - if (buffer->kernelLogical) + /* Rollback. */ + if (database) { - gcmkVERIFY_OK( - gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical)); - } + if (database->table) + { + gcmkOS_SAFE_FREE(Kernel->os, database->table); + } - if (buffer->physical) - { - gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes)); + gcmkOS_SAFE_FREE(Kernel->os, database); } - gcmkVERIFY_OK(gckOS_Free(os, buffer)); - - /* Return the status. */ gcmkFOOTER(); return status; } gceSTATUS -gckKERNEL_DestroyVirtualCommandBuffer( +gckKERNEL_DestroyIntegerDatabase( IN gckKERNEL Kernel, - IN gctSIZE_T Bytes, - IN gctPHYS_ADDR Physical, - IN gctPOINTER Logical + IN gctPOINTER Database ) { - gckOS os; - gckKERNEL kernel; - gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical; + gckINTEGERDB database = Database; - gcmkHEADER(); - gcmkVERIFY_ARGUMENT(buffer != gcvNULL); + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database); - kernel = buffer->kernel; - os = kernel->os; + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Database != gcvNULL); - if (buffer->userLogical) - { - gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical)); - } - else + /* Destroy pointer table. */ + gcmkOS_SAFE_FREE(Kernel->os, database->table); + + /* Destroy database mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex)); + + /* Destroy database. */ + gcmkOS_SAFE_FREE(Kernel->os, database); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +gceSTATUS +gckKERNEL_AllocateIntegerId( + IN gctPOINTER Database, + IN gctPOINTER Pointer, + OUT gctUINT32 * Id + ) +{ + gceSTATUS status; + gckINTEGERDB database = Database; + gctUINT32 i, unused, currentID, tableLen; + gctPOINTER * table; + gckOS os = database->os; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer); + + gcmkVERIFY_ARGUMENT(Id != gcvNULL); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + acquired = gcvTRUE; + + if (database->unused < 1) { - gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical)); + /* Extend table. */ + gcmkONERROR( + gckOS_Allocate(os, + gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH), + (gctPOINTER *)&table)); + + gcmkONERROR(gckOS_ZeroMemory(table + database->tableLen, + gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH)); + + /* Copy data from old table. */ + gckOS_MemCopy(table, + database->table, + database->tableLen * gcmSIZEOF(gctPOINTER)); + + gcmkOS_SAFE_FREE(os, database->table); + + /* Update databse with new allocated table. */ + database->table = table; + database->currentID = database->tableLen; + database->tableLen += gcdID_TABLE_LENGTH; + database->unused += gcdID_TABLE_LENGTH; } - gcmkVERIFY_OK( - gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount)); + table = database->table; + currentID = database->currentID; + tableLen = database->tableLen; + unused = database->unused; - gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes)); + /* Connect id with pointer. */ + table[currentID] = Pointer; - gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE)); + *Id = currentID + 1; - if (buffer == kernel->virtualBufferHead) + /* Update the currentID. */ + if (--unused > 0) { - if ((kernel->virtualBufferHead = buffer->next) == gcvNULL) + for (i = 0; i < tableLen; i++) { - kernel->virtualBufferTail = gcvNULL; - } - } - else - { - buffer->prev->next = buffer->next; + if (++currentID >= tableLen) + { + /* Wrap to the begin. */ + currentID = 0; + } - if (buffer == kernel->virtualBufferTail) - { - kernel->virtualBufferTail = buffer->prev; - } - else - { - buffer->next->prev = buffer->prev; + if (table[currentID] == gcvNULL) + { + break; + } } } - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock)); + database->table = table; + database->currentID = currentID; + database->tableLen = tableLen; + database->unused = unused; - gcmkVERIFY_OK(gckOS_Free(os, buffer)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + acquired = gcvFALSE; - gcmkFOOTER_NO(); + gcmkFOOTER_ARG("*Id=%d", *Id); return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + } + + gcmkFOOTER(); + return status; } gceSTATUS -gckKERNEL_GetGPUAddress( - IN gckKERNEL Kernel, - IN gctPOINTER Logical, - OUT gctUINT32 * Address +gckKERNEL_FreeIntegerId( + IN gctPOINTER Database, + IN gctUINT32 Id ) { gceSTATUS status; - gckVIRTUAL_COMMAND_BUFFER_PTR buffer; - gctPOINTER start; - gctINT pid; + gckINTEGERDB database = Database; + gckOS os = database->os; + gctBOOL acquired = gcvFALSE; - gcmkHEADER_ARG("Logical = %x", Logical); + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id); - gckOS_GetProcessID(&pid); + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + acquired = gcvTRUE; - status = gcvSTATUS_INVALID_ADDRESS; + if (!(Id > 0 && Id <= database->tableLen)) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } - gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE)); + Id -= 1; - /* Walk all command buffer. */ - for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next) + database->table[Id] = gcvNULL; + + if (database->unused++ == 0) { - if (buffer->userLogical) - { - start = buffer->userLogical; - } - else - { - start = buffer->kernelLogical; - } + database->currentID = Id; + } - if (Logical >= start - && (Logical < (start + buffer->pageCount * 4096)) - && pid == buffer->pid - ) - { - * Address = buffer->gpuAddress + (Logical - start); - status = gcvSTATUS_OK; - break; - } + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); } - gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock)); - - gcmkFOOTER_NO(); + gcmkFOOTER(); return status; } gceSTATUS -gckKERNEL_QueryGPUAddress( - IN gckKERNEL Kernel, - IN gctUINT32 GpuAddress, - OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer +gckKERNEL_QueryIntegerId( + IN gctPOINTER Database, + IN gctUINT32 Id, + OUT gctPOINTER * Pointer ) { - gckVIRTUAL_COMMAND_BUFFER_PTR buffer; - gctUINT32 start; - gceSTATUS status = gcvSTATUS_NOT_SUPPORTED; + gceSTATUS status; + gckINTEGERDB database = Database; + gctPOINTER pointer; + gckOS os = database->os; + gctBOOL acquired = gcvFALSE; - gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE)); + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id); + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL); - /* Walk all command buffers. */ - for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next) + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + acquired = gcvTRUE; + + if (!(Id > 0 && Id <= database->tableLen)) { - start = (gctUINT32)buffer->gpuAddress; + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } - if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096)) - { - /* Find a range matched. */ - *Buffer = buffer; - status = gcvSTATUS_OK; - break; - } + Id -= 1; + + pointer = database->table[Id]; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + acquired = gcvFALSE; + + if (pointer) + { + *Pointer = pointer; + } + else + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); } - gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock)); + gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + } + gcmkFOOTER(); return status; } -#endif -#if gcdLINK_QUEUE_SIZE -static void -gckLINKQUEUE_Dequeue( - IN gckLINKQUEUE LinkQueue + +gctUINT32 +gckKERNEL_AllocateNameFromPointer( + IN gckKERNEL Kernel, + IN gctPOINTER Pointer ) { - gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE); + gceSTATUS status; + gctUINT32 name; + gctPOINTER database = Kernel->db->pointerDatabase; - LinkQueue->count--; - LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE; + gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer); + + gcmkONERROR( + gckKERNEL_AllocateIntegerId(database, Pointer, &name)); + + gcmkFOOTER_ARG("name=%d", name); + return name; + +OnError: + gcmkFOOTER(); + return 0; } -void -gckLINKQUEUE_Enqueue( - IN gckLINKQUEUE LinkQueue, - IN gctUINT32 start, - IN gctUINT32 end +gctPOINTER +gckKERNEL_QueryPointerFromName( + IN gckKERNEL Kernel, + IN gctUINT32 Name ) { - if (LinkQueue->count == gcdLINK_QUEUE_SIZE) - { - gckLINKQUEUE_Dequeue(LinkQueue); - } - - gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE); + gceSTATUS status; + gctPOINTER pointer = gcvNULL; + gctPOINTER database = Kernel->db->pointerDatabase; - LinkQueue->count++; + gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name); - LinkQueue->data[LinkQueue->rear].start = start; - LinkQueue->data[LinkQueue->rear].end = end; + /* Lookup in database to get pointer. */ + gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer)); - gcmkVERIFY_OK( - gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid)); + gcmkFOOTER_ARG("pointer=0x%X", pointer); + return pointer; - LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE; +OnError: + gcmkFOOTER(); + return gcvNULL; } -void -gckLINKQUEUE_GetData( - IN gckLINKQUEUE LinkQueue, - IN gctUINT32 Index, - OUT gckLINKDATA * Data +gceSTATUS +gckKERNEL_DeleteName( + IN gckKERNEL Kernel, + IN gctUINT32 Name ) { - gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE); + gctPOINTER database = Kernel->db->pointerDatabase; - *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE]; + gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name); + + /* Free name if exists. */ + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name)); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; } -#endif -/******************************************************************************\ -*************************** Pointer - ID translation *************************** -\******************************************************************************/ -#define gcdID_TABLE_LENGTH 1024 -typedef struct _gcsINTEGERDB * gckINTEGERDB; -typedef struct _gcsINTEGERDB +gceSTATUS +gckKERNEL_SetRecovery( + IN gckKERNEL Kernel, + IN gctBOOL Recovery, + IN gctUINT32 StuckDump + ) { - gckOS os; - gctPOINTER* table; - gctPOINTER mutex; - gctUINT32 tableLen; - gctUINT32 currentID; - gctUINT32 unused; + Kernel->recovery = Recovery; + + if (Recovery == gcvFALSE) + { + /* Dump stuck information if Recovery is disabled. */ + Kernel->stuckDump = gcmMAX(StuckDump, gcdSTUCK_DUMP_MIDDLE); + } + + return gcvSTATUS_OK; } -gcsINTEGERDB; + +/******************************************************************************* +***** 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_CreateIntegerDatabase( +gckKERNEL_CreateShBuffer( IN gckKERNEL Kernel, - OUT gctPOINTER * Database + IN gctUINT32 Size, + OUT gctSHBUF * ShBuf ) { gceSTATUS status; - gckINTEGERDB database = gcvNULL; + gcsSHBUF_PTR shBuf = gcvNULL; - gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database); + gcmkHEADER_ARG("Kernel=0x%X, Size=%u", Kernel, Size); + /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - gcmkVERIFY_ARGUMENT(Database != gcvNULL); - /* Allocate a database. */ - gcmkONERROR(gckOS_Allocate( - Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database)); + if (Size == 0) + { + /* Invalid size. */ + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + else if (Size > 1024) + { + /* Limite shared buffer size. */ + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } - gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB)); + /* Create a shared buffer structure. */ + gcmkONERROR( + gckOS_Allocate(Kernel->os, + sizeof (gcsSHBUF), + (gctPOINTER *)&shBuf)); - /* Allocate a pointer table. */ - gcmkONERROR(gckOS_Allocate( - Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table)); + /* Initialize shared buffer. */ + shBuf->id = 0; + shBuf->reference = gcvNULL; + shBuf->size = Size; + shBuf->data = gcvNULL; - gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH); + /* Allocate integer id for this shared buffer. */ + gcmkONERROR( + gckKERNEL_AllocateIntegerId(Kernel->db->pointerDatabase, + shBuf, + &shBuf->id)); - /* Allocate a database mutex. */ - gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex)); + /* Allocate atom. */ + gcmkONERROR(gckOS_AtomConstruct(Kernel->os, &shBuf->reference)); - /* Initialize. */ - database->currentID = 0; - database->unused = gcdID_TABLE_LENGTH; - database->os = Kernel->os; - database->tableLen = gcdID_TABLE_LENGTH; + /* Set default reference count to 1. */ + gcmkVERIFY_OK(gckOS_AtomSet(Kernel->os, shBuf->reference, 1)); - *Database = database; + /* Return integer id. */ + *ShBuf = (gctSHBUF)(gctUINTPTR_T)shBuf->id; - gcmkFOOTER_ARG("*Database=0x%08X", *Database); + gcmkFOOTER_ARG("*ShBuf=%u", shBuf->id); return gcvSTATUS_OK; OnError: - /* Rollback. */ - if (database) + /* Error roll back. */ + if (shBuf != gcvNULL) { - if (database->table) + if (shBuf->id != 0) { - gcmkOS_SAFE_FREE(Kernel->os, database->table); + gcmkVERIFY_OK( + gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase, + shBuf->id)); } - gcmkOS_SAFE_FREE(Kernel->os, database); + 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_DestroyIntegerDatabase( - IN gckKERNEL Kernel, - IN gctPOINTER Database - ) -{ - gckINTEGERDB database = Database; - - gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database); - - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - gcmkVERIFY_ARGUMENT(Database != gcvNULL); - - /* Destroy pointer table. */ - gcmkOS_SAFE_FREE(Kernel->os, database->table); - - /* Destroy database mutex. */ - gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex)); - - /* Destroy database. */ - gcmkOS_SAFE_FREE(Kernel->os, database); - - gcmkFOOTER_NO(); - return gcvSTATUS_OK; -} - -gceSTATUS -gckKERNEL_AllocateIntegerId( - IN gctPOINTER Database, - IN gctPOINTER Pointer, - OUT gctUINT32 * Id +gckKERNEL_DestroyShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf ) { gceSTATUS status; - gckINTEGERDB database = Database; - gctUINT32 i, unused, currentID, tableLen; - gctPOINTER * table; - gckOS os = database->os; + gcsSHBUF_PTR shBuf; + gctINT32 oldValue = 0; gctBOOL acquired = gcvFALSE; - gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer); + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf); - gcmkVERIFY_ARGUMENT(Id != gcvNULL); + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); - gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); acquired = gcvTRUE; - if (database->unused < 1) - { - /* Extend table. */ - gcmkONERROR( - gckOS_Allocate(os, - gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH), - (gctPOINTER *)&table)); - - gckOS_ZeroMemory(table + database->tableLen, - gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH); - - /* Copy data from old table. */ - gckOS_MemCopy(table, - database->table, - database->tableLen * gcmSIZEOF(gctPOINTER)); - - gcmkOS_SAFE_FREE(os, database->table); + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); - /* Update databse with new allocated table. */ - database->table = table; - database->currentID = database->tableLen; - database->tableLen += gcdID_TABLE_LENGTH; - database->unused += gcdID_TABLE_LENGTH; - } + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); - table = database->table; - currentID = database->currentID; - tableLen = database->tableLen; - unused = database->unused; + /* Decrease the reference count. */ + gckOS_AtomDecrement(Kernel->os, shBuf->reference, &oldValue); - /* Connect id with pointer. */ - table[currentID] = Pointer; + if (oldValue == 1) + { + /* Free integer id. */ + gcmkVERIFY_OK( + gckKERNEL_FreeIntegerId(Kernel->db->pointerDatabase, + shBuf->id)); - *Id = currentID + 1; + /* Free atom. */ + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, shBuf->reference)); - /* Update the currentID. */ - if (--unused > 0) - { - for (i = 0; i < tableLen; i++) + if (shBuf->data) { - if (++currentID >= tableLen) - { - /* Wrap to the begin. */ - currentID = 0; - } - - if (table[currentID] == gcvNULL) - { - break; - } + gcmkOS_SAFE_FREE(Kernel->os, shBuf->data); + shBuf->data = gcvNULL; } - } - database->table = table; - database->currentID = currentID; - database->tableLen = tableLen; - database->unused = unused; + /* Free the shared buffer. */ + gcmkOS_SAFE_FREE(Kernel->os, shBuf); + } - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); acquired = gcvFALSE; - gcmkFOOTER_ARG("*Id=%d", *Id); + gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: if (acquired) { - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + /* 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_FreeIntegerId( - IN gctPOINTER Database, - IN gctUINT32 Id +gckKERNEL_MapShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf ) { gceSTATUS status; - gckINTEGERDB database = Database; - gckOS os = database->os; + gcsSHBUF_PTR shBuf; + gctINT32 oldValue = 0; gctBOOL acquired = gcvFALSE; - gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id); + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf); - gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); - acquired = gcvTRUE; + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); - if (!(Id > 0 && Id <= database->tableLen)) - { - gcmkONERROR(gcvSTATUS_NOT_FOUND); - } + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; - Id -= 1; + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); - database->table[Id] = gcvNULL; + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); - if (database->unused++ == 0) - { - database->currentID = Id; - } + /* Increase the reference count. */ + gckOS_AtomIncrement(Kernel->os, shBuf->reference, &oldValue); - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); acquired = gcvFALSE; gcmkFOOTER_NO(); @@ -3836,129 +4812,226 @@ gckKERNEL_FreeIntegerId( OnError: if (acquired) { - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + /* 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_QueryIntegerId( - IN gctPOINTER Database, - IN gctUINT32 Id, - OUT gctPOINTER * Pointer +gckKERNEL_WriteShBuffer( + IN gckKERNEL Kernel, + IN gctSHBUF ShBuf, + IN gctPOINTER UserData, + IN gctUINT32 ByteCount ) { gceSTATUS status; - gckINTEGERDB database = Database; - gctPOINTER pointer; - gckOS os = database->os; + gcsSHBUF_PTR shBuf; gctBOOL acquired = gcvFALSE; - gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id); - gcmkVERIFY_ARGUMENT(Pointer != gcvNULL); - - gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); - acquired = gcvTRUE; + gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u", + Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount); - if (!(Id > 0 && Id <= database->tableLen)) - { - gcmkONERROR(gcvSTATUS_NOT_FOUND); - } + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL); - Id -= 1; + /* Acquire mutex. */ + gcmkONERROR( + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; - pointer = database->table[Id]; + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); - acquired = gcvFALSE; + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); - if (pointer) + if ((ByteCount > shBuf->size) || + (ByteCount == 0) || + (UserData == gcvNULL)) { - *Pointer = pointer; + /* Exceeds buffer max size or invalid. */ + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } - else + + if (shBuf->data == gcvNULL) { - gcmkONERROR(gcvSTATUS_NOT_FOUND); + /* Allocate buffer data when first time write. */ + gcmkONERROR(gckOS_Allocate(Kernel->os, ByteCount, &shBuf->data)); } - gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer); + /* 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) { - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); } gcmkFOOTER(); return status; } - -gctUINT32 -gckKERNEL_AllocateNameFromPointer( +/******************************************************************************* +** +** 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 gctPOINTER Pointer + IN gctSHBUF ShBuf, + IN gctPOINTER UserData, + IN gctUINT32 ByteCount, + OUT gctUINT32 * BytesRead ) { gceSTATUS status; - gctUINT32 name; - gctPOINTER database = Kernel->db->pointerDatabase; + gcsSHBUF_PTR shBuf; + gctUINT32 bytes; + gctBOOL acquired = gcvFALSE; - gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer); + 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( - gckKERNEL_AllocateIntegerId(database, Pointer, &name)); + gckOS_AcquireMutex(Kernel->os, + Kernel->db->pointerDatabaseMutex, + gcvINFINITE)); + acquired = gcvTRUE; - gcmkFOOTER_ARG("name=%d", name); - return name; + /* Find shared buffer structure. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase, + (gctUINT32)(gctUINTPTR_T)ShBuf, + (gctPOINTER)&shBuf)); -OnError: - gcmkFOOTER(); - return 0; -} + gcmkASSERT(shBuf->id == (gctUINT32)(gctUINTPTR_T)ShBuf); -gctPOINTER -gckKERNEL_QueryPointerFromName( - IN gckKERNEL Kernel, - IN gctUINT32 Name - ) -{ - gceSTATUS status; - gctPOINTER pointer = gcvNULL; - gctPOINTER database = Kernel->db->pointerDatabase; + if (shBuf->data == gcvNULL) + { + *BytesRead = 0; - gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name); + /* No data in shared buffer, skip copy. */ + status = gcvSTATUS_SKIP; + goto OnError; + } + else if (ByteCount == 0) + { + /* Invalid size to read. */ + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } - /* Lookup in database to get pointer. */ - gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer)); + /* Determine bytes to copy. */ + bytes = (ByteCount < shBuf->size) ? ByteCount : shBuf->size; - gcmkFOOTER_ARG("pointer=0x%X", pointer); - return pointer; + /* Copy data to user. */ + gcmkONERROR( + gckOS_CopyToUserData(Kernel->os, + shBuf->data, + UserData, + bytes)); -OnError: - gcmkFOOTER(); - return gcvNULL; -} + /* Return copied size. */ + *BytesRead = bytes; -gceSTATUS -gckKERNEL_DeleteName( - IN gckKERNEL Kernel, - IN gctUINT32 Name - ) -{ - gctPOINTER database = Kernel->db->pointerDatabase; + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + acquired = gcvFALSE; - gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name); + gcmkFOOTER_ARG("*BytesRead=%u", bytes); + return gcvSTATUS_OK; - /* Free name if exists. */ - gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name)); +OnError: + if (acquired) + { + /* Release the mutex. */ + gcmkVERIFY_OK( + gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); + } - gcmkFOOTER_NO(); - return gcvSTATUS_OK; + 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 d7ff9cf16372..93764878a42d 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -30,6 +30,10 @@ #include "gc_hal_kernel_vg.h" #endif +#if gcdSECURITY +#include "gc_hal_security_interface.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -68,6 +72,21 @@ extern "C" { #define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS) #define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1) +#define gcdMMU_MTLB_PRESENT 0x00000001 +#define gcdMMU_MTLB_EXCEPTION 0x00000002 +#define gcdMMU_MTLB_4K_PAGE 0x00000000 + +#define gcdMMU_STLB_PRESENT 0x00000001 +#define gcdMMU_STLB_EXCEPTION 0x00000002 +#define gcdMMU_STLB_4K_PAGE 0x00000000 + +/******************************************************************************* +***** Stuck Dump Level ********************************************************/ + +#define gcdSTUCK_DUMP_MINIMAL 1 +#define gcdSTUCK_DUMP_MIDDLE 2 +#define gcdSTUCK_DUMP_MAXIMAL 3 + /******************************************************************************* ***** Process Secure Cache ****************************************************/ @@ -76,6 +95,9 @@ extern "C" { #define gcdSECURE_CACHE_HASH 3 #define gcdSECURE_CACHE_TABLE 4 +#define gcvPAGE_TABLE_DIRTY_BIT_OTHER (1 << 0) +#define gcvPAGE_TABLE_DIRTY_BIT_FE (1 << 1) + typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR; typedef struct _gcskLOGICAL_CACHE gcskLOGICAL_CACHE; struct _gcskLOGICAL_CACHE @@ -140,15 +162,19 @@ typedef enum _gceDATABASE_TYPE gcvDB_CONTEXT, /* Context */ gcvDB_IDLE, /* GPU idle. */ gcvDB_MAP_MEMORY, /* Map memory */ - gcvDB_SHARED_INFO, /* Private data */ gcvDB_MAP_USER_MEMORY, /* Map user memory */ gcvDB_SYNC_POINT, /* Sync point. */ - gcvDB_VIDEO_MEMORY_RESERVED, /* Reserved video memory */ - gcvDB_VIDEO_MEMORY_CONTIGUOUS, /* Contiguous video memory */ - gcvDB_VIDEO_MEMORY_VIRTUAL, /* Virtual video memory */ + gcvDB_SHBUF, /* Shared buffer. */ } gceDATABASE_TYPE; +#define gcdDATABASE_TYPE_MASK 0x000000FF +#define gcdDB_VIDEO_MEMORY_TYPE_MASK 0x0000FF00 +#define gcdDB_VIDEO_MEMORY_TYPE_SHIFT 8 + +#define gcdDB_VIDEO_MEMORY_POOL_MASK 0x00FF0000 +#define gcdDB_VIDEO_MEMORY_POOL_SHIFT 16 + typedef struct _gcsDATABASE_RECORD * gcsDATABASE_RECORD_PTR; typedef struct _gcsDATABASE_RECORD { @@ -184,9 +210,12 @@ typedef struct _gcsDATABASE gcsDATABASE_COUNTERS contiguous; gcsDATABASE_COUNTERS mapUserMemory; gcsDATABASE_COUNTERS mapMemory; - gcsDATABASE_COUNTERS vidMemResv; - gcsDATABASE_COUNTERS vidMemCont; - gcsDATABASE_COUNTERS vidMemVirt; + gcsDATABASE_COUNTERS virtualCommandBuffer; + + gcsDATABASE_COUNTERS vidMemType[gcvSURF_NUM_TYPES]; + /* Counter for each video memory pool. */ + gcsDATABASE_COUNTERS vidMemPool[gcvPOOL_NUMBER_OF_POOLS]; + gctPOINTER counterMutex; /* Idle time management. */ gctUINT64 lastIdle; @@ -202,9 +231,22 @@ typedef struct _gcsDATABASE gctPOINTER handleDatabase; gctPOINTER handleDatabaseMutex; + +#if gcdPROCESS_ADDRESS_SPACE + gckMMU mmu; +#endif } gcsDATABASE; +typedef struct _gcsRECORDER * gckRECORDER; + +typedef struct _gcsFDPRIVATE * gcsFDPRIVATE_PTR; +typedef struct _gcsFDPRIVATE +{ + gctINT (* release) (gcsFDPRIVATE_PTR Private); +} +gcsFDPRIVATE; + /* Create a process database that will contain all its allocations. */ gceSTATUS gckKERNEL_CreateProcessDB( @@ -266,7 +308,62 @@ gckKERNEL_DumpProcessDB( IN gckKERNEL Kernel ); -/* ID database */ +/* Dump the video memory usage for process specified. */ +gceSTATUS +gckKERNEL_DumpVidMemUsage( + IN gckKERNEL Kernel, + IN gctINT32 ProcessID + ); + +gceSTATUS +gckKERNEL_FindDatabase( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN gctBOOL LastProcessID, + OUT gcsDATABASE_PTR * Database + ); + +gceSTATUS +gckKERNEL_FindHandleDatbase( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + OUT gctPOINTER * HandleDatabase, + OUT gctPOINTER * HandleDatabaseMutex + ); + +gceSTATUS +gckKERNEL_GetProcessMMU( + IN gckKERNEL Kernel, + OUT gckMMU * Mmu + ); + +gceSTATUS +gckKERNEL_SetRecovery( + IN gckKERNEL Kernel, + IN gctBOOL Recovery, + IN gctUINT32 StuckDump + ); + +gceSTATUS +gckMMU_FlatMapping( + IN gckMMU Mmu, + IN gctUINT32 Physical + ); + +gceSTATUS +gckMMU_GetPageEntry( + IN gckMMU Mmu, + IN gctUINT32 Address, + IN gctUINT32_PTR *PageTable + ); + +gceSTATUS +gckMMU_FreePagesEx( + IN gckMMU Mmu, + IN gctUINT32 Address, + IN gctSIZE_T PageCount + ); + gceSTATUS gckKERNEL_CreateIntegerDatabase( IN gckKERNEL Kernel, @@ -299,6 +396,7 @@ gckKERNEL_QueryIntegerId( OUT gctPOINTER * Pointer ); +/* Pointer rename */ gctUINT32 gckKERNEL_AllocateNameFromPointer( IN gckKERNEL Kernel, @@ -356,18 +454,20 @@ struct _gckDB gctUINT64 idleTime; gctUINT64 lastSlowdown; gctUINT64 lastSlowdownIdle; - /* ID - Pointer database*/ + gctPOINTER nameDatabase; + gctPOINTER nameDatabaseMutex; + gctPOINTER pointerDatabase; gctPOINTER pointerDatabaseMutex; }; -#if gcdVIRTUAL_COMMAND_BUFFER typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR; typedef struct _gckVIRTUAL_COMMAND_BUFFER { gctPHYS_ADDR physical; gctPOINTER userLogical; gctPOINTER kernelLogical; + gctSIZE_T bytes; gctSIZE_T pageCount; gctPOINTER pageTable; gctUINT32 gpuAddress; @@ -375,9 +475,11 @@ typedef struct _gckVIRTUAL_COMMAND_BUFFER gckVIRTUAL_COMMAND_BUFFER_PTR next; gckVIRTUAL_COMMAND_BUFFER_PTR prev; gckKERNEL kernel; +#if gcdPROCESS_ADDRESS_SPACE + gckMMU mmu; +#endif } gckVIRTUAL_COMMAND_BUFFER; -#endif /* gckKERNEL object. */ struct _gckKERNEL @@ -412,10 +514,8 @@ struct _gckKERNEL #if VIVANTE_PROFILER /* Enable profiling */ gctBOOL profileEnable; - /* Clear profile register or not*/ gctBOOL profileCleanRegister; - #endif #ifdef QNX_SINGLE_THREADED_DEBUGGING @@ -426,11 +526,7 @@ struct _gckKERNEL gckDB db; gctBOOL dbCreated; -#if gcdENABLE_RECOVERY - gctPOINTER resetFlagClearTimer; - gctPOINTER resetAtom; gctUINT64 resetTimeStamp; -#endif /* Pointer to gckEVENT object. */ gcsTIMER timers[8]; @@ -440,11 +536,13 @@ struct _gckKERNEL gckVGKERNEL vg; #endif -#if gcdVIRTUAL_COMMAND_BUFFER + /* Virtual command buffer list. */ gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead; gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail; gctPOINTER virtualBufferLock; -#endif + + /* Enable virtual command buffer. */ + gctBOOL virtualCommandBuffer; #if gcdDVFS gckDVFS dvfs; @@ -453,6 +551,29 @@ struct _gckKERNEL #if gcdANDROID_NATIVE_FENCE_SYNC gctHANDLE timeline; #endif + + /* Enable recovery. */ + gctBOOL recovery; + + /* Level of dump information after stuck. */ + gctUINT stuckDump; + +#if gcdSECURITY + gctUINT32 securityChannel; +#endif + + /* Timer to monitor GPU stuck. */ + gctPOINTER monitorTimer; + + /* Flag to quit monitor timer. */ + gctBOOL monitorTimerStop; + + /* Monitor states. */ + gctBOOL monitoring; + gctUINT32 lastCommitStamp; + gctUINT32 timer; + gctUINT32 restoreAddress; + gctUINT32 restoreMask; }; struct _FrequencyHistory @@ -486,7 +607,7 @@ struct _gckCOMMAND gckOS os; /* Number of bytes per page. */ - gctSIZE_T pageSize; + gctUINT32 pageSize; /* Current pipe select. */ gcePIPE_SELECT pipeSelect; @@ -518,11 +639,13 @@ struct _gckCOMMAND gctSIGNAL signal; gctPHYS_ADDR physical; gctPOINTER logical; + gctUINT32 address; } queues[gcdCOMMAND_QUEUES]; gctPHYS_ADDR physical; gctPOINTER logical; + gctUINT32 address; gctUINT32 offset; gctINT index; #if gcmIS_DEBUG(gcdDEBUG_TRACE) @@ -538,12 +661,12 @@ struct _gckCOMMAND /* Pointer to last WAIT command. */ gctPHYS_ADDR waitPhysical; gctPOINTER waitLogical; - gctSIZE_T waitSize; + gctUINT32 waitSize; /* Command buffer alignment. */ - gctSIZE_T alignment; - gctSIZE_T reservedHead; - gctSIZE_T reservedTail; + gctUINT32 alignment; + gctUINT32 reservedHead; + gctUINT32 reservedTail; /* Commit counter. */ gctPOINTER atomCommit; @@ -560,6 +683,11 @@ struct _gckCOMMAND gctUINT hintArraySize; gctUINT32_PTR hintArray; #endif + +#if gcdPROCESS_ADDRESS_SPACE + gckMMU currentMmu; +#endif + struct _gckENTRYQUEUE queue; }; typedef struct _gcsEVENT * gcsEVENT_PTR; @@ -595,6 +723,11 @@ typedef struct _gcsEVENT_QUEUE /* Source of the event. */ gceKERNEL_WHERE source; +#if gcdMULTI_GPU + /* Which chip(s) of the event */ + gceCORE_3D_MASK chipEnable; +#endif + /* Pointer to head of event queue. */ gcsEVENT_PTR head; @@ -632,22 +765,35 @@ struct _gckEVENT /* Time stamp. */ gctUINT64 stamp; - gctUINT64 lastCommitStamp; + gctUINT32 lastCommitStamp; /* Queue mutex. */ gctPOINTER eventQueueMutex; /* Array of event queues. */ - gcsEVENT_QUEUE queues[30]; + gcsEVENT_QUEUE queues[29]; gctUINT8 lastID; gctPOINTER freeAtom; /* Pending events. */ #if gcdSMP +#if gcdMULTI_GPU + gctPOINTER pending3D[gcdMULTI_GPU]; + gctPOINTER pending3DMask[gcdMULTI_GPU]; + gctPOINTER pendingMask; +#endif gctPOINTER pending; #else +#if gcdMULTI_GPU + volatile gctUINT pending3D[gcdMULTI_GPU]; + volatile gctUINT pending3DMask[gcdMULTI_GPU]; + volatile gctUINT pendingMask; +#endif volatile gctUINT pending; #endif +#if gcdMULTI_GPU + gctUINT32 busy; +#endif /* List of free event structures and its mutex. */ gcsEVENT_PTR freeEventList; @@ -663,7 +809,13 @@ struct _gckEVENT gctPOINTER submitTimer; - volatile gctBOOL inNotify; +#if gcdINTERRUPT_STATISTIC + gctPOINTER interruptCount; +#endif + +#if gcdRECORD_COMMAND + gckRECORDER recorder; +#endif }; /* Free all events belonging to a process. */ @@ -680,13 +832,29 @@ gckEVENT_Stop( IN gctPHYS_ADDR Handle, IN gctPOINTER Logical, IN gctSIGNAL Signal, - IN OUT gctSIZE_T * waitSize + IN OUT gctUINT32 * waitSize ); -gceSTATUS -gckEVENT_WaitEmpty( - IN gckEVENT Event - ); +typedef struct _gcsLOCK_INFO * gcsLOCK_INFO_PTR; +typedef struct _gcsLOCK_INFO +{ + gctUINT32 GPUAddresses[gcdMAX_GPU_COUNT]; + gctPOINTER pageTables[gcdMAX_GPU_COUNT]; + gctUINT32 lockeds[gcdMAX_GPU_COUNT]; + gckKERNEL lockKernels[gcdMAX_GPU_COUNT]; + gckMMU lockMmus[gcdMAX_GPU_COUNT]; +} +gcsLOCK_INFO; + +typedef struct _gcsGPU_MAP * gcsGPU_MAP_PTR; +typedef struct _gcsGPU_MAP +{ + gctINT pid; + gcsLOCK_INFO lockInfo; + gcsGPU_MAP_PTR prev; + gcsGPU_MAP_PTR next; +} +gcsGPU_MAP; /* gcuVIDMEM_NODE structure. */ typedef union _gcuVIDMEM_NODE @@ -706,12 +874,12 @@ typedef union _gcuVIDMEM_NODE gcuVIDMEM_NODE_PTR prevFree; /* Information for this node. */ - gctUINT32 offset; + gctSIZE_T offset; gctSIZE_T bytes; gctUINT32 alignment; #ifdef __QNXNTO__ - /* Client/server vaddr (mapped using mmap_join). */ + /* Client virtual address. */ gctPOINTER logical; #endif @@ -725,18 +893,9 @@ typedef union _gcuVIDMEM_NODE /* Process ID owning this memory. */ gctUINT32 processID; - /* Prevent compositor from freeing until client unlocks. */ - gctBOOL freePending; - - /* */ - gcsVIDMEM_NODE_SHARED_INFO sharedInfo; - -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG gctPOINTER kernelVirtual; #endif - - /* Surface type. */ - gceSURF_TYPE type; } VidMem; @@ -755,6 +914,17 @@ 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 + + /* Customer private handle */ + gctUINT32 gid; + /* Page table information. */ /* Used only when node is not contiguous */ gctSIZE_T pageCount; @@ -766,34 +936,12 @@ typedef union _gcuVIDMEM_NODE /* Actual physical address */ gctUINT32 addresses[gcdMAX_GPU_COUNT]; - /* Mutex. */ - gctPOINTER mutex; - /* Locked counter. */ gctINT32 lockeds[gcdMAX_GPU_COUNT]; -#ifdef __QNXNTO__ - /* Single linked list of nodes. */ - gcuVIDMEM_NODE_PTR next; - - /* Unlock pending flag. */ - gctBOOL unlockPendings[gcdMAX_GPU_COUNT]; - - /* Free pending flag. */ - gctBOOL freePending; -#endif - /* Process ID owning this memory. */ gctUINT32 processID; - /* Owner process sets freed to true - * when it trys to free a locked - * node */ - gctBOOL freed; - - /* */ - gcsVIDMEM_NODE_SHARED_INFO sharedInfo; - /* Surface type. */ gceSURF_TYPE type; } @@ -826,14 +974,158 @@ struct _gckVIDMEM /* The heap mutex. */ gctPOINTER mutex; +}; + +typedef struct _gcsVIDMEM_NODE +{ + /* Pointer to gcuVIDMEM_NODE. */ + gcuVIDMEM_NODE_PTR node; + + /* Mutex to protect node. */ + gctPOINTER mutex; + + /* Reference count. */ + gctPOINTER reference; + + /* Name for client to import. */ + gctUINT32 name; -#if gcdUSE_VIDMEM_PER_PID - /* The Pid this VidMem belongs to. */ - gctUINT32 pid; +#if gcdPROCESS_ADDRESS_SPACE + /* Head of mapping list. */ + gcsGPU_MAP_PTR mapHead; - struct _gckVIDMEM* next; + /* Tail of mapping list. */ + gcsGPU_MAP_PTR mapTail; + + gctPOINTER mapMutex; +#endif + + /* Surface Type. */ + gceSURF_TYPE type; + + /* Pool from which node is allocated. */ + gcePOOL pool; +} +gcsVIDMEM_NODE; + +typedef struct _gcsVIDMEM_HANDLE * gckVIDMEM_HANDLE; +typedef struct _gcsVIDMEM_HANDLE +{ + /* Pointer to gckVIDMEM_NODE. */ + gckVIDMEM_NODE node; + + /* Handle for current process. */ + gctUINT32 handle; + + /* Reference count for this handle. */ + gctPOINTER reference; +} +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, + IN gctUINT32 ProcessID, + IN gctUINT32 Handle + ); + +gceSTATUS +gckVIDMEM_HANDLE_Dereference( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN gctUINT32 Handle + ); + +gceSTATUS +gckVIDMEM_NODE_Allocate( + IN gckKERNEL Kernel, + IN gcuVIDMEM_NODE_PTR VideoNode, + IN gceSURF_TYPE Type, + IN gcePOOL Pool, + IN gctUINT32 * Handle + ); + +gceSTATUS +gckVIDMEM_Node_Lock( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node, + OUT gctUINT32 *Address + ); + +gceSTATUS +gckVIDMEM_NODE_Unlock( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node, + IN gctUINT32 ProcessID + ); + +gceSTATUS +gckVIDMEM_NODE_Dereference( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node + ); + +gceSTATUS +gckVIDMEM_NODE_Name( + IN gckKERNEL Kernel, + IN gctUINT32 Handle, + IN gctUINT32 * Name + ); + +gceSTATUS +gckVIDMEM_NODE_Import( + IN gckKERNEL Kernel, + IN gctUINT32 Name, + IN gctUINT32 * Handle + ); + +gceSTATUS +gckVIDMEM_HANDLE_LookupAndReference( + IN gckKERNEL Kernel, + IN gctUINT32 Handle, + OUT gckVIDMEM_NODE * Node + ); + +gceSTATUS +gckVIDMEM_HANDLE_Lookup( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN gctUINT32 Handle, + OUT gckVIDMEM_NODE * Node + ); + +gceSTATUS +gckVIDMEM_NODE_GetFd( + IN gckKERNEL Kernel, + IN gctUINT32 Handle, + OUT gctINT * Fd + ); + +#if gcdPROCESS_ADDRESS_SPACE +gceSTATUS +gckEVENT_DestroyMmu( + IN gckEVENT Event, + IN gckMMU Mmu, + IN gceKERNEL_WHERE FromWhere + ); #endif -}; /* gckMMU object. */ struct _gckMMU @@ -871,26 +1163,54 @@ struct _gckMMU gctUINT32 dynamicMappingStart; -#ifdef __QNXNTO__ - /* Single linked list of all allocated nodes. */ - gctPOINTER nodeMutex; - gcuVIDMEM_NODE_PTR nodeList; + gctUINT32_PTR mapLogical; +#if gcdPROCESS_ADDRESS_SPACE + gctPOINTER pageTableDirty[gcdMAX_GPU_COUNT]; + gctPOINTER stlbs; #endif }; -#if gcdVIRTUAL_COMMAND_BUFFER gceSTATUS gckOS_CreateKernelVirtualMapping( + IN gckOS Os, IN gctPHYS_ADDR Physical, - OUT gctSIZE_T * PageCount, - OUT gctPOINTER * Logical + IN gctSIZE_T Bytes, + OUT gctPOINTER * Logical, + OUT gctSIZE_T * PageCount ); gceSTATUS gckOS_DestroyKernelVirtualMapping( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T Bytes, IN gctPOINTER Logical ); +gceSTATUS +gckOS_CreateUserVirtualMapping( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T Bytes, + OUT gctPOINTER * Logical, + OUT gctSIZE_T * PageCount + ); + +gceSTATUS +gckOS_DestroyUserVirtualMapping( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T Bytes, + IN gctPOINTER Logical + ); + +gceSTATUS +gckOS_GetFd( + IN gctSTRING Name, + IN gcsFDPRIVATE_PTR Private, + OUT gctINT *Fd + ); + gceSTATUS gckKERNEL_AllocateVirtualCommandBuffer( IN gckKERNEL Kernel, @@ -912,6 +1232,7 @@ gceSTATUS gckKERNEL_GetGPUAddress( IN gckKERNEL Kernel, IN gctPOINTER Logical, + IN gctBOOL InUserSpace, OUT gctUINT32 * Address ); @@ -921,7 +1242,6 @@ gckKERNEL_QueryGPUAddress( IN gctUINT32 GpuAddress, OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer ); -#endif gceSTATUS gckKERNEL_AttachProcess( @@ -959,6 +1279,104 @@ 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 ******************************* \******************************************************************************/ @@ -983,6 +1401,14 @@ gckCONTEXT_Update( IN gcsSTATE_DELTA_PTR StateDelta ); +gceSTATUS +gckCONTEXT_MapBuffer( + IN gckCONTEXT Context, + OUT gctUINT32 *Physicals, + OUT gctUINT64 *Logicals, + OUT gctUINT32 *Bytes + ); + #if gcdLINK_QUEUE_SIZE void gckLINKQUEUE_Enqueue( @@ -999,6 +1425,62 @@ gckLINKQUEUE_GetData( ); #endif +gceSTATUS +gckENTRYQUEUE_Enqueue( + IN gckKERNEL Kernel, + IN gckENTRYQUEUE Queue, + IN gctUINT32 physical, + IN gctUINT32 bytes + ); + +gceSTATUS +gckENTRYQUEUE_Dequeue( + IN gckENTRYQUEUE Queue, + OUT gckENTRYDATA * Data + ); + +/******************************************************************************\ +****************************** gckRECORDER Object ****************************** +\******************************************************************************/ +gceSTATUS +gckRECORDER_Construct( + IN gckOS Os, + IN gckHARDWARE Hardware, + OUT gckRECORDER * Recorder + ); + +gceSTATUS +gckRECORDER_Destory( + IN gckOS Os, + IN gckRECORDER Recorder + ); + +void +gckRECORDER_AdvanceIndex( + gckRECORDER Recorder, + gctUINT64 CommitStamp + ); + +void +gckRECORDER_Record( + gckRECORDER Recorder, + gctUINT8_PTR CommandBuffer, + gctUINT32 CommandBytes, + gctUINT8_PTR ContextBuffer, + gctUINT32 ContextBytes + ); + +void +gckRECORDER_Dump( + gckRECORDER Recorder + ); + +gceSTATUS +gckRECORDER_UpdateMirror( + gckRECORDER Recorder, + gctUINT32 State, + gctUINT32 Data + ); #ifdef __cplusplus } 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 73dab8117525..72aa966d6dad 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,10 +22,6 @@ #include "gc_hal_kernel_precomp.h" #include "gc_hal_kernel_context.h" -#ifdef __QNXNTO__ -#include -#endif - #define _GC_OBJ_ZONE gcvZONE_COMMAND /******************************************************************************\ @@ -105,14 +101,14 @@ _NewQueue( Command->index = newIndex; Command->newQueue = gcvTRUE; Command->logical = Command->queues[newIndex].logical; + Command->address = Command->queues[newIndex].address; Command->offset = 0; - gcmkONERROR( - gckOS_GetPhysicalAddress( - Command->os, - Command->logical, - (gctUINT32 *) &Command->physical - )); + gcmkONERROR(gckOS_GetPhysicalAddress( + Command->os, + Command->logical, + (gctUINT32 *) &Command->physical + )); if (currentIndex != -1) { @@ -326,9 +322,20 @@ _FlushMMU( IN gckCOMMAND Command ) { +#if gcdSECURITY + return gcvSTATUS_OK; +#else gceSTATUS status; gctUINT32 oldValue; gckHARDWARE hardware = Command->kernel->hardware; + gctBOOL pause = gcvFALSE; + + gctUINT8_PTR pointer; + gctUINT32 eventBytes; + gctUINT32 endBytes; + gctUINT32 bufferSize; + gctUINT32 executeBytes; + gctUINT32 waitLinkBytes; gcmkONERROR(gckOS_AtomicExchange(Command->os, hardware->pageTableDirty, @@ -339,14 +346,70 @@ _FlushMMU( { /* Page Table is upated, flush mmu before commit. */ gcmkONERROR(gckHARDWARE_FlushMMU(hardware)); + + if ((oldValue & gcvPAGE_TABLE_DIRTY_BIT_FE) + && (hardware->endAfterFlushMmuCache) + ) + { + pause = gcvTRUE; + } + } + + if (pause) + { + /* Query size. */ + gcmkONERROR(gckHARDWARE_Event(hardware, gcvNULL, 0, gcvKERNEL_PIXEL, &eventBytes)); + gcmkONERROR(gckHARDWARE_End(hardware, gcvNULL, &endBytes)); + + executeBytes = eventBytes + endBytes; + + gcmkONERROR(gckHARDWARE_WaitLink( + hardware, + gcvNULL, + Command->offset + executeBytes, + &waitLinkBytes, + gcvNULL, + gcvNULL + )); + + /* Reserve space. */ + gcmkONERROR(gckCOMMAND_Reserve( + Command, + executeBytes, + (gctPOINTER *)&pointer, + &bufferSize + )); + + /* Append EVENT(29). */ + gcmkONERROR(gckHARDWARE_Event( + hardware, + pointer, + 29, + gcvKERNEL_PIXEL, + &eventBytes + )); + + /* Append END. */ + pointer += eventBytes; + gcmkONERROR(gckHARDWARE_End(hardware, pointer, &endBytes)); + + /* Store address to queue. */ + gcmkONERROR(gckENTRYQUEUE_Enqueue( + Command->kernel, + &Command->queue, + Command->address + Command->offset + executeBytes, + waitLinkBytes + )); + + gcmkONERROR(gckCOMMAND_Execute(Command, executeBytes)); } return gcvSTATUS_OK; OnError: return status; +#endif } -#if gcdVIRTUAL_COMMAND_BUFFER static void _DumpBuffer( IN gctPOINTER Buffer, @@ -354,13 +417,12 @@ _DumpBuffer( IN gctSIZE_T Size ) { - gctINT i, line, left; + gctSIZE_T i, line, left; gctUINT32_PTR data = Buffer; line = Size / 32; left = Size % 32; - for (i = 0; i < line; i++) { gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X %08X ", @@ -407,11 +469,11 @@ _DumpBuffer( static void _DumpKernelCommandBuffer( IN gckCOMMAND Command -) + ) { gctINT i; - gctUINT32 physical; - gctPOINTER entry; + gctUINT32 physical = 0; + gctPOINTER entry = gcvNULL; for (i = 0; i < gcdCOMMAND_QUEUES; i++) { @@ -424,7 +486,6 @@ _DumpKernelCommandBuffer( _DumpBuffer(entry, physical, Command->pageSize); } } -#endif /******************************************************************************\ ****************************** gckCOMMAND API Code ****************************** @@ -458,6 +519,7 @@ gckCOMMAND_Construct( gceSTATUS status; gctINT i; gctPOINTER pointer = gcvNULL; + gctSIZE_T pageSize; gcmkHEADER_ARG("Kernel=0x%x", Kernel); @@ -506,7 +568,9 @@ gckCOMMAND_Construct( gcmkONERROR(gckOS_AtomConstruct(os, &command->atomCommit)); /* Get the page size from teh OS. */ - gcmkONERROR(gckOS_GetPageSize(os, &command->pageSize)); + gcmkONERROR(gckOS_GetPageSize(os, &pageSize)); + + gcmkSAFECASTSIZET(command->pageSize, pageSize); /* Get process ID. */ gcmkONERROR(gckOS_GetProcessID(&command->kernelProcessID)); @@ -520,11 +584,18 @@ gckCOMMAND_Construct( gcmkONERROR(gckOS_AllocateNonPagedMemory( os, gcvFALSE, - &command->pageSize, + &pageSize, &command->queues[i].physical, &command->queues[i].logical )); + gcmkONERROR(gckHARDWARE_ConvertLogical( + Kernel->hardware, + command->queues[i].logical, + gcvFALSE, + &command->queues[i].address + )); + gcmkONERROR(gckOS_CreateSignal( os, gcvFALSE, &command->queues[i].signal )); @@ -534,6 +605,10 @@ gckCOMMAND_Construct( )); } +#if gcdRECORD_COMMAND + gcmkONERROR(gckRECORDER_Construct(os, Kernel->hardware, &command->recorder)); +#endif + /* No command queue in use yet. */ command->index = -1; command->logical = gcvNULL; @@ -551,6 +626,10 @@ gckCOMMAND_Construct( /* END event signal not created. */ command->endEventSignal = gcvNULL; + command->queue.front = 0; + command->queue.rear = 0; + command->queue.count = 0; + /* Return pointer to the gckCOMMAND object. */ *Command = command; @@ -697,6 +776,10 @@ gckCOMMAND_Destroy( } #endif +#if gcdRECORD_COMMAND + gckRECORDER_Destory(Command->os, Command->recorder); +#endif + /* Mark object as unknown. */ Command->object.type = gcvOBJ_UNKNOWN; @@ -867,8 +950,8 @@ gckCOMMAND_Start( { gceSTATUS status; gckHARDWARE hardware; - gctUINT32 waitOffset; - gctSIZE_T waitLinkBytes; + gctUINT32 waitOffset = 0; + gctUINT32 waitLinkBytes; gcmkHEADER_ARG("Command=0x%x", Command); @@ -917,7 +1000,7 @@ gckCOMMAND_Start( Command->os, Command->kernelProcessID, gcvNULL, - Command->physical, + (gctUINT32)Command->physical, Command->logical, waitLinkBytes )); @@ -927,19 +1010,16 @@ gckCOMMAND_Start( Command->offset = waitLinkBytes; Command->newQueue = gcvFALSE; - /* Enable command processor. */ -#ifdef __QNXNTO__ - gcmkONERROR(gckHARDWARE_Execute( - hardware, - Command->logical, - Command->physical, - gcvTRUE, - waitLinkBytes - )); +#if gcdSECURITY + /* Start FE by calling security service. */ + gckKERNEL_SecurityStartCommand( + Command->kernel + ); #else + /* Enable command processor. */ gcmkONERROR(gckHARDWARE_Execute( hardware, - Command->logical, + Command->address, waitLinkBytes )); #endif @@ -1015,7 +1095,7 @@ gckCOMMAND_Stop( Command->waitPhysical, Command->waitLogical, Command->endEventSignal, - &Command->waitSize)); + &Command->waitSize)); } else { @@ -1024,6 +1104,12 @@ 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, Command->logical, @@ -1035,7 +1121,7 @@ gckCOMMAND_Stop( Command->os, Command->kernelProcessID, gcvNULL, - Command->waitPhysical, + (gctUINT32)Command->waitPhysical, Command->waitLogical, Command->waitSize )); @@ -1085,6 +1171,18 @@ OnError: ** ** Nothing. */ +#if gcdMULTI_GPU +gceSTATUS +gckCOMMAND_Commit( + IN gckCOMMAND Command, + IN gckCONTEXT Context, + IN gcoCMDBUF CommandBuffer, + IN gcsSTATE_DELTA_PTR StateDelta, + IN gcsQUEUE_PTR EventQueue, + IN gctUINT32 ProcessID, + IN gceCORE_3D_MASK ChipEnable + ) +#else gceSTATUS gckCOMMAND_Commit( IN gckCOMMAND Command, @@ -1094,6 +1192,7 @@ gckCOMMAND_Commit( IN gcsQUEUE_PTR EventQueue, IN gctUINT32 ProcessID ) +#endif { gceSTATUS status; gctBOOL commitEntered = gcvFALSE; @@ -1110,31 +1209,53 @@ gckCOMMAND_Commit( gcsCONTEXT_PTR contextBuffer; struct _gcoCMDBUF _commandBufferObject; gctPHYS_ADDR commandBufferPhysical; - gctUINT8_PTR commandBufferLogical; - gctUINT8_PTR commandBufferLink; + gctUINT8_PTR commandBufferLogical = gcvNULL; + gctUINT32 commandBufferAddress = 0; + gctUINT8_PTR commandBufferLink = gcvNULL; gctUINT commandBufferSize; gctSIZE_T nopBytes; - gctSIZE_T pipeBytes; - gctSIZE_T linkBytes; + gctUINT32 pipeBytes; + gctUINT32 linkBytes; gctSIZE_T bytes; gctUINT32 offset; #if gcdNONPAGED_MEMORY_CACHEABLE gctPHYS_ADDR entryPhysical; #endif gctPOINTER entryLogical; - gctSIZE_T entryBytes; + gctUINT32 entryAddress; + gctUINT32 entryBytes; #if gcdNONPAGED_MEMORY_CACHEABLE gctPHYS_ADDR exitPhysical; #endif gctPOINTER exitLogical; - gctSIZE_T exitBytes; + gctUINT32 exitAddress; + gctUINT32 exitBytes; gctPHYS_ADDR waitLinkPhysical; gctPOINTER waitLinkLogical; - gctSIZE_T waitLinkBytes; + gctUINT32 waitLinkAddress; + gctUINT32 waitLinkBytes; gctPHYS_ADDR waitPhysical; gctPOINTER waitLogical; gctUINT32 waitOffset; - gctSIZE_T waitSize; + gctUINT32 waitSize; + +#ifdef __QNXNTO__ + gctPOINTER userCommandBufferLogical = gcvNULL; + gctBOOL userCommandBufferLogicalMapped = gcvFALSE; + gctPOINTER userCommandBufferLink = gcvNULL; + gctBOOL userCommandBufferLinkMapped = gcvFALSE; +#endif + +#if gcdPROCESS_ADDRESS_SPACE + gctSIZE_T mmuConfigureBytes; + gctPOINTER mmuConfigureLogical = gcvNULL; + gctUINT32 mmuConfigureAddress; + gctPOINTER mmuConfigurePhysical = 0; + gctSIZE_T mmuConfigureWaitLinkOffset; + gckMMU mmu; + gctSIZE_T reservedBytes; + gctUINT32 oldValue; +#endif #if gcdDUMP_COMMAND gctPOINTER contextDumpLogical = gcvNULL; @@ -1150,6 +1271,10 @@ gckCOMMAND_Commit( gctPOINTER pointer = gcvNULL; +#if gcdMULTI_GPU + gctSIZE_T chipEnableBytes; +#endif + gcmkHEADER_ARG( "Command=0x%x CommandBuffer=0x%x ProcessID=%d", Command, CommandBuffer, ProcessID @@ -1158,13 +1283,21 @@ gckCOMMAND_Commit( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); - if (Command->kernel->core == gcvCORE_2D) + if (Command->kernel->hardware->type== gcvHARDWARE_2D) { /* There is no context for 2D. */ Context = gcvNULL; } - gcmkONERROR(_FlushMMU(Command)); +#if gcdPROCESS_ADDRESS_SPACE + gcmkONERROR(gckKERNEL_GetProcessMMU(Command->kernel, &mmu)); + + gcmkONERROR(gckOS_AtomicExchange(Command->os, + mmu->pageTableDirty[Command->kernel->core], + 0, + &oldValue)); +#else +#endif #if VIVANTE_PROFILER_CONTEXT if((Command->kernel->hardware->gpuProfiler) && (Command->kernel->profileEnable)) @@ -1200,9 +1333,9 @@ gckCOMMAND_Commit( /* Yes, merge in the deltas. */ gckCONTEXT_Update(Context, ProcessID, StateDelta); - /* Update the current context. */ - Command->currContext = Context; - } + /* Update the current context. */ + Command->currContext = Context; + } #else if (needCopy) { @@ -1244,31 +1377,112 @@ gckCOMMAND_Commit( /* Query the size of LINK command. */ gcmkONERROR(gckHARDWARE_Link( - hardware, gcvNULL, gcvNULL, 0, &linkBytes + hardware, gcvNULL, 0, 0, &linkBytes )); +#if gcdMULTI_GPU + /* Query the size of chip enable command sequence. */ + gcmkONERROR(gckHARDWARE_ChipEnable( + hardware, gcvNULL, 0, &chipEnableBytes + )); +#endif + /* Compute the command buffer entry and the size. */ commandBufferLogical = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical) + commandBufferObject->startOffset; - gcmkONERROR(gckOS_GetPhysicalAddress( + /* Get the hardware address. */ + if (Command->kernel->virtualCommandBuffer) + { + gcmkONERROR(gckKERNEL_GetGPUAddress( + Command->kernel, + commandBufferLogical, + gcvTRUE, + &commandBufferAddress + )); + } + else + { + gcmkONERROR(gckHARDWARE_ConvertLogical( + hardware, + commandBufferLogical, + gcvTRUE, + &commandBufferAddress + )); + } + + /* Get the physical address. */ + gcmkONERROR(gckOS_UserLogicalToPhysical( Command->os, commandBufferLogical, (gctUINT32_PTR)&commandBufferPhysical )); +#ifdef __QNXNTO__ + userCommandBufferLogical = (gctPOINTER) commandBufferLogical; + + gcmkONERROR(gckOS_MapUserPointer( + Command->os, + userCommandBufferLogical, + 0, + &pointer)); + + commandBufferLogical = pointer; + + userCommandBufferLogicalMapped = gcvTRUE; +#endif + commandBufferSize = commandBufferObject->offset + Command->reservedTail - commandBufferObject->startOffset; + gcmkONERROR(_FlushMMU(Command)); + /* Get the current offset. */ offset = Command->offset; /* Compute number of bytes left in current kernel command queue. */ bytes = Command->pageSize - offset; +#if gcdMULTI_GPU + if (Command->kernel->core == gcvCORE_MAJOR) + { + commandBufferSize += chipEnableBytes; + + gcmkONERROR(gckHARDWARE_ChipEnable( + hardware, + commandBufferLogical + pipeBytes, + ChipEnable, + &chipEnableBytes + )); + + gcmkONERROR(gckHARDWARE_ChipEnable( + hardware, + commandBufferLogical + commandBufferSize - linkBytes - chipEnableBytes, + gcvCORE_3D_ALL_MASK, + &chipEnableBytes + )); + } + else + { + commandBufferSize += nopBytes; + + gcmkONERROR(gckHARDWARE_Nop( + hardware, + commandBufferLogical + pipeBytes, + &nopBytes + )); + + gcmkONERROR(gckHARDWARE_Nop( + hardware, + commandBufferLogical + commandBufferSize - linkBytes - nopBytes, + &nopBytes + )); + } +#endif + /* Query the size of WAIT/LINK command sequence. */ gcmkONERROR(gckHARDWARE_WaitLink( hardware, @@ -1296,6 +1510,7 @@ gckCOMMAND_Commit( /* Compute the location if WAIT/LINK command sequence. */ waitLinkPhysical = (gctUINT8_PTR) Command->physical + offset; waitLinkLogical = (gctUINT8_PTR) Command->logical + offset; + waitLinkAddress = Command->address + offset; /* Context switch required? */ if (Context == gcvNULL) @@ -1326,7 +1541,10 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset; #endif entryLogical = commandBufferLogical + offset; + entryAddress = commandBufferAddress + offset; entryBytes = commandBufferSize - offset; + + Command->currContext = gcvNULL; } else if (Command->currContext != Context) { @@ -1361,6 +1579,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes; + entryAddress = contextBuffer->address + pipeBytes; entryBytes = Context->bufferSize - pipeBytes; } else @@ -1369,6 +1588,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical; + entryAddress = contextBuffer->address; entryBytes = Context->bufferSize; } @@ -1407,7 +1627,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link3D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1431,6 +1651,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes; + entryAddress = contextBuffer->address + pipeBytes; entryBytes = Context->entryOffset3D - pipeBytes; } else @@ -1439,6 +1660,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical; + entryAddress = contextBuffer->address; entryBytes = Context->entryOffset3D; } @@ -1472,7 +1694,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link2D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1482,8 +1704,6 @@ gckCOMMAND_Commit( /* Not using 2D. */ else { - /* Mark 2D as dirty. */ - Context->dirty2D = gcvTRUE; /* Store the current context buffer. */ Context->dirtyBuffer = contextBuffer; @@ -1501,7 +1721,7 @@ gckCOMMAND_Commit( offset = (Command->pipeSelect == gcvPIPE_3D) /* Skip pipe switching sequence. */ - ? Context->entryOffset3D + pipeBytes + ? Context->entryOffset3D + Context->pipeSelectBytes /* Do not skip pipe switching sequence. */ : Context->entryOffset3D; @@ -1511,6 +1731,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset; + entryAddress = contextBuffer->address + offset; entryBytes = Context->bufferSize - offset; /* See if we have to switch pipes between the context @@ -1540,7 +1761,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link3D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1566,6 +1787,10 @@ gckCOMMAND_Commit( = (gctUINT8_PTR) contextBuffer->logical + Context->entryOffsetXDFrom3D; + entryAddress + = contextBuffer->address + + Context->entryOffsetXDFrom3D; + entryBytes = Context->bufferSize - Context->entryOffsetXDFrom3D; @@ -1581,6 +1806,10 @@ gckCOMMAND_Commit( = (gctUINT8_PTR) contextBuffer->logical + Context->entryOffsetXDFrom2D; + entryAddress + = contextBuffer->address + + Context->entryOffsetXDFrom2D; + entryBytes = Context->totalSize - Context->entryOffsetXDFrom2D; @@ -1613,7 +1842,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link3D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1626,7 +1855,7 @@ gckCOMMAND_Commit( Command->os, Command->kernelProcessID, gcvNULL, - entryPhysical, + (gctUINT32)entryPhysical, entryLogical, entryBytes )); @@ -1639,6 +1868,25 @@ gckCOMMAND_Commit( contextDumpLogical = entryLogical; contextDumpBytes = entryBytes; #endif + +#if gcdSECURITY + /* Commit context buffer to trust zone. */ + gckKERNEL_SecurityExecute( + Command->kernel, + entryLogical, + entryBytes - 8 + ); +#endif + +#if gcdRECORD_COMMAND + gckRECORDER_Record( + Command->recorder, + gcvNULL, + 0xFFFFFFFF, + entryLogical, + entryBytes - 8 + ); +#endif } /* Same context. */ @@ -1665,6 +1913,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes; + entryAddress = contextBuffer->address + pipeBytes; entryBytes = Context->bufferSize - pipeBytes; } else @@ -1673,6 +1922,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical; + entryAddress = contextBuffer->address; entryBytes = Context->bufferSize; } @@ -1711,7 +1961,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link3D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1725,6 +1975,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes; + entryAddress = contextBuffer->address + pipeBytes; entryBytes = Context->entryOffset3D - pipeBytes; } else @@ -1733,6 +1984,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical; + entryAddress = contextBuffer->address; entryBytes = Context->entryOffset3D; } @@ -1763,7 +2015,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link2D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1793,6 +2045,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset; #endif entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset; + entryAddress = contextBuffer->address + offset; entryBytes = Context->bufferSize - offset; /* See if we have to switch pipes between the context @@ -1822,7 +2075,7 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, contextBuffer->link3D, - commandBufferLogical + offset, + commandBufferAddress + offset, commandBufferSize - offset, &linkBytes )); @@ -1855,6 +2108,7 @@ gckCOMMAND_Commit( entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset; #endif entryLogical = commandBufferLogical + offset; + entryAddress = commandBufferAddress + offset; entryBytes = commandBufferSize - offset; } } @@ -1878,7 +2132,9 @@ gckCOMMAND_Commit( #if gcdNONPAGED_MEMORY_CACHEABLE exitPhysical = Command->physical; #endif + exitLogical = Command->logical; + exitAddress = Command->address; exitBytes = Command->offset + waitLinkBytes; } else @@ -1889,6 +2145,7 @@ gckCOMMAND_Commit( exitPhysical = waitLinkPhysical; #endif exitLogical = waitLinkLogical; + exitAddress = waitLinkAddress; exitBytes = waitLinkBytes; } @@ -1914,7 +2171,7 @@ gckCOMMAND_Commit( Command->os, Command->kernelProcessID, gcvNULL, - exitPhysical, + (gctUINT32)exitPhysical, exitLogical, exitBytes )); @@ -1925,15 +2182,52 @@ gckCOMMAND_Commit( = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical) + commandBufferObject->offset; +#ifdef __QNXNTO__ + userCommandBufferLink = (gctPOINTER) commandBufferLink; + + gcmkONERROR(gckOS_MapUserPointer( + Command->os, + userCommandBufferLink, + 0, + &pointer)); + + commandBufferLink = pointer; + + userCommandBufferLinkMapped = gcvTRUE; +#endif + +#if gcdMULTI_GPU + if (Command->kernel->core == gcvCORE_MAJOR) + { + commandBufferLink += chipEnableBytes; + } + else + { + commandBufferLink += nopBytes; + } +#endif + /* 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, - exitLogical, + exitAddress, exitBytes, &linkBytes )); +#endif + +#ifdef __QNXNTO__ + gcmkONERROR(gckOS_UnmapUserPointer( + Command->os, + userCommandBufferLink, + 0, + commandBufferLink)); + + userCommandBufferLinkMapped = gcvFALSE; +#endif #if gcdNONPAGED_MEMORY_CACHEABLE /* Flush the command buffer cache. */ @@ -1941,12 +2235,34 @@ gckCOMMAND_Commit( Command->os, ProcessID, gcvNULL, - commandBufferPhysical, + (gctUINT32)commandBufferPhysical, commandBufferLogical, commandBufferSize )); #endif +#if gcdRECORD_COMMAND + gckRECORDER_Record( + Command->recorder, + commandBufferLogical + offset, + commandBufferSize - offset - 8, + gcvNULL, + 0xFFFFFFFF + ); + + gckRECORDER_AdvanceIndex(Command->recorder, Command->commitStamp); + + Command->commitStamp++; +#endif + +#if gcdSECURITY + /* Submit command buffer to trust zone. */ + gckKERNEL_SecurityExecute( + 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 @@ -1955,10 +2271,11 @@ gckCOMMAND_Commit( gcmkONERROR(gckHARDWARE_Link( hardware, Command->waitLogical, - entryLogical, + entryAddress, entryBytes, &Command->waitSize )); +#endif #if gcdNONPAGED_MEMORY_CACHEABLE /* Flush the cache for the link. */ @@ -1966,7 +2283,7 @@ gckCOMMAND_Commit( Command->os, Command->kernelProcessID, gcvNULL, - Command->waitPhysical, + (gctUINT32)Command->waitPhysical, Command->waitLogical, Command->waitSize )); @@ -2037,7 +2354,11 @@ gckCOMMAND_Commit( #if VIVANTE_PROFILER_CONTEXT if(sequenceAcquired) { +#if gcdMULTI_GPU + gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE, ChipEnable)); +#else gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE)); +#endif if (Command->currContext) { gcmkONERROR(gckHARDWARE_UpdateContextProfile( @@ -2106,8 +2427,11 @@ gckCOMMAND_Commit( } /* Submit events. */ +#if gcdMULTI_GPU + status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE, ChipEnable); +#else status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE); - +#endif if (status == gcvSTATUS_INTERRUPTED) { gcmkTRACE( @@ -2122,6 +2446,19 @@ gckCOMMAND_Commit( gcmkONERROR(status); } +#ifdef __QNXNTO__ + if (userCommandBufferLogicalMapped) + { + gcmkONERROR(gckOS_UnmapUserPointer( + Command->os, + userCommandBufferLogical, + 0, + commandBufferLogical)); + + userCommandBufferLogicalMapped = gcvFALSE; + } +#endif + /* Unmap the command buffer pointer. */ if (commandBufferMapped) { @@ -2171,6 +2508,26 @@ OnError: } #endif +#ifdef __QNXNTO__ + if (userCommandBufferLinkMapped) + { + gcmkONERROR(gckOS_UnmapUserPointer( + Command->os, + userCommandBufferLink, + 0, + commandBufferLink)); + } + + if (userCommandBufferLogicalMapped) + { + gcmkVERIFY_OK(gckOS_UnmapUserPointer( + Command->os, + userCommandBufferLogical, + 0, + commandBufferLogical)); + } +#endif + /* Unmap the command buffer pointer. */ if (commandBufferMapped) { @@ -2214,14 +2571,14 @@ OnError: gceSTATUS gckCOMMAND_Reserve( IN gckCOMMAND Command, - IN gctSIZE_T RequestedBytes, + IN gctUINT32 RequestedBytes, OUT gctPOINTER * Buffer, - OUT gctSIZE_T * BufferSize + OUT gctUINT32 * BufferSize ) { gceSTATUS status; - gctSIZE_T bytes; - gctSIZE_T requiredBytes; + gctUINT32 bytes; + gctUINT32 requiredBytes; gctUINT32 requestedAligned; gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes); @@ -2306,7 +2663,7 @@ OnError: gceSTATUS gckCOMMAND_Execute( IN gckCOMMAND Command, - IN gctSIZE_T RequestedBytes + IN gctUINT32 RequestedBytes ) { gceSTATUS status; @@ -2314,18 +2671,19 @@ gckCOMMAND_Execute( gctPHYS_ADDR waitLinkPhysical; gctUINT8_PTR waitLinkLogical; gctUINT32 waitLinkOffset; - gctSIZE_T waitLinkBytes; + gctUINT32 waitLinkBytes; gctPHYS_ADDR waitPhysical; gctPOINTER waitLogical; gctUINT32 waitOffset; - gctSIZE_T waitBytes; + gctUINT32 waitBytes; #if gcdNONPAGED_MEMORY_CACHEABLE gctPHYS_ADDR execPhysical; #endif gctPOINTER execLogical; - gctSIZE_T execBytes; + gctUINT32 execAddress; + gctUINT32 execBytes; gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes); @@ -2365,6 +2723,7 @@ gckCOMMAND_Execute( execPhysical = Command->physical; #endif execLogical = Command->logical; + execAddress = Command->address; execBytes = waitLinkOffset + waitLinkBytes; } else @@ -2375,6 +2734,7 @@ gckCOMMAND_Execute( execPhysical = (gctUINT8 *) Command->physical + Command->offset; #endif execLogical = (gctUINT8 *) Command->logical + Command->offset; + execAddress = Command->address + Command->offset; execBytes = RequestedBytes + waitLinkBytes; } @@ -2384,7 +2744,7 @@ gckCOMMAND_Execute( Command->os, Command->kernelProcessID, gcvNULL, - execPhysical, + (gctUINT32)execPhysical, execLogical, execBytes )); @@ -2394,7 +2754,7 @@ gckCOMMAND_Execute( gcmkONERROR(gckHARDWARE_Link( Command->kernel->hardware, Command->waitLogical, - execLogical, + execAddress, execBytes, &Command->waitSize )); @@ -2405,7 +2765,7 @@ gckCOMMAND_Execute( Command->os, Command->kernelProcessID, gcvNULL, - Command->waitPhysical, + (gctUINT32)Command->waitPhysical, Command->waitLogical, Command->waitSize )); @@ -2475,11 +2835,20 @@ OnError: ** ** Nothing. */ +#if gcdMULTI_GPU +gceSTATUS +gckCOMMAND_Stall( + IN gckCOMMAND Command, + IN gctBOOL FromPower, + IN gceCORE_3D_MASK ChipEnable + ) +#else gceSTATUS gckCOMMAND_Stall( IN gckCOMMAND Command, IN gctBOOL FromPower ) +#endif { #if gcdNULL_DRIVER /* Do nothing with infinite hardware. */ @@ -2516,7 +2885,11 @@ gckCOMMAND_Stall( gcmkONERROR(gckEVENT_Signal(eventObject, signal, gcvKERNEL_PIXEL)); /* Submit the event queue. */ +#if gcdMULTI_GPU + gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower, ChipEnable)); +#else gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower)); +#endif #if gcdDUMP_COMMAND gcmkPRINT("@[kernel.stall]"); @@ -2549,47 +2922,9 @@ gckCOMMAND_Stall( __FUNCTION__, __LINE__, idle ); - gcmkONERROR(gckOS_MemoryBarrier(os, gcvNULL)); - -#ifdef __QNXNTO__ - gctUINT32 reg_cmdbuf_fetch; - gctUINT32 reg_intr; - - gcmkVERIFY_OK(gckOS_ReadRegisterEx( - Command->kernel->hardware->os, Command->kernel->core, 0x0664, ®_cmdbuf_fetch - )); - - if (idle == 0x7FFFFFFE) - { - /* - * GPU is idle so there should not be pending interrupts. - * Just double check. - * - * Note that reading interrupt register clears it. - * That's why we don't read it in all cases. - */ - gcmkVERIFY_OK(gckOS_ReadRegisterEx( - Command->kernel->hardware->os, Command->kernel->core, 0x10, ®_intr - )); - - slogf( - _SLOG_SETCODE(1, 0), - _SLOG_CRITICAL, - "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)", - idle, reg_cmdbuf_fetch, reg_intr - ); - } - else - { - slogf( - _SLOG_SETCODE(1, 0), - _SLOG_CRITICAL, - "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)", - idle, reg_cmdbuf_fetch - ); - } -#endif + gcmkVERIFY_OK(gckOS_MemoryBarrier(os, gcvNULL)); #endif + /* Advance timer. */ timer += gcdGPU_ADVANCETIMER; } @@ -2599,11 +2934,7 @@ gckCOMMAND_Stall( } } - while (gcmIS_ERROR(status) -#if gcdGPU_TIMEOUT - && (timer < Command->kernel->timeOut) -#endif - ); + while (gcmIS_ERROR(status)); /* Bail out on timeout. */ if (gcmIS_ERROR(status)) @@ -2658,6 +2989,7 @@ OnError: ** Pointer to a variable that will receive the number of states ** in the context buffer. */ +#if (gcdENABLE_3D || gcdENABLE_2D) gceSTATUS gckCOMMAND_Attach( IN gckCOMMAND Command, @@ -2712,6 +3044,7 @@ OnError: gcmkFOOTER(); return status; } +#endif /******************************************************************************* ** @@ -2782,7 +3115,6 @@ OnError: return status; } -#if gcdVIRTUAL_COMMAND_BUFFER /******************************************************************************* ** ** gckCOMMAND_DumpExecutingBuffer @@ -2810,16 +3142,14 @@ gckCOMMAND_DumpExecutingBuffer( gctPOINTER entry; gckOS os = Command->os; gckKERNEL kernel = Command->kernel; -#if gcdLINK_QUEUE_SIZE gctINT pid; - gctINT i, rear; + gctUINT32 i, rear; gctUINT32 start, end; gctUINT32 dumpFront, dumpRear; gckLINKQUEUE queue = &kernel->hardware->linkQueue; gckLINKQUEUE queueMirror; gctUINT32 bytes; gckLINKDATA linkData; -#endif gcmkPRINT("**************************\n"); gcmkPRINT("**** COMMAND BUF DUMP ****\n"); @@ -2829,214 +3159,265 @@ gckCOMMAND_DumpExecutingBuffer( gcmkPRINT("DMA Address 0x%08X", gpuAddress); -#if gcdLINK_QUEUE_SIZE - /* Duplicate queue because it will be changed.*/ - gcmkONERROR(gckOS_AllocateMemory(os, - sizeof(struct _gckLINKQUEUE), - (gctPOINTER *)&queueMirror)); - - gcmkONERROR(gckOS_MemCopy(queueMirror, - queue, - sizeof(struct _gckLINKQUEUE))); - - /* If kernel command buffer link to a context buffer, then link to a user command - ** buffer, the second link will be in queue first, so we must fix this. - ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3 - ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5 - ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless. - */ - for (i = 0; i < gcdLINK_QUEUE_SIZE; i++) + if (Command->kernel->stuckDump > gcdSTUCK_DUMP_MIDDLE) { - gckLINKQUEUE_GetData(queueMirror, i, &linkData); + gcmkPRINT("Dump Level is %d", Command->kernel->stuckDump); - status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer); + /* Duplicate queue because it will be changed.*/ + gcmkONERROR(gckOS_AllocateMemory(os, + sizeof(struct _gckLINKQUEUE), + (gctPOINTER *)&queueMirror)); - if (gcmIS_ERROR(status)) - { - /* Can't find it in virtual command buffer list, ignore it. */ - continue; - } + gckOS_MemCopy(queueMirror, + queue, + sizeof(struct _gckLINKQUEUE)); - if (buffer->kernelLogical) + /* If kernel command buffer link to a context buffer, then link to a user command + ** buffer, the second link will be in queue first, so we must fix this. + ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3 + ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5 + ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless. + */ + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++) { - /* It is a context buffer. */ - if (i == 0) + gckLINKQUEUE_GetData(queueMirror, i, &linkData); + + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer); + + if (gcmIS_ERROR(status)) { - /* The real command buffer is out, so clear this slot. */ - linkData->start = 0; - linkData->end = 0; - linkData->pid = 0; + /* Can't find it in virtual command buffer list, ignore it. */ + continue; } - else + + if (buffer->kernelLogical) { - /* switch context buffer and command buffer. */ - struct _gckLINKDATA tmp = *linkData; - gckLINKDATA linkDataPrevious; - - gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious); - *linkData = *linkDataPrevious; - *linkDataPrevious = tmp; - } + /* It is a context buffer. */ + if (i == 0) + { + /* The real command buffer is out, so clear this slot. */ + linkData->start = 0; + linkData->end = 0; + linkData->pid = 0; + } + else + { + /* switch context buffer and command buffer. */ + struct _gckLINKDATA tmp = *linkData; + gckLINKDATA linkDataPrevious; + + gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious); + *linkData = *linkDataPrevious; + *linkDataPrevious = tmp; + } + } } - } - /* Clear search result. */ - dumpFront = dumpRear = gcvINFINITE; + /* Clear search result. */ + dumpFront = dumpRear = gcvINFINITE; - gcmkPRINT("Link Stack:"); + gcmkPRINT("Link Stack:"); - /* Search stuck address in link queue from rear. */ - rear = gcdLINK_QUEUE_SIZE - 1; - for (i = 0; i < gcdLINK_QUEUE_SIZE; i++) - { - gckLINKQUEUE_GetData(queueMirror, rear, &linkData); + /* Search stuck address in link queue from rear. */ + rear = gcdLINK_QUEUE_SIZE - 1; + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++) + { + gckLINKQUEUE_GetData(queueMirror, rear, &linkData); - start = linkData->start; - end = linkData->end; - pid = linkData->pid; + start = linkData->start; + end = linkData->end; + pid = linkData->pid; - if (gpuAddress >= start && gpuAddress < end) - { - /* Find latest matched command buffer. */ - gcmkPRINT(" %d, [%08X - %08X]", pid, start, end); + if (gpuAddress >= start && gpuAddress < end) + { + /* Find latest matched command buffer. */ + gcmkPRINT(" %d, [%08X - %08X]", pid, start, end); - /* Initiliaze dump information. */ - dumpFront = dumpRear = rear; - } + /* Initiliaze dump information. */ + dumpFront = dumpRear = rear; + } - /* Advance to previous one. */ - rear--; + /* Advance to previous one. */ + rear--; + + if (dumpFront != gcvINFINITE) + { + break; + } + } - if (dumpFront != gcvINFINITE) + if (dumpFront == gcvINFINITE) { - break; + /* Can't find matched record in link queue, dump kernel command buffer. */ + _DumpKernelCommandBuffer(Command); + + /* Free local copy. */ + gcmkOS_SAFE_FREE(os, queueMirror); + return gcvSTATUS_OK; } - } - if (dumpFront == gcvINFINITE) - { - /* Can't find matched record in link queue, dump kernel command buffer. */ - _DumpKernelCommandBuffer(Command); + /* Search the last context buffer linked. */ + while (rear > 0) + { + gckLINKQUEUE_GetData(queueMirror, rear, &linkData); - /* Free local copy. */ - gcmkOS_SAFE_FREE(os, queueMirror); - return gcvSTATUS_OK; - } + gcmkPRINT(" %d, [%08X - %08X]", + linkData->pid, + linkData->start, + linkData->end); - /* Search the last context buffer linked. */ - while (rear >= 0) - { - gckLINKQUEUE_GetData(queueMirror, rear, &linkData); + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer); - gcmkPRINT(" %d, [%08X - %08X]", - linkData->pid, - linkData->start, - linkData->end); + if (gcmIS_SUCCESS(status) && buffer->kernelLogical) + { + /* Find a context buffer. */ + dumpFront = rear; + break; + } - status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer); + rear--; + } - if (gcmIS_SUCCESS(status) && buffer->kernelLogical) + if (dumpFront == dumpRear) { - /* Find a context buffer. */ - dumpFront = rear; - break; + /* No context buffer is found, dump all we got.*/ + dumpFront = 0; } - rear--; - } - - /* Dump from last context buffer to last command buffer where hang happens. */ - for (i = dumpFront; i <= dumpRear; i++) - { - gckLINKQUEUE_GetData(queueMirror, i, &linkData); + /* Dump from last context buffer to last command buffer where hang happens. */ + for (i = dumpFront; i <= dumpRear; i++) + { + gckLINKQUEUE_GetData(queueMirror, i, &linkData); - /* Get gpu address of this command buffer. */ - gpuAddress = linkData->start; - bytes = linkData->end - gpuAddress; + /* Get gpu address of this command buffer. */ + gpuAddress = linkData->start; + bytes = linkData->end - gpuAddress; - /* Get the whole buffer. */ - status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer); + /* Get the whole buffer. */ + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer); - if (gcmIS_ERROR(status)) - { - gcmkPRINT("Buffer [%08X - %08X] is lost", - linkData->start, - linkData->end); - continue; - } + if (gcmIS_ERROR(status)) + { + gcmkPRINT("Buffer [%08X - %08X] is lost or not belong to current process", + linkData->start, + linkData->end); + continue; + } - /* Get kernel logical for dump. */ - if (buffer->kernelLogical) - { - /* Get kernel logical directly if it is a context buffer. */ - entry = buffer->kernelLogical; - gcmkPRINT("Context Buffer:"); - } - else - { - /* Make it accessiable by kernel if it is a user command buffer. */ - gcmkVERIFY_OK( - gckOS_CreateKernelVirtualMapping(buffer->physical, - &pageCount, - &entry)); - gcmkPRINT("User Command Buffer:"); - } + /* Get kernel logical for dump. */ + if (buffer->kernelLogical) + { + /* Get kernel logical directly if it is a context buffer. */ + entry = buffer->kernelLogical; + gcmkPRINT("Context Buffer:"); + } + else + { + /* Make it accessiable by kernel if it is a user command buffer. */ + gcmkVERIFY_OK( + gckOS_CreateKernelVirtualMapping(os, + buffer->physical, + buffer->bytes, + &entry, + &pageCount)); + gcmkPRINT("User Command Buffer:"); + } - /* Dump from the entry. */ - _DumpBuffer(entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes); + /* Dump from the entry. */ + _DumpBuffer((gctUINT8_PTR)entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes); - /* Release kernel logical address if neccessary. */ - if (!buffer->kernelLogical) - { - gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(entry)); + /* Release kernel logical address if neccessary. */ + if (!buffer->kernelLogical) + { + gcmkVERIFY_OK( + gckOS_DestroyKernelVirtualMapping(os, + buffer->physical, + buffer->bytes, + entry)); + } } - } - /* Free local copy. */ - gcmkOS_SAFE_FREE(os, queueMirror); - return gcvSTATUS_OK; -OnError: - return status; -#else - /* Without link queue information, we don't know the entry of last command - ** buffer, just dump the page where GPU stuck. */ - status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer); - - if (gcmIS_SUCCESS(status)) + /* Free local copy. */ + gcmkOS_SAFE_FREE(os, queueMirror); + return gcvSTATUS_OK; + OnError: + return status; + } + else { - gcmkVERIFY_OK( - gckOS_CreateKernelVirtualMapping(buffer->physical, &pageCount, &entry)); + gcmkPRINT("Dump Level is %d, dump memory near the stuck address", + Command->kernel->stuckDump); - if (entry) + /* Without link queue information, we don't know the entry of last command + ** buffer, just dump the page where GPU stuck. */ + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer); + + if (gcmIS_SUCCESS(status)) { - gctUINT32 offset = gpuAddress - buffer->gpuAddress; - gctPOINTER entryDump = entry; + gcmkVERIFY_OK( + gckOS_CreateKernelVirtualMapping(os, + buffer->physical, + buffer->bytes, + &entry, + &pageCount)); - /* Dump one pages. */ - gctUINT32 bytes = 4096; + if (entry) + { + gctUINT32 offset = gpuAddress - buffer->gpuAddress; + gctPOINTER entryDump = entry; + + /* Dump one pages. */ + gctUINT32 bytes = 4096; - /* Align to page. */ - offset &= 0xfffff000; + /* Align to page. */ + offset &= 0xfffff000; - /* Kernel address of page where stall point stay. */ - entryDump += offset; + /* Kernel address of page where stall point stay. */ + entryDump = (gctUINT8_PTR)entryDump + offset; - /* Align to page. */ - gpuAddress &= 0xfffff000; + /* Align to page. */ + gpuAddress &= 0xfffff000; - gcmkPRINT("User Command Buffer:\n"); - _DumpBuffer(entryDump, gpuAddress, bytes); + gcmkPRINT("User Command Buffer:\n"); + _DumpBuffer(entryDump, gpuAddress, bytes); + } + + gcmkVERIFY_OK( + gckOS_DestroyKernelVirtualMapping(os, + buffer->physical, + buffer->bytes, + entry)); + } + else + { + _DumpKernelCommandBuffer(Command); } - gcmkVERIFY_OK( - gckOS_DestroyKernelVirtualMapping(entry)); + return gcvSTATUS_OK; } - else +} + +gceSTATUS +gckCOMMAND_AddressInKernelCommandBuffer( + IN gckCOMMAND Command, + IN gctUINT32 Address, + OUT gctBOOL *In + ) +{ + gctBOOL in = gcvFALSE; + gctINT i; + + for (i = 0; i < gcdCOMMAND_QUEUES; i++) { - _DumpKernelCommandBuffer(Command); + if ((Address >= Command->queues[i].address) + && (Address < (Command->queues[i].address + Command->pageSize)) + ) + { + in = gcvTRUE; + break; + } } + *In = in; return gcvSTATUS_OK; -#endif } -#endif 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 ce2c18a102b6..0eafaf6c0e38 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -536,7 +536,7 @@ _FreeTaskContainer( gcsTASK_CONTAINER_PTR next; gcsTASK_CONTAINER_PTR merged; - gctSIZE_T mergedSize; + gctUINT32 mergedSize; /* Verify arguments. */ gcmkASSERT(Buffer != gcvNULL); @@ -605,11 +605,17 @@ _RemoveRecordFromProcesDB( IN gcsTASK_HEADER_PTR Task ) { + gceSTATUS status; gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK)); gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory; gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory; gctINT pid; gctUINT32 size; + gctUINT32 handle; + gckKERNEL kernel = Command->kernel->kernel; + gckVIDMEM_NODE unlockNode = gcvNULL; + gckVIDMEM_NODE nodeObject = gcvNULL; + gceDATABASE_TYPE type; /* Get the total size of all tasks. */ size = task->size; @@ -623,12 +629,32 @@ _RemoveRecordFromProcesDB( case gcvTASK_FREE_VIDEO_MEMORY: freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task; + handle = (gctUINT32)freeVideoMemory->node; + + status = gckVIDMEM_HANDLE_Lookup( + Command->kernel->kernel, + pid, + handle, + &nodeObject); + + if (gcmIS_ERROR(status)) + { + return status; + } + + gckVIDMEM_HANDLE_Dereference(kernel, pid, handle); + freeVideoMemory->node = gcmALL_TO_UINT32(nodeObject); + + type = gcvDB_VIDEO_MEMORY + | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT) + | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT); + /* Remove record from process db. */ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( Command->kernel->kernel, pid, - gcvDB_VIDEO_MEMORY, - gcmUINT64_TO_PTR(freeVideoMemory->node))); + type, + gcmINT2PTR(handle))); /* Advance to next task. */ size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY); @@ -645,6 +671,22 @@ _RemoveRecordFromProcesDB( gcvDB_VIDEO_MEMORY_LOCKED, gcmUINT64_TO_PTR(unlockVideoMemory->node))); + handle = (gctUINT32)unlockVideoMemory->node; + + status = gckVIDMEM_HANDLE_Lookup( + Command->kernel->kernel, + pid, + handle, + &unlockNode); + + if (gcmIS_ERROR(status)) + { + return status; + } + + gckVIDMEM_HANDLE_Dereference(kernel, pid, handle); + unlockVideoMemory->node = gcmPTR_TO_UINT64(unlockNode); + /* Advance to next task. */ size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY); Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1); @@ -685,6 +727,11 @@ _ScheduleTasks( gctINT32 interrupt; gctUINT8_PTR eventCommand; +#ifdef __QNXNTO__ + gcsTASK_PTR oldUserTask = gcvNULL; + gctPOINTER pointer; +#endif + /* Nothing to schedule? */ if (TaskTable->size == 0) { @@ -782,7 +829,21 @@ _ScheduleTasks( /* Copy tasks. */ do { - gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1); + gcsTASK_HEADER_PTR taskHeader; + +#ifdef __QNXNTO__ + oldUserTask = userTask; + + gcmkERR_BREAK(gckOS_MapUserPointer( + Command->os, + oldUserTask, + 0, + &pointer)); + + userTask = pointer; +#endif + + taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1); gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader)); @@ -799,7 +860,8 @@ _ScheduleTasks( ((gcsTASK_SIGNAL_PTR)taskHeader)->coid = TaskTable->coid; ((gcsTASK_SIGNAL_PTR)taskHeader)->rcvid = TaskTable->rcvid; } -#endif /* __QNXNTO__ */ +#endif + /* Copy the task data. */ gcmkVERIFY_OK(gckOS_MemCopy( kernelTask, taskHeader, userTask->size @@ -808,6 +870,14 @@ _ScheduleTasks( /* Advance to the next task. */ kernelTask += userTask->size; userTask = userTask->next; + +#ifdef __QNXNTO__ + gcmkERR_BREAK(gckOS_UnmapUserPointer( + Command->os, + oldUserTask, + 0, + pointer)); +#endif } while (userTask != gcvNULL); @@ -887,24 +957,31 @@ _HardwareToKernel( gceSTATUS status; gckVIDMEM memory; gctUINT32 offset; -#if gcdDYNAMIC_MAP_RESERVED_MEMORY gctUINT32 nodePhysical; -#endif + gctPOINTER *logical; + gctSIZE_T bytes; status = gcvSTATUS_OK; - /* 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 - + Node->VidMem.alignment; + if (memory->object.type == gcvOBJ_VIDMEM) + { + nodePhysical = memory->baseAddress + + (gctUINT32)Node->VidMem.offset + + Node->VidMem.alignment; + bytes = Node->VidMem.bytes; + logical = &Node->VidMem.kernelVirtual; + } + else + { + nodePhysical = Node->Virtual.physicalAddress; + bytes = Node->Virtual.bytes; + logical = &Node->Virtual.kernelVirtual; + } - if (Node->VidMem.kernelVirtual == gcvNULL) + if (*logical == gcvNULL) { - status = gckOS_MapPhysical(Os, - nodePhysical, - Node->VidMem.bytes, - (gctPOINTER *)&Node->VidMem.kernelVirtual); + status = gckOS_MapPhysical(Os, nodePhysical, bytes, logical); if (gcmkIS_ERROR(status)) { @@ -913,19 +990,7 @@ _HardwareToKernel( } 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 + *KernelPointer = (gctPOINTER)((gctUINT8_PTR)(*logical) + offset); /* Return status. */ return status; @@ -940,6 +1005,11 @@ _ConvertUserCommandBufferPointer( { gceSTATUS status, last; gcsCMDBUFFER_PTR mappedUserCommandBuffer = gcvNULL; + gckKERNEL kernel = Command->kernel->kernel; + gctUINT32 pid; + gckVIDMEM_NODE node; + + gckOS_GetProcessID(&pid); do { @@ -958,10 +1028,16 @@ _ConvertUserCommandBufferPointer( = mappedUserCommandBuffer->address - mappedUserCommandBuffer->bufferOffset; + gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup( + kernel, + pid, + gcmPTR2INT32(mappedUserCommandBuffer->node), + &node)); + /* Translate the logical address to the kernel space. */ gcmkERR_BREAK(_HardwareToKernel( Command->os, - gcmUINT64_TO_PTR(mappedUserCommandBuffer->node), + node->node, headerAddress, (gctPOINTER *) KernelCommandBuffer )); @@ -994,51 +1070,25 @@ _AllocateLinear( ) { gceSTATUS status, last; - gcuVIDMEM_NODE_PTR node = gcvNULL; - gctUINT32 address = (gctUINT32)~0; + gctPOINTER logical; + gctPHYS_ADDR physical; + gctUINT32 address; + gctSIZE_T size = Size; do { - gcePOOL pool; - gctPOINTER logical; - - /* Allocate from the system pool. */ - pool = gcvPOOL_SYSTEM; - - /* Allocate memory. */ - gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory( - Command->kernel->kernel, &pool, - Size, Alignment, - gcvSURF_TYPE_UNKNOWN, - &node - )); - - /* Do not accept virtual pools for now because we don't handle the - kernel pointer translation at the moment. */ - if (pool == gcvPOOL_VIRTUAL) - { - status = gcvSTATUS_OUT_OF_MEMORY; - break; - } - - /* Lock the command buffer. */ - gcmkERR_BREAK(gckVIDMEM_Lock( - Command->kernel->kernel, - node, - gcvFALSE, - &address - )); - - /* Translate the logical address to the kernel space. */ - gcmkERR_BREAK(_HardwareToKernel( + gcmkERR_BREAK(gckOS_AllocateContiguous( Command->os, - node, - address, + gcvFALSE, + &size, + &physical, &logical )); + gcmkERR_BREAK(gckOS_GetPhysicalAddress(Command->os, logical, &address)); + /* Set return values. */ - * Node = node; + * Node = physical; * Address = address; * Logical = logical; @@ -1048,20 +1098,10 @@ _AllocateLinear( while (gcvFALSE); /* Roll back. */ - if (node != gcvNULL) + if (physical != gcvNULL) { - /* Unlock the command buffer. */ - if (address != ~0) - { - gcmkCHECK_STATUS(gckVIDMEM_Unlock( - Command->kernel->kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL - )); - } - /* Free the command buffer. */ - gcmkCHECK_STATUS(gckVIDMEM_Free( - node - )); + gcmkCHECK_STATUS(gckOS_FreeContiguous(Command->os, physical, logical, size)); } /* Return status. */ @@ -1071,18 +1111,15 @@ _AllocateLinear( static gceSTATUS _FreeLinear( IN gckVGKERNEL Kernel, - IN gcuVIDMEM_NODE_PTR Node + IN gcuVIDMEM_NODE_PTR Node, + IN gctPOINTER Logical ) { - gceSTATUS status; + gceSTATUS status = gcvSTATUS_OK; do { - /* Unlock the linear buffer. */ - gcmkERR_BREAK(gckVIDMEM_Unlock(Kernel->kernel, Node, gcvSURF_TYPE_UNKNOWN, gcvNULL)); - - /* Free the linear buffer. */ - gcmkERR_BREAK(gckVIDMEM_Free(Node)); + gcmkERR_BREAK(gckOS_FreeContiguous(Kernel->os, Node, Logical, 1)); } while (gcvFALSE); @@ -1099,6 +1136,7 @@ _AllocateCommandBuffer( { gceSTATUS status, last; gcuVIDMEM_NODE_PTR node = gcvNULL; + gcsCMDBUFFER_PTR commandBuffer = gcvNULL; do { @@ -1106,22 +1144,21 @@ _AllocateCommandBuffer( gctUINT requestedSize; gctUINT allocationSize; gctUINT32 address = 0; - gcsCMDBUFFER_PTR commandBuffer; gctUINT8_PTR endCommand; /* Determine the aligned header size. */ alignedHeaderSize - = gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment); + = (gctUINT32)gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment); /* Align the requested size. */ requestedSize - = gcmALIGN(Size, Command->info.commandAlignment); + = (gctUINT32)gcmALIGN(Size, Command->info.commandAlignment); /* Determine the size of the buffer to allocate. */ allocationSize = alignedHeaderSize + requestedSize - + Command->info.staticTailSize; + + (gctUINT32)Command->info.staticTailSize; /* Allocate the command buffer. */ gcmkERR_BREAK(_AllocateLinear( @@ -1135,7 +1172,7 @@ _AllocateCommandBuffer( /* Initialize the structure. */ commandBuffer->completion = gcvVACANT_BUFFER; - commandBuffer->node = gcmPTR_TO_UINT64(node); + commandBuffer->node = node; commandBuffer->address = address + alignedHeaderSize; commandBuffer->bufferOffset = alignedHeaderSize; commandBuffer->size = requestedSize; @@ -1174,7 +1211,7 @@ _AllocateCommandBuffer( if (node != gcvNULL) { /* Free the command buffer. */ - gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node)); + gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node, commandBuffer)); } /* Return status. */ @@ -1190,7 +1227,7 @@ _FreeCommandBuffer( gceSTATUS status; /* Free the buffer. */ - status = _FreeLinear(Kernel, gcmUINT64_TO_PTR(CommandBuffer->node)); + status = _FreeLinear(Kernel, CommandBuffer->node, CommandBuffer); /* Return status. */ return status; @@ -1645,10 +1682,14 @@ _TaskUnlockVideoMemory( /* Unlock video memory. */ gcmkERR_BREAK(gckVIDMEM_Unlock( Command->kernel->kernel, - gcmUINT64_TO_PTR(task->node), + (gckVIDMEM_NODE)gcmUINT64_TO_PTR(task->node), gcvSURF_TYPE_UNKNOWN, gcvNULL)); + gcmkERR_BREAK(gckVIDMEM_NODE_Dereference( + Command->kernel->kernel, + gcmUINT64_TO_PTR(task->node))); + /* Update the reference counter. */ TaskHeader->container->referenceCount -= 1; @@ -1676,7 +1717,9 @@ _TaskFreeVideoMemory( = (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task; /* Free video memory. */ - gcmkERR_BREAK(gckVIDMEM_Free(gcmUINT64_TO_PTR(task->node))); + gcmkERR_BREAK(gckVIDMEM_NODE_Dereference( + Command->kernel->kernel, + gcmINT2PTR(task->node))); /* Update the reference counter. */ TaskHeader->container->referenceCount -= 1; @@ -1728,6 +1771,7 @@ _TaskUnmapUserMemory( ) { gceSTATUS status; + gctPOINTER info; do { @@ -1735,9 +1779,12 @@ _TaskUnmapUserMemory( gcsTASK_UNMAP_USER_MEMORY_PTR task = (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task; + info = gckKERNEL_QueryPointerFromName( + Command->kernel->kernel, gcmALL_TO_UINT32(task->info)); + /* Unmap the user memory. */ gcmkERR_BREAK(gckOS_UnmapUserMemory( - Command->os, gcvCORE_VG, task->memory, task->size, task->info, task->address + Command->os, gcvCORE_VG, task->memory, task->size, info, task->address )); /* Update the reference counter. */ @@ -1763,12 +1810,18 @@ _EventHandler_Block( IN gctBOOL ProcessAll ) { - gceSTATUS status, last; + gceSTATUS status = gcvSTATUS_OK, last; gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + if (TaskHeader->task == gcvNULL) + { + gcmkFOOTER(); + return gcvSTATUS_OK; + } + do { gckVGCOMMAND command; @@ -3377,6 +3430,14 @@ gckVGCOMMAND_Commit( gceSTATUS status, last; +#ifdef __QNXNTO__ + gcsVGCONTEXT_PTR userContext = gcvNULL; + gctBOOL userContextMapped = gcvFALSE; + gcsTASK_MASTER_TABLE_PTR userTaskTable = gcvNULL; + gctBOOL userTaskTableMapped = gcvFALSE; + gctPOINTER pointer = gcvNULL; +#endif + gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x", Command, Context, Queue, EntryCount, TaskTable); @@ -3386,11 +3447,6 @@ gckVGCOMMAND_Commit( gcmkVERIFY_ARGUMENT(Queue != gcvNULL); gcmkVERIFY_ARGUMENT(EntryCount > 1); -#ifdef __QNXNTO__ - TaskTable->coid = Context->coid; - TaskTable->rcvid = Context->rcvid; -#endif /* __QNXNTO__ */ - do { gctBOOL haveFETasks; @@ -3407,6 +3463,38 @@ gckVGCOMMAND_Commit( gctBOOL previousExecuted; gctUINT controlIndex; +#ifdef __QNXNTO__ + /* Map the context into the kernel space. */ + userContext = Context; + + gcmkERR_BREAK(gckOS_MapUserPointer( + Command->os, + userContext, + gcmSIZEOF(*userContext), + &pointer)); + + Context = pointer; + + userContextMapped = gcvTRUE; + + /* Map the taskTable into the kernel space. */ + userTaskTable = TaskTable; + + gcmkERR_BREAK(gckOS_MapUserPointer( + Command->os, + userTaskTable, + gcmSIZEOF(*userTaskTable), + &pointer)); + + TaskTable = pointer; + + userTaskTableMapped = gcvTRUE; + + /* Update the signal info. */ + TaskTable->coid = Context->coid; + TaskTable->rcvid = Context->rcvid; +#endif + gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState( Command->hardware, gcvPOWER_ON_AUTO )); @@ -3669,6 +3757,28 @@ gckVGCOMMAND_Commit( } while (gcvFALSE); +#ifdef __QNXNTO__ + if (userContextMapped) + { + /* Unmap the user context. */ + gcmkVERIFY_OK(gckOS_UnmapUserPointer( + Command->os, + userContext, + gcmSIZEOF(*userContext), + Context)); + } + + if (userTaskTableMapped) + { + /* Unmap the user taskTable. */ + gcmkVERIFY_OK(gckOS_UnmapUserPointer( + Command->os, + userTaskTable, + gcmSIZEOF(*userTaskTable), + TaskTable)); + } +#endif + gcmkFOOTER(); /* Return status. */ return status; 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 b181f55ec55e..021f6338d1ef 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -27,7 +27,7 @@ ***** Private fuctions ********************************************************/ #define _GetSlot(database, x) \ - (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list))) + (gctUINT32)(gcmPTR_TO_UINT64(x) % gcmCOUNTOF(database->list)) /******************************************************************************* ** gckKERNEL_NewDatabase @@ -97,7 +97,11 @@ gckKERNEL_NewDatabase( gcmSIZEOF(gcsDATABASE), &pointer)); + gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsDATABASE)); + database = pointer; + + gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->counterMutex)); } /* Insert the database into the hash. */ @@ -154,7 +158,7 @@ OnError: ** Pointer to a variable receiving the database structure pointer on ** success. */ -static gceSTATUS +gceSTATUS gckKERNEL_FindDatabase( IN gckKERNEL Kernel, IN gctUINT32 ProcessID, @@ -323,6 +327,18 @@ gckKERNEL_DeleteDatabase( /* Keep database as the last database. */ Kernel->db->lastDatabase = Database; + /* Destory handle db. */ + gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Database->handleDatabase)); + Database->handleDatabase = gcvNULL; + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Database->handleDatabaseMutex)); + Database->handleDatabaseMutex = gcvNULL; + +#if gcdPROCESS_ADDRESS_SPACE + /* Destory process MMU. */ + gcmkVERIFY_OK(gckEVENT_DestroyMmu(Kernel->eventObj, Database->mmu, gcvKERNEL_PIXEL)); + Database->mmu = gcvNULL; +#endif + /* Release the database mutex. */ gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex)); @@ -476,7 +492,6 @@ gckKERNEL_DeleteRecord( gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE)); acquired = gcvTRUE; - /* Scan the database for this record. */ for (record = Database->list[slot], previous = gcvNULL; record != gcvNULL; @@ -633,7 +648,6 @@ OnError: return status; } - /******************************************************************************* ***** Public API **************************************************************/ @@ -689,21 +703,43 @@ gckKERNEL_CreateProcessDB( database->mapUserMemory.bytes = 0; database->mapUserMemory.maxBytes = 0; database->mapUserMemory.totalBytes = 0; - database->vidMemResv.bytes = 0; - database->vidMemResv.maxBytes = 0; - database->vidMemResv.totalBytes = 0; - database->vidMemCont.bytes = 0; - database->vidMemCont.maxBytes = 0; - database->vidMemCont.totalBytes = 0; - database->vidMemVirt.bytes = 0; - database->vidMemVirt.maxBytes = 0; - database->vidMemVirt.totalBytes = 0; + database->virtualCommandBuffer.bytes = 0; + database->virtualCommandBuffer.maxBytes = 0; + database->virtualCommandBuffer.totalBytes = 0; for (i = 0; i < gcmCOUNTOF(database->list); i++) { database->list[i] = gcvNULL; } + for (i = 0; i < gcvSURF_NUM_TYPES; i++) + { + database->vidMemType[i].bytes = 0; + database->vidMemType[i].maxBytes = 0; + database->vidMemType[i].totalBytes = 0; + } + + for (i = 0; i < gcvPOOL_NUMBER_OF_POOLS; i++) + { + database->vidMemPool[i].bytes = 0; + database->vidMemPool[i].maxBytes = 0; + database->vidMemPool[i].totalBytes = 0; + } + + gcmkASSERT(database->handleDatabase == gcvNULL); + gcmkONERROR( + gckKERNEL_CreateIntegerDatabase(Kernel, &database->handleDatabase)); + + gcmkASSERT(database->handleDatabaseMutex == gcvNULL); + gcmkONERROR( + gckOS_CreateMutex(Kernel->os, &database->handleDatabaseMutex)); + +#if gcdPROCESS_ADDRESS_SPACE + gcmkASSERT(database->mmu == gcvNULL); + gcmkONERROR( + gckMMU_Construct(Kernel, gcdMMU_SIZE, &database->mmu)); +#endif + #if gcdSECURE_USER { gctINT slot; @@ -807,6 +843,8 @@ gckKERNEL_AddProcessDB( gcsDATABASE_PTR database; gcsDATABASE_RECORD_PTR record = gcvNULL; gcsDATABASE_COUNTERS * count; + gctUINT32 vidMemType; + gcePOOL vidMemPool; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x " "Physical=0x%x Size=%lu", @@ -815,6 +853,12 @@ gckKERNEL_AddProcessDB( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + /* Decode type. */ + vidMemType = (Type & gcdDB_VIDEO_MEMORY_TYPE_MASK) >> gcdDB_VIDEO_MEMORY_TYPE_SHIFT; + vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT; + + Type &= gcdDATABASE_TYPE_MASK; + /* Special case the idle record. */ if (Type == gcvDB_IDLE) { @@ -914,16 +958,8 @@ gckKERNEL_AddProcessDB( count = &database->mapUserMemory; break; - case gcvDB_VIDEO_MEMORY_RESERVED: - count = &database->vidMemResv; - break; - - case gcvDB_VIDEO_MEMORY_CONTIGUOUS: - count = &database->vidMemCont; - break; - - case gcvDB_VIDEO_MEMORY_VIRTUAL: - count = &database->vidMemVirt; + case gcvDB_COMMAND_BUFFER: + count = &database->virtualCommandBuffer; break; default: @@ -931,6 +967,8 @@ gckKERNEL_AddProcessDB( break; } + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE)); + if (count != gcvNULL) { /* Adjust counters. */ @@ -943,6 +981,33 @@ gckKERNEL_AddProcessDB( } } + if (Type == gcvDB_VIDEO_MEMORY) + { + count = &database->vidMemType[vidMemType]; + + /* Adjust counters. */ + count->totalBytes += Size; + count->bytes += Size; + + if (count->bytes > count->maxBytes) + { + count->maxBytes = count->bytes; + } + + count = &database->vidMemPool[vidMemPool]; + + /* Adjust counters. */ + count->totalBytes += Size; + count->bytes += Size; + + if (count->bytes > count->maxBytes) + { + count->maxBytes = count->bytes; + } + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex)); + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -987,6 +1052,8 @@ gckKERNEL_RemoveProcessDB( gceSTATUS status; gcsDATABASE_PTR database; gctSIZE_T bytes = 0; + gctUINT32 vidMemType; + gcePOOL vidMempool; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x", Kernel, ProcessID, Type, Pointer); @@ -995,6 +1062,12 @@ gckKERNEL_RemoveProcessDB( gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); gcmkVERIFY_ARGUMENT(Pointer != gcvNULL); + /* Decode type. */ + vidMemType = (Type & gcdDB_VIDEO_MEMORY_TYPE_MASK) >> gcdDB_VIDEO_MEMORY_TYPE_SHIFT; + vidMempool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT; + + Type &= gcdDATABASE_TYPE_MASK; + /* Find the database. */ gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database)); @@ -1002,11 +1075,15 @@ gckKERNEL_RemoveProcessDB( gcmkONERROR( gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes)); + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE)); + /* Update counters. */ switch (Type) { case gcvDB_VIDEO_MEMORY: database->vidMem.bytes -= bytes; + database->vidMemType[vidMemType].bytes -= bytes; + database->vidMemPool[vidMempool].bytes -= bytes; break; case gcvDB_NON_PAGED: @@ -1025,22 +1102,16 @@ gckKERNEL_RemoveProcessDB( database->mapUserMemory.bytes -= bytes; break; - case gcvDB_VIDEO_MEMORY_RESERVED: - database->vidMemResv.bytes -= bytes; - break; - - case gcvDB_VIDEO_MEMORY_CONTIGUOUS: - database->vidMemCont.bytes -= bytes; - break; - - case gcvDB_VIDEO_MEMORY_VIRTUAL: - database->vidMemVirt.bytes -= bytes; + case gcvDB_COMMAND_BUFFER: + database->virtualCommandBuffer.bytes -= bytes; break; default: break; } + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex)); + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -1140,10 +1211,11 @@ gckKERNEL_DestroyProcessDB( gceSTATUS status; gcsDATABASE_PTR database; gcsDATABASE_RECORD_PTR record, next; - gctBOOL asynchronous; + gctBOOL asynchronous = gcvTRUE; + gckVIDMEM_NODE nodeObject; gctPHYS_ADDR physical; - gcuVIDMEM_NODE_PTR node; gckKERNEL kernel = Kernel; + gctUINT32 handle; gctUINT32 i; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID); @@ -1198,8 +1270,18 @@ gckKERNEL_DestroyProcessDB( switch (record->type) { case gcvDB_VIDEO_MEMORY: + gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(record->kernel, + ProcessID, + gcmPTR2INT32(record->data), + &nodeObject)); + /* Free the video memory. */ - status = gckVIDMEM_Free(gcmUINT64_TO_PTR(record->data)); + gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel, + ProcessID, + gcmPTR2INT32(record->data))); + + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel, + nodeObject)); gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, "DB: VIDEO_MEMORY 0x%x (status=%d)", @@ -1215,10 +1297,11 @@ gckKERNEL_DestroyProcessDB( record->data); /* Free the non paged memory. */ - status = gckOS_FreeNonPagedMemory(Kernel->os, - record->bytes, - physical, - record->data); + status = gckEVENT_FreeNonPagedMemory(Kernel->eventObj, + record->bytes, + physical, + record->data, + gcvKERNEL_PIXEL); gcmRELEASE_NAME(record->physical); gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, @@ -1226,7 +1309,6 @@ gckKERNEL_DestroyProcessDB( record->data, record->bytes, status); break; -#if gcdVIRTUAL_COMMAND_BUFFER case gcvDB_COMMAND_BUFFER: /* Free the command buffer. */ status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj, @@ -1240,7 +1322,6 @@ gckKERNEL_DestroyProcessDB( "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)", record->data, record->bytes, status); break; -#endif case gcvDB_CONTIGUOUS: physical = gcmNAME_TO_PTR(record->physical); @@ -1269,7 +1350,7 @@ gckKERNEL_DestroyProcessDB( #else /* Free the user signal. */ status = gckOS_DestroyUserSignal(Kernel->os, - gcmPTR2INT(record->data)); + gcmPTR2INT32(record->data)); #endif /* USE_NEW_LINUX_SIGNAL */ gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, @@ -1278,25 +1359,62 @@ gckKERNEL_DestroyProcessDB( break; case gcvDB_VIDEO_MEMORY_LOCKED: - node = gcmUINT64_TO_PTR(record->data); + handle = gcmPTR2INT32(record->data); + + gcmkERR_BREAK(gckVIDMEM_HANDLE_Lookup(record->kernel, + ProcessID, + handle, + &nodeObject)); + /* Unlock what we still locked */ status = gckVIDMEM_Unlock(record->kernel, - node, - gcvSURF_TYPE_UNKNOWN, + nodeObject, + nodeObject->type, &asynchronous); - if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous)) +#if gcdENABLE_VG + if (record->kernel->core == gcvCORE_VG) + { + if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous)) + { + /* TODO: we maybe need to schedule a event here */ + status = gckVIDMEM_Unlock(record->kernel, + nodeObject, + nodeObject->type, + gcvNULL); + } + + gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel, + ProcessID, + handle)); + + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel, + nodeObject)); + } + else +#endif { - /* TODO: we maybe need to schedule a event here */ - status = gckVIDMEM_Unlock(record->kernel, - node, - gcvSURF_TYPE_UNKNOWN, - gcvNULL); + gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel, + ProcessID, + handle)); + + if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous)) + { + status = gckEVENT_Unlock(record->kernel->eventObj, + gcvKERNEL_PIXEL, + nodeObject, + nodeObject->type); + } + else + { + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel, + nodeObject)); + } } gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, "DB: VIDEO_MEMORY_LOCKED 0x%x (status=%d)", - node, status); + record->data, status); break; case gcvDB_CONTEXT: @@ -1318,7 +1436,7 @@ gckKERNEL_DestroyProcessDB( gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, "DB: MAP MEMORY %d (status=%d)", - gcmPTR2INT(record->data), status); + gcmPTR2INT32(record->data), status); break; case gcvDB_MAP_USER_MEMORY: @@ -1333,11 +1451,7 @@ gckKERNEL_DestroyProcessDB( gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE, "DB: MAP USER MEMORY %d (status=%d)", - gcmPTR2INT(record->data), status); - break; - - case gcvDB_SHARED_INFO: - status = gckOS_FreeMemory(Kernel->os, record->physical); + gcmPTR2INT32(record->data), status); break; #if gcdANDROID_NATIVE_FENCE_SYNC @@ -1352,10 +1466,15 @@ gckKERNEL_DestroyProcessDB( break; #endif - case gcvDB_VIDEO_MEMORY_RESERVED: - case gcvDB_VIDEO_MEMORY_CONTIGUOUS: - case gcvDB_VIDEO_MEMORY_VIRTUAL: - break;//Nothing to do + 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, @@ -1424,6 +1543,7 @@ gckKERNEL_QueryProcessDB( { gceSTATUS status; gcsDATABASE_PTR database; + gcePOOL vidMemPool; gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x", Kernel, ProcessID, Type, Info); @@ -1432,69 +1552,110 @@ gckKERNEL_QueryProcessDB( gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); gcmkVERIFY_ARGUMENT(Info != gcvNULL); - /* Find the database. */ - gcmkONERROR( - gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database)); + /* Deocde pool. */ + vidMemPool = (Type & gcdDB_VIDEO_MEMORY_POOL_MASK) >> gcdDB_VIDEO_MEMORY_POOL_SHIFT; - /* Get pointer to counters. */ - switch (Type) + Type &= gcdDATABASE_TYPE_MASK; + + /* Find the database. */ + if(Type != gcvDB_IDLE) { - case gcvDB_VIDEO_MEMORY: - gckOS_MemCopy(&Info->counters, - &database->vidMem, - gcmSIZEOF(database->vidMem)); - break; + gcmkONERROR( + gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database)); - case gcvDB_NON_PAGED: - gckOS_MemCopy(&Info->counters, - &database->nonPaged, - gcmSIZEOF(database->vidMem)); - break; + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, database->counterMutex, gcvINFINITE)); - case gcvDB_CONTIGUOUS: - gckOS_MemCopy(&Info->counters, - &database->contiguous, - gcmSIZEOF(database->vidMem)); - break; + /* Get pointer to counters. */ + switch (Type) + { + case gcvDB_VIDEO_MEMORY: + if (vidMemPool != gcvPOOL_UNKNOWN) + { + gckOS_MemCopy(&Info->counters, + &database->vidMemPool[vidMemPool], + gcmSIZEOF(database->vidMemPool[vidMemPool])); + } + else + { + gckOS_MemCopy(&Info->counters, + &database->vidMem, + gcmSIZEOF(database->vidMem)); + } + break; - case gcvDB_IDLE: + case gcvDB_NON_PAGED: + gckOS_MemCopy(&Info->counters, + &database->nonPaged, + gcmSIZEOF(database->vidMem)); + break; + + case gcvDB_CONTIGUOUS: + gckOS_MemCopy(&Info->counters, + &database->contiguous, + gcmSIZEOF(database->vidMem)); + break; + + case gcvDB_MAP_MEMORY: + gckOS_MemCopy(&Info->counters, + &database->mapMemory, + gcmSIZEOF(database->mapMemory)); + break; + + case gcvDB_MAP_USER_MEMORY: + gckOS_MemCopy(&Info->counters, + &database->mapUserMemory, + gcmSIZEOF(database->mapUserMemory)); + break; + + case gcvDB_COMMAND_BUFFER: + gckOS_MemCopy(&Info->counters, + &database->virtualCommandBuffer, + gcmSIZEOF(database->virtualCommandBuffer)); + break; + + default: + break; + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, database->counterMutex)); + } + else + { Info->time = Kernel->db->idleTime; Kernel->db->idleTime = 0; - break; + } + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - case gcvDB_MAP_MEMORY: - gckOS_MemCopy(&Info->counters, - &database->mapMemory, - gcmSIZEOF(database->mapMemory)); - break; +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} - case gcvDB_MAP_USER_MEMORY: - gckOS_MemCopy(&Info->counters, - &database->mapUserMemory, - gcmSIZEOF(database->mapUserMemory)); - break; +gceSTATUS +gckKERNEL_FindHandleDatbase( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + OUT gctPOINTER * HandleDatabase, + OUT gctPOINTER * HandleDatabaseMutex + ) +{ + gceSTATUS status; + gcsDATABASE_PTR database; - case gcvDB_VIDEO_MEMORY_RESERVED: - gckOS_MemCopy(&Info->counters, - &database->vidMemResv, - gcmSIZEOF(database->vidMemResv)); - break; + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", + Kernel, ProcessID); - case gcvDB_VIDEO_MEMORY_CONTIGUOUS: - gckOS_MemCopy(&Info->counters, - &database->vidMemCont, - gcmSIZEOF(database->vidMemCont)); - break; + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - case gcvDB_VIDEO_MEMORY_VIRTUAL: - gckOS_MemCopy(&Info->counters, - &database->vidMemVirt, - gcmSIZEOF(database->vidMemVirt)); - break; + /* Find the database. */ + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database)); - default: - break; - } + *HandleDatabase = database->handleDatabase; + *HandleDatabaseMutex = database->handleDatabaseMutex; /* Success. */ gcmkFOOTER_NO(); @@ -1506,6 +1667,30 @@ OnError: return status; } +#if gcdPROCESS_ADDRESS_SPACE +gceSTATUS +gckKERNEL_GetProcessMMU( + IN gckKERNEL Kernel, + OUT gckMMU * Mmu + ) +{ + gceSTATUS status; + gcsDATABASE_PTR database; + gctUINT32 processID; + + gcmkONERROR(gckOS_GetProcessID(&processID)); + + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, processID, gcvFALSE, &database)); + + *Mmu = database->mmu; + + return gcvSTATUS_OK; + +OnError: + return status; +} +#endif + #if gcdSECURE_USER /******************************************************************************* ** gckKERNEL_GetProcessDBCache @@ -1602,3 +1787,75 @@ gckKERNEL_DumpProcessDB( gcmkFOOTER_NO(); return gcvSTATUS_OK; } + +void +_DumpCounter( + IN gcsDATABASE_COUNTERS * Counter, + IN gctCONST_STRING Name + ) +{ + gcmkPRINT("%s:", Name); + gcmkPRINT(" Currently allocated : %10lld", Counter->bytes); + gcmkPRINT(" Maximum allocated : %10lld", Counter->maxBytes); + gcmkPRINT(" Total allocated : %10lld", Counter->totalBytes); +} + +gceSTATUS +gckKERNEL_DumpVidMemUsage( + IN gckKERNEL Kernel, + IN gctINT32 ProcessID + ) +{ + gceSTATUS status; + gcsDATABASE_PTR database; + gcsDATABASE_COUNTERS * counter; + gctUINT32 i = 0; + + static gctCONST_STRING surfaceTypes[] = { + "UNKNOWN", + "INDEX", + "VERTEX", + "TEXTURE", + "RENDER_TARGET", + "DEPTH", + "BITMAP", + "TILE_STATUS", + "IMAGE", + "MASK", + "SCISSOR", + "HIERARCHICAL_DEPTH", + }; + + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", + Kernel, ProcessID); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + + /* Find the database. */ + gcmkONERROR( + gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database)); + + gcmkPRINT("VidMem Usage (Process %d):", ProcessID); + + /* Get pointer to counters. */ + counter = &database->vidMem; + + _DumpCounter(counter, "Total Video Memory"); + + for (i = 0; i < gcvSURF_NUM_TYPES; i++) + { + counter = &database->vidMemType[i]; + + _DumpCounter(counter, surfaceTypes[i]); + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c index a36de6ec7dc0..b2b078e6c66c 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -138,7 +138,7 @@ static gctUINT32 _debugZones = gcvZONE_NONE; #define gcmPTRALIGNMENT(Pointer, Alignemnt) \ ( \ - gcmALIGN(gcmPTR2INT(Pointer), Alignemnt) - gcmPTR2INT(Pointer) \ + gcmALIGN(gcmPTR2INT32(Pointer), Alignemnt) - gcmPTR2INT32(Pointer) \ ) #if gcdALIGNBYSIZE @@ -146,7 +146,7 @@ static gctUINT32 _debugZones = gcvZONE_NONE; (((Offset) & ((Alignment) - 1)) == 0) # define gcmkALIGNPTR(Type, Pointer, Alignment) \ - Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT(Pointer), Alignment)) + Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT32(Pointer), Alignment)) #else # define gcmISALIGNED(Offset, Alignment) \ gcvTRUE @@ -502,7 +502,7 @@ _DirectPrint( gctARGUMENTS arguments; gcmkARGUMENTS_START(arguments, Message); - len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, arguments); + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, &arguments); gcmkARGUMENTS_END(arguments); buffer[len] = '\0'; @@ -1711,7 +1711,7 @@ _Print( IN gctUINT ArgumentSize, IN gctBOOL CopyMessage, IN gctCONST_STRING Message, - IN gctARGUMENTS Arguments + IN gctARGUMENTS * Arguments ) { gcsBUFFERED_OUTPUT_PTR outputBuffer; @@ -1759,14 +1759,14 @@ _Print( { gcdOUTPUTCOPY( outputBuffer, outputBuffer->indent, - Message, ArgumentSize, * (gctPOINTER *) &Arguments + Message, ArgumentSize, (gctPOINTER) Arguments ); } else { gcdOUTPUTSTRING( outputBuffer, outputBuffer->indent, - Message, ArgumentSize, * (gctPOINTER *) &Arguments + Message, ArgumentSize, ((gctPOINTER) Arguments) ); } @@ -1794,7 +1794,7 @@ extern volatile unsigned g_nQnxInIsrs; { \ gctARGUMENTS __arguments__; \ gcmkARGUMENTS_START(__arguments__, Message); \ - _Print(ArgumentSize, CopyMessage, Message, __arguments__); \ + _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \ gcmkARGUMENTS_END(__arguments__); \ } \ atomic_sub(&g_nQnxInIsrs, 1); \ @@ -1806,7 +1806,7 @@ extern volatile unsigned g_nQnxInIsrs; { \ gctARGUMENTS __arguments__; \ gcmkARGUMENTS_START(__arguments__, Message); \ - _Print(ArgumentSize, CopyMessage, Message, __arguments__); \ + _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \ gcmkARGUMENTS_END(__arguments__); \ } @@ -1940,10 +1940,10 @@ gckOS_DumpBuffer( IN gctBOOL CopyMessage ) { - gctUINT32 address; - gcsBUFFERED_OUTPUT_PTR outputBuffer; + gctUINT32 address = 0; + gcsBUFFERED_OUTPUT_PTR outputBuffer = gcvNULL; static gctBOOL userLocked; - gctCHAR *buffer = (gctCHAR*)Buffer; + gctCHAR *buffer = (gctCHAR*)Buffer; gcmkDECLARE_LOCK(lockHandle); @@ -2441,119 +2441,345 @@ gckOS_DebugFlush( } gctCONST_STRING gckOS_DebugStatus2Name( - gceSTATUS status - ) + gceSTATUS status + ) { - switch (status) - { - case gcvSTATUS_OK: - return "gcvSTATUS_OK"; - case gcvSTATUS_TRUE: - return "gcvSTATUS_TRUE"; - case gcvSTATUS_NO_MORE_DATA: - return "gcvSTATUS_NO_MORE_DATA"; - case gcvSTATUS_CACHED: - return "gcvSTATUS_CACHED"; - case gcvSTATUS_MIPMAP_TOO_LARGE: - return "gcvSTATUS_MIPMAP_TOO_LARGE"; - case gcvSTATUS_NAME_NOT_FOUND: - return "gcvSTATUS_NAME_NOT_FOUND"; - case gcvSTATUS_NOT_OUR_INTERRUPT: - return "gcvSTATUS_NOT_OUR_INTERRUPT"; - case gcvSTATUS_MISMATCH: - return "gcvSTATUS_MISMATCH"; - case gcvSTATUS_MIPMAP_TOO_SMALL: - return "gcvSTATUS_MIPMAP_TOO_SMALL"; - case gcvSTATUS_LARGER: - return "gcvSTATUS_LARGER"; - case gcvSTATUS_SMALLER: - return "gcvSTATUS_SMALLER"; - case gcvSTATUS_CHIP_NOT_READY: - return "gcvSTATUS_CHIP_NOT_READY"; - case gcvSTATUS_NEED_CONVERSION: - return "gcvSTATUS_NEED_CONVERSION"; - case gcvSTATUS_SKIP: - return "gcvSTATUS_SKIP"; - case gcvSTATUS_DATA_TOO_LARGE: - return "gcvSTATUS_DATA_TOO_LARGE"; - case gcvSTATUS_INVALID_CONFIG: - return "gcvSTATUS_INVALID_CONFIG"; - case gcvSTATUS_CHANGED: - return "gcvSTATUS_CHANGED"; - case gcvSTATUS_NOT_SUPPORT_DITHER: - return "gcvSTATUS_NOT_SUPPORT_DITHER"; - - case gcvSTATUS_INVALID_ARGUMENT: - return "gcvSTATUS_INVALID_ARGUMENT"; - case gcvSTATUS_INVALID_OBJECT: - return "gcvSTATUS_INVALID_OBJECT"; - case gcvSTATUS_OUT_OF_MEMORY: - return "gcvSTATUS_OUT_OF_MEMORY"; - case gcvSTATUS_MEMORY_LOCKED: - return "gcvSTATUS_MEMORY_LOCKED"; - case gcvSTATUS_MEMORY_UNLOCKED: - return "gcvSTATUS_MEMORY_UNLOCKED"; - case gcvSTATUS_HEAP_CORRUPTED: - return "gcvSTATUS_HEAP_CORRUPTED"; - case gcvSTATUS_GENERIC_IO: - return "gcvSTATUS_GENERIC_IO"; - case gcvSTATUS_INVALID_ADDRESS: - return "gcvSTATUS_INVALID_ADDRESS"; - case gcvSTATUS_CONTEXT_LOSSED: - return "gcvSTATUS_CONTEXT_LOSSED"; - case gcvSTATUS_TOO_COMPLEX: - return "gcvSTATUS_TOO_COMPLEX"; - case gcvSTATUS_BUFFER_TOO_SMALL: - return "gcvSTATUS_BUFFER_TOO_SMALL"; - case gcvSTATUS_INTERFACE_ERROR: - return "gcvSTATUS_INTERFACE_ERROR"; - case gcvSTATUS_NOT_SUPPORTED: - return "gcvSTATUS_NOT_SUPPORTED"; - case gcvSTATUS_MORE_DATA: - return "gcvSTATUS_MORE_DATA"; - case gcvSTATUS_TIMEOUT: - return "gcvSTATUS_TIMEOUT"; - case gcvSTATUS_OUT_OF_RESOURCES: - return "gcvSTATUS_OUT_OF_RESOURCES"; - case gcvSTATUS_INVALID_DATA: - return "gcvSTATUS_INVALID_DATA"; - case gcvSTATUS_INVALID_MIPMAP: - return "gcvSTATUS_INVALID_MIPMAP"; - case gcvSTATUS_NOT_FOUND: - return "gcvSTATUS_NOT_FOUND"; - case gcvSTATUS_NOT_ALIGNED: - return "gcvSTATUS_NOT_ALIGNED"; - case gcvSTATUS_INVALID_REQUEST: - return "gcvSTATUS_INVALID_REQUEST"; - case gcvSTATUS_GPU_NOT_RESPONDING: - return "gcvSTATUS_GPU_NOT_RESPONDING"; - case gcvSTATUS_TIMER_OVERFLOW: - return "gcvSTATUS_TIMER_OVERFLOW"; - case gcvSTATUS_VERSION_MISMATCH: - return "gcvSTATUS_VERSION_MISMATCH"; - case gcvSTATUS_LOCKED: - return "gcvSTATUS_LOCKED"; + switch (status) + { + case gcvSTATUS_OK: + return "gcvSTATUS_OK"; + case gcvSTATUS_TRUE: + return "gcvSTATUS_TRUE"; + case gcvSTATUS_NO_MORE_DATA: + return "gcvSTATUS_NO_MORE_DATA"; + case gcvSTATUS_CACHED: + return "gcvSTATUS_CACHED"; + case gcvSTATUS_MIPMAP_TOO_LARGE: + return "gcvSTATUS_MIPMAP_TOO_LARGE"; + case gcvSTATUS_NAME_NOT_FOUND: + return "gcvSTATUS_NAME_NOT_FOUND"; + case gcvSTATUS_NOT_OUR_INTERRUPT: + return "gcvSTATUS_NOT_OUR_INTERRUPT"; + case gcvSTATUS_MISMATCH: + return "gcvSTATUS_MISMATCH"; + case gcvSTATUS_MIPMAP_TOO_SMALL: + return "gcvSTATUS_MIPMAP_TOO_SMALL"; + case gcvSTATUS_LARGER: + return "gcvSTATUS_LARGER"; + case gcvSTATUS_SMALLER: + return "gcvSTATUS_SMALLER"; + case gcvSTATUS_CHIP_NOT_READY: + return "gcvSTATUS_CHIP_NOT_READY"; + case gcvSTATUS_NEED_CONVERSION: + return "gcvSTATUS_NEED_CONVERSION"; + case gcvSTATUS_SKIP: + return "gcvSTATUS_SKIP"; + case gcvSTATUS_DATA_TOO_LARGE: + return "gcvSTATUS_DATA_TOO_LARGE"; + case gcvSTATUS_INVALID_CONFIG: + return "gcvSTATUS_INVALID_CONFIG"; + case gcvSTATUS_CHANGED: + return "gcvSTATUS_CHANGED"; + case gcvSTATUS_NOT_SUPPORT_DITHER: + return "gcvSTATUS_NOT_SUPPORT_DITHER"; + + case gcvSTATUS_INVALID_ARGUMENT: + return "gcvSTATUS_INVALID_ARGUMENT"; + case gcvSTATUS_INVALID_OBJECT: + return "gcvSTATUS_INVALID_OBJECT"; + case gcvSTATUS_OUT_OF_MEMORY: + return "gcvSTATUS_OUT_OF_MEMORY"; + case gcvSTATUS_MEMORY_LOCKED: + return "gcvSTATUS_MEMORY_LOCKED"; + case gcvSTATUS_MEMORY_UNLOCKED: + return "gcvSTATUS_MEMORY_UNLOCKED"; + case gcvSTATUS_HEAP_CORRUPTED: + return "gcvSTATUS_HEAP_CORRUPTED"; + case gcvSTATUS_GENERIC_IO: + return "gcvSTATUS_GENERIC_IO"; + case gcvSTATUS_INVALID_ADDRESS: + return "gcvSTATUS_INVALID_ADDRESS"; + case gcvSTATUS_CONTEXT_LOSSED: + return "gcvSTATUS_CONTEXT_LOSSED"; + case gcvSTATUS_TOO_COMPLEX: + return "gcvSTATUS_TOO_COMPLEX"; + case gcvSTATUS_BUFFER_TOO_SMALL: + return "gcvSTATUS_BUFFER_TOO_SMALL"; + case gcvSTATUS_INTERFACE_ERROR: + return "gcvSTATUS_INTERFACE_ERROR"; + case gcvSTATUS_NOT_SUPPORTED: + return "gcvSTATUS_NOT_SUPPORTED"; + case gcvSTATUS_MORE_DATA: + return "gcvSTATUS_MORE_DATA"; + case gcvSTATUS_TIMEOUT: + return "gcvSTATUS_TIMEOUT"; + case gcvSTATUS_OUT_OF_RESOURCES: + return "gcvSTATUS_OUT_OF_RESOURCES"; + case gcvSTATUS_INVALID_DATA: + return "gcvSTATUS_INVALID_DATA"; + case gcvSTATUS_INVALID_MIPMAP: + return "gcvSTATUS_INVALID_MIPMAP"; + case gcvSTATUS_NOT_FOUND: + return "gcvSTATUS_NOT_FOUND"; + case gcvSTATUS_NOT_ALIGNED: + return "gcvSTATUS_NOT_ALIGNED"; + case gcvSTATUS_INVALID_REQUEST: + return "gcvSTATUS_INVALID_REQUEST"; + case gcvSTATUS_GPU_NOT_RESPONDING: + return "gcvSTATUS_GPU_NOT_RESPONDING"; + case gcvSTATUS_TIMER_OVERFLOW: + return "gcvSTATUS_TIMER_OVERFLOW"; + case gcvSTATUS_VERSION_MISMATCH: + return "gcvSTATUS_VERSION_MISMATCH"; + case gcvSTATUS_LOCKED: + return "gcvSTATUS_LOCKED"; + case gcvSTATUS_INTERRUPTED: + return "gcvSTATUS_INTERRUPTED"; + case gcvSTATUS_DEVICE: + return "gcvSTATUS_DEVICE"; + case gcvSTATUS_NOT_MULTI_PIPE_ALIGNED: + return "gcvSTATUS_NOT_MULTI_PIPE_ALIGNED"; /* Linker errors. */ - case gcvSTATUS_GLOBAL_TYPE_MISMATCH: - return "gcvSTATUS_GLOBAL_TYPE_MISMATCH"; - case gcvSTATUS_TOO_MANY_ATTRIBUTES: - return "gcvSTATUS_TOO_MANY_ATTRIBUTES"; - case gcvSTATUS_TOO_MANY_UNIFORMS: - return "gcvSTATUS_TOO_MANY_UNIFORMS"; - case gcvSTATUS_TOO_MANY_VARYINGS: - return "gcvSTATUS_TOO_MANY_VARYINGS"; - case gcvSTATUS_UNDECLARED_VARYING: - return "gcvSTATUS_UNDECLARED_VARYING"; - case gcvSTATUS_VARYING_TYPE_MISMATCH: - return "gcvSTATUS_VARYING_TYPE_MISMATCH"; - case gcvSTATUS_MISSING_MAIN: - return "gcvSTATUS_MISSING_MAIN"; - case gcvSTATUS_NAME_MISMATCH: - return "gcvSTATUS_NAME_MISMATCH"; - case gcvSTATUS_INVALID_INDEX: - return "gcvSTATUS_INVALID_INDEX"; - default: - return "nil"; - } + case gcvSTATUS_GLOBAL_TYPE_MISMATCH: + return "gcvSTATUS_GLOBAL_TYPE_MISMATCH"; + case gcvSTATUS_TOO_MANY_ATTRIBUTES: + return "gcvSTATUS_TOO_MANY_ATTRIBUTES"; + case gcvSTATUS_TOO_MANY_UNIFORMS: + return "gcvSTATUS_TOO_MANY_UNIFORMS"; + case gcvSTATUS_TOO_MANY_SAMPLER: + return "gcvSTATUS_TOO_MANY_SAMPLER"; + case gcvSTATUS_TOO_MANY_VARYINGS: + return "gcvSTATUS_TOO_MANY_VARYINGS"; + case gcvSTATUS_UNDECLARED_VARYING: + return "gcvSTATUS_UNDECLARED_VARYING"; + case gcvSTATUS_VARYING_TYPE_MISMATCH: + return "gcvSTATUS_VARYING_TYPE_MISMATCH"; + case gcvSTATUS_MISSING_MAIN: + return "gcvSTATUS_MISSING_MAIN"; + case gcvSTATUS_NAME_MISMATCH: + return "gcvSTATUS_NAME_MISMATCH"; + case gcvSTATUS_INVALID_INDEX: + return "gcvSTATUS_INVALID_INDEX"; + case gcvSTATUS_UNIFORM_MISMATCH: + return "gcvSTATUS_UNIFORM_MISMATCH"; + case gcvSTATUS_UNSAT_LIB_SYMBOL: + return "gcvSTATUS_UNSAT_LIB_SYMBOL"; + case gcvSTATUS_TOO_MANY_SHADERS: + return "gcvSTATUS_TOO_MANY_SHADERS"; + case gcvSTATUS_LINK_INVALID_SHADERS: + return "gcvSTATUS_LINK_INVALID_SHADERS"; + case gcvSTATUS_CS_NO_WORKGROUP_SIZE: + return "gcvSTATUS_CS_NO_WORKGROUP_SIZE"; + case gcvSTATUS_LINK_LIB_ERROR: + return "gcvSTATUS_LINK_LIB_ERROR"; + case gcvSTATUS_SHADER_VERSION_MISMATCH: + return "gcvSTATUS_SHADER_VERSION_MISMATCH"; + case gcvSTATUS_TOO_MANY_INSTRUCTION: + return "gcvSTATUS_TOO_MANY_INSTRUCTION"; + case gcvSTATUS_SSBO_MISMATCH: + return "gcvSTATUS_SSBO_MISMATCH"; + case gcvSTATUS_TOO_MANY_OUTPUT: + return "gcvSTATUS_TOO_MANY_OUTPUT"; + case gcvSTATUS_TOO_MANY_INPUT: + return "gcvSTATUS_TOO_MANY_INPUT"; + case gcvSTATUS_NOT_SUPPORT_CL: + return "gcvSTATUS_NOT_SUPPORT_CL"; + case gcvSTATUS_NOT_SUPPORT_INTEGER: + return "gcvSTATUS_NOT_SUPPORT_INTEGER"; + + /* Compiler errors. */ + case gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR: + return "gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR"; + case gcvSTATUS_COMPILER_FE_PARSER_ERROR: + return "gcvSTATUS_COMPILER_FE_PARSER_ERROR"; + + default: + return "nil"; + } } + +/******************************************************************************* +***** Binary Trace ************************************************************* +*******************************************************************************/ + +/******************************************************************************* +** _VerifyMessage +** +** Verify a binary trace message, decode it to human readable string and print +** it. +** +** ARGUMENTS: +** +** gctCONST_STRING Buffer +** Pointer to buffer to store. +** +** gctSIZE_T Bytes +** Buffer length. +*/ +void +_VerifyMessage( + IN gctCONST_STRING Buffer, + IN gctSIZE_T Bytes + ) +{ + char arguments[150] = {0}; + char format[100] = {0}; + + gctSTRING function; + gctPOINTER args; + gctUINT32 numArguments; + int i = 0; + gctUINT32 functionBytes; + + gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)Buffer; + + /* Check signature. */ + if (message->signature != 0x7FFFFFFF) + { + gcmkPRINT("Signature error"); + return; + } + + /* Get function name. */ + function = (gctSTRING)&message->payload; + functionBytes = (gctUINT32)strlen(function) + 1; + + /* Get arguments number. */ + numArguments = message->numArguments; + + /* Get arguments . */ + args = function + functionBytes; + + /* Prepare format string. */ + while (numArguments--) + { + format[i++] = '%'; + format[i++] = 'x'; + format[i++] = ' '; + } + + format[i] = '\0'; + + if (numArguments) + { + gcmkVSPRINTF(arguments, 150, format, (gctARGUMENTS *) &args); + } + + gcmkPRINT("[%d](%d): %s(%d) %s", + message->pid, + message->tid, + function, + message->line, + arguments); +} + + +/******************************************************************************* +** gckOS_WriteToRingBuffer +** +** Store a buffer to ring buffer. +** +** ARGUMENTS: +** +** gctCONST_STRING Buffer +** Pointer to buffer to store. +** +** gctSIZE_T Bytes +** Buffer length. +*/ +void +gckOS_WriteToRingBuffer( + IN gctCONST_STRING Buffer, + IN gctSIZE_T Bytes + ) +{ + +} + +/******************************************************************************* +** gckOS_BinaryTrace +** +** Output a binary trace message. +** +** ARGUMENTS: +** +** gctCONST_STRING Function +** Pointer to function name. +** +** gctINT Line +** Line number. +** +** gctCONST_STRING Text OPTIONAL +** Optional pointer to a descriptive text. +** +** ... +** Optional arguments to the descriptive text. +*/ +void +gckOS_BinaryTrace( + IN gctCONST_STRING Function, + IN gctINT Line, + IN gctCONST_STRING Text OPTIONAL, + ... + ) +{ + static gctUINT32 messageSignature = 0x7FFFFFFF; + char buffer[gcdBINARY_TRACE_MESSAGE_SIZE]; + gctUINT32 numArguments = 0; + gctUINT32 functionBytes; + gctUINT32 i = 0; + gctSTRING payload; + gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)buffer; + + /* Calculate arguments number. */ + if (Text) + { + while (Text[i] != '\0') + { + if (Text[i] == '%') + { + numArguments++; + } + i++; + } + } + + message->signature = messageSignature; + message->pid = gcmkGETPROCESSID(); + message->tid = gcmkGETTHREADID(); + message->line = Line; + message->numArguments = numArguments; + + payload = (gctSTRING)&message->payload; + + /* Function name. */ + functionBytes = (gctUINT32)gcmkSTRLEN(Function) + 1; + gcmkMEMCPY(payload, Function, functionBytes); + + /* Advance to next payload. */ + payload += functionBytes; + + /* Arguments value. */ + if (numArguments) + { + gctARGUMENTS p; + gcmkARGUMENTS_START(p, Text); + + for (i = 0; i < numArguments; ++i) + { + gctPOINTER value = gcmkARGUMENTS_ARG(p, gctPOINTER); + gcmkMEMCPY(payload, &value, gcmSIZEOF(gctPOINTER)); + payload += gcmSIZEOF(gctPOINTER); + } + + gcmkARGUMENTS_END(p); + } + + gcmkASSERT(payload - buffer <= gcdBINARY_TRACE_MESSAGE_SIZE); + + + /* Send buffer to ring buffer. */ + gckOS_WriteToRingBuffer(buffer, (gctUINT32)(payload - buffer)); +} + 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 01f71d8e4176..1c6300787fad 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -249,7 +249,6 @@ OnError: if (powerLocked) { gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex)); - powerLocked = gcvFALSE; } gcmkFOOTER(); @@ -300,41 +299,6 @@ __RemoveRecordFromProcessDB( gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical))); break; - case gcvHAL_FREE_VIDEO_MEMORY: - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( - Event->kernel, - Record->processID, - gcvDB_VIDEO_MEMORY, - gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node))); - - { - gcuVIDMEM_NODE_PTR node = (gcuVIDMEM_NODE_PTR)(gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node)); - - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel, - Record->processID, - gcvDB_VIDEO_MEMORY_RESERVED, - node)); - } - else if(node->Virtual.contiguous) - { - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel, - Record->processID, - gcvDB_VIDEO_MEMORY_CONTIGUOUS, - node)); - } - else - { - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel, - Record->processID, - gcvDB_VIDEO_MEMORY_VIRTUAL, - node)); - } - } - - break; - case gcvHAL_UNLOCK_VIDEO_MEMORY: gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( Event->kernel, @@ -369,13 +333,112 @@ __RemoveRecordFromProcessDB( return gcvSTATUS_OK; } +gceSTATUS +_ReleaseVideoMemoryHandle( + IN gckKERNEL Kernel, + IN OUT gcsEVENT_PTR Record, + IN OUT gcsHAL_INTERFACE * Interface + ) +{ + gceSTATUS status; + gckVIDMEM_NODE nodeObject; + gctUINT32 handle; + + switch(Interface->command) + { + case gcvHAL_UNLOCK_VIDEO_MEMORY: + handle = (gctUINT32)Interface->u.UnlockVideoMemory.node; + + gcmkONERROR(gckVIDMEM_HANDLE_Lookup( + Kernel, Record->processID, handle, &nodeObject)); + + Record->info.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(nodeObject); + + gckVIDMEM_HANDLE_Dereference(Kernel, Record->processID, handle); + break; + + default: + break; + } + + return gcvSTATUS_OK; +OnError: + return status; +} + +/******************************************************************************* +** +** _QueryFlush +** +** Check the type of surfaces which will be released by current event and +** determine the cache needed to flush. +** +*/ +static gceSTATUS +_QueryFlush( + IN gckEVENT Event, + IN gcsEVENT_PTR Record, + OUT gceKERNEL_FLUSH *Flush + ) +{ + gceKERNEL_FLUSH flush = 0; + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record); + gcmkVERIFY_ARGUMENT(Record != gcvNULL); + + while (Record != gcvNULL) + { + switch (Record->info.command) + { + case gcvHAL_UNLOCK_VIDEO_MEMORY: + switch(Record->info.u.UnlockVideoMemory.type) + { + case gcvSURF_TILE_STATUS: + flush |= gcvFLUSH_TILE_STATUS; + break; + case gcvSURF_RENDER_TARGET: + flush |= gcvFLUSH_COLOR; + break; + case gcvSURF_DEPTH: + flush |= gcvFLUSH_DEPTH; + break; + case gcvSURF_TEXTURE: + flush |= gcvFLUSH_TEXTURE; + break; + case gcvSURF_TYPE_UNKNOWN: + gcmkASSERT(0); + break; + default: + break; + } + break; + case gcvHAL_UNMAP_USER_MEMORY: + *Flush = gcvFLUSH_ALL; + return gcvSTATUS_OK; + + default: + break; + } + + Record = Record->next; + } + + *Flush = flush; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + void _SubmitTimerFunction( gctPOINTER Data ) { gckEVENT event = (gckEVENT)Data; +#if gcdMULTI_GPU + gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE, gcvCORE_3D_ALL_MASK)); +#else gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE)); +#endif } /******************************************************************************\ @@ -468,6 +531,17 @@ gckEVENT_Construct( #if gcdSMP gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending)); + +#if gcdMULTI_GPU + for (i = 0; i < gcdMULTI_GPU; i++) + { + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending3D[i])); + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending3DMask[i])); + } + + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pendingMask)); +#endif + #endif gcmkVERIFY_OK(gckOS_CreateTimer(os, @@ -475,6 +549,11 @@ gckEVENT_Construct( (gctPOINTER)eventObj, &eventObj->submitTimer)); +#if gcdINTERRUPT_STATISTIC + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->interruptCount)); + gcmkONERROR(gckOS_AtomSet(os,eventObj->interruptCount, 0)); +#endif + /* Return pointer to the gckEVENT object. */ *Event = eventObj; @@ -519,6 +598,28 @@ OnError: { gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending)); } + +#if gcdMULTI_GPU + for (i = 0; i < gcdMULTI_GPU; i++) + { + if (eventObj->pending3D[i] != gcvNULL) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending3D[i])); + } + + if (eventObj->pending3DMask[i] != gcvNULL) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending3DMask[i])); + } + } +#endif +#endif + +#if gcdINTERRUPT_STATISTIC + if (eventObj->interruptCount) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->interruptCount)); + } #endif gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj)); } @@ -622,6 +723,21 @@ gckEVENT_Destroy( #if gcdSMP gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending)); + +#if gcdMULTI_GPU + { + gctINT i; + for (i = 0; i < gcdMULTI_GPU; i++) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending3D[i])); + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending3DMask[i])); + } + } +#endif +#endif + +#if gcdINTERRUPT_STATISTIC + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->interruptCount)); #endif /* Mark the gckEVENT object as unknown. */ @@ -658,6 +774,18 @@ gckEVENT_Destroy( ** gctUINT8 * EventID ** Reserved event ID. */ +#define gcdINVALID_EVENT_PTR ((gcsEVENT_PTR)gcvMAXUINTPTR_T) + +#if gcdMULTI_GPU +gceSTATUS +gckEVENT_GetEvent( + IN gckEVENT Event, + IN gctBOOL Wait, + OUT gctUINT8 * EventID, + IN gceKERNEL_WHERE Source, + IN gceCORE_3D_MASK ChipEnable + ) +#else gceSTATUS gckEVENT_GetEvent( IN gckEVENT Event, @@ -665,14 +793,14 @@ gckEVENT_GetEvent( OUT gctUINT8 * EventID, IN gceKERNEL_WHERE Source ) +#endif { gctINT i, id; gceSTATUS status; gctBOOL acquired = gcvFALSE; gctINT32 free; - -#if gcdGPU_TIMEOUT - gctUINT32 timer = 0; +#if gcdMULTI_GPU + gctINT j; #endif gcmkHEADER_ARG("Event=0x%x Source=%d", Event, Source); @@ -699,9 +827,34 @@ gckEVENT_GetEvent( Event->lastID = (gctUINT8) nextID; /* Save time stamp of event. */ + Event->queues[id].head = gcdINVALID_EVENT_PTR; Event->queues[id].stamp = ++(Event->stamp); Event->queues[id].source = Source; +#if gcdMULTI_GPU + Event->queues[id].chipEnable = ChipEnable; + + if (ChipEnable == gcvCORE_3D_ALL_MASK) + { + gckOS_AtomSetMask(Event->pendingMask, (1 << id)); + + for (j = 0; j < gcdMULTI_GPU; j++) + { + gckOS_AtomSetMask(Event->pending3DMask[j], (1 << id)); + } + } + else + { + for (j = 0; j < gcdMULTI_GPU; j++) + { + if (ChipEnable & (1 << j)) + { + gckOS_AtomSetMask(Event->pending3DMask[j], (1 << id)); + } + } + } +#endif + gcmkONERROR(gckOS_AtomDecrement(Event->os, Event->freeAtom, &free)); @@ -754,30 +907,6 @@ gckEVENT_GetEvent( /* Delay a while. */ gcmkONERROR(gckOS_Delay(Event->os, 1)); - -#if gcdGPU_TIMEOUT - /* Increment the wait timer. */ - timer += 1; - - if (timer == Event->kernel->timeOut) - { - /* Try to call any outstanding events. */ - gcmkONERROR(gckHARDWARE_Interrupt(Event->kernel->hardware, - gcvTRUE)); - } - else if (timer > Event->kernel->timeOut) - { - gcmkTRACE_N( - gcvLEVEL_ERROR, - gcmSIZEOF(gctCONST_STRING) + gcmSIZEOF(gctINT), - "%s(%d): no available events\n", - __FUNCTION__, __LINE__ - ); - - /* Bail out. */ - gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING); - } -#endif } OnError: @@ -861,7 +990,6 @@ gckEVENT_AllocateRecord( /* Release the mutex. */ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex)); - acquired = gcvFALSE; /* Success. */ gcmkFOOTER_ARG("*Record=0x%x", gcmOPT_POINTER(Record)); @@ -916,6 +1044,7 @@ gckEVENT_AddList( gctBOOL acquired = gcvFALSE; gcsEVENT_PTR record = gcvNULL; gcsEVENT_QUEUE_PTR queue; + gckVIRTUAL_COMMAND_BUFFER_PTR buffer; gckKERNEL kernel = Event->kernel; gcmkHEADER_ARG("Event=0x%x Interface=0x%x", @@ -933,7 +1062,6 @@ gckEVENT_AddList( gcmkASSERT ( (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY) || (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY) - || (Interface->command == gcvHAL_FREE_VIDEO_MEMORY) || (Interface->command == gcvHAL_WRITE_DATA) || (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY) || (Interface->command == gcvHAL_SIGNAL) @@ -942,6 +1070,7 @@ gckEVENT_AddList( || (Interface->command == gcvHAL_COMMIT_DONE) || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER) || (Interface->command == gcvHAL_SYNC_POINT) + || (Interface->command == gcvHAL_DESTROY_MMU) ); /* Validate the source. */ @@ -966,12 +1095,25 @@ gckEVENT_AddList( /* Get process ID. */ gcmkONERROR(gckOS_GetProcessID(&record->processID)); + gcmkONERROR(__RemoveRecordFromProcessDB(Event, record)); + + /* Handle is belonged to current process, it must be released now. */ + if (FromKernel == gcvFALSE) + { + status = _ReleaseVideoMemoryHandle(Event->kernel, record, Interface); + + if (gcmIS_ERROR(status)) + { + /* Ingore error because there are other events in the queue. */ + status = gcvSTATUS_OK; + goto OnError; + } + } + #ifdef __QNXNTO__ record->kernel = Event->kernel; #endif - gcmkONERROR(__RemoveRecordFromProcessDB(Event, record)); - /* Acquire the mutex. */ gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE)); acquired = gcvTRUE; @@ -1036,11 +1178,23 @@ gckEVENT_AddList( (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes, gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical))); break; + + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER: + buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical); + if (buffer->userLogical) + { + gcmkONERROR(gckOS_DestroyUserVirtualMapping( + Event->os, + buffer->physical, + (gctSIZE_T) Interface->u.FreeVirtualCommandBuffer.bytes, + gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical))); + } + break; + default: break; } - /* Release the mutex. */ gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex)); @@ -1094,7 +1248,7 @@ gceSTATUS gckEVENT_Unlock( IN gckEVENT Event, IN gceKERNEL_WHERE FromWhere, - IN gcuVIDMEM_NODE_PTR Node, + IN gctPOINTER Node, IN gceSURF_TYPE Type ) { @@ -1127,61 +1281,6 @@ OnError: return status; } -/******************************************************************************* -** -** gckEVENT_FreeVideoMemory -** -** Schedule an event to free video memory. -** -** INPUT: -** -** gckEVENT Event -** Pointer to an gckEVENT object. -** -** gcuVIDMEM_NODE_PTR VideoMemory -** Pointer to a gcuVIDMEM_NODE object to free. -** -** gceKERNEL_WHERE FromWhere -** Place in the pipe where the event needs to be generated. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gckEVENT_FreeVideoMemory( - IN gckEVENT Event, - IN gcuVIDMEM_NODE_PTR VideoMemory, - IN gceKERNEL_WHERE FromWhere - ) -{ - gceSTATUS status; - gcsHAL_INTERFACE iface; - - gcmkHEADER_ARG("Event=0x%x VideoMemory=0x%x FromWhere=%d", - Event, VideoMemory, FromWhere); - - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT); - gcmkVERIFY_ARGUMENT(VideoMemory != gcvNULL); - - /* Create an event. */ - iface.command = gcvHAL_FREE_VIDEO_MEMORY; - iface.u.FreeVideoMemory.node = gcmPTR_TO_UINT64(VideoMemory); - - /* Append it to the queue. */ - gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); - - /* Success. */ - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; -} - /******************************************************************************* ** ** gckEVENT_FreeNonPagedMemory @@ -1461,6 +1560,40 @@ OnError: gcmkFOOTER(); return status; } + +#if gcdPROCESS_ADDRESS_SPACE +gceSTATUS +gckEVENT_DestroyMmu( + IN gckEVENT Event, + IN gckMMU Mmu, + IN gceKERNEL_WHERE FromWhere + ) +{ + gceSTATUS status; + gcsHAL_INTERFACE iface; + + gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT); + + iface.command = gcvHAL_DESTROY_MMU; + iface.u.DestroyMmu.mmu = gcmPTR_TO_UINT64(Mmu); + + /* Append it to the queue. */ + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE)); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} +#endif + /******************************************************************************* ** ** gckEVENT_Submit @@ -1486,12 +1619,22 @@ OnError: ** ** Nothing. */ +#if gcdMULTI_GPU +gceSTATUS +gckEVENT_Submit( + IN gckEVENT Event, + IN gctBOOL Wait, + IN gctBOOL FromPower, + IN gceCORE_3D_MASK ChipEnable + ) +#else gceSTATUS gckEVENT_Submit( IN gckEVENT Event, IN gctBOOL Wait, IN gctBOOL FromPower ) +#endif { gceSTATUS status; gctUINT8 id = 0xFF; @@ -1500,14 +1643,37 @@ gckEVENT_Submit( gckCOMMAND command = gcvNULL; gctBOOL commitEntered = gcvFALSE; #if !gcdNULL_DRIVER - gctSIZE_T bytes; + gctUINT32 bytes; gctPOINTER buffer; #endif +#if gcdMULTI_GPU + gctSIZE_T chipEnableBytes; +#endif + +#if gcdINTERRUPT_STATISTIC + gctINT32 oldValue; +#endif + +#if gcdSECURITY + gctPOINTER reservedBuffer; +#endif + + gctUINT32 flushBytes; + gctUINT32 executeBytes; + gckHARDWARE hardware; + + gceKERNEL_FLUSH flush = gcvFALSE; + gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait); /* Get gckCOMMAND object. */ command = Event->kernel->command; + hardware = Event->kernel->hardware; + + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE); + + gckOS_GetTicks(&Event->lastCommitStamp); /* Are there event queues? */ if (Event->queueHead != gcvNULL) @@ -1529,7 +1695,11 @@ gckEVENT_Submit( queue = Event->queueHead; /* Allocate an event ID. */ +#if gcdMULTI_GPU + gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source, ChipEnable)); +#else gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source)); +#endif /* Copy event list to event ID queue. */ Event->queues[id].head = queue->head; @@ -1552,40 +1722,120 @@ gckEVENT_Submit( gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex)); acquired = gcvFALSE; + /* Determine cache needed to flush. */ + gcmkVERIFY_OK(_QueryFlush(Event, Event->queues[id].head, &flush)); + +#if gcdINTERRUPT_STATISTIC + gcmkVERIFY_OK(gckOS_AtomIncrement( + Event->os, + Event->interruptCount, + &oldValue + )); +#endif + #if gcdNULL_DRIVER /* Notify immediately on infinite hardware. */ gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id)); - gcmkONERROR(gckEVENT_Notify(Event, 0)); -#else - /* Get the size of the hardware event. */ - gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware, - gcvNULL, - id, - Event->queues[id].source, - &bytes)); + gcmkONERROR(gckEVENT_Notify(Event, 0)); +#else + /* Get the size of the hardware event. */ + gcmkONERROR(gckHARDWARE_Event( + hardware, + gcvNULL, + id, + Event->queues[id].source, + &bytes + )); + + /* Get the size of flush command. */ + gcmkONERROR(gckHARDWARE_Flush( + hardware, + flush, + gcvNULL, + &flushBytes + )); + + bytes += flushBytes; + +#if gcdMULTI_GPU + gcmkONERROR(gckHARDWARE_ChipEnable( + hardware, + gcvNULL, + 0, + &chipEnableBytes + )); + + bytes += chipEnableBytes * 2; +#endif + + /* Total bytes need to execute. */ + executeBytes = bytes; + + /* Reserve space in the command queue. */ + gcmkONERROR(gckCOMMAND_Reserve(command, bytes, &buffer, &bytes)); +#if gcdSECURITY + reservedBuffer = buffer; +#endif + +#if gcdMULTI_GPU + gcmkONERROR(gckHARDWARE_ChipEnable( + hardware, + buffer, + ChipEnable, + &chipEnableBytes + )); + + buffer = (gctUINT8_PTR)buffer + chipEnableBytes; +#endif + + /* Set the flush in the command queue. */ + gcmkONERROR(gckHARDWARE_Flush( + hardware, + flush, + buffer, + &flushBytes + )); - /* Reserve space in the command queue. */ - gcmkONERROR(gckCOMMAND_Reserve(command, - bytes, - &buffer, - &bytes)); + /* Advance to next command. */ + buffer = (gctUINT8_PTR)buffer + flushBytes; /* Set the hardware event in the command queue. */ - gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware, - buffer, - id, - Event->queues[id].source, - &bytes)); + gcmkONERROR(gckHARDWARE_Event( + hardware, + buffer, + id, + Event->queues[id].source, + &bytes + )); + + /* Advance to next command. */ + buffer = (gctUINT8_PTR)buffer + bytes; + +#if gcdMULTI_GPU + gcmkONERROR(gckHARDWARE_ChipEnable( + hardware, + buffer, + gcvCORE_3D_ALL_MASK, + &chipEnableBytes + )); +#endif +#if gcdSECURITY + gckKERNEL_SecurityExecute( + Event->kernel, + reservedBuffer, + executeBytes + ); +#else /* Execute the hardware event. */ - gcmkONERROR(gckCOMMAND_Execute(command, bytes)); + gcmkONERROR(gckCOMMAND_Execute(command, executeBytes)); +#endif #endif } /* Release the command queue. */ gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower)); - commitEntered = gcvFALSE; #if !gcdNULL_DRIVER gcmkVERIFY_OK(_TryToIdleGPU(Event)); @@ -1597,18 +1847,18 @@ gckEVENT_Submit( return gcvSTATUS_OK; OnError: - if (commitEntered) - { - /* Release the command queue mutex. */ - gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower)); - } - if (acquired) { /* Need to unroll the mutex acquire. */ gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex)); } + if (commitEntered) + { + /* Release the command queue mutex. */ + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower)); + } + if (id != 0xFF) { /* Need to unroll the event allocation. */ @@ -1646,11 +1896,20 @@ OnError: ** ** Nothing. */ +#if gcdMULTI_GPU +gceSTATUS +gckEVENT_Commit( + IN gckEVENT Event, + IN gcsQUEUE_PTR Queue, + IN gceCORE_3D_MASK ChipEnable + ) +#else gceSTATUS gckEVENT_Commit( IN gckEVENT Event, IN gcsQUEUE_PTR Queue ) +#endif { gceSTATUS status; gcsQUEUE_PTR record = gcvNULL, next; @@ -1719,7 +1978,11 @@ gckEVENT_Commit( } /* Submit the event list. */ +#if gcdMULTI_GPU + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE, ChipEnable)); +#else gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE)); +#endif /* Success */ gcmkFOOTER_NO(); @@ -1778,7 +2041,11 @@ gckEVENT_Compose( gcmkVERIFY_ARGUMENT(Info != gcvNULL); /* Allocate an event ID. */ +#if gcdMULTI_GPU + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL, gcvCORE_3D_ALL_MASK)); +#else gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL)); +#endif /* Get process ID. */ gcmkONERROR(gckOS_GetProcessID(&processID)); @@ -1826,7 +2093,6 @@ gckEVENT_Compose( /* Allocate a record. */ gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord)); tailRecord->next = tempRecord; - tailRecord = tempRecord; /* Initialize the record. */ tempRecord->info.command = gcvHAL_SIGNAL; @@ -1841,7 +2107,7 @@ gckEVENT_Compose( tempRecord->processID = processID; } - /* Set the event list. */ + /* Set the event list. */ Event->queues[id].head = headRecord; /* Start composition. */ @@ -1882,21 +2148,118 @@ OnError: gceSTATUS gckEVENT_Interrupt( IN gckEVENT Event, +#if gcdMULTI_GPU + IN gctUINT CoreId, +#endif IN gctUINT32 Data ) { +#if gcdMULTI_GPU +#if defined(WIN32) + gctUINT32 i; +#endif +#endif gcmkHEADER_ARG("Event=0x%x Data=0x%x", Event, Data); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT); + if (Data & 0x20000000) + { + gckENTRYDATA data; + gctUINT32 idle; + Data &= ~0x20000000; + +#if gcdMULTI_GPU + if (Event->kernel->core == gcvCORE_MAJOR) +#endif + { + /* Get first entry information. */ + gcmkVERIFY_OK( + gckENTRYQUEUE_Dequeue(&Event->kernel->command->queue, &data)); + + /* Make sure FE is idle. */ + do + { + gcmkVERIFY_OK(gckOS_ReadRegisterEx( + Event->os, + Event->kernel->core, + 0x4, + &idle)); + } + while (idle != 0x7FFFFFFF); + + /* Start Command Parser. */ + gcmkVERIFY_OK(gckHARDWARE_Execute( + Event->kernel->hardware, + data->physical, + data->bytes + )); + } + } + /* Combine current interrupt status with pending flags. */ #if gcdSMP - gckOS_AtomSetMask(Event->pending, Data); +#if gcdMULTI_GPU + if (Event->kernel->core == gcvCORE_MAJOR) + { + gckOS_AtomSetMask(Event->pending3D[CoreId], Data); + } + else +#endif + { + gckOS_AtomSetMask(Event->pending, Data); + } #elif defined(__QNXNTO__) - atomic_set(&Event->pending, Data); +#if gcdMULTI_GPU + if (Event->kernel->core == gcvCORE_MAJOR) + { + atomic_set(&Event->pending3D[CoreId], Data); + } + else +#endif + { + atomic_set(&Event->pending, Data); + } +#else +#if gcdMULTI_GPU +#if defined(WIN32) + if (Event->kernel->core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + Event->pending3D[i] |= Data; + } + } + else #else - Event->pending |= Data; + if (Event->kernel->core == gcvCORE_MAJOR) + { + Event->pending3D[CoreId] |= Data; + } + else +#endif +#endif + { + Event->pending |= Data; + } +#endif + +#if gcdINTERRUPT_STATISTIC + { + gctINT j = 0; + gctINT32 oldValue; + + for (j = 0; j < gcmCOUNTOF(Event->queues); j++) + { + if ((Data & (1 << j))) + { + gcmkVERIFY_OK(gckOS_AtomDecrement(Event->os, + Event->interruptCount, + &oldValue)); + } + } + } #endif /* Success. */ @@ -1930,11 +2293,16 @@ gckEVENT_Notify( gcsEVENT_QUEUE * queue; gctUINT mask = 0; gctBOOL acquired = gcvFALSE; - gcuVIDMEM_NODE_PTR node; gctPOINTER info; gctSIGNAL signal; - gctUINT pending; + gctUINT pending = 0; gckKERNEL kernel = Event->kernel; +#if gcdMULTI_GPU + gceCORE core = Event->kernel->core; + gctUINT32 busy; + gctUINT32 oldValue; + gctUINT pendingMask; +#endif #if !gcdSMP gctBOOL suspended = gcvFALSE; #endif @@ -1945,6 +2313,8 @@ gckEVENT_Notify( #if gcdSECURE_USER gcskSECURE_CACHE_PTR cache; #endif + gckVIDMEM_NODE nodeObject; + gcuVIDMEM_NODE_PTR node; gcmkHEADER_ARG("Event=0x%x IDs=0x%x", Event, IDs); @@ -1968,36 +2338,117 @@ gckEVENT_Notify( } ); +#if gcdMULTI_GPU + /* Set busy flag. */ + gckOS_AtomicExchange(Event->os, &Event->busy, 1, &busy); + if (busy) + { + /* Another thread is already busy - abort. */ + goto OnSuccess; + } +#endif + for (;;) { gcsEVENT_PTR record; +#if gcdMULTI_GPU + gctUINT32 pend[gcdMULTI_GPU]; + gctUINT32 pendMask[gcdMULTI_GPU]; +#endif + + /* Grab the mutex queue. */ + gcmkONERROR(gckOS_AcquireMutex(Event->os, + Event->eventQueueMutex, + gcvINFINITE)); + acquired = gcvTRUE; #if gcdSMP - /* Get current interrupts. */ - gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending); +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + /* Get current interrupts. */ + for (i = 0; i < gcdMULTI_GPU; i++) + { + gckOS_AtomGet(Event->os, Event->pending3D[i], (gctINT32_PTR)&pend[i]); + gckOS_AtomGet(Event->os, Event->pending3DMask[i], (gctINT32_PTR)&pendMask[i]); + } + + gckOS_AtomGet(Event->os, Event->pendingMask, (gctINT32_PTR)&pendingMask); + } + else +#endif + { + gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending); + } #else /* Suspend interrupts. */ gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core)); suspended = gcvTRUE; - /* Get current interrupts. */ - pending = Event->pending; +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + /* Get current interrupts. */ + pend[i] = Event->pending3D[i]; + pendMask[i] = Event->pending3DMask[i]; + } + + pendingMask = Event->pendingMask; + } + else +#endif + { + pending = Event->pending; + } /* Resume interrupts. */ gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core)); suspended = gcvFALSE; #endif +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + gctUINT32 bad_pend = (pend[i] & ~pendMask[i]); + + if (bad_pend != 0) + { + gcmkTRACE_ZONE_N( + gcvLEVEL_ERROR, gcvZONE_EVENT, + gcmSIZEOF(bad_pend) + gcmSIZEOF(i), + "Interrupts 0x%x are not unexpected for Core%d.", + bad_pend, i + ); + + gckOS_AtomClearMask(Event->pending3D[i], bad_pend); + + pend[i] &= pendMask[i]; + } + } + + pending = (pend[0] & pend[1] & pendingMask) /* Check combined events on both GPUs */ + | (pend[0] & ~pendingMask) /* Check individual events on GPU 0 */ + | (pend[1] & ~pendingMask); /* Check individual events on GPU 1 */ + } +#endif + if (pending == 0) { + /* Release the mutex queue. */ + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex)); + acquired = gcvFALSE; + /* No more pending interrupts - done. */ break; } if (pending & 0x80000000) { - gckOS_Print("!!!!!!!!!!!!! AXI BUS ERROR !!!!!!!!!!!!!\n"); - gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_EVENT, "AXI BUS ERROR"); + gcmkPRINT("AXI BUS ERROR"); pending &= 0x7FFFFFFF; } @@ -2064,23 +2515,70 @@ gckEVENT_Notify( ); #if gcdSMP - /* Mark pending interrupts as handled. */ - gckOS_AtomClearMask(Event->pending, pending); +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + /* Mark pending interrupts as handled. */ + for (i = 0; i < gcdMULTI_GPU; i++) + { + gckOS_AtomClearMask(Event->pending3D[i], pending); + gckOS_AtomClearMask(Event->pending3DMask[i], pending); + } + + gckOS_AtomClearMask(Event->pendingMask, pending); + } + else +#endif + { + gckOS_AtomClearMask(Event->pending, pending); + } + #elif defined(__QNXNTO__) - /* Mark pending interrupts as handled. */ - atomic_clr((gctUINT32_PTR)&Event->pending, pending); +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + atomic_clr((gctUINT32_PTR)&Event->pending3D[i], pending); + atomic_clr((gctUINT32_PTR)&Event->pending3DMask[i], pending); + } + + atomic_clr((gctUINT32_PTR)&Event->pendingMask, pending); + } + else +#endif + { + atomic_clr((gctUINT32_PTR)&Event->pending, pending); + } #else /* Suspend interrupts. */ gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core)); suspended = gcvTRUE; - /* Mark pending interrupts as handled. */ - Event->pending &= ~pending; +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + /* Mark pending interrupts as handled. */ + Event->pending3D[i] &= ~pending; + Event->pending3DMask[i] &= ~pending; + } + } + else +#endif + { + Event->pending &= ~pending; + } /* Resume interrupts. */ gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core)); suspended = gcvFALSE; #endif + + /* Release the mutex queue. */ + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex)); + acquired = gcvFALSE; break; } @@ -2090,6 +2588,9 @@ gckEVENT_Notify( if ((Event->queues[i].head != gcvNULL) && (Event->queues[i].stamp < queue->stamp) && (Event->queues[i].source <= queue->source) +#if gcdMULTI_GPU + && (Event->queues[i].chipEnable == queue->chipEnable) +#endif ) { gcmkTRACE_N( @@ -2118,33 +2619,69 @@ gckEVENT_Notify( } #if gcdSMP - /* Mark pending interrupt as handled. */ - gckOS_AtomClearMask(Event->pending, mask); +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + /* Mark pending interrupt as handled. */ + gckOS_AtomClearMask(Event->pending3D[i], mask); + gckOS_AtomClearMask(Event->pending3DMask[i], mask); + } + + gckOS_AtomClearMask(Event->pendingMask, mask); + } + else +#endif + { + gckOS_AtomClearMask(Event->pending, mask); + } + #elif defined(__QNXNTO__) - /* Mark pending interrupt as handled. */ - atomic_clr(&Event->pending, mask); +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + atomic_clr(&Event->pending3D[i], mask); + atomic_clr(&Event->pending3DMask[i], mask); + } + + atomic_clr(&Event->pendingMask, mask); + } + else +#endif + { + atomic_clr(&Event->pending, mask); + } #else /* Suspend interrupts. */ gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core)); suspended = gcvTRUE; - /* Mark pending interrupt as handled. */ - Event->pending &= ~mask; +#if gcdMULTI_GPU + if (core == gcvCORE_MAJOR) + { + for (i = 0; i < gcdMULTI_GPU; i++) + { + /* Mark pending interrupt as handled. */ + Event->pending3D[i] &= ~mask; + Event->pending3DMask[i] &= ~mask; + } + + Event->pendingMask &= ~mask; + } + else +#endif + { + Event->pending &= ~mask; + } /* Resume interrupts. */ gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core)); suspended = gcvFALSE; #endif - /* Grab the mutex queue. */ - gcmkONERROR(gckOS_AcquireMutex(Event->os, - Event->eventQueueMutex, - gcvINFINITE)); - acquired = gcvTRUE; - - /* We are in the notify loop. */ - Event->inNotify = gcvTRUE; - /* Grab the event head. */ record = queue->head; @@ -2239,51 +2776,13 @@ gckEVENT_Notify( gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( Event->kernel, cache, - gcmUINT64_TO_PTR(record->record.u.FreeContiguousMemory.logical), - (gctSIZE_T) record->record.u.FreeContiguousMemory.bytes)); + gcmUINT64_TO_PTR(event->event.u.FreeContiguousMemory.logical), + (gctSIZE_T) event->event.u.FreeContiguousMemory.bytes)); #endif } gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical); break; - case gcvHAL_FREE_VIDEO_MEMORY: - node = gcmUINT64_TO_PTR(record->info.u.FreeVideoMemory.node); - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_FREE_VIDEO_MEMORY: 0x%x", - node); -#ifdef __QNXNTO__ -#if gcdUSE_VIDMEM_PER_PID - /* Check if the VidMem object still exists. */ - if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel, - gcvPOOL_SYSTEM, - record->processID, - gcvNULL) == gcvSTATUS_NOT_FOUND) - { - /*printf("Vidmem not found for process:%d\n", queue->processID);*/ - status = gcvSTATUS_OK; - break; - } -#else - if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - && (node->VidMem.logical != gcvNULL) - ) - { - gcmkERR_BREAK( - gckKERNEL_UnmapVideoMemory(record->kernel, - node->VidMem.logical, - record->processID, - node->VidMem.bytes)); - node->VidMem.logical = gcvNULL; - } -#endif -#endif - - /* Free video memory. */ - status = - gckVIDMEM_Free(node); - - break; - case gcvHAL_WRITE_DATA: #ifndef __QNXNTO__ /* Convert physical into logical address. */ @@ -2315,14 +2814,17 @@ gckEVENT_Notify( break; case gcvHAL_UNLOCK_VIDEO_MEMORY: - node = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node); - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x", - node); + record->info.u.UnlockVideoMemory.node); + + nodeObject = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node); + + node = nodeObject->node; /* Save node information before it disappears. */ #if gcdSECURE_USER + node = event->event.u.UnlockVideoMemory.node; if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { logical = gcvNULL; @@ -2338,7 +2840,7 @@ gckEVENT_Notify( /* Unlock. */ status = gckVIDMEM_Unlock( Event->kernel, - node, + nodeObject, record->info.u.UnlockVideoMemory.type, gcvNULL); @@ -2352,6 +2854,16 @@ gckEVENT_Notify( bytes)); } #endif + +#if gcdPROCESS_ADDRESS_SPACE + gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock( + Event->kernel, + nodeObject, + record->processID + )); +#endif + + status = gckVIDMEM_NODE_Dereference(Event->kernel, nodeObject); break; case gcvHAL_SIGNAL: @@ -2465,7 +2977,6 @@ gckEVENT_Notify( } break; -#if gcdVIRTUAL_COMMAND_BUFFER case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER: gcmkVERIFY_OK( gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel, @@ -2475,7 +2986,6 @@ gckEVENT_Notify( )); gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical); break; -#endif #if gcdANDROID_NATIVE_FENCE_SYNC case gcvHAL_SYNC_POINT: @@ -2488,6 +2998,12 @@ gckEVENT_Notify( break; #endif +#if gcdPROCESS_ADDRESS_SPACE + case gcvHAL_DESTROY_MMU: + status = gckMMU_Destroy(gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu)); + break; +#endif + case gcvHAL_COMMIT_DONE: break; @@ -2525,14 +3041,19 @@ gckEVENT_Notify( "Handled interrupt 0x%x", mask); } +#if gcdMULTI_GPU + /* Clear busy flag. */ + gckOS_AtomicExchange(Event->os, &Event->busy, 0, &oldValue); +#endif + if (IDs == 0) { gcmkONERROR(_TryToIdleGPU(Event)); } - /* We are out the notify loop. */ - Event->inNotify = gcvFALSE; - +#if gcdMULTI_GPU +OnSuccess: +#endif /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -2552,9 +3073,6 @@ OnError: } #endif - /* We are out the notify loop. */ - Event->inNotify = gcvFALSE; - /* Return the status. */ gcmkFOOTER(); return status; @@ -2713,7 +3231,7 @@ gckEVENT_Stop( IN gctPHYS_ADDR Handle, IN gctPOINTER Logical, IN gctSIGNAL Signal, - IN OUT gctSIZE_T * waitSize + IN OUT gctUINT32 * waitSize ) { gceSTATUS status; @@ -2729,9 +3247,16 @@ gckEVENT_Stop( gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT); /* Submit the current event queue. */ +#if gcdMULTI_GPU + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE, gcvCORE_3D_ALL_MASK)); +#else gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE)); - +#endif +#if gcdMULTI_GPU + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL, gcvCORE_3D_ALL_MASK)); +#else gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL)); +#endif /* Allocate a record. */ gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record)); @@ -2762,7 +3287,7 @@ gckEVENT_Stop( Event->os, ProcessID, gcvNULL, - Handle, + (gctUINT32)Handle, Logical, *waitSize )); @@ -2797,10 +3322,6 @@ _PrintRecord( gcmkPRINT(" gcvHAL_FREE_CONTIGUOUS_MEMORY"); break; - case gcvHAL_FREE_VIDEO_MEMORY: - gcmkPRINT(" gcvHAL_FREE_VIDEO_MEMORY"); - break; - case gcvHAL_WRITE_DATA: gcmkPRINT(" gcvHAL_WRITE_DATA"); break; @@ -2832,6 +3353,17 @@ _PrintRecord( record->info.u.FreeVirtualCommandBuffer.logical); break; + case gcvHAL_SYNC_POINT: + gcmkPRINT(" gcvHAL_SYNC_POINT syncPoint=0x%08x", + gcmUINT64_TO_PTR(record->info.u.SyncPoint.syncPoint)); + + break; + + case gcvHAL_DESTROY_MMU: + gcmkPRINT(" gcvHAL_DESTORY_MMU mmu=0x%08x", + gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu)); + + break; default: gcmkPRINT(" Illegal Event %d", record->info.command); break; @@ -2853,6 +3385,10 @@ gckEVENT_Dump( gcsEVENT_QUEUE_PTR queue; gcsEVENT_PTR record = gcvNULL; gctINT i; +#if gcdINTERRUPT_STATISTIC + gctINT32 pendingInterrupt; + gctUINT32 intrAcknowledge; +#endif gcmkHEADER_ARG("Event=0x%x", Event); @@ -2860,7 +3396,6 @@ gckEVENT_Dump( gcmkPRINT("*** EVENT STATE DUMP ***\n"); gcmkPRINT("**************************\n"); - gcmkPRINT(" Unsumbitted Event:"); while(queueHead) { @@ -2885,7 +3420,7 @@ gckEVENT_Dump( } gcmkPRINT(" Untriggered Event:"); - for (i = 0; i < 30; i++) + for (i = 0; i < gcmCOUNTOF(Event->queues); i++) { queue = &Event->queues[i]; record = queue->head; @@ -2898,15 +3433,24 @@ gckEVENT_Dump( } } - gcmkFOOTER_NO(); - return gcvSTATUS_OK; -} +#if gcdINTERRUPT_STATISTIC + gckOS_AtomGet(Event->os, Event->interruptCount, &pendingInterrupt); + gcmkPRINT(" Number of Pending Interrupt: %d", pendingInterrupt); -gceSTATUS gckEVENT_WaitEmpty(gckEVENT Event) -{ - gctBOOL isEmpty; + if (Event->kernel->recovery == 0) + { + gckOS_ReadRegisterEx( + Event->os, + Event->kernel->core, + 0x10, + &intrAcknowledge + ); - while (Event->inNotify || (gcmIS_SUCCESS(gckEVENT_IsEmpty(Event, &isEmpty)) && !isEmpty)) ; + gcmkPRINT(" INTR_ACKNOWLEDGE=0x%x", intrAcknowledge); + } +#endif + gcmkFOOTER_NO(); return gcvSTATUS_OK; } + 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 a5affb978f4e..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -33,8 +33,7 @@ /******************************************************************************* ***** Structures *************************************************************** *******************************************************************************/ - -#define gcdIN_USE ((gcskNODE_PTR) ~0) +#define gcdIN_USE ((gcskNODE_PTR)gcvMAXUINTPTR_T) typedef struct _gcskNODE * gcskNODE_PTR; typedef struct _gcskNODE 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 50bc63e3a88c..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 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 456ec246241e..7f545f24a6e1 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -35,7 +35,7 @@ gceMMU_TYPE; #define gcdMMU_TABLE_DUMP 0 -#define gcdUSE_MMU_EXCEPTION 0 +#define gcdUSE_MMU_EXCEPTION 1 /* gcdMMU_CLEAR_VALUE @@ -46,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; @@ -177,19 +176,19 @@ _Link( else { /* Address page table. */ - gctUINT32_PTR pageTable = Mmu->pageTableLogical; + gctUINT32_PTR map = Mmu->mapLogical; /* Dispatch on node type. */ - switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index]))) + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[Index]))) { case gcvMMU_SINGLE: /* Set single index. */ - _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE); + _WritePageEntry(&map[Index], (Next << 8) | gcvMMU_SINGLE); break; case gcvMMU_FREE: /* Set index. */ - _WritePageEntry(&pageTable[Index + 1], Next); + _WritePageEntry(&map[Index + 1], Next); break; default: @@ -210,18 +209,18 @@ _AddFree( IN gctUINT32 Count ) { - gctUINT32_PTR pageTable = Mmu->pageTableLogical; + gctUINT32_PTR map = Mmu->mapLogical; if (Count == 1) { /* Initialize a single page node. */ - _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE); + _WritePageEntry(map + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE); } else { /* Initialize the node. */ - _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE); - _WritePageEntry(pageTable + Node + 1, ~0U); + _WritePageEntry(map + Node + 0, (Count << 8) | gcvMMU_FREE); + _WritePageEntry(map + Node + 1, ~0U); } /* Append the node. */ @@ -233,7 +232,7 @@ _Collect( IN gckMMU Mmu ) { - gctUINT32_PTR pageTable = Mmu->pageTableLogical; + gctUINT32_PTR map = Mmu->mapLogical; gceSTATUS status; gctUINT32 i, previous, start = 0, count = 0; @@ -244,7 +243,7 @@ _Collect( for (i = 0; i < Mmu->pageTableEntries; ++i) { /* Dispatch based on type of page. */ - switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i]))) + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[i]))) { case gcvMMU_USED: /* Used page, so close any open node. */ @@ -277,10 +276,10 @@ _Collect( } /* Advance the count. */ - count += _ReadPageEntry(&pageTable[i]) >> 8; + count += _ReadPageEntry(&map[i]) >> 8; /* Advance the index into the page table. */ - i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1; + i += (_ReadPageEntry(&map[i]) >> 8) - 1; break; default: @@ -319,6 +318,112 @@ _SetPage(gctUINT32 PageAddress) | (1 << 0); } +#if gcdPROCESS_ADDRESS_SPACE +gctUINT32 +_AddressToIndex( + IN gckMMU Mmu, + IN gctUINT32 Address + ) +{ + gctUINT32 mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT; + gctUINT32 stlbOffset = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT; + + return (mtlbOffset - Mmu->dynamicMappingStart) * gcdMMU_STLB_4K_ENTRY_NUM + stlbOffset; +} + +gctUINT32 +_MtlbOffset( + gctUINT32 Address + ) +{ + return (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT; +} + +gctUINT32 +_StlbOffset( + gctUINT32 Address + ) +{ + return (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT; +} + +static gceSTATUS +_AllocateStlb( + IN gckOS Os, + OUT gcsMMU_STLB_PTR *Stlb + ) +{ + gceSTATUS status; + gcsMMU_STLB_PTR stlb; + gctPOINTER pointer; + + /* Allocate slave TLB record. */ + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsMMU_STLB), &pointer)); + stlb = pointer; + + stlb->size = gcdMMU_STLB_4K_SIZE; + + /* Allocate slave TLB entries. */ + gcmkONERROR(gckOS_AllocateContiguous( + Os, + gcvFALSE, + &stlb->size, + &stlb->physical, + (gctPOINTER)&stlb->logical + )); + + gcmkONERROR(gckOS_GetPhysicalAddress(Os, stlb->logical, &stlb->physBase)); + +#if gcdUSE_MMU_EXCEPTION + _FillPageTable(stlb->logical, stlb->size / 4, gcdMMU_STLB_EXCEPTION); +#else + gckOS_ZeroMemory(stlb->logical, stlb->size); +#endif + + *Stlb = stlb; + + return gcvSTATUS_OK; + +OnError: + return status; +} + +gceSTATUS +_SetupProcessAddressSpace( + IN gckMMU Mmu + ) +{ + gceSTATUS status; + gctINT numEntries = 0; + gctUINT32_PTR map; + + numEntries = gcdPROCESS_ADDRESS_SPACE_SIZE + /* Address space mapped by one MTLB entry. */ + / (1 << gcdMMU_MTLB_SHIFT); + + Mmu->dynamicMappingStart = 0; + + Mmu->pageTableSize = numEntries * 4096; + + Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32); + + gcmkONERROR(gckOS_Allocate(Mmu->os, + Mmu->pageTableSize, + (void **)&Mmu->mapLogical)); + + /* Initilization. */ + map = Mmu->mapLogical; + _WritePageEntry(map, (Mmu->pageTableEntries << 8) | gcvMMU_FREE); + _WritePageEntry(map + 1, ~0U); + Mmu->heapList = 0; + Mmu->freeNodes = gcvFALSE; + + return gcvSTATUS_OK; + +OnError: + return status; +} +#else static gceSTATUS _FillFlatMapping( IN gckMMU Mmu, @@ -335,6 +440,7 @@ _FillFlatMapping( gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT; gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT; gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT; + gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE); /* Grab the mutex. */ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE)); @@ -348,6 +454,7 @@ _FillFlatMapping( gcsMMU_STLB_PTR stlb; gctPOINTER pointer = gcvNULL; gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1); + gctUINT32 mtlbEntry; gcmkONERROR(gckOS_Allocate(Mmu->os, sizeof(struct _gcsMMU_STLB), &pointer)); stlb = pointer; @@ -389,15 +496,23 @@ _FillFlatMapping( gcmkONERROR(gcvSTATUS_NOT_ALIGNED); } - _WritePageEntry(Mmu->mtlbLogical + mStart, - stlb->physBase - /* 64KB page size */ - | (1 << 2) - /* Ignore exception */ - | (0 << 1) - /* Present */ - | (1 << 0) - ); + mtlbEntry = stlb->physBase + /* 64KB page size */ + | (1 << 2) + /* Ignore exception */ + | (0 << 1) + /* Present */ + | (1 << 0); + + if (ace) + { + mtlbEntry = mtlbEntry + /* Secure */ + | (1 << 4); + } + + _WritePageEntry(Mmu->mtlbLogical + mStart, mtlbEntry); + #if gcdMMU_TABLE_DUMP gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n", __FUNCTION__, __LINE__, @@ -587,8 +702,10 @@ _SetupDynamicSpace( gctINT i, nodeArraySize = 0; gctUINT32 physical; gctINT numEntries = 0; - gctUINT32_PTR pageTable; + gctUINT32_PTR map; gctBOOL acquired = gcvFALSE; + gctUINT32 mtlbEntry; + gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE); /* Find all the dynamic address space. */ gcmkONERROR(_FindDynamicSpace(Mmu, &nodeArray, &nodeArraySize)); @@ -607,7 +724,11 @@ _SetupDynamicSpace( Mmu->pageTableSize = numEntries * 4096; - Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32); + gcmkSAFECASTSIZET(Mmu->pageTableEntries, Mmu->pageTableSize / gcmSIZEOF(gctUINT32)); + + gcmkONERROR(gckOS_Allocate(Mmu->os, + Mmu->pageTableSize, + (void **)&Mmu->mapLogical)); /* Construct Slave TLB. */ gcmkONERROR(gckOS_AllocateContiguous(Mmu->os, @@ -628,9 +749,9 @@ _SetupDynamicSpace( #endif /* Initilization. */ - pageTable = Mmu->pageTableLogical; - _WritePageEntry(pageTable, (Mmu->pageTableEntries << 8) | gcvMMU_FREE); - _WritePageEntry(pageTable + 1, ~0U); + map = Mmu->mapLogical; + _WritePageEntry(map, (Mmu->pageTableEntries << 8) | gcvMMU_FREE); + _WritePageEntry(map + 1, ~0U); Mmu->heapList = 0; Mmu->freeNodes = gcvFALSE; @@ -647,15 +768,23 @@ _SetupDynamicSpace( i < (gctINT)Mmu->dynamicMappingStart + numEntries; i++) { - _WritePageEntry(Mmu->mtlbLogical + i, - physical - /* 4KB page size */ - | (0 << 2) - /* Ignore exception */ - | (0 << 1) - /* Present */ - | (1 << 0) - ); + mtlbEntry = physical + /* 4KB page size */ + | (0 << 2) + /* Ignore exception */ + | (0 << 1) + /* Present */ + | (1 << 0); + + if (ace) + { + mtlbEntry = mtlbEntry + /* Secure */ + | (1 << 4); + } + + _WritePageEntry(Mmu->mtlbLogical + i, mtlbEntry); + #if gcdMMU_TABLE_DUMP gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n", __FUNCTION__, __LINE__, @@ -671,14 +800,17 @@ _SetupDynamicSpace( return gcvSTATUS_OK; OnError: - if (Mmu->pageTableLogical) + if (Mmu->mapLogical) { - /* Free the page table. */ gcmkVERIFY_OK( - gckOS_FreeContiguous(Mmu->os, - Mmu->pageTablePhysical, - (gctPOINTER) Mmu->pageTableLogical, - Mmu->pageTableSize)); + gckOS_Free(Mmu->os, (gctPOINTER) Mmu->mapLogical)); + + + gcmkVERIFY_OK( + gckOS_FreeContiguous(Mmu->os, + Mmu->pageTablePhysical, + (gctPOINTER) Mmu->pageTableLogical, + Mmu->pageTableSize)); } if (acquired) @@ -689,6 +821,7 @@ OnError: return status; } +#endif /******************************************************************************* ** @@ -720,8 +853,15 @@ _Construct( gckHARDWARE hardware; gceSTATUS status; gckMMU mmu = gcvNULL; - gctUINT32_PTR pageTable; + gctUINT32_PTR map; gctPOINTER pointer = gcvNULL; +#if gcdPROCESS_ADDRESS_SPACE + gctUINT32 i; + gctUINT32 physical; +#endif + gctUINT32 physBase; + gctUINT32 physSize; + gctUINT32 gpuAddress; gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize); @@ -752,50 +892,44 @@ _Construct( mmu->mtlbLogical = gcvNULL; mmu->staticSTLB = gcvNULL; mmu->enabled = gcvFALSE; -#ifdef __QNXNTO__ - mmu->nodeList = gcvNULL; - mmu->nodeMutex = gcvNULL; -#endif + mmu->mapLogical = gcvNULL; /* Create the page table mutex. */ gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex)); -#ifdef __QNXNTO__ - /* Create the node list mutex. */ - gcmkONERROR(gckOS_CreateMutex(os, &mmu->nodeMutex)); -#endif - if (hardware->mmuVersion == 0) { mmu->pageTableSize = MmuSize; - gcmkONERROR( - gckOS_AllocateContiguous(os, - gcvFALSE, - &mmu->pageTableSize, - &mmu->pageTablePhysical, - &pointer)); + /* Construct address space management table. */ + gcmkONERROR(gckOS_Allocate(mmu->os, + mmu->pageTableSize, + &pointer)); + + mmu->mapLogical = pointer; + + /* Construct page table read by GPU. */ + gcmkONERROR(gckOS_AllocateContiguous(mmu->os, + gcvFALSE, + &mmu->pageTableSize, + &mmu->pageTablePhysical, + (gctPOINTER)&mmu->pageTableLogical)); - mmu->pageTableLogical = pointer; /* Compute number of entries in page table. */ - mmu->pageTableEntries = mmu->pageTableSize / sizeof(gctUINT32); + gcmkSAFECASTSIZET(mmu->pageTableEntries, mmu->pageTableSize / sizeof(gctUINT32)); /* Mark all pages as free. */ - pageTable = mmu->pageTableLogical; + map = mmu->mapLogical; #if gcdMMU_CLEAR_VALUE - _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE); + _FillPageTable(mmu->pageTableLogical, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE); #endif - _WritePageEntry(pageTable, (mmu->pageTableEntries << 8) | gcvMMU_FREE); - _WritePageEntry(pageTable + 1, ~0U); + _WritePageEntry(map, (mmu->pageTableEntries << 8) | gcvMMU_FREE); + _WritePageEntry(map + 1, ~0U); mmu->heapList = 0; mmu->freeNodes = gcvFALSE; - - /* Set page table address. */ - gcmkONERROR( - gckHARDWARE_SetMMU(hardware, (gctPOINTER) mmu->pageTableLogical)); } else { @@ -811,9 +945,55 @@ _Construct( mmu->mtlbLogical = pointer; +#if gcdPROCESS_ADDRESS_SPACE + _FillPageTable(pointer, mmu->mtlbSize / 4, gcdMMU_MTLB_EXCEPTION); + + /* Allocate a array to store stlbs. */ + gcmkONERROR(gckOS_Allocate(os, mmu->mtlbSize, &mmu->stlbs)); + + gckOS_ZeroMemory(mmu->stlbs, mmu->mtlbSize); + + for (i = 0; i < gcdMAX_GPU_COUNT; i++) + { + gcmkONERROR(gckOS_AtomConstruct(os, &mmu->pageTableDirty[i])); + } + + _SetupProcessAddressSpace(mmu); + + /* Map kernel command buffer in MMU. */ + for (i = 0; i < gcdCOMMAND_QUEUES; i++) + { + gcmkONERROR(gckOS_GetPhysicalAddress( + mmu->os, + Kernel->command->queues[i].logical, + &physical + )); + + gcmkONERROR(gckMMU_FlatMapping(mmu, physical)); + } +#else /* Invalid all the entries. */ gcmkONERROR( gckOS_ZeroMemory(pointer, mmu->mtlbSize)); + + gcmkONERROR( + gckOS_QueryOption(mmu->os, "physBase", &physBase)); + + gcmkONERROR( + gckOS_QueryOption(mmu->os, "physSize", &physSize)); + + gcmkONERROR( + gckOS_CPUPhysicalToGPUPhysical(mmu->os, physBase, &gpuAddress)); + + /* Setup [physBase - physSize) flat mapping. */ + gcmkONERROR(_FillFlatMapping( + mmu, + gpuAddress, + physSize + )); + + gcmkONERROR(_SetupDynamicSpace(mmu)); +#endif } /* Return the gckMMU object pointer. */ @@ -827,15 +1007,17 @@ OnError: /* Roll back. */ if (mmu != gcvNULL) { - if (mmu->pageTableLogical != gcvNULL) + if (mmu->mapLogical != gcvNULL) { - /* Free the page table. */ + gcmkVERIFY_OK( + gckOS_Free(os, (gctPOINTER) mmu->mapLogical)); + + gcmkVERIFY_OK( gckOS_FreeContiguous(os, mmu->pageTablePhysical, (gctPOINTER) mmu->pageTableLogical, mmu->pageTableSize)); - } if (mmu->mtlbLogical != gcvNULL) @@ -854,15 +1036,6 @@ OnError: gckOS_DeleteMutex(os, mmu->pageTableMutex)); } -#ifdef __QNXNTO__ - if (mmu->nodeMutex != gcvNULL) - { - /* Delete the mutex. */ - gcmkVERIFY_OK( - gckOS_DeleteMutex(os, mmu->nodeMutex)); - } -#endif - /* Mark the gckMMU object as unknown. */ mmu->object.type = gcvOBJ_UNKNOWN; @@ -895,24 +1068,14 @@ _Destroy( IN gckMMU Mmu ) { -#ifdef __QNXNTO__ - gcuVIDMEM_NODE_PTR node, next; +#if gcdPROCESS_ADDRESS_SPACE + gctUINT32 i; #endif - gcmkHEADER_ARG("Mmu=0x%x", Mmu); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU); -#ifdef __QNXNTO__ - /* Free all associated virtual memory. */ - for (node = Mmu->nodeList; node != gcvNULL; node = next) - { - next = node->Virtual.next; - gcmkVERIFY_OK(gckVIDMEM_Free(node)); - } -#endif - while (Mmu->staticSTLB != gcvNULL) { gcsMMU_STLB_PTR pre = Mmu->staticSTLB; @@ -950,21 +1113,46 @@ _Destroy( Mmu->mtlbSize)); } - /* Free the page table. */ - gcmkVERIFY_OK( - gckOS_FreeContiguous(Mmu->os, - Mmu->pageTablePhysical, - (gctPOINTER) Mmu->pageTableLogical, - Mmu->pageTableSize)); + /* Free address space management table. */ + if (Mmu->mapLogical != gcvNULL) + { + gcmkVERIFY_OK( + gckOS_Free(Mmu->os, (gctPOINTER) Mmu->mapLogical)); + } -#ifdef __QNXNTO__ - /* Delete the node list mutex. */ - gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->nodeMutex)); -#endif + if (Mmu->pageTableLogical != gcvNULL) + { + /* Free page table. */ + gcmkVERIFY_OK( + gckOS_FreeContiguous(Mmu->os, + Mmu->pageTablePhysical, + (gctPOINTER) Mmu->pageTableLogical, + Mmu->pageTableSize)); + } /* Delete the page table mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex)); +#if gcdPROCESS_ADDRESS_SPACE + for (i = 0; i < Mmu->mtlbSize / 4; i++) + { + struct _gcsMMU_STLB *stlb = ((struct _gcsMMU_STLB **)Mmu->stlbs)[i]; + + if (stlb) + { + gcmkVERIFY_OK(gckOS_FreeContiguous( + Mmu->os, + stlb->physical, + stlb->logical, + stlb->size)); + + gcmkOS_SAFE_FREE(Mmu->os, stlb); + } + } + + gcmkOS_SAFE_FREE(Mmu->os, Mmu->stlbs); +#endif + /* Mark the gckMMU object as unknown. */ Mmu->object.type = gcvOBJ_UNKNOWN; @@ -993,7 +1181,7 @@ _AdjustIndex( { gceSTATUS status; gctUINT32 index = Index; - gctUINT32_PTR map = Mmu->pageTableLogical; + gctUINT32_PTR map = Mmu->mapLogical; gcmkHEADER(); @@ -1085,12 +1273,6 @@ gckMMU_Construct( gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu)); } - else if (Kernel->hardware->mmuVersion == 0) - { - /* Set page table address. */ - gcmkONERROR( - gckHARDWARE_SetMMU(Kernel->hardware, (gctPOINTER) sharedPageTable->mmu->pageTableLogical)); - } *Mmu = sharedPageTable->mmu; @@ -1166,6 +1348,8 @@ gckMMU_Destroy( ) { #if gcdSHARED_PAGETABLE + gckOS os = Mmu->os; + sharedPageTable->reference--; if (sharedPageTable->reference == 0) @@ -1175,7 +1359,7 @@ gckMMU_Destroy( gcmkVERIFY_OK(_Destroy(Mmu)); } - gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, sharedPageTable)); + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, sharedPageTable)); } return gcvSTATUS_OK; @@ -1229,9 +1413,10 @@ _AllocatePages( gceSTATUS status; gctBOOL mutex = gcvFALSE; gctUINT32 index = 0, previous = ~0U, left; - gctUINT32_PTR pageTable; + gctUINT32_PTR map; gctBOOL gotIt; gctUINT32 address; + gctUINT32 pageCount; gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount); @@ -1242,19 +1427,18 @@ _AllocatePages( if (PageCount > Mmu->pageTableEntries) { - gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.", - __FUNCTION__, __LINE__); - /* Not enough pages avaiable. */ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } + gcmkSAFECASTSIZET(pageCount, PageCount); + /* Grab the mutex. */ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE)); mutex = gcvTRUE; /* Cast pointer to page table. */ - for (pageTable = Mmu->pageTableLogical, gotIt = gcvFALSE; !gotIt;) + for (map = Mmu->mapLogical, gotIt = gcvFALSE; !gotIt;) { index = Mmu->heapList; @@ -1263,7 +1447,7 @@ _AllocatePages( gcmkONERROR(_AdjustIndex( Mmu, index, - PageCount, + pageCount, gcdVERTEX_START / gcmSIZEOF(gctUINT32), &index )); @@ -1273,11 +1457,11 @@ _AllocatePages( for (; !gotIt && (index < Mmu->pageTableEntries);) { /* Check the node type. */ - switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index]))) + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[index]))) { case gcvMMU_SINGLE: /* Single odes are valid if we only need 1 page. */ - if (PageCount == 1) + if (pageCount == 1) { gotIt = gcvTRUE; } @@ -1285,13 +1469,13 @@ _AllocatePages( { /* Move to next node. */ previous = index; - index = _ReadPageEntry(&pageTable[index]) >> 8; + index = _ReadPageEntry(&map[index]) >> 8; } break; case gcvMMU_FREE: /* Test if the node has enough space. */ - if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8)) + if (pageCount <= (_ReadPageEntry(&map[index]) >> 8)) { gotIt = gcvTRUE; } @@ -1299,7 +1483,7 @@ _AllocatePages( { /* Move to next node. */ previous = index; - index = _ReadPageEntry(&pageTable[index + 1]); + index = _ReadPageEntry(&map[index + 1]); } break; @@ -1319,45 +1503,42 @@ _AllocatePages( } else { - gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.", - __FUNCTION__, __LINE__); - /* Out of resources. */ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } } } - switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index]))) + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[index]))) { case gcvMMU_SINGLE: /* Unlink single node from free list. */ gcmkONERROR( - _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8)); + _Link(Mmu, previous, _ReadPageEntry(&map[index]) >> 8)); break; case gcvMMU_FREE: /* Check how many pages will be left. */ - left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount; + left = (_ReadPageEntry(&map[index]) >> 8) - pageCount; switch (left) { case 0: /* The entire node is consumed, just unlink it. */ gcmkONERROR( - _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1]))); + _Link(Mmu, previous, _ReadPageEntry(&map[index + 1]))); break; case 1: /* One page will remain. Convert the node to a single node and ** advance the index. */ - _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE); + _WritePageEntry(&map[index], (_ReadPageEntry(&map[index + 1]) << 8) | gcvMMU_SINGLE); index ++; break; default: /* Enough pages remain for a new node. However, we will just adjust ** the size of the current node and advance the index. */ - _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE); + _WritePageEntry(&map[index], (left << 8) | gcvMMU_FREE); index += left; break; } @@ -1365,10 +1546,10 @@ _AllocatePages( } /* Mark node as used. */ - gcmkONERROR(_FillPageTable(&pageTable[index], PageCount, gcvMMU_USED)); + gcmkONERROR(_FillPageTable(&map[index], pageCount, gcvMMU_USED)); /* Return pointer to page table. */ - *PageTable = &pageTable[index]; + *PageTable = &Mmu->pageTableLogical[index]; /* Build virtual address. */ if (Mmu->hardware->mmuVersion == 0) @@ -1440,9 +1621,10 @@ _FreePages( IN gctSIZE_T PageCount ) { - gctUINT32_PTR pageTable; + gctUINT32_PTR node; gceSTATUS status; gctBOOL acquired = gcvFALSE; + gctUINT32 pageCount; gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu", Mmu, PageTable, PageCount); @@ -1452,8 +1634,10 @@ _FreePages( gcmkVERIFY_ARGUMENT(PageTable != gcvNULL); gcmkVERIFY_ARGUMENT(PageCount > 0); - /* Convert the pointer. */ - pageTable = (gctUINT32_PTR) PageTable; + gcmkSAFECASTSIZET(pageCount, PageCount); + + /* Get the node by index. */ + node = Mmu->mapLogical + ((gctUINT32_PTR)PageTable - Mmu->pageTableLogical); gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE)); acquired = gcvTRUE; @@ -1461,36 +1645,28 @@ _FreePages( #if gcdMMU_CLEAR_VALUE if (Mmu->hardware->mmuVersion == 0) { - _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE); + _FillPageTable(PageTable, pageCount, gcdMMU_CLEAR_VALUE); } #endif if (PageCount == 1) { - /* Single page node. */ - _WritePageEntry(pageTable, - (~((1U<<8)-1)) | gcvMMU_SINGLE + /* Single page node. */ + _WritePageEntry(node, (~((1U<<8)-1)) | gcvMMU_SINGLE); #if gcdUSE_MMU_EXCEPTION - /* Enable exception */ - | 1 << 1 + /* Enable exception */ + _WritePageEntry(PageTable, (1 << 1)); #endif - ); } else { /* Mark the node as free. */ - _WritePageEntry(pageTable, - (PageCount << 8) | gcvMMU_FREE -#if gcdUSE_MMU_EXCEPTION - /* Enable exception */ - | 1 << 1 -#endif - ); - _WritePageEntry(pageTable + 1, ~0U); + _WritePageEntry(node, (pageCount << 8) | gcvMMU_FREE); + _WritePageEntry(node + 1, ~0U); #if gcdUSE_MMU_EXCEPTION /* Enable exception */ - gcmkVERIFY_OK(_FillPageTable(pageTable + 2, PageCount - 2, 1 << 1)); + gcmkVERIFY_OK(_FillPageTable(PageTable, pageCount, 1 << 1)); #endif } @@ -1523,7 +1699,7 @@ gckMMU_AllocatePages( ) { return gckMMU_AllocatePagesEx( - Mmu, PageCount, gcvSURF_UNKNOWN, PageTable, Address); + Mmu, PageCount, gcvSURF_TYPE_UNKNOWN, PageTable, Address); } gceSTATUS @@ -1630,93 +1806,6 @@ gckMMU_FreePages( #endif } -gceSTATUS -gckMMU_Enable( - IN gckMMU Mmu, - IN gctUINT32 PhysBaseAddr, - IN gctUINT32 PhysSize - ) -{ - gceSTATUS status; -#if gcdSHARED_PAGETABLE - gckHARDWARE hardware; - gctINT i; -#endif - - gcmkHEADER_ARG("Mmu=0x%x", Mmu); - - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU); - -#if gcdSHARED_PAGETABLE - if (Mmu->enabled) - { - gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP); - return gcvSTATUS_SKIP; - } -#endif - - if (Mmu->hardware->mmuVersion == 0) - { - /* Success. */ - gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP); - return gcvSTATUS_SKIP; - } - else - { - if (PhysSize != 0) - { - gcmkONERROR(_FillFlatMapping( - Mmu, - PhysBaseAddr, - PhysSize - )); - } - - gcmkONERROR(_SetupDynamicSpace(Mmu)); - -#if gcdSHARED_PAGETABLE - for(i = 0; i < gcdMAX_GPU_COUNT; i++) - { - hardware = sharedPageTable->hardwares[i]; - if (hardware != gcvNULL) - { - gcmkONERROR( - gckHARDWARE_SetMMUv2( - hardware, - gcvTRUE, - Mmu->mtlbLogical, - gcvMMU_MODE_4K, - (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE, - gcvFALSE - )); - } - } -#else - gcmkONERROR( - gckHARDWARE_SetMMUv2( - Mmu->hardware, - gcvTRUE, - Mmu->mtlbLogical, - gcvMMU_MODE_4K, - (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE, - gcvFALSE - )); -#endif - - Mmu->enabled = gcvTRUE; - - /* Success. */ - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - } - -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; -} - gceSTATUS gckMMU_SetPage( IN gckMMU Mmu, @@ -1731,7 +1820,6 @@ gckMMU_SetPage( gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical; #endif - gctUINT32 data; gcmkHEADER_ARG("Mmu=0x%x", Mmu); /* Verify the arguments. */ @@ -1741,15 +1829,13 @@ gckMMU_SetPage( if (Mmu->hardware->mmuVersion == 0) { - data = PageAddress; + _WritePageEntry(PageEntry, PageAddress); } else { - data = _SetPage(PageAddress); + _WritePageEntry(PageEntry, _SetPage(PageAddress)); } - _WritePageEntry(PageEntry, data); - #if gcdMIRROR_PAGETABLE for (i = 0; i < (gctINT)mirrorPageTable->reference; i++) { @@ -1771,130 +1857,272 @@ gckMMU_SetPage( } #endif + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; } -#ifdef __QNXNTO__ +#if gcdPROCESS_ADDRESS_SPACE gceSTATUS -gckMMU_InsertNode( +gckMMU_GetPageEntry( IN gckMMU Mmu, - IN gcuVIDMEM_NODE_PTR Node) + IN gctUINT32 Address, + IN gctUINT32_PTR *PageTable + ) { gceSTATUS status; - gctBOOL mutex = gcvFALSE; + struct _gcsMMU_STLB *stlb; + struct _gcsMMU_STLB **stlbs = Mmu->stlbs; + gctUINT32 offset = _MtlbOffset(Address); + gctUINT32 mtlbEntry; + gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE); - gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node); + gcmkHEADER_ARG("Mmu=0x%x", Mmu); + /* Verify the arguments. */ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU); + gcmkVERIFY_ARGUMENT((Address & 0xFFF) == 0); - gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE)); - mutex = gcvTRUE; + stlb = stlbs[offset]; - Node->Virtual.next = Mmu->nodeList; - Mmu->nodeList = Node; + if (stlb == gcvNULL) + { + gcmkONERROR(_AllocateStlb(Mmu->os, &stlb)); - gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex)); + mtlbEntry = stlb->physBase + | gcdMMU_MTLB_4K_PAGE + | gcdMMU_MTLB_PRESENT + ; - gcmkFOOTER(); + if (ace) + { + mtlbEntry = mtlbEntry + /* Secure */ + | (1 << 4); + } + + /* Insert Slave TLB address to Master TLB entry.*/ + _WritePageEntry(Mmu->mtlbLogical + offset, mtlbEntry); + + /* Record stlb. */ + stlbs[offset] = stlb; + } + + *PageTable = &stlb->logical[_StlbOffset(Address)]; + + /* Success. */ + gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: - if (mutex) + gcmkFOOTER(); + return status; +} + +gceSTATUS +_CheckMap( + IN gckMMU Mmu + ) +{ + gceSTATUS status; + gctUINT32_PTR map = Mmu->mapLogical; + gctUINT32 index; + + for (index = Mmu->heapList; index < Mmu->pageTableEntries;) { - gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex)); + /* Check the node type. */ + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[index]))) + { + case gcvMMU_SINGLE: + /* Move to next node. */ + index = _ReadPageEntry(&map[index]) >> 8; + break; + + case gcvMMU_FREE: + /* Move to next node. */ + index = _ReadPageEntry(&map[index + 1]); + break; + + default: + gcmkFATAL("MMU table correcupted at index [%u] = %x!", index, map[index]); + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } } - gcmkFOOTER(); + return gcvSTATUS_OK; + +OnError: return status; } gceSTATUS -gckMMU_RemoveNode( +gckMMU_FlatMapping( IN gckMMU Mmu, - IN gcuVIDMEM_NODE_PTR Node) + IN gctUINT32 Physical + ) { gceSTATUS status; - gctBOOL mutex = gcvFALSE; - gcuVIDMEM_NODE_PTR *iter; + gctUINT32 index = _AddressToIndex(Mmu, Physical); + gctUINT32 i; + gctBOOL gotIt = gcvFALSE; + gctUINT32_PTR map = Mmu->mapLogical; + gctUINT32 previous = ~0U; + gctUINT32_PTR pageTable; - gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node); + gckMMU_GetPageEntry(Mmu, Physical, &pageTable); - gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU); + _WritePageEntry(pageTable, _SetPage(Physical)); - gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE)); - mutex = gcvTRUE; - - for (iter = &Mmu->nodeList; *iter; iter = &(*iter)->Virtual.next) + if (map) { - if (*iter == Node) + /* Find node which contains index. */ + for (i = 0; !gotIt && (i < Mmu->pageTableEntries);) + { + gctUINT32 numPages; + + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[i]))) + { + case gcvMMU_SINGLE: + if (i == index) + { + gotIt = gcvTRUE; + } + else + { + previous = i; + i = _ReadPageEntry(&map[i]) >> 8; + } + break; + + case gcvMMU_FREE: + numPages = _ReadPageEntry(&map[i]) >> 8; + if (index >= i && index < i + numPages) + { + gotIt = gcvTRUE; + } + else + { + previous = i; + i = _ReadPageEntry(&map[i + 1]); + } + break; + + default: + gcmkFATAL("MMU table correcupted at index %u!", index); + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } + } + + switch (gcmENTRY_TYPE(_ReadPageEntry(&map[i]))) { - *iter = Node->Virtual.next; + case gcvMMU_SINGLE: + /* Unlink single node from free list. */ + gcmkONERROR( + _Link(Mmu, previous, _ReadPageEntry(&map[i]) >> 8)); + break; + + case gcvMMU_FREE: + /* Split the node. */ + { + gctUINT32 start; + gctUINT32 next = _ReadPageEntry(&map[i+1]); + gctUINT32 total = _ReadPageEntry(&map[i]) >> 8; + gctUINT32 countLeft = index - i; + gctUINT32 countRight = total - countLeft - 1; + + if (countLeft) + { + start = i; + _AddFree(Mmu, previous, start, countLeft); + previous = start; + } + + if (countRight) + { + start = index + 1; + _AddFree(Mmu, previous, start, countRight); + previous = start; + } + + _Link(Mmu, previous, next); + } break; } } - gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex)); - - gcmkFOOTER(); return gcvSTATUS_OK; OnError: - if (mutex) - { - gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex)); - } - gcmkFOOTER(); + /* Roll back. */ return status; } + + gceSTATUS -gckMMU_FreeHandleMemory( - IN gckKERNEL Kernel, +gckMMU_FreePagesEx( IN gckMMU Mmu, - IN gctUINT32 Pid + IN gctUINT32 Address, + IN gctSIZE_T PageCount ) { + gctUINT32_PTR node; gceSTATUS status; - gctBOOL acquired = gcvFALSE; - gcuVIDMEM_NODE_PTR curr, next; - gcmkHEADER_ARG("Kernel=0x%x, Mmu=0x%x Pid=%u", Kernel, Mmu, Pid); +#if gcdUSE_MMU_EXCEPTION + gctUINT32 i; + struct _gcsMMU_STLB *stlb; + struct _gcsMMU_STLB **stlbs = Mmu->stlbs; +#endif + + gcmkHEADER_ARG("Mmu=0x%x Address=0x%x PageCount=%lu", + Mmu, Address, PageCount); - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + /* Verify the arguments. */ gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU); + gcmkVERIFY_ARGUMENT(PageCount > 0); - gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE)); - acquired = gcvTRUE; + /* Get the node by index. */ + node = Mmu->mapLogical + _AddressToIndex(Mmu, Address); - for (curr = Mmu->nodeList; curr != gcvNULL; curr = next) + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE)); + + if (PageCount == 1) { - next = curr->Virtual.next; + /* Single page node. */ + _WritePageEntry(node, (~((1U<<8)-1)) | gcvMMU_SINGLE); + } + else + { + /* Mark the node as free. */ + _WritePageEntry(node, (PageCount << 8) | gcvMMU_FREE); + _WritePageEntry(node + 1, ~0U); + } - if (curr->Virtual.processID == Pid) - { - while (curr->Virtual.unlockPendings[Kernel->core] == 0 && curr->Virtual.lockeds[Kernel->core] > 0) - { - gcmkONERROR(gckVIDMEM_Unlock(Kernel, curr, gcvSURF_TYPE_UNKNOWN, gcvNULL)); - } + /* We have free nodes. */ + Mmu->freeNodes = gcvTRUE; - gcmkVERIFY_OK(gckVIDMEM_Free(curr)); - } +#if gcdUSE_MMU_EXCEPTION + for (i = 0; i < PageCount; i++) + { + /* Get */ + stlb = stlbs[_MtlbOffset(Address)]; + + /* Enable exception */ + stlb->logical[_StlbOffset(Address)] = gcdMMU_STLB_EXCEPTION; } +#endif - gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex)); - gcmkFOOTER(); + + /* Success. */ + gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: - if (acquired) - { - gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex)); - } - gcmkFOOTER(); return status; } @@ -1902,42 +2130,53 @@ OnError: gceSTATUS gckMMU_Flush( - IN gckMMU Mmu + IN gckMMU Mmu, + IN gceSURF_TYPE Type ) { gckHARDWARE hardware; -#if gcdSHARED_PAGETABLE + gctUINT32 mask; gctINT i; + + if (Type == gcvSURF_VERTEX || Type == gcvSURF_INDEX) + { + mask = gcvPAGE_TABLE_DIRTY_BIT_FE; + } + else + { + mask = gcvPAGE_TABLE_DIRTY_BIT_OTHER; + } + +#if gcdPROCESS_ADDRESS_SPACE + for (i = 0; i < gcdMAX_GPU_COUNT; i++) + { + gcmkVERIFY_OK( + gckOS_AtomSetMask(Mmu->pageTableDirty[i], mask)); + } +#else +#if gcdSHARED_PAGETABLE for (i = 0; i < gcdMAX_GPU_COUNT; i++) { -#if gcdENABLE_VG - if (i == gcvCORE_VG) - { - continue; - } -#endif hardware = sharedPageTable->hardwares[i]; if (hardware) { - /* Notify cores who use this page table. */ - gcmkVERIFY_OK( - gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1)); + gcmkVERIFY_OK(gckOS_AtomSetMask(hardware->pageTableDirty, mask)); } } #elif gcdMIRROR_PAGETABLE - gctINT i; - for (i = 0; i < mirrorPageTable->reference; i++) + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++) { hardware = mirrorPageTable->hardwares[i]; /* Notify cores who use this page table. */ gcmkVERIFY_OK( - gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1)); + gckOS_AtomSetMask(hardware->pageTableDirty, mask)); } #else hardware = Mmu->hardware; gcmkVERIFY_OK( - gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1)); + gckOS_AtomSetMask(hardware->pageTableDirty, mask)); +#endif #endif return gcvSTATUS_OK; @@ -1949,20 +2188,37 @@ gckMMU_DumpPageTableEntry( IN gctUINT32 Address ) { +#if gcdPROCESS_ADDRESS_SPACE + gcsMMU_STLB_PTR *stlbs = Mmu->stlbs; + gcsMMU_STLB_PTR stlbDesc = stlbs[_MtlbOffset(Address)]; +#else gctUINT32_PTR pageTable; gctUINT32 index; gctUINT32 mtlb, stlb; +#endif gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address); gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU); gcmkASSERT(Mmu->hardware->mmuVersion > 0); +#if gcdPROCESS_ADDRESS_SPACE + if (stlbDesc) + { + gcmkPRINT(" STLB entry = 0x%08X", + _ReadPageEntry(&stlbDesc->logical[_StlbOffset(Address)])); + } + else + { + gcmkPRINT(" MTLB entry is empty."); + } +#else mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT; - stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT; - if (Address >= 0x80000000) + if (mtlb >= Mmu->dynamicMappingStart) { + stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT; + pageTable = Mmu->pageTableLogical; index = (mtlb - Mmu->dynamicMappingStart) @@ -1971,6 +2227,28 @@ gckMMU_DumpPageTableEntry( gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index)); } + else + { + gcsMMU_STLB_PTR stlbObj = Mmu->staticSTLB; + gctUINT32 entry = Mmu->mtlbLogical[mtlb]; + + stlb = (Address & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT; + + entry &= 0xFFFFFFF0; + + while (stlbObj) + { + + if (entry == stlbObj->physBase) + { + gcmkPRINT(" Page table entry = 0x%08X", stlbObj->logical[stlb]); + break; + } + + stlbObj = stlbObj->next; + } + } +#endif gcmkFOOTER_NO(); return gcvSTATUS_OK; 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 0c20290166a0..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -46,7 +46,7 @@ */ gceSTATUS gckVGMMU_Construct( IN gckVGKERNEL Kernel, - IN gctSIZE_T MmuSize, + IN gctUINT32 MmuSize, OUT gckVGMMU * Mmu ) { @@ -107,7 +107,7 @@ gceSTATUS gckVGMMU_Construct( } /* Allocate the page table. */ - mmu->pageTableSize = MmuSize; + mmu->pageTableSize = (gctUINT32)MmuSize; status = gckOS_AllocateContiguous(os, gcvFALSE, &mmu->pageTableSize, @@ -133,7 +133,7 @@ gceSTATUS gckVGMMU_Construct( } /* Compute number of entries in page table. */ - mmu->entryCount = mmu->pageTableSize / sizeof(gctUINT32); + mmu->entryCount = (gctUINT32)mmu->pageTableSize / sizeof(gctUINT32); mmu->entry = 0; /* Mark the entire page table as available. */ @@ -313,7 +313,7 @@ gceSTATUS gckVGMMU_AllocatePages( } /* Compute the tail for this allocation. */ - tail = Mmu->entryCount - PageCount; + tail = Mmu->entryCount - (gctUINT32)PageCount; /* Walk all entries until we find enough slots. */ for (index = Mmu->entry; index <= tail;) @@ -395,7 +395,7 @@ gceSTATUS gckVGMMU_AllocatePages( if (status >= 0) { /* Update current entry into page table. */ - Mmu->entry = index + PageCount; + Mmu->entry = index + (gctUINT32)PageCount; /* Return pointer to page table. */ *PageTable = (gctUINT32 *) Mmu->pageTableLogical + index; 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 df7579da7587..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 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 1e764c25710b..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 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 new file mode 100644 index 000000000000..54e5ce39f44c --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c @@ -0,0 +1,239 @@ +/**************************************************************************** +* +* 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_precomp.h" + + + + +#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 d7b8e0873252..eac565cd65f9 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -23,8 +23,6 @@ #if gcdENABLE_VG -#define ENABLE_VG_TRY_VIRTUAL_MEMORY 0 - #define _GC_OBJ_ZONE gcvZONE_VG /******************************************************************************\ @@ -251,11 +249,11 @@ gceSTATUS gckVGKERNEL_Destroy( ** Allocated node. */ gceSTATUS -gckKERNEL_AllocateLinearMemory( +gckVGKERNEL_AllocateLinearMemory( IN gckKERNEL Kernel, IN OUT gcePOOL * Pool, IN gctSIZE_T Bytes, - IN gctSIZE_T Alignment, + IN gctUINT32 Alignment, IN gceSURF_TYPE Type, OUT gcuVIDMEM_NODE_PTR * Node ) @@ -305,13 +303,13 @@ gckKERNEL_AllocateLinearMemory( if (status == gcvSTATUS_OK) { - if(*Pool == gcvPOOL_SYSTEM) - Type |= gcvSURF_VG; /* Allocate memory. */ - status = gckVIDMEM_AllocateLinear(videoMemory, + status = gckVIDMEM_AllocateLinear(Kernel, + videoMemory, Bytes, Alignment, Type, + (*Pool == gcvPOOL_SYSTEM), Node); if (status == gcvSTATUS_OK) @@ -335,18 +333,11 @@ gckKERNEL_AllocateLinearMemory( else if (pool == gcvPOOL_SYSTEM) { /* Advance to virtual memory. */ -#if ENABLE_VG_TRY_VIRTUAL_MEMORY pool = gcvPOOL_VIRTUAL; -#else - /*VG non-contiguous memory support is not ready yet, disable it temporary*/ - status = gcvSTATUS_OUT_OF_MEMORY; - break; -#endif } else { /* Out of pools. */ - status = gcvSTATUS_OUT_OF_MEMORY; break; } } @@ -395,7 +386,6 @@ gceSTATUS gckVGKERNEL_Dispatch( { gceSTATUS status; gcsHAL_INTERFACE * kernelInterface = Interface; - gcuVIDMEM_NODE_PTR node; gctUINT32 processID; gckKERNEL kernel = Kernel; gctPOINTER info = gcvNULL; @@ -443,7 +433,7 @@ gceSTATUS gckVGKERNEL_Dispatch( case gcvHAL_ALLOCATE_NON_PAGED_MEMORY: bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes; /* Allocate non-paged memory. */ - gcmkERR_BREAK(gckOS_AllocateContiguous( + gcmkERR_BREAK(gckOS_AllocateNonPagedMemory( Kernel->os, gcvTRUE, &bytes, @@ -516,97 +506,28 @@ gceSTATUS gckVGKERNEL_Dispatch( break; case gcvHAL_ALLOCATE_VIDEO_MEMORY: - { - gctSIZE_T bytes; - gctUINT32 bitsPerPixel; - gctUINT32 bits; - - /* Align width and height to tiles. */ - gcmkERR_BREAK(gckVGHARDWARE_AlignToTile( - Kernel->vg->hardware, - kernelInterface->u.AllocateVideoMemory.type, - &kernelInterface->u.AllocateVideoMemory.width, - &kernelInterface->u.AllocateVideoMemory.height - )); - - /* Convert format into bytes per pixel and bytes per tile. */ - gcmkERR_BREAK(gckVGHARDWARE_ConvertFormat( - Kernel->vg->hardware, - kernelInterface->u.AllocateVideoMemory.format, - &bitsPerPixel, - gcvNULL - )); - - /* Compute number of bits for the allocation. */ - bits - = kernelInterface->u.AllocateVideoMemory.width - * kernelInterface->u.AllocateVideoMemory.height - * kernelInterface->u.AllocateVideoMemory.depth - * bitsPerPixel; - - /* Compute number of bytes for the allocation. */ - bytes = gcmALIGN(bits, 8) / 8; - - /* Allocate memory. */ - gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory( - Kernel, - &kernelInterface->u.AllocateVideoMemory.pool, - bytes, - 64, - kernelInterface->u.AllocateVideoMemory.type, - &node - )); - - kernelInterface->u.AllocateVideoMemory.node = gcmPTR_TO_UINT64(node); - } + gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED); break; case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY: /* Allocate memory. */ gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory( - Kernel, + Kernel, processID, &kernelInterface->u.AllocateLinearVideoMemory.pool, kernelInterface->u.AllocateLinearVideoMemory.bytes, kernelInterface->u.AllocateLinearVideoMemory.alignment, kernelInterface->u.AllocateLinearVideoMemory.type, - &node + kernelInterface->u.AllocateLinearVideoMemory.flag, + &kernelInterface->u.AllocateLinearVideoMemory.node )); - gcmkERR_BREAK(gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY, - node, - gcvNULL, - kernelInterface->u.AllocateLinearVideoMemory.bytes - )); - - kernelInterface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node); break; - case gcvHAL_FREE_VIDEO_MEMORY: - node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node); -#ifdef __QNXNTO__ - /* Unmap the video memory */ - - if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) && - (node->VidMem.logical != gcvNULL)) - { - gckKERNEL_UnmapVideoMemory(Kernel, - node->VidMem.logical, - processID, - node->VidMem.bytes); - node->VidMem.logical = gcvNULL; - } -#endif /* __QNXNTO__ */ - + case gcvHAL_RELEASE_VIDEO_MEMORY: /* Free video memory. */ - gcmkERR_BREAK(gckVIDMEM_Free( - node - )); - - gcmkERR_BREAK(gckKERNEL_RemoveProcessDB( - Kernel, - processID, gcvDB_VIDEO_MEMORY, - node + gcmkERR_BREAK(gckKERNEL_ReleaseVideoMemory( + Kernel, processID, + (gctUINT32)kernelInterface->u.ReleaseVideoMemory.node )); break; @@ -645,6 +566,9 @@ gceSTATUS gckVGKERNEL_Dispatch( )); kernelInterface->u.MapUserMemory.info = gcmPTR_TO_NAME(info); + + /* Clear temp storage. */ + info = gcvNULL; break; case gcvHAL_UNMAP_USER_MEMORY: @@ -657,111 +581,18 @@ gceSTATUS gckVGKERNEL_Dispatch( gcmNAME_TO_PTR(kernelInterface->u.UnmapUserMemory.info), kernelInterface->u.UnmapUserMemory.address )); + gcmRELEASE_NAME(kernelInterface->u.UnmapUserMemory.info); break; - case gcvHAL_LOCK_VIDEO_MEMORY: - node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node); - - /* Lock video memory. */ - gcmkERR_BREAK( - gckVIDMEM_Lock(Kernel, - node, - gcvFALSE, - &Interface->u.LockVideoMemory.address)); - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - /* Map video memory address into user space. */ -#ifdef __QNXNTO__ - if (node->VidMem.logical == gcvNULL) - { - gcmkONERROR( - gckKERNEL_MapVideoMemory(Kernel, - FromUser, - Interface->u.LockVideoMemory.address, - processID, - node->VidMem.bytes, - &node->VidMem.logical)); - } - - Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical); -#else - gcmkERR_BREAK( - gckKERNEL_MapVideoMemoryEx(Kernel, - gcvCORE_VG, - FromUser, - Interface->u.LockVideoMemory.address, - &logical)); - Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical); -#endif - } - else - { - Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical); - - /* Success. */ - status = gcvSTATUS_OK; - } - -#if gcdSECURE_USER - /* Return logical address as physical address. */ - Interface->u.LockVideoMemory.address = - (gctUINT32)(Interface->u.LockVideoMemory.memory); -#endif - gcmkERR_BREAK( - gckKERNEL_AddProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_LOCKED, - node, - gcvNULL, - 0)); + case gcvHAL_LOCK_VIDEO_MEMORY: + gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, gcvCORE_VG, processID, FromUser, Interface)); break; case gcvHAL_UNLOCK_VIDEO_MEMORY: - /* Unlock video memory. */ - node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node); - -#if gcdSECURE_USER - /* Save node information before it disappears. */ - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - logical = gcvNULL; - bytes = 0; - } - else - { - logical = node->Virtual.logical; - bytes = node->Virtual.bytes; - } -#endif - - /* Unlock video memory. */ - gcmkERR_BREAK( - gckVIDMEM_Unlock(Kernel, - node, - Interface->u.UnlockVideoMemory.type, - &Interface->u.UnlockVideoMemory.asynchroneous)); - -#if gcdSECURE_USER - /* Flush the translation cache for virtual surfaces. */ - if (logical != gcvNULL) - { - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel, - cache, - logical, - bytes)); - } -#endif - - if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE) - { - /* There isn't a event to unlock this node, remove record now */ - gcmkERR_BREAK( - gckKERNEL_RemoveProcessDB(Kernel, - processID, gcvDB_VIDEO_MEMORY_LOCKED, - node)); - } - + gcmkONERROR(gckKERNEL_UnlockVideoMemory(Kernel, processID, Interface)); break; + case gcvHAL_USER_SIGNAL: #if !USE_NEW_LINUX_SIGNAL /* Dispatch depends on the user signal subcommands. */ @@ -783,15 +614,16 @@ gceSTATUS gckVGKERNEL_Dispatch( break; case gcvUSER_SIGNAL_DESTROY: + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( + Kernel, + processID, gcvDB_SIGNAL, + gcmINT2PTR(Interface->u.UserSignal.id))); + /* Destroy the signal. */ gcmkERR_BREAK( gckOS_DestroyUserSignal(Kernel->os, Interface->u.UserSignal.id)); - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( - Kernel, - processID, gcvDB_SIGNAL, - gcmINT2PTR(Interface->u.UserSignal.id))); break; case gcvUSER_SIGNAL_SIGNAL: @@ -840,6 +672,112 @@ gceSTATUS gckVGKERNEL_Dispatch( gckOS_GetBaseAddress(Kernel->os, &kernelInterface->u.GetBaseAddress.baseAddress)); break; + case gcvHAL_IMPORT_VIDEO_MEMORY: + gcmkONERROR(gckVIDMEM_NODE_Import(Kernel, + Interface->u.ImportVideoMemory.name, + &Interface->u.ImportVideoMemory.handle)); + gcmkONERROR(gckKERNEL_AddProcessDB(Kernel, + processID, gcvDB_VIDEO_MEMORY, + gcmINT2PTR(Interface->u.ImportVideoMemory.handle), + gcvNULL, + 0)); + break; + + case gcvHAL_NAME_VIDEO_MEMORY: + gcmkONERROR(gckVIDMEM_NODE_Name(Kernel, + 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 b6c6d7e3bd50..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 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 5699996125cd..237b85674906 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -91,16 +91,8 @@ _Split( node->VidMem.pool = Node->VidMem.pool; node->VidMem.physical = Node->VidMem.physical; #ifdef __QNXNTO__ -#if gcdUSE_VIDMEM_PER_PID - gcmkASSERT(Node->VidMem.physical != 0); - gcmkASSERT(Node->VidMem.logical != gcvNULL); - node->VidMem.processID = Node->VidMem.processID; - node->VidMem.physical = Node->VidMem.physical + Bytes; - node->VidMem.logical = Node->VidMem.logical + Bytes; -#else node->VidMem.processID = 0; node->VidMem.logical = gcvNULL; -#endif #endif /* Insert node behind specified node. */ @@ -150,15 +142,6 @@ _Merge( /* Save pointer to next node. */ node = Node->VidMem.next; -#if gcdUSE_VIDMEM_PER_PID - /* Check if the nodes are adjacent physically. */ - if ( ((Node->VidMem.physical + Node->VidMem.bytes) != node->VidMem.physical) || - ((Node->VidMem.logical + Node->VidMem.bytes) != node->VidMem.logical) ) - { - /* Can't merge. */ - return gcvSTATUS_OK; - } -#else /* This is a good time to make sure the heap is not corrupted. */ if (Node->VidMem.offset + Node->VidMem.bytes != node->VidMem.offset) @@ -168,7 +151,6 @@ _Merge( Node->VidMem.offset + Node->VidMem.bytes == node->VidMem.offset); return gcvSTATUS_HEAP_CORRUPTED; } -#endif /* Adjust byte count. */ Node->VidMem.bytes += node->VidMem.bytes; @@ -211,7 +193,7 @@ _Merge( gceSTATUS gckVIDMEM_ConstructVirtual( IN gckKERNEL Kernel, - IN gctBOOL Contiguous, + IN gctUINT32 Flag, IN gctSIZE_T Bytes, OUT gcuVIDMEM_NODE_PTR * Node ) @@ -222,7 +204,7 @@ gckVIDMEM_ConstructVirtual( gctPOINTER pointer = gcvNULL; gctINT i; - gcmkHEADER_ARG("Kernel=0x%x Contiguous=%d Bytes=%lu", Kernel, Contiguous, Bytes); + gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); @@ -240,8 +222,11 @@ gckVIDMEM_ConstructVirtual( /* Initialize gcuVIDMEM_NODE union for virtual memory. */ node->Virtual.kernel = Kernel; - node->Virtual.contiguous = Contiguous; + node->Virtual.contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS; node->Virtual.logical = gcvNULL; +#if gcdENABLE_VG + node->Virtual.kernelVirtual = gcvNULL; +#endif for (i = 0; i < gcdMAX_GPU_COUNT; i++) { @@ -250,44 +235,16 @@ gckVIDMEM_ConstructVirtual( node->Virtual.lockKernels[i] = gcvNULL; } - node->Virtual.mutex = gcvNULL; - gcmkONERROR(gckOS_GetProcessID(&node->Virtual.processID)); -#ifdef __QNXNTO__ - node->Virtual.next = gcvNULL; - node->Virtual.freePending = gcvFALSE; - for (i = 0; i < gcdMAX_GPU_COUNT; i++) - { - node->Virtual.unlockPendings[i] = gcvFALSE; - } -#endif - - node->Virtual.freed = gcvFALSE; - - gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO))); - - /* Create the mutex. */ - gcmkONERROR( - gckOS_CreateMutex(os, &node->Virtual.mutex)); - /* Allocate the virtual memory. */ gcmkONERROR( gckOS_AllocatePagedMemoryEx(os, - node->Virtual.contiguous, + Flag, node->Virtual.bytes = Bytes, + &node->Virtual.gid, &node->Virtual.physical)); -#ifdef __QNXNTO__ - /* Register. */ -#if gcdENABLE_VG - if (Kernel->core != gcvCORE_VG) -#endif - { - gckMMU_InsertNode(Kernel->mmu, node); - } -#endif - /* Return pointer to the gcuVIDMEM_NODE union. */ *Node = node; @@ -303,12 +260,6 @@ OnError: /* Roll back. */ if (node != gcvNULL) { - if (node->Virtual.mutex != gcvNULL) - { - /* Destroy the mutex. */ - gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->Virtual.mutex)); - } - /* Free the structure. */ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node)); } @@ -339,7 +290,6 @@ gckVIDMEM_DestroyVirtual( ) { gckOS os; - gctINT i; gcmkHEADER_ARG("Node=0x%x", Node); @@ -350,43 +300,6 @@ gckVIDMEM_DestroyVirtual( os = Node->Virtual.kernel->os; gcmkVERIFY_OBJECT(os, gcvOBJ_OS); -#ifdef __QNXNTO__ - /* Unregister. */ -#if gcdENABLE_VG - if (Node->Virtual.kernel->core != gcvCORE_VG) -#endif - { - gcmkVERIFY_OK( - gckMMU_RemoveNode(Node->Virtual.kernel->mmu, Node)); - } -#endif - - /* Delete the mutex. */ - gcmkVERIFY_OK(gckOS_DeleteMutex(os, Node->Virtual.mutex)); - - for (i = 0; i < gcdMAX_GPU_COUNT; i++) - { - if (Node->Virtual.pageTables[i] != gcvNULL) - { -#if gcdENABLE_VG - if (i == gcvCORE_VG) - { - /* Free the pages. */ - gcmkVERIFY_OK(gckVGMMU_FreePages(Node->Virtual.lockKernels[i]->vg->mmu, - Node->Virtual.pageTables[i], - Node->Virtual.pageCount)); - } - else -#endif - { - /* Free the pages. */ - gcmkVERIFY_OK(gckMMU_FreePages(Node->Virtual.lockKernels[i]->mmu, - Node->Virtual.pageTables[i], - Node->Virtual.pageCount)); - } - } - } - /* Delete the gcuVIDMEM_NODE union. */ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node)); @@ -441,6 +354,8 @@ gckVIDMEM_Construct( gcuVIDMEM_NODE_PTR node; gctINT i, banks = 0; gctPOINTER pointer = gcvNULL; + gctUINT32 heapBytes; + gctUINT32 bankSize; gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu " "BankSize=%lu", @@ -451,6 +366,9 @@ gckVIDMEM_Construct( gcmkVERIFY_ARGUMENT(Bytes > 0); gcmkVERIFY_ARGUMENT(Memory != gcvNULL); + gcmkSAFECASTSIZET(heapBytes, Bytes); + gcmkSAFECASTSIZET(bankSize, BankSize); + /* Allocate the gckVIDMEM object. */ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckVIDMEM), &pointer)); @@ -462,35 +380,32 @@ gckVIDMEM_Construct( /* Set video memory heap information. */ memory->baseAddress = BaseAddress; - memory->bytes = Bytes; - memory->freeBytes = Bytes; + memory->bytes = heapBytes; + memory->freeBytes = heapBytes; memory->threshold = Threshold; memory->mutex = gcvNULL; -#if gcdUSE_VIDMEM_PER_PID - gcmkONERROR(gckOS_GetProcessID(&memory->pid)); -#endif BaseAddress = 0; /* Walk all possible banks. */ for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i) { - gctSIZE_T bytes; + gctUINT32 bytes; if (BankSize == 0) { /* Use all bytes for the first bank. */ - bytes = Bytes; + bytes = heapBytes; } else { /* Compute number of bytes for this bank. */ - bytes = gcmALIGN(BaseAddress + 1, BankSize) - BaseAddress; + bytes = gcmALIGN(BaseAddress + 1, bankSize) - BaseAddress; - if (bytes > Bytes) + if (bytes > heapBytes) { /* Make sure we don't exceed the total number of bytes. */ - bytes = Bytes; + bytes = heapBytes; } } @@ -525,24 +440,13 @@ gckVIDMEM_Construct( node->VidMem.locked = 0; -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG - node->VidMem.kernelVirtual = gcvNULL; -#endif - - gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO))); - #ifdef __QNXNTO__ -#if gcdUSE_VIDMEM_PER_PID - node->VidMem.processID = memory->pid; - node->VidMem.physical = memory->baseAddress + BaseAddress; - gcmkONERROR(gckOS_GetLogicalAddressProcess(Os, - node->VidMem.processID, - node->VidMem.physical, - &node->VidMem.logical)); -#else node->VidMem.processID = 0; node->VidMem.logical = gcvNULL; #endif + +#if gcdENABLE_VG + node->VidMem.kernelVirtual = gcvNULL; #endif /* Initialize the linked list of nodes. */ @@ -556,7 +460,7 @@ gckVIDMEM_Construct( /* Adjust address for next bank. */ BaseAddress += bytes; - Bytes -= bytes; + heapBytes -= bytes; banks ++; } @@ -702,89 +606,6 @@ gckVIDMEM_Destroy( return gcvSTATUS_OK; } -/******************************************************************************* -** -** gckVIDMEM_Allocate -** -** Allocate rectangular memory from the gckVIDMEM object. -** -** INPUT: -** -** gckVIDMEM Memory -** Pointer to an gckVIDMEM object. -** -** gctUINT Width -** Width of rectangle to allocate. Make sure the width is properly -** aligned. -** -** gctUINT Height -** Height of rectangle to allocate. Make sure the height is properly -** aligned. -** -** gctUINT Depth -** Depth of rectangle to allocate. This equals to the number of -** rectangles to allocate contiguously (i.e., for cubic maps and volume -** textures). -** -** gctUINT BytesPerPixel -** Number of bytes per pixel. -** -** gctUINT32 Alignment -** Byte alignment for allocation. -** -** gceSURF_TYPE Type -** Type of surface to allocate (use by bank optimization). -** -** OUTPUT: -** -** gcuVIDMEM_NODE_PTR * Node -** Pointer to a variable that will hold the allocated memory node. -*/ -gceSTATUS -gckVIDMEM_Allocate( - IN gckVIDMEM Memory, - IN gctUINT Width, - IN gctUINT Height, - IN gctUINT Depth, - IN gctUINT BytesPerPixel, - IN gctUINT32 Alignment, - IN gceSURF_TYPE Type, - OUT gcuVIDMEM_NODE_PTR * Node - ) -{ - gctSIZE_T bytes; - gceSTATUS status; - - gcmkHEADER_ARG("Memory=0x%x Width=%u Height=%u Depth=%u BytesPerPixel=%u " - "Alignment=%u Type=%d", - Memory, Width, Height, Depth, BytesPerPixel, Alignment, - Type); - - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM); - gcmkVERIFY_ARGUMENT(Width > 0); - gcmkVERIFY_ARGUMENT(Height > 0); - gcmkVERIFY_ARGUMENT(Depth > 0); - gcmkVERIFY_ARGUMENT(BytesPerPixel > 0); - gcmkVERIFY_ARGUMENT(Node != gcvNULL); - - /* Compute linear size. */ - bytes = Width * Height * Depth * BytesPerPixel; - - /* Allocate through linear function. */ - gcmkONERROR( - gckVIDMEM_AllocateLinear(Memory, bytes, Alignment, Type, Node)); - - /* Success. */ - gcmkFOOTER_ARG("*Node=0x%x", *Node); - return gcvSTATUS_OK; - -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; -} - #if gcdENABLE_BANK_ALIGNMENT #if !gcdBANK_BIT_START @@ -820,6 +641,7 @@ OnError: */ static gceSTATUS _GetSurfaceBankAlignment( + IN gckKERNEL Kernel, IN gceSURF_TYPE Type, IN gctUINT32 BaseAddress, OUT gctUINT32_PTR AlignmentOffset @@ -857,8 +679,14 @@ _GetSurfaceBankAlignment( 0 : ((1 << (gcdBANK_BIT_END + 1)) + (2 << gcdBANK_BIT_START)) - (BaseAddress & byteMask); - /* Add a channel offset at the channel bit. */ - *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT); + /* Minimum 256 byte alignment needed for fast_msaa. */ + if ((gcdBANK_CHANNEL_BIT > 7) || + ((gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_FAST_MSAA) != gcvSTATUS_TRUE) && + (gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_SMALL_MSAA) != gcvSTATUS_TRUE))) + { + /* Add a channel offset at the channel bit. */ + *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT); + } break; default: @@ -874,6 +702,7 @@ _GetSurfaceBankAlignment( static gcuVIDMEM_NODE_PTR _FindNode( + IN gckKERNEL Kernel, IN gckVIDMEM Memory, IN gctINT Bank, IN gctSIZE_T Bytes, @@ -902,7 +731,13 @@ _FindNode( node->VidMem.bytes != 0; node = node->VidMem.nextFree) { + if (node->VidMem.bytes < Bytes) + { + continue; + } + gcmkONERROR(_GetSurfaceBankAlignment( + Kernel, Type, node->VidMem.memory->baseAddress + node->VidMem.offset, &bankAlignment)); @@ -935,8 +770,13 @@ _FindNode( node->VidMem.bytes != 0; node = node->VidMem.nextFree) { + gctUINT offset; - gctINT modulo = gckMATH_ModuloInt(node->VidMem.offset, *Alignment); + gctINT modulo; + + gcmkSAFECASTSIZET(offset, node->VidMem.offset); + + modulo = gckMATH_ModuloInt(offset, *Alignment); /* Compute number of bytes to skip for alignment. */ alignment = (*Alignment == 0) ? 0 : (*Alignment - modulo); @@ -982,6 +822,11 @@ OnError: ** gceSURF_TYPE Type ** Type of surface to allocate (use by bank optimization). ** +** gctBOOL Specified +** If user must use this pool, it should set Specified to gcvTRUE, +** otherwise allocator may reserve some memory for other usage, such +** as small block size allocation request. +** ** OUTPUT: ** ** gcuVIDMEM_NODE_PTR * Node @@ -989,10 +834,12 @@ OnError: */ gceSTATUS gckVIDMEM_AllocateLinear( + IN gckKERNEL Kernel, IN gckVIDMEM Memory, IN gctSIZE_T Bytes, IN gctUINT32 Alignment, IN gceSURF_TYPE Type, + IN gctBOOL Specified, OUT gcuVIDMEM_NODE_PTR * Node ) { @@ -1001,14 +848,10 @@ gckVIDMEM_AllocateLinear( gctUINT32 alignment; gctINT bank, i; gctBOOL acquired = gcvFALSE; -#if gcdSMALL_BLOCK_SIZE - gctBOOL force_allocate = (Type == gcvSURF_TILE_STATUS) || (Type & gcvSURF_VG); -#endif gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d", Memory, Bytes, Alignment, Type); - Type &= ~gcvSURF_VG; /* Verify the arguments. */ gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM); gcmkVERIFY_ARGUMENT(Bytes > 0); @@ -1019,7 +862,6 @@ gckVIDMEM_AllocateLinear( gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE)); acquired = gcvTRUE; -#if !gcdUSE_VIDMEM_PER_PID if (Bytes > Memory->freeBytes) { @@ -1027,11 +869,11 @@ gckVIDMEM_AllocateLinear( status = gcvSTATUS_OUT_OF_MEMORY; goto OnError; } -#endif #if gcdSMALL_BLOCK_SIZE - if ((!force_allocate) && (Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY)) + if ((Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY)) && (Bytes >= gcdSMALL_BLOCK_SIZE) + && (Specified == gcvFALSE) ) { /* The left memory is for small memory.*/ @@ -1045,12 +887,8 @@ gckVIDMEM_AllocateLinear( bank = Memory->mapping[Type]; alignment = Alignment; -#if gcdUSE_VIDMEM_PER_PID - if (Bytes <= Memory->freeBytes) - { -#endif /* Find a free node in the default bank. */ - node = _FindNode(Memory, bank, Bytes, Type, &alignment); + node = _FindNode(Kernel, Memory, bank, Bytes, Type, &alignment); /* Out of memory? */ if (node == gcvNULL) @@ -1059,7 +897,7 @@ gckVIDMEM_AllocateLinear( for (i = bank - 1; i >= 0; --i) { /* Find a free node inside the current bank. */ - node = _FindNode(Memory, i, Bytes, Type, &alignment); + node = _FindNode(Kernel, Memory, i, Bytes, Type, &alignment); if (node != gcvNULL) { break; @@ -1079,79 +917,19 @@ gckVIDMEM_AllocateLinear( } /* Find a free node inside the current bank. */ - node = _FindNode(Memory, i, Bytes, Type, &alignment); + node = _FindNode(Kernel, Memory, i, Bytes, Type, &alignment); if (node != gcvNULL) { break; } } } -#if gcdUSE_VIDMEM_PER_PID - } -#endif if (node == gcvNULL) { /* Out of memory. */ -#if gcdUSE_VIDMEM_PER_PID - /* Allocate more memory from shared pool. */ - gctSIZE_T bytes; - gctPHYS_ADDR physical_temp; - gctUINT32 physical; - gctPOINTER logical; - - bytes = gcmALIGN(Bytes, gcdUSE_VIDMEM_PER_PID_SIZE); - - gcmkONERROR(gckOS_AllocateContiguous(Memory->os, - gcvTRUE, - &bytes, - &physical_temp, - &logical)); - - /* physical address is returned as 0 for user space. workaround. */ - if (physical_temp == gcvNULL) - { - gcmkONERROR(gckOS_GetPhysicalAddress(Memory->os, logical, &physical)); - } - - /* Allocate one gcuVIDMEM_NODE union. */ - gcmkONERROR( - gckOS_Allocate(Memory->os, - gcmSIZEOF(gcuVIDMEM_NODE), - (gctPOINTER *) &node)); - - /* Initialize gcuVIDMEM_NODE union. */ - node->VidMem.memory = Memory; - - node->VidMem.offset = 0; - node->VidMem.bytes = bytes; - node->VidMem.alignment = 0; - node->VidMem.physical = physical; - node->VidMem.pool = gcvPOOL_UNKNOWN; - - node->VidMem.locked = 0; - -#ifdef __QNXNTO__ - gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID)); - node->VidMem.logical = logical; - gcmkASSERT(logical != gcvNULL); -#endif - - /* Insert node behind sentinel node. */ - node->VidMem.next = Memory->sentinel[bank].VidMem.next; - node->VidMem.prev = &Memory->sentinel[bank]; - Memory->sentinel[bank].VidMem.next = node->VidMem.next->VidMem.prev = node; - - /* Insert free node behind sentinel node. */ - node->VidMem.nextFree = Memory->sentinel[bank].VidMem.nextFree; - node->VidMem.prevFree = &Memory->sentinel[bank]; - Memory->sentinel[bank].VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node; - - Memory->freeBytes += bytes; -#else status = gcvSTATUS_OUT_OF_MEMORY; goto OnError; -#endif } /* Do we have an alignment? */ @@ -1185,20 +963,14 @@ gckVIDMEM_AllocateLinear( node->VidMem.alignment = alignment; node->VidMem.memory = Memory; #ifdef __QNXNTO__ -#if !gcdUSE_VIDMEM_PER_PID node->VidMem.logical = gcvNULL; gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID)); -#else - gcmkASSERT(node->VidMem.logical != gcvNULL); -#endif #endif /* Adjust the number of free bytes. */ Memory->freeBytes -= node->VidMem.bytes; - node->VidMem.freePending = gcvFALSE; - -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG node->VidMem.kernelVirtual = gcvNULL; #endif @@ -1236,6 +1008,9 @@ OnError: ** ** INPUT: ** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** ** gcuVIDMEM_NODE_PTR Node ** Pointer to a gcuVIDMEM_NODE object. ** @@ -1245,6 +1020,7 @@ OnError: */ gceSTATUS gckVIDMEM_Free( + IN gckKERNEL Kernel, IN gcuVIDMEM_NODE_PTR Node ) { @@ -1253,9 +1029,6 @@ gckVIDMEM_Free( gckVIDMEM memory = gcvNULL; gcuVIDMEM_NODE_PTR node; gctBOOL mutexAcquired = gcvFALSE; - gckOS os = gcvNULL; - gctBOOL acquired = gcvFALSE; - gctINT32 i, totalLocked; gcmkHEADER_ARG("Node=0x%x", Node); @@ -1272,19 +1045,6 @@ gckVIDMEM_Free( if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { - if (Node->VidMem.locked > 0) - { - /* Client still has a lock, defer free op 'till when lock reaches 0. */ - Node->VidMem.freePending = gcvTRUE; - - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, - "Node 0x%x is locked (%d)... deferring free.", - Node, Node->VidMem.locked); - - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - } - /* Extract pointer to gckVIDMEM object owning the node. */ memory = Node->VidMem.memory; @@ -1295,11 +1055,19 @@ gckVIDMEM_Free( mutexAcquired = gcvTRUE; #ifdef __QNXNTO__ -#if !gcdUSE_VIDMEM_PER_PID + /* Unmap the video memory. */ + if (Node->VidMem.logical != gcvNULL) + { + gckKERNEL_UnmapVideoMemory( + Kernel, + Node->VidMem.logical, + Node->VidMem.processID, + Node->VidMem.bytes); + Node->VidMem.logical = gcvNULL; + } + /* Reset. */ Node->VidMem.processID = 0; - Node->VidMem.logical = gcvNULL; -#endif /* Don't try to re-free an already freed node. */ if ((Node->VidMem.nextFree == gcvNULL) @@ -1307,7 +1075,7 @@ gckVIDMEM_Free( ) #endif { -#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG +#if gcdENABLE_VG if (Node->VidMem.kernelVirtual) { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, @@ -1389,44 +1157,30 @@ gckVIDMEM_Free( /* Verify the gckKERNEL object pointer. */ gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL); - /* Get the gckOS object pointer. */ - os = kernel->os; - gcmkVERIFY_OBJECT(os, gcvOBJ_OS); - - /* Grab the mutex. */ - gcmkONERROR( - gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE)); - - acquired = gcvTRUE; - - for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++) - { - totalLocked += Node->Virtual.lockeds[i]; - } - - if (totalLocked > 0) +#if gcdENABLE_VG + if (Node->Virtual.kernelVirtual) { - gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_VIDMEM, - "gckVIDMEM_Free: Virtual node 0x%x is locked (%d)", - Node, totalLocked); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, + "%s(%d) Unmap %x from kernel space.", + __FUNCTION__, __LINE__, + Node->Virtual.kernelVirtual); - /* Set Flag */ - Node->Virtual.freed = gcvTRUE; + gcmkVERIFY_OK( + gckOS_UnmapPhysical(kernel->os, + Node->Virtual.kernelVirtual, + Node->Virtual.bytes)); - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + Node->Virtual.kernelVirtual = gcvNULL; } - else - { - /* Free the virtual memory. */ - gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os, - Node->Virtual.physical, - Node->Virtual.bytes)); +#endif - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + /* Free the virtual memory. */ + gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os, + Node->Virtual.physical, + Node->Virtual.bytes)); - /* Destroy the gcuVIDMEM_NODE union. */ - gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node)); - } + /* Destroy the gcuVIDMEM_NODE union. */ + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node)); /* Success. */ gcmkFOOTER_NO(); @@ -1441,209 +1195,196 @@ OnError: )); } - if (acquired) - { - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); - } - /* Return the status. */ gcmkFOOTER(); return status; } - -#ifdef __QNXNTO__ +#if !gcdPROCESS_ADDRESS_SPACE /******************************************************************************* ** -** gcoVIDMEM_FreeHandleMemory +** _NeedVirtualMapping ** -** Free all allocated video memory nodes for a handle. +** Whether setup GPU page table for video node. ** ** INPUT: +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. ** -** gcoVIDMEM Memory -** Pointer to an gcoVIDMEM object.. +** gcuVIDMEM_NODE_PTR Node +** Pointer to a gcuVIDMEM_NODE union. ** -** OUTPUT: +** gceCORE Core +** Id of current GPU. ** -** Nothing. +** OUTPUT: +** gctBOOL * NeedMapping +** A pointer hold the result whether Node should be mapping. */ -gceSTATUS -gckVIDMEM_FreeHandleMemory( +static gceSTATUS +_NeedVirtualMapping( IN gckKERNEL Kernel, - IN gckVIDMEM Memory, - IN gctUINT32 Pid - ) + IN gceCORE Core, + IN gcuVIDMEM_NODE_PTR Node, + OUT gctBOOL * NeedMapping +) { gceSTATUS status; - gctBOOL mutex = gcvFALSE; - gcuVIDMEM_NODE_PTR node; - gctINT i; - gctUINT32 nodeCount = 0, byteCount = 0; - gctBOOL again; - - gcmkHEADER_ARG("Kernel=0x%x, Memory=0x%x Pid=0x%u", Kernel, Memory, Pid); + gctUINT32 phys; + gctUINT32 end; + gcePOOL pool; + gctUINT32 offset; + gctUINT32 baseAddress; + gctUINT32 bytes; - gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM); + gcmkHEADER_ARG("Node=0x%X", Node); - gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE)); - mutex = gcvTRUE; + /* Verify the arguments. */ + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL); + gcmkVERIFY_ARGUMENT(Node != gcvNULL); + gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL); + gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT); - /* Walk all sentinels. */ - for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i) + if (Node->Virtual.contiguous) { - /* Bail out of the heap if it is not used. */ - if (Memory->sentinel[i].VidMem.next == gcvNULL) +#if gcdENABLE_VG + if (Core == gcvCORE_VG) { - break; + *NeedMapping = gcvFALSE; } - - do + else +#endif { - again = gcvFALSE; + /* Convert logical address into a physical address. */ + gcmkONERROR(gckOS_UserLogicalToPhysical( + Kernel->os, Node->Virtual.logical, &phys + )); - /* Walk all the nodes until we reach the sentinel. */ - for (node = Memory->sentinel[i].VidMem.next; - node->VidMem.bytes != 0; - node = node->VidMem.next) - { - /* Free the node if it was allocated by Handle. */ - if (node->VidMem.processID == Pid) - { - /* Unlock video memory. */ - while (node->VidMem.locked > 0) - { - gckVIDMEM_Unlock(Kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL); - } + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress)); - nodeCount++; - byteCount += node->VidMem.bytes; + gcmkASSERT(phys >= baseAddress); - /* Free video memory. */ - gcmkVERIFY_OK(gckVIDMEM_Free(node)); + /* Subtract baseAddress to get a GPU address used for programming. */ + phys -= baseAddress; - /* - * Freeing may cause a merge which will invalidate our iteration. - * Don't be clever, just restart. - */ - again = gcvTRUE; + /* If part of region is belong to gcvPOOL_VIRTUAL, + ** whole region has to be mapped. */ + gcmkSAFECASTSIZET(bytes, Node->Virtual.bytes); + end = phys + bytes - 1; - break; - } -#if gcdUSE_VIDMEM_PER_PID - else - { - gcmkASSERT(node->VidMem.processID == Pid); - } -#endif - } + gcmkONERROR(gckHARDWARE_SplitMemory( + Kernel->hardware, end, &pool, &offset + )); + + *NeedMapping = (pool == gcvPOOL_VIRTUAL); } - while (again); + } + else + { + *NeedMapping = gcvTRUE; } - gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex)); - gcmkFOOTER(); + gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping); return gcvSTATUS_OK; OnError: - if (mutex) - { - gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex)); - } - gcmkFOOTER(); return status; } #endif -/******************************************************************************* -** -** _NeedVirtualMapping -** -** Whether setup GPU page table for video node. -** -** INPUT: -** gckKERNEL Kernel -** Pointer to an gckKERNEL object. -** -** gcuVIDMEM_NODE_PTR Node -** Pointer to a gcuVIDMEM_NODE union. -** -** gceCORE Core -** Id of current GPU. -** -** OUTPUT: -** gctBOOL * NeedMapping -** A pointer hold the result whether Node should be mapping. -*/ -static gceSTATUS -_NeedVirtualMapping( - IN gckKERNEL Kernel, - IN gceCORE Core, - IN gcuVIDMEM_NODE_PTR Node, - OUT gctBOOL * NeedMapping -) +#if gcdPROCESS_ADDRESS_SPACE +gcsGPU_MAP_PTR +_FindGPUMap( + IN gcsGPU_MAP_PTR Head, + IN gctINT ProcessID + ) { - gceSTATUS status; - gctUINT32 phys; - gctUINT32 end; - gcePOOL pool; - gctUINT32 offset; - gctUINT32 baseAddress; - - gcmkHEADER_ARG("Node=0x%X", Node); - - /* Verify the arguments. */ - gcmkVERIFY_ARGUMENT(Kernel != gcvNULL); - gcmkVERIFY_ARGUMENT(Node != gcvNULL); - gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL); - gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT); + gcsGPU_MAP_PTR map = Head; - if (Node->Virtual.contiguous) + while (map) { -#if gcdENABLE_VG - if (Core == gcvCORE_VG) + if (map->pid == ProcessID) { - *NeedMapping = gcvFALSE; + return map; } - else -#endif - { - /* Convert logical address into a physical address. */ - gcmkONERROR( - gckOS_GetPhysicalAddress(Kernel->os, Node->Virtual.logical, &phys)); - gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress)); + map = map->next; + } - gcmkASSERT(phys >= baseAddress); + return gcvNULL; +} - /* Subtract baseAddress to get a GPU address used for programming. */ - phys -= baseAddress; +gcsGPU_MAP_PTR +_CreateGPUMap( + IN gckOS Os, + IN gcsGPU_MAP_PTR *Head, + IN gcsGPU_MAP_PTR *Tail, + IN gctINT ProcessID + ) +{ + gcsGPU_MAP_PTR gpuMap; + gctPOINTER pointer = gcvNULL; - /* If part of region is belong to gcvPOOL_VIRTUAL, - ** whole region has to be mapped. */ - end = phys + Node->Virtual.bytes - 1; + gckOS_Allocate(Os, sizeof(gcsGPU_MAP), &pointer); - gcmkONERROR(gckHARDWARE_SplitMemory( - Kernel->hardware, end, &pool, &offset - )); + if (pointer == gcvNULL) + { + return gcvNULL; + } - *NeedMapping = (pool == gcvPOOL_VIRTUAL); - } + gpuMap = pointer; + + gckOS_ZeroMemory(pointer, sizeof(gcsGPU_MAP)); + + gpuMap->pid = ProcessID; + + if (!*Head) + { + *Head = *Tail = gpuMap; } else { - *NeedMapping = gcvTRUE; + gpuMap->prev = *Tail; + (*Tail)->next = gpuMap; + *Tail = gpuMap; } - gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping); - return gcvSTATUS_OK; + return gpuMap; +} -OnError: - gcmkFOOTER(); - return status; +void +_DestroyGPUMap( + IN gckOS Os, + IN gcsGPU_MAP_PTR *Head, + IN gcsGPU_MAP_PTR *Tail, + IN gcsGPU_MAP_PTR gpuMap + ) +{ + + if (gpuMap == *Head) + { + if ((*Head = gpuMap->next) == gcvNULL) + { + *Tail = gcvNULL; + } + } + else + { + gpuMap->prev->next = gpuMap->next; + if (gpuMap == *Tail) + { + *Tail = gpuMap->prev; + } + else + { + gpuMap->next->prev = gpuMap->prev; + } + } + + gcmkOS_SAFE_FREE(Os, gpuMap); } +#endif /******************************************************************************* ** @@ -1663,55 +1404,76 @@ OnError: ** ** 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 gckVIDMEM_NODE Node, IN gctBOOL Cacheable, - OUT gctUINT32 * Address + OUT gctUINT32 * Address, + OUT gctUINT32 * Gid, + OUT gctUINT64 * PhysicalAddress ) { gceSTATUS status; gctBOOL acquired = gcvFALSE; gctBOOL locked = gcvFALSE; gckOS os = gcvNULL; - gctBOOL needMapping; +#if !gcdPROCESS_ADDRESS_SPACE + gctBOOL needMapping = gcvFALSE; +#endif gctUINT32 baseAddress; + gctUINT32 physicalAddress; + gcuVIDMEM_NODE_PTR node = Node->node; gcmkHEADER_ARG("Node=0x%x", Node); /* Verify the arguments. */ gcmkVERIFY_ARGUMENT(Address != gcvNULL); + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); - if ((Node == gcvNULL) - || (Node->VidMem.memory == gcvNULL) + /* Extract the gckOS object pointer. */ + os = Kernel->os; + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + + if ((node == gcvNULL) + || (node->VidMem.memory == gcvNULL) ) { /* Invalid object. */ gcmkONERROR(gcvSTATUS_INVALID_OBJECT); } + /* Grab the mutex. */ + gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE)); + acquired = gcvTRUE; + /**************************** Video Memory ********************************/ - if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { + gctUINT32 offset; + if (Cacheable == gcvTRUE) { gcmkONERROR(gcvSTATUS_INVALID_REQUEST); } /* Increment the lock count. */ - Node->VidMem.locked ++; + node->VidMem.locked ++; /* Return the physical address of the node. */ -#if !gcdUSE_VIDMEM_PER_PID - *Address = Node->VidMem.memory->baseAddress - + Node->VidMem.offset - + Node->VidMem.alignment; -#else - *Address = Node->VidMem.physical; -#endif + gcmkSAFECASTSIZET(offset, node->VidMem.offset); + + *Address = node->VidMem.memory->baseAddress + + offset + + node->VidMem.alignment; + + physicalAddress = *Address; /* Get hardware specific address. */ #if gcdENABLE_VG @@ -1727,10 +1489,16 @@ gckVIDMEM_Lock( } } + gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical( + Kernel->os, + *Address, + Address + )); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Locked node 0x%x (%d) @ 0x%08X", - Node, - Node->VidMem.locked, + node, + node->VidMem.locked, *Address); } @@ -1738,16 +1506,8 @@ gckVIDMEM_Lock( else { - /* Verify the gckKERNEL object pointer. */ - gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL); - - /* Extract the gckOS object pointer. */ - os = Node->Virtual.kernel->os; - gcmkVERIFY_OBJECT(os, gcvOBJ_OS); - /* Grab the mutex. */ - gcmkONERROR(gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE)); - acquired = gcvTRUE; + *Gid = node->Virtual.gid; #if gcdPAGED_MEMORY_CACHEABLE /* Force video memory cacheable. */ @@ -1756,36 +1516,29 @@ gckVIDMEM_Lock( gcmkONERROR( gckOS_LockPages(os, - Node->Virtual.physical, - Node->Virtual.bytes, + node->Virtual.physical, + node->Virtual.bytes, Cacheable, - &Node->Virtual.logical, - &Node->Virtual.pageCount)); + &node->Virtual.logical, + &node->Virtual.pageCount)); - /* Increment the lock count. */ - if (Node->Virtual.lockeds[Kernel->core] ++ == 0) - { - /* Is this node pending for a final unlock? */ -#ifdef __QNXNTO__ - if (!Node->Virtual.contiguous && Node->Virtual.unlockPendings[Kernel->core]) - { - /* Make sure we have a page table. */ - gcmkASSERT(Node->Virtual.pageTables[Kernel->core] != gcvNULL); - - /* Remove pending unlock. */ - Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE; - } - - /* First lock - create a page table. */ - gcmkASSERT(Node->Virtual.pageTables[Kernel->core] == gcvNULL); + gcmkONERROR(gckOS_GetPhysicalAddress( + os, + node->Virtual.logical, + &physicalAddress + )); - /* Make sure we mark our node as not flushed. */ - Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE; +#if gcdENABLE_VG + node->Virtual.physicalAddress = physicalAddress; #endif +#if !gcdPROCESS_ADDRESS_SPACE + /* Increment the lock count. */ + if (node->Virtual.lockeds[Kernel->core] ++ == 0) + { locked = gcvTRUE; - gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, Node, &needMapping)); + gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, node, &needMapping)); if (needMapping == gcvFALSE) { @@ -1793,29 +1546,59 @@ gckVIDMEM_Lock( #if gcdENABLE_VG if (Kernel->vg != gcvNULL) { - gcmkONERROR(gckVGHARDWARE_ConvertLogical(Kernel->vg->hardware, - Node->Virtual.logical, - &Node->Virtual.addresses[Kernel->core])); + gcmkONERROR(gckVGHARDWARE_ConvertLogical( + Kernel->vg->hardware, + node->Virtual.logical, + gcvTRUE, + &node->Virtual.addresses[Kernel->core])); } else #endif { - gcmkONERROR(gckHARDWARE_ConvertLogical(Kernel->hardware, - Node->Virtual.logical, - &Node->Virtual.addresses[Kernel->core])); + gcmkONERROR(gckHARDWARE_ConvertLogical( + Kernel->hardware, + node->Virtual.logical, + gcvTRUE, + &node->Virtual.addresses[Kernel->core])); } } 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) { /* Allocate pages inside the MMU. */ gcmkONERROR( gckVGMMU_AllocatePages(Kernel->vg->mmu, - Node->Virtual.pageCount, - &Node->Virtual.pageTables[Kernel->core], - &Node->Virtual.addresses[Kernel->core])); + node->Virtual.pageCount, + &node->Virtual.pageTables[Kernel->core], + &node->Virtual.addresses[Kernel->core])); } else #endif @@ -1823,31 +1606,22 @@ gckVIDMEM_Lock( /* Allocate pages inside the MMU. */ gcmkONERROR( gckMMU_AllocatePagesEx(Kernel->mmu, - Node->Virtual.pageCount, - Node->Virtual.type, - &Node->Virtual.pageTables[Kernel->core], - &Node->Virtual.addresses[Kernel->core])); + node->Virtual.pageCount, + node->Virtual.type, + &node->Virtual.pageTables[Kernel->core], + &node->Virtual.addresses[Kernel->core])); } - Node->Virtual.lockKernels[Kernel->core] = Kernel; + node->Virtual.lockKernels[Kernel->core] = Kernel; /* Map the pages. */ -#ifdef __QNXNTO__ - gcmkONERROR( - gckOS_MapPagesEx(os, - Kernel->core, - Node->Virtual.physical, - Node->Virtual.logical, - Node->Virtual.pageCount, - Node->Virtual.pageTables[Kernel->core])); -#else gcmkONERROR( gckOS_MapPagesEx(os, Kernel->core, - Node->Virtual.physical, - Node->Virtual.pageCount, - Node->Virtual.pageTables[Kernel->core])); -#endif + node->Virtual.physical, + node->Virtual.pageCount, + node->Virtual.addresses[Kernel->core], + node->Virtual.pageTables[Kernel->core])); #if gcdENABLE_VG if (Kernel->core == gcvCORE_VG) @@ -1857,22 +1631,26 @@ gckVIDMEM_Lock( else #endif { - gcmkONERROR(gckMMU_Flush(Kernel->mmu)); + gcmkONERROR(gckMMU_Flush(Kernel->mmu, node->Virtual.type)); } +#endif } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Mapped virtual node 0x%x to 0x%08X", - Node, - Node->Virtual.addresses[Kernel->core]); + node, + node->Virtual.addresses[Kernel->core]); } /* Return hardware address. */ - *Address = Node->Virtual.addresses[Kernel->core]; - - /* Release the mutex. */ - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + *Address = node->Virtual.addresses[Kernel->core]; +#endif } + /* Release the mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex)); + + *PhysicalAddress = (gctUINT64)physicalAddress; + /* Success. */ gcmkFOOTER_ARG("*Address=%08x", *Address); return gcvSTATUS_OK; @@ -1880,7 +1658,7 @@ gckVIDMEM_Lock( OnError: if (locked) { - if (Node->Virtual.pageTables[Kernel->core] != gcvNULL) + if (node->Virtual.pageTables[Kernel->core] != gcvNULL) { #if gcdENABLE_VG if (Kernel->vg != gcvNULL) @@ -1888,8 +1666,8 @@ OnError: /* Free the pages from the MMU. */ gcmkVERIFY_OK( gckVGMMU_FreePages(Kernel->vg->mmu, - Node->Virtual.pageTables[Kernel->core], - Node->Virtual.pageCount)); + node->Virtual.pageTables[Kernel->core], + node->Virtual.pageCount)); } else #endif @@ -1897,28 +1675,28 @@ OnError: /* Free the pages from the MMU. */ gcmkVERIFY_OK( gckMMU_FreePages(Kernel->mmu, - Node->Virtual.pageTables[Kernel->core], - Node->Virtual.pageCount)); + node->Virtual.pageTables[Kernel->core], + node->Virtual.pageCount)); } - Node->Virtual.pageTables[Kernel->core] = gcvNULL; - Node->Virtual.lockKernels[Kernel->core] = gcvNULL; + node->Virtual.pageTables[Kernel->core] = gcvNULL; + node->Virtual.lockKernels[Kernel->core] = gcvNULL; } /* Unlock the pages. */ gcmkVERIFY_OK( gckOS_UnlockPages(os, - Node->Virtual.physical, - Node->Virtual.bytes, - Node->Virtual.logical + node->Virtual.physical, + node->Virtual.bytes, + node->Virtual.logical )); - Node->Virtual.lockeds[Kernel->core]--; + node->Virtual.lockeds[Kernel->core]--; } if (acquired) { /* Release the mutex. */ - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex)); } /* Return the status. */ @@ -1957,308 +1735,1073 @@ OnError: gceSTATUS gckVIDMEM_Unlock( IN gckKERNEL Kernel, - IN gcuVIDMEM_NODE_PTR Node, + IN gckVIDMEM_NODE Node, IN gceSURF_TYPE Type, IN OUT gctBOOL * Asynchroneous ) { gceSTATUS status; - gckHARDWARE hardware; - gctPOINTER buffer; - gctSIZE_T requested, bufferSize; - gckCOMMAND command = gcvNULL; - gceKERNEL_FLUSH flush; gckOS os = gcvNULL; gctBOOL acquired = gcvFALSE; - gctBOOL commitEntered = gcvFALSE; - gctINT32 i, totalLocked; + gcuVIDMEM_NODE_PTR node = Node->node; gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d", Node, Type, gcmOPT_VALUE(Asynchroneous)); + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + + /* Get the gckOS object pointer. */ + os = Kernel->os; + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + /* Verify the arguments. */ - if ((Node == gcvNULL) - || (Node->VidMem.memory == gcvNULL) + if ((node == gcvNULL) + || (node->VidMem.memory == gcvNULL) ) { /* Invalid object. */ gcmkONERROR(gcvSTATUS_INVALID_OBJECT); } + /* Grab the mutex. */ + gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE)); + acquired = gcvTRUE; + /**************************** Video Memory ********************************/ - if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { - if (Node->VidMem.locked <= 0) + if (node->VidMem.locked <= 0) { /* The surface was not locked. */ status = gcvSTATUS_MEMORY_UNLOCKED; goto OnError; } - /* Decrement the lock count. */ - Node->VidMem.locked --; - if (Asynchroneous != gcvNULL) { - /* No need for any events. */ - *Asynchroneous = gcvFALSE; + /* Schedule an event to sync with GPU. */ + *Asynchroneous = gcvTRUE; + } + else + { + /* Decrement the lock count. */ + node->VidMem.locked --; } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Unlocked node 0x%x (%d)", - Node, - Node->VidMem.locked); - -#ifdef __QNXNTO__ - /* Unmap the video memory */ - if ((Node->VidMem.locked == 0) && (Node->VidMem.logical != gcvNULL)) - { - if (Kernel->core == gcvCORE_VG) - { - gckKERNEL_UnmapVideoMemory(Kernel, - Node->VidMem.logical, - Node->VidMem.processID, - Node->VidMem.bytes); - Node->VidMem.logical = gcvNULL; - } - } -#endif /* __QNXNTO__ */ - - if (Node->VidMem.freePending && (Node->VidMem.locked == 0)) - { - /* Client has unlocked node previously attempted to be freed by compositor. Free now. */ - Node->VidMem.freePending = gcvFALSE; - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, - "Deferred-freeing Node 0x%x.", - Node); - gcmkONERROR(gckVIDMEM_Free(Node)); - } + node, + node->VidMem.locked); } /*************************** Virtual Memory *******************************/ else { - /* Verify the gckHARDWARE object pointer. */ - hardware = Kernel->hardware; - gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE); - - /* Verify the gckCOMMAND object pointer. */ - command = Kernel->command; - gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); - - /* Get the gckOS object pointer. */ - os = Kernel->os; - gcmkVERIFY_OBJECT(os, gcvOBJ_OS); - - /* Grab the mutex. */ - gcmkONERROR( - gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE)); - acquired = gcvTRUE; if (Asynchroneous == gcvNULL) { - if (Node->Virtual.lockeds[Kernel->core] == 0) +#if !gcdPROCESS_ADDRESS_SPACE + if (node->Virtual.lockeds[Kernel->core] == 0) { status = gcvSTATUS_MEMORY_UNLOCKED; goto OnError; } /* Decrement lock count. */ - -- Node->Virtual.lockeds[Kernel->core]; + -- node->Virtual.lockeds[Kernel->core]; /* See if we can unlock the resources. */ - if (Node->Virtual.lockeds[Kernel->core] == 0) + 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) + if (node->Virtual.pageTables[Kernel->core] != gcvNULL) { #if gcdENABLE_VG if (Kernel->vg != gcvNULL) { gcmkONERROR( gckVGMMU_FreePages(Kernel->vg->mmu, - Node->Virtual.pageTables[Kernel->core], - Node->Virtual.pageCount)); + node->Virtual.pageTables[Kernel->core], + node->Virtual.pageCount)); } else #endif { gcmkONERROR( gckMMU_FreePages(Kernel->mmu, - Node->Virtual.pageTables[Kernel->core], - Node->Virtual.pageCount)); + node->Virtual.pageTables[Kernel->core], + node->Virtual.pageCount)); } - /* Mark page table as freed. */ - Node->Virtual.pageTables[Kernel->core] = gcvNULL; - Node->Virtual.lockKernels[Kernel->core] = gcvNULL; - } - -#ifdef __QNXNTO__ - /* Mark node as unlocked. */ - Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE; -#endif - } - - for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++) - { - totalLocked += Node->Virtual.lockeds[i]; - } - - if (totalLocked == 0) - { - /* Owner have already freed this node - ** and we are the last one to unlock, do - ** real free */ - if (Node->Virtual.freed) - { - /* Free the virtual memory. */ - gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os, - Node->Virtual.physical, - Node->Virtual.bytes)); - - /* Release mutex before node is destroyed */ - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); - acquired = gcvFALSE; - - /* Destroy the gcuVIDMEM_NODE union. */ - gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node)); + gcmkONERROR(gckOS_UnmapPages( + Kernel->os, + node->Virtual.pageCount, + node->Virtual.addresses[Kernel->core] + )); - /* Node has been destroyed, so we should not touch it any more */ - gcmkFOOTER(); - return gcvSTATUS_OK; + /* Mark page table as freed. */ + node->Virtual.pageTables[Kernel->core] = gcvNULL; + node->Virtual.lockKernels[Kernel->core] = gcvNULL; } +#endif } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, "Unmapped virtual node 0x%x from 0x%08X", - Node, Node->Virtual.addresses[Kernel->core]); + node, node->Virtual.addresses[Kernel->core]); +#endif } else { - /* If we need to unlock a node from virtual memory we have to be - ** very carefull. If the node is still inside the caches we - ** might get a bus error later if the cache line needs to be - ** replaced. So - we have to flush the caches before we do - ** anything. */ - - /* gckCommand_EnterCommit() can't be called in interrupt handler because - ** of a dead lock situation: - ** process call Command_Commit(), and acquire Command->mutexQueue in - ** gckCOMMAND_EnterCommit(). Then it will wait for a signal which depends - ** on interrupt handler to generate, if interrupt handler enter - ** gckCommand_EnterCommit(), process will never get the signal. */ - - /* So, flush cache when we still in process context, and then ask caller to - ** schedule a event. */ - gcmkONERROR( gckOS_UnlockPages(os, - Node->Virtual.physical, - Node->Virtual.bytes, - Node->Virtual.logical)); - - if (!Node->Virtual.contiguous - && (Node->Virtual.lockeds[Kernel->core] == 1) -#if gcdENABLE_VG - && (Kernel->vg == gcvNULL) -#endif - ) - { - if (Type == gcvSURF_BITMAP) - { - /* Flush 2D cache. */ - flush = gcvFLUSH_2D; - } - else if (Type == gcvSURF_RENDER_TARGET) - { - /* Flush color cache. */ - flush = gcvFLUSH_COLOR; - } - else if (Type == gcvSURF_DEPTH) - { - /* Flush depth cache. */ - flush = gcvFLUSH_DEPTH; - } - else - { - /* No flush required. */ - flush = (gceKERNEL_FLUSH) 0; - } - if(hardware) - { - gcmkONERROR( - gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested)); + node->Virtual.physical, + node->Virtual.bytes, + node->Virtual.logical)); - if (requested != 0) - { - /* Acquire the command queue. */ - gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE)); - commitEntered = gcvTRUE; + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, + "Scheduled unlock for virtual node 0x%x", + node); - gcmkONERROR(gckCOMMAND_Reserve( - command, requested, &buffer, &bufferSize - )); + /* Schedule the surface to be unlocked. */ + *Asynchroneous = gcvTRUE; + } + } - gcmkONERROR(gckHARDWARE_Flush( - hardware, flush, buffer, &bufferSize - )); + /* Release the mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex)); + acquired = gcvFALSE; - /* Mark node as pending. */ -#ifdef __QNXNTO__ - Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE; -#endif + /* Success. */ + gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous)); + return gcvSTATUS_OK; - gcmkONERROR(gckCOMMAND_Execute(command, requested)); +OnError: + if (acquired) + { + /* Release the mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex)); + } - /* Release the command queue. */ - gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE)); - commitEntered = gcvFALSE; - } - } - else - { - gckOS_Print("Hardware already is freed.\n"); - } + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +#if gcdPROCESS_ADDRESS_SPACE +gceSTATUS +gckVIDMEM_Node_Lock( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node, + OUT gctUINT32 *Address + ) +{ + gceSTATUS status; + gckOS os; + gcuVIDMEM_NODE_PTR node = Node->node; + gcsGPU_MAP_PTR gpuMap; + gctPHYS_ADDR physical = gcvNULL; + gctUINT32 phys = gcvINVALID_ADDRESS; + gctUINT32 processID; + gcsLOCK_INFO_PTR lockInfo; + gctUINT32 pageCount; + gckMMU mmu; + gctUINT32 i; + gctUINT32_PTR pageTableEntry; + gctUINT32 offset = 0; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Node = %x", Node); + + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Node != gcvNULL); + gcmkVERIFY_ARGUMENT(Address != gcvNULL); + + os = Kernel->os; + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + + gcmkONERROR(gckOS_GetProcessID(&processID)); + + gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu)); + + gcmkONERROR(gckOS_AcquireMutex(os, Node->mapMutex, gcvINFINITE)); + acquired = gcvTRUE; + + /* Get map information for current process. */ + gpuMap = _FindGPUMap(Node->mapHead, processID); + + if (gpuMap == gcvNULL) + { + gpuMap = _CreateGPUMap(os, &Node->mapHead, &Node->mapTail, processID); + + if (gpuMap == gcvNULL) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + } + + lockInfo = &gpuMap->lockInfo; + + if (lockInfo->lockeds[Kernel->core] ++ == 0) + { + /* Get necessary information. */ + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + { + phys = node->VidMem.memory->baseAddress + + node->VidMem.offset + + node->VidMem.alignment; + + /* GPU page table use 4K page. */ + pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12) + - (phys >> 12); + + offset = phys & 0xFFF; + } + else + { + pageCount = node->Virtual.pageCount; + physical = node->Virtual.physical; + } + + /* Allocate pages inside the MMU. */ + gcmkONERROR(gckMMU_AllocatePages( + mmu, + pageCount, + &lockInfo->pageTables[Kernel->core], + &lockInfo->GPUAddresses[Kernel->core])); + + /* Record MMU from which pages are allocated. */ + lockInfo->lockMmus[Kernel->core] = mmu; + + pageTableEntry = lockInfo->pageTables[Kernel->core]; + + /* Fill page table entries. */ + if (phys != gcvINVALID_ADDRESS) + { + gctUINT32 address = lockInfo->GPUAddresses[Kernel->core]; + for (i = 0; i < pageCount; i++) + { + gckMMU_GetPageEntry(mmu, address, &pageTableEntry); + gckMMU_SetPage(mmu, phys & 0xFFFFF000, pageTableEntry); + phys += 4096; + address += 4096; + pageTableEntry += 1; } + } + else + { + gctUINT32 address = lockInfo->GPUAddresses[Kernel->core]; + gcmkASSERT(physical != gcvNULL); + gcmkONERROR(gckOS_MapPagesEx(os, + Kernel->core, + physical, + pageCount, + address, + pageTableEntry)); + } - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM, - "Scheduled unlock for virtual node 0x%x", - Node); + gcmkONERROR(gckMMU_Flush(mmu)); + } - /* Schedule the surface to be unlocked. */ - *Asynchroneous = gcvTRUE; + *Address = lockInfo->GPUAddresses[Kernel->core] + offset; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex)); + acquired = gcvFALSE; + + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckVIDMEM_NODE_Unlock( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node, + IN gctUINT32 ProcessID + ) +{ + gceSTATUS status; + gcsGPU_MAP_PTR gpuMap; + gcsLOCK_INFO_PTR lockInfo; + gckMMU mmu; + gcuVIDMEM_NODE_PTR node; + gctUINT32 pageCount; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%08X, Node = %x, ProcessID=%d", + Kernel, Node, ProcessID); + + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Node != gcvNULL); + + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Node->mapMutex, gcvINFINITE)); + acquired = gcvTRUE; + + /* Get map information for current process. */ + gpuMap = _FindGPUMap(Node->mapHead, ProcessID); + + if (gpuMap == gcvNULL) + { + /* No mapping for this process. */ + gcmkONERROR(gcvSTATUS_INVALID_DATA); + } + + lockInfo = &gpuMap->lockInfo; + + if (--lockInfo->lockeds[Kernel->core] == 0) + { + node = Node->node; + + /* Get necessary information. */ + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + { + gctUINT32 phys = node->VidMem.memory->baseAddress + + node->VidMem.offset + + node->VidMem.alignment; + + /* GPU page table use 4K page. */ + pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12) + - (phys >> 12); + } + else + { + pageCount = node->Virtual.pageCount; } - /* Release the mutex. */ - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + /* Get MMU which allocates pages. */ + mmu = lockInfo->lockMmus[Kernel->core]; + + /* Free virtual spaces in page table. */ + gcmkVERIFY_OK(gckMMU_FreePagesEx( + mmu, + lockInfo->GPUAddresses[Kernel->core], + pageCount + )); - acquired = gcvFALSE; + _DestroyGPUMap(Kernel->os, &Node->mapHead, &Node->mapTail, gpuMap); } - /* Success. */ - gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: - if (commitEntered) + if (acquired) { - /* Release the command queue mutex. */ - gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvFALSE)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex)); } + gcmkFOOTER(); + return status; +} +#endif + +/******************************************************************************* +** +** gckVIDMEM_HANDLE_Allocate +** +** Allocate a handle for a gckVIDMEM_NODE object. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gckVIDMEM_NODE Node +** Pointer to a gckVIDMEM_NODE object. +** +** OUTPUT: +** +** gctUINT32 * Handle +** Pointer to a variable receiving a handle represent this +** gckVIDMEM_NODE in userspace. +*/ +static gceSTATUS +gckVIDMEM_HANDLE_Allocate( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node, + OUT gctUINT32 * Handle + ) +{ + gceSTATUS status; + gctUINT32 processID = 0; + gctPOINTER pointer = gcvNULL; + gctPOINTER handleDatabase = gcvNULL; + gctPOINTER mutex = gcvNULL; + gctUINT32 handle = 0; + gckVIDMEM_HANDLE handleObject = gcvNULL; + gckOS os = Kernel->os; + + gcmkHEADER_ARG("Kernel=0x%X, Node=0x%X", Kernel, Node); + + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + + /* Allocate a gckVIDMEM_HANDLE object. */ + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_HANDLE), &pointer)); + + gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_HANDLE))); + + handleObject = pointer; + + gcmkONERROR(gckOS_AtomConstruct(os, &handleObject->reference)); + + /* Set default reference count to 1. */ + gckOS_AtomSet(os, handleObject->reference, 1); + + gcmkVERIFY_OK(gckOS_GetProcessID(&processID)); + + gcmkONERROR( + gckKERNEL_FindHandleDatbase(Kernel, + processID, + &handleDatabase, + &mutex)); + + /* Allocate a handle for this object. */ + gcmkONERROR( + gckKERNEL_AllocateIntegerId(handleDatabase, handleObject, &handle)); + + handleObject->node = Node; + handleObject->handle = handle; + + *Handle = handle; + + gcmkFOOTER_ARG("*Handle=%d", *Handle); + return gcvSTATUS_OK; + +OnError: + if (handleObject != gcvNULL) + { + if (handleObject->reference != gcvNULL) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(os, handleObject->reference)); + } + + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, handleObject)); + } + + gcmkFOOTER(); + return status; +} + +static gceSTATUS +gckVIDMEM_NODE_Reference( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node + ) +{ + gctINT32 oldValue; + gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node); + + gckOS_AtomIncrement(Kernel->os, Node->reference, &oldValue); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +gceSTATUS +gckVIDMEM_HANDLE_Reference( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN gctUINT32 Handle + ) +{ + gceSTATUS status; + gckVIDMEM_HANDLE handleObject = gcvNULL; + gctPOINTER database = gcvNULL; + gctPOINTER mutex = gcvNULL; + gctINT32 oldValue = 0; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Handle=%d PrcoessID=%d", Handle, ProcessID); + + gcmkONERROR( + gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex)); + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + acquired = gcvTRUE; + + /* Translate handle to gckVIDMEM_HANDLE object. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject)); + + /* Increase the reference count. */ + gckOS_AtomIncrement(Kernel->os, handleObject->reference, &oldValue); + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: if (acquired) { - /* Release the mutex. */ - gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex)); + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckVIDMEM_HANDLE_Dereference( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN gctUINT32 Handle + ) +{ + gceSTATUS status; + gctPOINTER handleDatabase = gcvNULL; + gctPOINTER mutex = gcvNULL; + gctINT32 oldValue = 0; + gckVIDMEM_HANDLE handleObject = gcvNULL; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Handle=%d PrcoessID=%d", Handle, ProcessID); + + gcmkONERROR( + gckKERNEL_FindHandleDatbase(Kernel, + ProcessID, + &handleDatabase, + &mutex)); + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + acquired = gcvTRUE; + + /* Translate handle to gckVIDMEM_HANDLE. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(handleDatabase, Handle, (gctPOINTER *)&handleObject)); + + gckOS_AtomDecrement(Kernel->os, handleObject->reference, &oldValue); + + if (oldValue == 1) + { + /* Remove handle from database if this is the last reference. */ + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(handleDatabase, Handle)); + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + acquired = gcvFALSE; + + if (oldValue == 1) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, handleObject->reference)); + gcmkOS_SAFE_FREE(Kernel->os, handleObject); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckVIDMEM_HANDLE_LookupAndReference( + IN gckKERNEL Kernel, + IN gctUINT32 Handle, + OUT gckVIDMEM_NODE * Node + ) +{ + gceSTATUS status; + gckVIDMEM_HANDLE handleObject = gcvNULL; + gckVIDMEM_NODE node = gcvNULL; + gctPOINTER database = gcvNULL; + gctPOINTER mutex = gcvNULL; + gctUINT32 processID = 0; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle); + + gckOS_GetProcessID(&processID); + + gcmkONERROR( + gckKERNEL_FindHandleDatbase(Kernel, processID, &database, &mutex)); + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + acquired = gcvTRUE; + + /* Translate handle to gckVIDMEM_HANDLE object. */ + gcmkONERROR( + gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject)); + + /* Get gckVIDMEM_NODE object. */ + node = handleObject->node; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + acquired = gcvFALSE; + + /* Reference this gckVIDMEM_NODE object. */ + gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(Kernel, node)); + + /* Return result. */ + *Node = node; + + gcmkFOOTER_ARG("*Node=%d", *Node); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckVIDMEM_HANDLE_Lookup( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN gctUINT32 Handle, + OUT gckVIDMEM_NODE * Node + ) +{ + gceSTATUS status; + gckVIDMEM_HANDLE handleObject = gcvNULL; + gckVIDMEM_NODE node = gcvNULL; + gctPOINTER database = gcvNULL; + gctPOINTER mutex = gcvNULL; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d Handle=%d", + Kernel, ProcessID, Handle); + + gcmkONERROR( + gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex)); + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + acquired = gcvTRUE; + + gcmkONERROR( + gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject)); + + node = handleObject->node; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + acquired = gcvFALSE; + + *Node = node; + + gcmkFOOTER_ARG("*Node=%d", *Node); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); } - /* Return the status. */ gcmkFOOTER(); return status; } + +/******************************************************************************* +** +** gckVIDMEM_NODE_Allocate +** +** Allocate a gckVIDMEM_NODE object. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gcuVIDMEM_NODE_PTR Node +** Pointer to a gcuVIDMEM_NODE union. +** +** OUTPUT: +** +** gctUINT32 * Handle +** Pointer to a variable receiving a handle represent this +** gckVIDMEM_NODE in userspace. +*/ +gceSTATUS +gckVIDMEM_NODE_Allocate( + IN gckKERNEL Kernel, + IN gcuVIDMEM_NODE_PTR VideoNode, + IN gceSURF_TYPE Type, + IN gcePOOL Pool, + IN gctUINT32 * Handle + ) +{ + gceSTATUS status; + gckVIDMEM_NODE node = gcvNULL; + gctPOINTER pointer = gcvNULL; + gctUINT32 handle = 0; + gckOS os = Kernel->os; + + gcmkHEADER_ARG("Kernel=0x%X VideoNode=0x%X", Kernel, VideoNode); + + /* Construct a node. */ + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_NODE), &pointer)); + + gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_NODE))); + + node = pointer; + + node->node = VideoNode; + node->type = Type; + node->pool = Pool; + +#if gcdPROCESS_ADDRESS_SPACE + gcmkONERROR(gckOS_CreateMutex(os, &node->mapMutex)); +#endif + + gcmkONERROR(gckOS_AtomConstruct(os, &node->reference)); + + gcmkONERROR(gckOS_CreateMutex(os, &node->mutex)); + + /* Reference is 1 by default . */ + gckVIDMEM_NODE_Reference(Kernel, node); + + /* Create a handle to represent this node. */ + gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, &handle)); + + *Handle = handle; + + gcmkFOOTER_ARG("*Handle=%d", *Handle); + return gcvSTATUS_OK; + +OnError: + if (node != gcvNULL) + { +#if gcdPROCESS_ADDRESS_SPACE + if (node->mapMutex != gcvNULL) + { + gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mapMutex)); + } +#endif + + if (node->mutex) + { + gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mutex)); + } + + if (node->reference != gcvNULL) + { + gcmkVERIFY_OK(gckOS_AtomDestroy(os, node->reference)); + } + + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckVIDMEM_NODE_Dereference( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node + ) +{ + gctINT32 oldValue = 0; + gctPOINTER database = Kernel->db->nameDatabase; + gctPOINTER mutex = Kernel->db->nameDatabaseMutex; + + gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node); + + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + + gcmkVERIFY_OK(gckOS_AtomDecrement(Kernel->os, Node->reference, &oldValue)); + + if (oldValue == 1 && Node->name) + { + /* Free name if exists. */ + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Node->name)); + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + + if (oldValue == 1) + { + /* Free gcuVIDMEM_NODE. */ + gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, Node->node)); + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Node->reference)); +#if gcdPROCESS_ADDRESS_SPACE + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mapMutex)); +#endif + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mutex)); + gcmkOS_SAFE_FREE(Kernel->os, Node); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckVIDMEM_NODE_Name +** +** Naming a gckVIDMEM_NODE object. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctUINT32 Handle +** Handle to a gckVIDMEM_NODE object. +** +** OUTPUT: +** +** gctUINT32 * Name +** Pointer to a variable receiving a name which can be pass to another +** process. +*/ +gceSTATUS +gckVIDMEM_NODE_Name( + IN gckKERNEL Kernel, + IN gctUINT32 Handle, + IN gctUINT32 * Name + ) +{ + gceSTATUS status; + gckVIDMEM_NODE node = gcvNULL; + gctUINT32 name = 0; + gctUINT32 processID = 0; + gctPOINTER database = Kernel->db->nameDatabase; + gctPOINTER mutex = Kernel->db->nameDatabaseMutex; + gctBOOL acquired = gcvFALSE; + gctBOOL referenced = gcvFALSE; + gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle); + + gcmkONERROR(gckOS_GetProcessID(&processID)); + + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + acquired = gcvTRUE; + + gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node)); + referenced = gcvTRUE; + + if (node->name == 0) + { + /* Name this node. */ + gcmkONERROR(gckKERNEL_AllocateIntegerId(database, node, &name)); + node->name = name; + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + acquired = gcvFALSE; + + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node)); + + if(node) + { + *Name = node->name; + } + + gcmkFOOTER_ARG("*Name=%d", *Name); + return gcvSTATUS_OK; + +OnError: + if (referenced) + { + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node)); + } + + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + } + + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckVIDMEM_NODE_Import +** +** Import a gckVIDMEM_NODE object. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctUINT32 Name +** Name of a gckVIDMEM_NODE object. +** +** OUTPUT: +** +** gctUINT32 * Handle +** Pointer to a variable receiving a handle represent this +** gckVIDMEM_NODE in userspace. +*/ +gceSTATUS +gckVIDMEM_NODE_Import( + IN gckKERNEL Kernel, + IN gctUINT32 Name, + IN gctUINT32 * Handle + ) +{ + gceSTATUS status; + gckVIDMEM_NODE node = gcvNULL; + gctPOINTER database = Kernel->db->nameDatabase; + gctPOINTER mutex = Kernel->db->nameDatabaseMutex; + gctBOOL acquired = gcvFALSE; + gctBOOL referenced = gcvFALSE; + + gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name); + + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE)); + acquired = gcvTRUE; + + /* Lookup in database to get the node. */ + gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, (gctPOINTER *)&node)); + + /* Reference the node. */ + gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, node)); + referenced = gcvTRUE; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + acquired = gcvFALSE; + + /* Allocate a handle for current process. */ + gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, Handle)); + + gcmkFOOTER_ARG("*Handle=%d", *Handle); + return gcvSTATUS_OK; + +OnError: + if (referenced) + { + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node)); + } + + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex)); + } + + gcmkFOOTER(); + return status; +} + + +typedef struct _gcsVIDMEM_NODE_FDPRIVATE +{ + gcsFDPRIVATE base; + gckKERNEL kernel; + gckVIDMEM_NODE node; +} +gcsVIDMEM_NODE_FDPRIVATE; + + +static gctINT +_ReleaseFdPrivate( + gcsFDPRIVATE_PTR FdPrivate + ) +{ + /* Cast private info. */ + gcsVIDMEM_NODE_FDPRIVATE * private = (gcsVIDMEM_NODE_FDPRIVATE *) FdPrivate; + + gckVIDMEM_NODE_Dereference(private->kernel, private->node); + gckOS_Free(private->kernel->os, private); + + return 0; +} + +/******************************************************************************* +** +** gckVIDMEM_NODE_GetFd +** +** Attach a gckVIDMEM_NODE object to a native fd. +** +** INPUT: +** +** gckKERNEL Kernel +** Pointer to an gckKERNEL object. +** +** gctUINT32 Handle +** Handle to a gckVIDMEM_NODE object. +** +** OUTPUT: +** +** gctUINT32 * Fd +** Pointer to a variable receiving a native fd from os. +*/ +gceSTATUS +gckVIDMEM_NODE_GetFd( + IN gckKERNEL Kernel, + IN gctUINT32 Handle, + OUT gctINT * Fd + ) +{ + gceSTATUS status; + gckVIDMEM_NODE node = gcvNULL; + gctBOOL referenced = gcvFALSE; + gcsVIDMEM_NODE_FDPRIVATE * fdPrivate = gcvNULL; + gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle); + + /* Query and reference handle. */ + gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node)); + referenced = gcvTRUE; + + /* Allocate memory for private info. */ + gcmkONERROR(gckOS_Allocate( + Kernel->os, + gcmSIZEOF(gcsVIDMEM_NODE_FDPRIVATE), + (gctPOINTER *)&fdPrivate + )); + + fdPrivate->base.release = _ReleaseFdPrivate; + fdPrivate->kernel = Kernel; + fdPrivate->node = node; + + /* Allocated fd owns a reference. */ + gcmkONERROR(gckOS_GetFd("vidmem", &fdPrivate->base, Fd)); + + gcmkFOOTER_ARG("*Fd=%d", *Fd); + return gcvSTATUS_OK; + +OnError: + if (referenced) + { + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node)); + } + + if (fdPrivate) + { + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, fdPrivate)); + } + + gcmkFOOTER(); + return status; +} + diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h index 63d5dad3a75a..f4b7d9911282 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -28,10 +28,14 @@ #include "gc_hal_base.h" #include "gc_hal_profiler.h" #include "gc_hal_driver.h" -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D #include "gc_hal_statistics.h" #endif +#if gcdSECURITY +#include "gc_hal_security_interface.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -40,6 +44,13 @@ extern "C" { ******************************* Alignment Macros ******************************* \******************************************************************************/ +/* Alignment with a non-power of two value. */ +#define gcmALIGN_NP2(n, align) \ +( \ + ((n) + (align) - 1) - (((n) + (align) - 1) % (align)) \ +) + +/* Alignment with a power of two value. */ #define gcmALIGN(n, align) \ ( \ ((n) + ((align) - 1)) & ~((align) - 1) \ @@ -76,30 +87,11 @@ extern "C" { #define gcmRELEASE_NAME(na) \ gckKERNEL_DeleteName(kernel, gcmALL_TO_UINT32(na)) -#ifdef __LP64__ - #define gcmALL_TO_UINT32(t) \ ( \ (gctUINT32) (gctUINTPTR_T) (t)\ ) -#define gcmPTR_TO_UINT64(p) \ -( \ - (gctUINT64) (p)\ -) - -#define gcmUINT64_TO_PTR(u) \ -( \ - (gctPOINTER) (u)\ -) - -#else /* 32 bit */ - -#define gcmALL_TO_UINT32(t) \ -( \ - (gctUINT32) (t)\ -) - #define gcmPTR_TO_UINT64(p) \ ( \ (gctUINT64) (gctUINTPTR_T) (p)\ @@ -110,8 +102,6 @@ extern "C" { (gctPOINTER) (gctUINTPTR_T) (u)\ ) -#endif - #define gcmUINT64_TO_TYPE(u, t) \ ( \ (t) (gctUINTPTR_T) (u)\ @@ -175,6 +165,9 @@ typedef enum _gceOBJECT_TYPE gcvOBJ_VERTEX = gcmCC('V','R','T','X'), gcvOBJ_VIDMEM = gcmCC('V','M','E','M'), gcvOBJ_VG = gcmCC('V','G',' ',' '), + gcvOBJ_BUFOBJ = gcmCC('B','U','F','O'), + gcvOBJ_UNIFORM_BLOCK = gcmCC('U','B','L','K'), + gcvOBJ_CL = gcmCC('C','L',' ',' '), } gceOBJECT_TYPE; @@ -193,11 +186,22 @@ typedef enum _gceCORE { gcvCORE_MAJOR = 0x0, gcvCORE_2D = 0x1, - gcvCORE_VG = 0x2 + gcvCORE_VG = 0x2, +#if gcdMULTI_GPU_AFFINITY + gcvCORE_OCL = 0x3, +#endif } gceCORE; +#if gcdMULTI_GPU_AFFINITY +#define gcdMAX_GPU_COUNT 4 +#else #define gcdMAX_GPU_COUNT 3 +#endif + +#define gcdMAX_SURF_LAYER 4 + +#define gcdMAX_DRAW_BUFFERS 4 /******************************************************************************* ** @@ -356,8 +360,9 @@ gckOS_AllocatePagedMemory( gceSTATUS gckOS_AllocatePagedMemoryEx( IN gckOS Os, - IN gctBOOL Contiguous, + IN gctUINT32 Flag, IN gctSIZE_T Bytes, + OUT gctUINT32 * Gid, OUT gctPHYS_ADDR * Physical ); @@ -377,9 +382,6 @@ gceSTATUS gckOS_MapPages( IN gckOS Os, IN gctPHYS_ADDR Physical, -#ifdef __QNXNTO__ - IN gctPOINTER Logical, -#endif IN gctSIZE_T PageCount, IN gctPOINTER PageTable ); @@ -390,13 +392,18 @@ gckOS_MapPagesEx( IN gckOS Os, IN gceCORE Core, IN gctPHYS_ADDR Physical, -#ifdef __QNXNTO__ - IN gctPOINTER Logical, -#endif IN gctSIZE_T PageCount, + IN gctUINT32 Address, IN gctPOINTER PageTable ); +gceSTATUS +gckOS_UnmapPages( + IN gckOS Os, + IN gctSIZE_T PageCount, + IN gctUINT32 Address + ); + /* Unlock pages. */ gceSTATUS gckOS_UnlockPages( @@ -467,6 +474,14 @@ gckOS_GetPhysicalAddress( OUT gctUINT32 * Address ); +/* Get the physical address of a corresponding user logical address. */ +gceSTATUS +gckOS_UserLogicalToPhysical( + IN gckOS Os, + IN gctPOINTER Logical, + OUT gctUINT32 * Address + ); + /* Get the physical address of a corresponding logical address. */ gceSTATUS gckOS_GetPhysicalAddressProcess( @@ -493,6 +508,14 @@ gckOS_UnmapPhysical( IN gctSIZE_T Bytes ); +/* Get real physical address from descriptor. */ +gceSTATUS +gckOS_PhysicalToPhysicalAddress( + IN gckOS Os, + IN gctPOINTER Physical, + OUT gctUINT32 * PhysicalAddress + ); + /* Read data from a hardware register. */ gceSTATUS gckOS_ReadRegister( @@ -527,6 +550,26 @@ gckOS_WriteRegisterEx( IN gctUINT32 Data ); +#if gcdMULTI_GPU +gceSTATUS +gckOS_ReadRegisterByCoreId( + IN gckOS Os, + IN gceCORE Core, + IN gctUINT32 CoreId, + IN gctUINT32 Address, + OUT gctUINT32 * Data + ); + +gceSTATUS +gckOS_WriteRegisterByCoreId( + IN gckOS Os, + IN gceCORE Core, + IN gctUINT32 CoreId, + IN gctUINT32 Address, + IN gctUINT32 Data + ); +#endif + /* Write data to a 32-bit memory location. */ gceSTATUS gckOS_WriteMemory( @@ -621,7 +664,6 @@ gckOS_AtomicExchangePtr( OUT gctPOINTER * OldValue ); -#if gcdSMP gceSTATUS gckOS_AtomSetMask( IN gctPOINTER Atom, @@ -633,7 +675,6 @@ gckOS_AtomClearMask( IN gctPOINTER Atom, IN gctUINT32 Mask ); -#endif gceSTATUS gckOS_DumpCallStack( @@ -647,8 +688,6 @@ gckOS_GetProcessNameByPid( OUT gctUINT8_PTR String ); - - /******************************************************************************* ** ** gckOS_AtomConstruct @@ -945,16 +984,6 @@ gckOS_CopyToUserData( IN gctSIZE_T Size ); -#ifdef __QNXNTO__ -/* Map user physical address. */ -gceSTATUS -gckOS_MapUserPhysical( - IN gckOS Os, - IN gctPHYS_ADDR Phys, - OUT gctPOINTER * KernelPointer - ); -#endif - gceSTATUS gckOS_SuspendInterrupt( IN gckOS Os @@ -1056,6 +1085,40 @@ 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 ********************************* \******************************************************************************/ @@ -1244,7 +1307,7 @@ gckOS_CacheClean( gckOS Os, gctUINT32 ProcessID, gctPHYS_ADDR Handle, - gctPOINTER Physical, + gctUINT32 Physical, gctPOINTER Logical, gctSIZE_T Bytes ); @@ -1254,7 +1317,7 @@ gckOS_CacheFlush( gckOS Os, gctUINT32 ProcessID, gctPHYS_ADDR Handle, - gctPOINTER Physical, + gctUINT32 Physical, gctPOINTER Logical, gctSIZE_T Bytes ); @@ -1264,11 +1327,32 @@ gckOS_CacheInvalidate( gckOS Os, gctUINT32 ProcessID, gctPHYS_ADDR Handle, - gctPOINTER Physical, + gctUINT32 Physical, gctPOINTER Logical, 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 + ); + +gceSTATUS +gckOS_QueryOption( + IN gckOS Os, + IN gctCONST_STRING Option, + OUT gctUINT32 * Value + ); + /******************************************************************************\ ** Debug Support */ @@ -1323,6 +1407,9 @@ typedef enum _gceBROADCAST /* AXI bus error. */ gcvBROADCAST_AXI_BUS_ERROR, + + /* Out of memory. */ + gcvBROADCAST_OUT_OF_MEMORY, } gceBROADCAST; @@ -1357,9 +1444,9 @@ gckOS_BroadcastCalibrateSpeed( ** INPUT: ** ** gckOS Os -** Pointer to a gckOS object.ß +** Pointer to a gckOS object. ** -** gckCORE Core +** gceCORE Core ** GPU whose power is set. ** ** gctBOOL Clock @@ -1571,32 +1658,22 @@ gckVIDMEM_Destroy( IN gckVIDMEM Memory ); -/* Allocate rectangular memory. */ -gceSTATUS -gckVIDMEM_Allocate( - IN gckVIDMEM Memory, - IN gctUINT Width, - IN gctUINT Height, - IN gctUINT Depth, - IN gctUINT BytesPerPixel, - IN gctUINT32 Alignment, - IN gceSURF_TYPE Type, - OUT gcuVIDMEM_NODE_PTR * Node - ); - /* Allocate linear memory. */ gceSTATUS gckVIDMEM_AllocateLinear( + IN gckKERNEL Kernel, IN gckVIDMEM Memory, IN gctSIZE_T Bytes, IN gctUINT32 Alignment, IN gceSURF_TYPE Type, + IN gctBOOL Specified, OUT gcuVIDMEM_NODE_PTR * Node ); /* Free memory. */ gceSTATUS gckVIDMEM_Free( + IN gckKERNEL Kernel, IN gcuVIDMEM_NODE_PTR Node ); @@ -1604,16 +1681,18 @@ gckVIDMEM_Free( gceSTATUS gckVIDMEM_Lock( IN gckKERNEL Kernel, - IN gcuVIDMEM_NODE_PTR Node, + IN gckVIDMEM_NODE Node, IN gctBOOL Cacheable, - OUT gctUINT32 * Address + OUT gctUINT32 * Address, + OUT gctUINT32 * Gid, + OUT gctUINT64 * PhysicalAddress ); /* Unlock memory. */ gceSTATUS gckVIDMEM_Unlock( IN gckKERNEL Kernel, - IN gcuVIDMEM_NODE_PTR Node, + IN gckVIDMEM_NODE Node, IN gceSURF_TYPE Type, IN OUT gctBOOL * Asynchroneous ); @@ -1622,7 +1701,7 @@ gckVIDMEM_Unlock( gceSTATUS gckVIDMEM_ConstructVirtual( IN gckKERNEL Kernel, - IN gctBOOL Contiguous, + IN gctUINT32 Flag, IN gctSIZE_T Bytes, OUT gcuVIDMEM_NODE_PTR * Node ); @@ -1654,10 +1733,18 @@ typedef enum _gceKERNEL_FLUSH gcvFLUSH_DEPTH = 0x02, gcvFLUSH_TEXTURE = 0x04, gcvFLUSH_2D = 0x08, +#if gcdMULTI_GPU + gcvFLUSH_L2 = 0x10, +#endif + gcvFLUSH_TILE_STATUS = 0x20, gcvFLUSH_ALL = gcvFLUSH_COLOR | gcvFLUSH_DEPTH | gcvFLUSH_TEXTURE - | gcvFLUSH_2D, + | gcvFLUSH_2D +#if gcdMULTI_GPU + | gcvFLUSH_L2 +#endif + | gcvFLUSH_TILE_STATUS } gceKERNEL_FLUSH; @@ -1685,6 +1772,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( @@ -1700,29 +1795,40 @@ gckKERNEL_GetVideoMemoryPool( OUT gckVIDMEM * VideoMemory ); -#if gcdUSE_VIDMEM_PER_PID gceSTATUS -gckKERNEL_GetVideoMemoryPoolPid( +gckKERNEL_AllocateLinearMemory( IN gckKERNEL Kernel, - IN gcePOOL Pool, - IN gctUINT32 Pid, - OUT gckVIDMEM * VideoMemory + IN gctUINT32 ProcessID, + IN OUT gcePOOL * Pool, + IN gctSIZE_T Bytes, + IN gctUINT32 Alignment, + IN gceSURF_TYPE Type, + IN gctUINT32 Flag, + OUT gctUINT32 * Node ); gceSTATUS -gckKERNEL_CreateVideoMemoryPoolPid( +gckKERNEL_ReleaseVideoMemory( IN gckKERNEL Kernel, - IN gcePOOL Pool, - IN gctUINT32 Pid, - OUT gckVIDMEM * VideoMemory + IN gctUINT32 ProcessID, + IN gctUINT32 Handle ); gceSTATUS -gckKERNEL_RemoveVideoMemoryPoolPid( +gckKERNEL_LockVideoMemory( IN gckKERNEL Kernel, - IN gckVIDMEM VideoMemory + IN gceCORE Core, + IN gctUINT32 ProcessID, + IN gctBOOL FromUser, + IN OUT gcsHAL_INTERFACE * Interface + ); + +gceSTATUS +gckKERNEL_UnlockVideoMemory( + IN gckKERNEL Kernel, + IN gctUINT32 ProcessID, + IN OUT gcsHAL_INTERFACE * Interface ); -#endif /* Map video memory. */ gceSTATUS @@ -1784,6 +1890,9 @@ gckKERNEL_UnmapMemory( gceSTATUS gckKERNEL_Notify( IN gckKERNEL Kernel, +#if gcdMULTI_GPU + IN gctUINT CoreId, +#endif IN gceNOTIFY Notifcation, IN gctBOOL Data ); @@ -1910,9 +2019,9 @@ gckHARDWARE_BuildVirtualAddress( gceSTATUS gckHARDWARE_QueryCommandBuffer( IN gckHARDWARE Hardware, - OUT gctSIZE_T * Alignment, - OUT gctSIZE_T * ReservedHead, - OUT gctSIZE_T * ReservedTail + OUT gctUINT32 * Alignment, + OUT gctUINT32 * ReservedHead, + OUT gctUINT32 * ReservedTail ); /* Add a WAIT/LINK pair in the command queue. */ @@ -1921,20 +2030,16 @@ gckHARDWARE_WaitLink( IN gckHARDWARE Hardware, IN gctPOINTER Logical, IN gctUINT32 Offset, - IN OUT gctSIZE_T * Bytes, + IN OUT gctUINT32 * Bytes, OUT gctUINT32 * WaitOffset, - OUT gctSIZE_T * WaitBytes + OUT gctUINT32 * WaitBytes ); /* Kickstart the command processor. */ gceSTATUS gckHARDWARE_Execute( IN gckHARDWARE Hardware, - IN gctPOINTER Logical, -#ifdef __QNXNTO__ - IN gctPOINTER Physical, - IN gctBOOL PhysicalAddresses, -#endif + IN gctUINT32 Address, IN gctSIZE_T Bytes ); @@ -1943,23 +2048,24 @@ gceSTATUS gckHARDWARE_End( IN gckHARDWARE Hardware, IN gctPOINTER Logical, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); -/* Add a NOP command in the command queue. */ +#if gcdMULTI_GPU gceSTATUS -gckHARDWARE_Nop( +gckHARDWARE_ChipEnable( IN gckHARDWARE Hardware, IN gctPOINTER Logical, + IN gceCORE_3D_MASK ChipEnable, IN OUT gctSIZE_T * Bytes ); +#endif -/* Add a WAIT command in the command queue. */ +/* Add a NOP command in the command queue. */ gceSTATUS -gckHARDWARE_Wait( +gckHARDWARE_Nop( IN gckHARDWARE Hardware, IN gctPOINTER Logical, - IN gctUINT32 Count, IN OUT gctSIZE_T * Bytes ); @@ -1969,7 +2075,7 @@ gckHARDWARE_PipeSelect( IN gckHARDWARE Hardware, IN gctPOINTER Logical, IN gcePIPE_SELECT Pipe, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Add a LINK command in the command queue. */ @@ -1977,9 +2083,9 @@ gceSTATUS gckHARDWARE_Link( IN gckHARDWARE Hardware, IN gctPOINTER Logical, - IN gctPOINTER FetchAddress, - IN gctSIZE_T FetchSize, - IN OUT gctSIZE_T * Bytes + IN gctUINT32 FetchAddress, + IN gctUINT32 FetchSize, + IN OUT gctUINT32 * Bytes ); /* Add an EVENT command in the command queue. */ @@ -1989,7 +2095,7 @@ gckHARDWARE_Event( IN gctPOINTER Logical, IN gctUINT8 Event, IN gceKERNEL_WHERE FromWhere, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Query the available memory. */ @@ -2013,13 +2119,13 @@ gckHARDWARE_QueryChipIdentity( OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity ); -/* Query the shader support. */ +/* Query the shader uniforms support. */ gceSTATUS gckHARDWARE_QueryShaderCaps( IN gckHARDWARE Hardware, OUT gctUINT * VertexUniforms, OUT gctUINT * FragmentUniforms, - OUT gctUINT * Varyings + OUT gctBOOL * UnifiedUnforms ); /* Split a harwdare specific address into API stuff. */ @@ -2044,23 +2150,17 @@ gceSTATUS gckHARDWARE_ConvertLogical( IN gckHARDWARE Hardware, IN gctPOINTER Logical, + IN gctBOOL InUserSpace, OUT gctUINT32 * Address ); -#ifdef __QNXNTO__ -/* Convert physical address to hardware specific address. */ -gceSTATUS -gckHARDWARE_ConvertPhysical( - IN gckHARDWARE Hardware, - IN gctPHYS_ADDR Physical, - OUT gctUINT32 * Address - ); -#endif - /* Interrupt manager. */ gceSTATUS gckHARDWARE_Interrupt( IN gckHARDWARE Hardware, +#if gcdMULTI_GPU + IN gctUINT CoreId, +#endif IN gctBOOL InterruptValid ); @@ -2088,6 +2188,20 @@ gckHARDWARE_SetMMUv2( IN gctBOOL FromPower ); +#if gcdPROCESS_ADDRESS_SPACE +/* Configure mmu configuration. */ +gceSTATUS +gckHARDWARE_ConfigMMU( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctPOINTER MtlbLogical, + IN gctUINT32 Offset, + IN OUT gctSIZE_T * Bytes, + OUT gctSIZE_T * WaitLinkOffset, + OUT gctSIZE_T * WaitLinkBytes + ); +#endif + /* Get idle register. */ gceSTATUS gckHARDWARE_GetIdle( @@ -2102,7 +2216,7 @@ gckHARDWARE_Flush( IN gckHARDWARE Hardware, IN gceKERNEL_FLUSH Flush, IN gctPOINTER Logical, - IN OUT gctSIZE_T * Bytes + IN OUT gctUINT32 * Bytes ); /* Enable/disable fast clear. */ @@ -2138,6 +2252,12 @@ gckHARDWARE_SetPowerManagement( IN gctBOOL PowerManagement ); +gceSTATUS +gckHARDWARE_SetPowerManagementLock( + IN gckHARDWARE Hardware, + IN gctBOOL Lock + ); + gceSTATUS gckHARDWARE_SetGpuProfiler( IN gckHARDWARE Hardware, @@ -2158,6 +2278,12 @@ gckHARDWARE_GetFscaleValue( IN gctUINT * MinFscaleValue, IN gctUINT * MaxFscaleValue ); + +gceSTATUS +gckHARDWARE_SetMinFscaleValue( + IN gckHARDWARE Hardware, + IN gctUINT MinFscaleValue + ); #endif #if gcdPOWEROFF_TIMEOUT @@ -2247,6 +2373,21 @@ gckHARDWARE_SetDVFSPeroid( IN gctUINT32 Frequency ); +gceSTATUS +gckHARDWARE_PrepareFunctions( + gckHARDWARE Hardware + ); + +gceSTATUS +gckHARDWARE_SetMMUStates( + IN gckHARDWARE Hardware, + IN gctPOINTER MtlbAddress, + IN gceMMU_MODE Mode, + IN gctPOINTER SafeAddress, + IN gctPOINTER Logical, + IN OUT gctUINT32 * Bytes + ); + #if !gcdENABLE_VG /******************************************************************************\ ***************************** gckINTERRUPT Object ****************************** @@ -2302,6 +2443,16 @@ gckEVENT_Destroy( ); /* Reserve the next available hardware event. */ +#if gcdMULTI_GPU +gceSTATUS +gckEVENT_GetEvent( + IN gckEVENT Event, + IN gctBOOL Wait, + OUT gctUINT8 * EventID, + IN gceKERNEL_WHERE Source, + IN gceCORE_3D_MASK ChipEnable + ); +#else gceSTATUS gckEVENT_GetEvent( IN gckEVENT Event, @@ -2309,6 +2460,7 @@ gckEVENT_GetEvent( OUT gctUINT8 * EventID, IN gceKERNEL_WHERE Source ); +#endif /* Add a new event to the list of events. */ gceSTATUS @@ -2361,7 +2513,7 @@ gceSTATUS gckEVENT_Unlock( IN gckEVENT Event, IN gceKERNEL_WHERE FromWhere, - IN gcuVIDMEM_NODE_PTR Node, + IN gctPOINTER Node, IN gceSURF_TYPE Type ); @@ -2371,7 +2523,6 @@ gckEVENT_CommitDone( IN gceKERNEL_WHERE FromWhere ); -#if gcdVIRTUAL_COMMAND_BUFFER /* Schedule a FreeVirtualCommandBuffer event. */ gceSTATUS gckEVENT_DestroyVirtualCommandBuffer( @@ -2381,21 +2532,38 @@ gckEVENT_DestroyVirtualCommandBuffer( IN gctPOINTER Logical, IN gceKERNEL_WHERE FromWhere ); -#endif +#if gcdMULTI_GPU +gceSTATUS +gckEVENT_Submit( + IN gckEVENT Event, + IN gctBOOL Wait, + IN gctBOOL FromPower, + IN gceCORE_3D_MASK ChipEnable + ); +#else gceSTATUS gckEVENT_Submit( IN gckEVENT Event, IN gctBOOL Wait, IN gctBOOL FromPower ); +#endif -/* Commit an event queue. */ +#if gcdMULTI_GPU +gceSTATUS +gckEVENT_Commit( + IN gckEVENT Event, + IN gcsQUEUE_PTR Queue, + IN gceCORE_3D_MASK ChipEnable + ); +#else gceSTATUS gckEVENT_Commit( IN gckEVENT Event, IN gcsQUEUE_PTR Queue ); +#endif /* Schedule a composition event. */ gceSTATUS @@ -2415,6 +2583,9 @@ gckEVENT_Notify( gceSTATUS gckEVENT_Interrupt( IN gckEVENT Event, +#if gcdMULTI_GPU + IN gctUINT CoreId, +#endif IN gctUINT32 IDs ); @@ -2468,8 +2639,20 @@ gckCOMMAND_Stop( IN gctBOOL FromRecovery ); +#if gcdMULTI_GPU /* Commit a buffer to the command queue. */ gceSTATUS +gckCOMMAND_Commit( + IN gckCOMMAND Command, + IN gckCONTEXT Context, + IN gcoCMDBUF CommandBuffer, + IN gcsSTATE_DELTA_PTR StateDelta, + IN gcsQUEUE_PTR EventQueue, + IN gctUINT32 ProcessID, + IN gceCORE_3D_MASK ChipEnable + ); +#else +gceSTATUS gckCOMMAND_Commit( IN gckCOMMAND Command, IN gckCONTEXT Context, @@ -2478,29 +2661,39 @@ gckCOMMAND_Commit( IN gcsQUEUE_PTR EventQueue, IN gctUINT32 ProcessID ); +#endif /* Reserve space in the command buffer. */ gceSTATUS gckCOMMAND_Reserve( IN gckCOMMAND Command, - IN gctSIZE_T RequestedBytes, + IN gctUINT32 RequestedBytes, OUT gctPOINTER * Buffer, - OUT gctSIZE_T * BufferSize + OUT gctUINT32 * BufferSize ); /* Execute reserved space in the command buffer. */ gceSTATUS gckCOMMAND_Execute( IN gckCOMMAND Command, - IN gctSIZE_T RequstedBytes + IN gctUINT32 RequstedBytes ); /* Stall the command queue. */ +#if gcdMULTI_GPU +gceSTATUS +gckCOMMAND_Stall( + IN gckCOMMAND Command, + IN gctBOOL FromPower, + IN gceCORE_3D_MASK ChipEnable + ); +#else gceSTATUS gckCOMMAND_Stall( IN gckCOMMAND Command, IN gctBOOL FromPower ); +#endif /* Attach user process. */ gceSTATUS @@ -2518,12 +2711,19 @@ gckCOMMAND_Detach( IN gckCONTEXT Context ); -#if gcdVIRTUAL_COMMAND_BUFFER +/* Dump command buffer being executed by GPU. */ gceSTATUS gckCOMMAND_DumpExecutingBuffer( IN gckCOMMAND Command ); -#endif + +/* Whether a kernel command buffer address. */ +gceSTATUS +gckCOMMAND_AddressInKernelCommandBuffer( + IN gckCOMMAND Command, + IN gctUINT32 Address, + OUT gctBOOL *In + ); /******************************************************************************\ ********************************* gckMMU Object ******************************** @@ -2545,14 +2745,6 @@ gckMMU_Destroy( IN gckMMU Mmu ); -/* Enable the MMU. */ -gceSTATUS -gckMMU_Enable( - IN gckMMU Mmu, - IN gctUINT32 PhysBaseAddr, - IN gctUINT32 PhysSize - ); - /* Allocate pages inside the MMU. */ gceSTATUS gckMMU_AllocatePages( @@ -2587,30 +2779,10 @@ gckMMU_SetPage( IN gctUINT32 *PageEntry ); -#ifdef __QNXNTO__ -gceSTATUS -gckMMU_InsertNode( - IN gckMMU Mmu, - IN gcuVIDMEM_NODE_PTR Node); - -gceSTATUS -gckMMU_RemoveNode( - IN gckMMU Mmu, - IN gcuVIDMEM_NODE_PTR Node); -#endif - -#ifdef __QNXNTO__ -gceSTATUS -gckMMU_FreeHandleMemory( - IN gckKERNEL Kernel, - IN gckMMU Mmu, - IN gctUINT32 Pid - ); -#endif - gceSTATUS gckMMU_Flush( - IN gckMMU Mmu + IN gckMMU Mmu, + IN gceSURF_TYPE Type ); gceSTATUS @@ -2624,7 +2796,7 @@ gckMMU_DumpPageTableEntry( gceSTATUS gckHARDWARE_QueryProfileRegisters( IN gckHARDWARE Hardware, - IN gctBOOL Clear, + IN gctBOOL Reset, OUT gcsPROFILER_COUNTERS * Counters ); #endif @@ -2633,7 +2805,7 @@ gckHARDWARE_QueryProfileRegisters( gceSTATUS gckHARDWARE_QueryContextProfile( IN gckHARDWARE Hardware, - IN gctBOOL Clear, + IN gctBOOL Reset, IN gckCONTEXT Context, OUT gcsPROFILER_COUNTERS * Counters ); @@ -2645,6 +2817,13 @@ gckHARDWARE_UpdateContextProfile( ); #endif +#if VIVANTE_PROFILER_NEW +gceSTATUS +gckHARDWARE_InitProfiler( + IN gckHARDWARE Hardware + ); +#endif + gceSTATUS gckOS_SignalQueryHardware( IN gckOS Os, @@ -2659,6 +2838,16 @@ gckOS_SignalSetHardware( gckHARDWARE Hardware ); +gceSTATUS +gckOS_DetectProcessByName( + IN gctCONST_POINTER Name + ); + +void +gckOS_DumpParam( + void + ); + #ifdef __cplusplus } #endif 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 375a8f5b03d1..b798152523af 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -18,13 +18,11 @@ * *****************************************************************************/ - #ifndef __gc_hal_base_h_ #define __gc_hal_base_h_ #include "gc_hal_enum.h" #include "gc_hal_types.h" - #include "gc_hal_dump.h" #ifdef __cplusplus @@ -39,9 +37,12 @@ typedef struct _gckOS * gckOS; typedef struct _gcoHAL * gcoHAL; typedef struct _gcoOS * gcoOS; typedef struct _gco2D * gco2D; +typedef struct gcsATOM * gcsATOM_PTR; -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D typedef struct _gco3D * gco3D; +typedef struct _gcoCL * gcoCL; +typedef struct _gcsFAST_FLUSH * gcsFAST_FLUSH_PTR; #endif typedef struct _gcoSURF * gcoSURF; @@ -55,29 +56,134 @@ typedef struct _gcsBOUNDARY * gcsBOUNDARY_PTR; typedef struct _gcoDUMP * gcoDUMP; typedef struct _gcoHARDWARE * gcoHARDWARE; typedef union _gcuVIDMEM_NODE * gcuVIDMEM_NODE_PTR; - -typedef struct gcsATOM * gcsATOM_PTR; +typedef struct _gcsVIDMEM_NODE * gckVIDMEM_NODE; #if gcdENABLE_VG typedef struct _gcoVG * gcoVG; -typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR; -typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR; +typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR; +typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR; #else typedef void * gcoVG; #endif #if gcdSYNC typedef struct _gcoFENCE * gcoFENCE; -typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR; +typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR; #endif +#if defined(ANDROID) typedef struct _gcoOS_SymbolsList gcoOS_SymbolsList; +#endif /******************************************************************************\ ******************************* Process local storage ************************* \******************************************************************************/ + typedef struct _gcsPLS * gcsPLS_PTR; +#if gcdENABLE_3D +/****************************************************************************** +** +** Patch defines which should be moved to dedicate file later +** +** !!! ALWAYS ADD new ID in the TAIL, otherwise will break exising TRACE FILE +*******************************************************************************/ +typedef enum _gcePATCH_ID +{ + gcvPATCH_NOTINIT = -1, + gcvPATCH_INVALID = 0, + +#if gcdDEBUG_OPTION + gcvPATCH_DEBUG, +#endif + + gcvPATCH_GTFES30, + gcvPATCH_CTGL11, + gcvPATCH_CTGL20, + gcvPATCH_GLBM11, + gcvPATCH_GLBM21, + gcvPATCH_GLBM25, + gcvPATCH_GLBM27, + gcvPATCH_GLBMGUI, + gcvPATCH_GFXBENCH, + gcvPATCH_ANTUTU, /* Antutu 3.x */ + gcvPATCH_ANTUTU4X, /* Antutu 4.x */ + gcvPATCH_QUADRANT, + gcvPATCH_GPUBENCH, + gcvPATCH_DUOKAN, + gcvPATCH_GLOFTSXHM, + gcvPATCH_XRUNNER, + gcvPATCH_BUSPARKING3D, + gcvPATCH_SIEGECRAFT, + gcvPATCH_PREMIUM, + gcvPATCH_RACEILLEGAL, + gcvPATCH_MEGARUN, + gcvPATCH_BMGUI, + gcvPATCH_NENAMARK, + gcvPATCH_NENAMARK2, + gcvPATCH_FISHNOODLE, + gcvPATCH_MM06, + gcvPATCH_MM07, + gcvPATCH_BM21, + gcvPATCH_SMARTBENCH, + gcvPATCH_JPCT, + gcvPATCH_NEOCORE, + gcvPATCH_RTESTVA, + gcvPATCH_NBA2013, + gcvPATCH_BARDTALE, + gcvPATCH_F18, + gcvPATCH_CARPARK, + gcvPATCH_CARCHALLENGE, + gcvPATCH_HEROESCALL, + gcvPATCH_GLOFTF3HM, + gcvPATCH_CRAZYRACING, + gcvPATCH_FIREFOX, + gcvPATCH_CHROME, + gcvPATCH_MONOPOLY, + gcvPATCH_SNOWCOLD, + gcvPATCH_BM3, + gcvPATCH_BASEMARKX, + gcvPATCH_DEQP, + gcvPATCH_SF4, + gcePATCH_MGOHEAVEN2, + gcePATCH_SILIBILI, + gcePATCH_ELEMENTSDEF, + gcePATCH_GLOFTKRHM, + gcvPATCH_OCLCTS, + gcvPATCH_A8HP, + gcvPATCH_A8CN, + gcvPATCH_WISTONESG, + gcvPATCH_SPEEDRACE, + gcvPATCH_FSBHAWAIIF, + gcvPATCH_AIRNAVY, + gcvPATCH_F18NEW, + gcvPATCH_CKZOMBIES2, + gcvPATCH_EADGKEEPER, + gcvPATCH_BASEMARK2V2, + gcvPATCH_RIPTIDEGP2, + gcvPATCH_OESCTS, + gcvPATCH_GANGSTAR, + gcvPATCH_WHRKYZIXOVAN, + gcvPATCH_NAMESGAS, + gcvPATCH_AFTERBURNER, + gcvPATCH_UIMARK, + gcvPATCH_FM_OES_PLAYER, + gcvPATCH_SUMSUNG_BENCH, + gcvPATCH_ROCKSTAR_MAXPAYNE, + gcvPATCH_TITANPACKING, + gcvPATCH_BASEMARKOSIICN, + gcvPATCH_FRUITNINJA, +#if defined(ANDROID) + gcePATCH_ANDROID_CTS_MEDIA_PRESENTATIONTIME, +#endif + gcvPATCH_ANDROID_COMPOSITOR, + gcvPATCH_CTS_TEXTUREVIEW, + gcvPATCH_WATER2_CHUKONG, + + gcvPATCH_COUNT +} gcePATCH_ID; +#endif /* gcdENABLE_3D */ + typedef void (* gctPLS_DESTRUCTOR) ( gcsPLS_PTR ); @@ -108,29 +214,86 @@ typedef struct _gcsPLS gctPOINTER eglSurfaceInfo; gceSURF_FORMAT eglConfigFormat; + /* PLS reference count */ + gcsATOM_PTR reference; + /* PorcessID of the constrcutor process */ gctUINT32 processID; -#if gcdFORCE_GAL_LOAD_TWICE + /* ThreadID of the constrcutor process. */ gctSIZE_T threadID; /* Flag for calling module destructor. */ gctBOOL exiting; -#endif - /* Reference count for destructor. */ - gcsATOM_PTR reference; - gctBOOL bKFS; -#if gcdUSE_NPOT_PATCH gctBOOL bNeedSupportNP2Texture; -#endif - /* Destructor for eglDisplayInfo. */ gctPLS_DESTRUCTOR destructor; + /* Mutex to guard PLS access. currently it's for EGL. + ** We can use this mutex for every PLS access. + */ + gctPOINTER accessLock; +#if gcdENABLE_3D + /* Global patchID to overwrite the detection */ + gcePATCH_ID patchID; +#endif } gcsPLS; extern gcsPLS gcPLS; +#if gcdENABLE_3D +#define gcPLS_INITIALIZER \ +{ \ + gcvNULL, /* gcoOS object. */ \ + gcvNULL, /* gcoHAL object. */ \ + 0, /* internalSize */ \ + gcvNULL, /* internalPhysical */ \ + gcvNULL, /* internalLogical */ \ + 0, /* externalSize */ \ + gcvNULL, /* externalPhysical */ \ + gcvNULL, /* externalLogical */ \ + 0, /* contiguousSize */ \ + gcvNULL, /* contiguousPhysical */ \ + gcvNULL, /* contiguousLogical */ \ + gcvNULL, /* eglDisplayInfo */ \ + gcvNULL, /* eglSurfaceInfo */ \ + gcvSURF_A8R8G8B8,/* eglConfigFormat */ \ + gcvNULL, /* reference */ \ + 0, /* processID */ \ + 0, /* threadID */ \ + gcvFALSE, /* exiting */ \ + gcvFALSE, /* Special flag for NP2 texture. */ \ + gcvNULL, /* destructor */ \ + gcvNULL, /* accessLock */ \ + gcvPATCH_NOTINIT,/* global patchID */ \ +} +#else +#define gcPLS_INITIALIZER \ +{ \ + gcvNULL, /* gcoOS object. */ \ + gcvNULL, /* gcoHAL object. */ \ + 0, /* internalSize */ \ + gcvNULL, /* internalPhysical */ \ + gcvNULL, /* internalLogical */ \ + 0, /* externalSize */ \ + gcvNULL, /* externalPhysical */ \ + gcvNULL, /* externalLogical */ \ + 0, /* contiguousSize */ \ + gcvNULL, /* contiguousPhysical */ \ + gcvNULL, /* contiguousLogical */ \ + gcvNULL, /* eglDisplayInfo */ \ + gcvNULL, /* eglSurfaceInfo */ \ + gcvSURF_A8R8G8B8,/* eglConfigFormat */ \ + gcvNULL, /* reference */ \ + 0, /* processID */ \ + 0, /* threadID */ \ + gcvFALSE, /* exiting */ \ + gcvFALSE, /* Special flag for NP2 texture. */ \ + gcvNULL, /* destructor */ \ + gcvNULL, /* accessLock */ \ +} +#endif + /******************************************************************************\ ******************************* Thread local storage ************************* \******************************************************************************/ @@ -144,30 +307,39 @@ typedef void (* gctTLS_DESTRUCTOR) ( typedef struct _gcsTLS { gceHARDWARE_TYPE currentType; - gcoHARDWARE hardware; + + /* Current 3D hardwre of this thread */ + gcoHARDWARE currentHardware; + + /* Default 3D hardware of this thread */ + gcoHARDWARE defaultHardware; + /* Only for separated 3D and 2D */ gcoHARDWARE hardware2D; #if gcdENABLE_VG gcoVGHARDWARE vg; gcoVG engineVG; #endif /* gcdENABLE_VG */ +#if gcdENABLE_3D + gco3D engine3D; +#endif +#if gcdENABLE_2D + gco2D engine2D; +#endif + + /*thread data */ gctPOINTER context; + /* ES(including es1 and es2) client driver context which is current state */ + gctPOINTER esClientCtx; gctTLS_DESTRUCTOR destructor; - gctBOOL ProcessExiting; -#ifndef VIVANTE_NO_3D - gco3D engine3D; -#endif -#if gcdSYNC - gctBOOL fenceEnable; -#endif - gco2D engine2D; gctBOOL copied; -#if gcdFORCE_GAL_LOAD_TWICE /* libGAL.so handle */ gctHANDLE handle; -#endif + + /* If true, do not releas 2d engine and hardware in hal layer */ + gctBOOL release2DUpper; } gcsTLS; @@ -197,14 +369,12 @@ typedef enum _gcePOOL gcvPOOL_VIRTUAL, gcvPOOL_USER, gcvPOOL_CONTIGUOUS, - gcvPOOL_DEFAULT_FORCE_CONTIGUOUS, - gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE, gcvPOOL_NUMBER_OF_POOLS } gcePOOL; -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D /* Blending functions. */ typedef enum _gceBLEND_FUNCTION { @@ -237,16 +407,6 @@ typedef enum _gceBLEND_MODE } gceBLEND_MODE; -/* API flags. */ -typedef enum _gceAPI -{ - gcvAPI_D3D = 0x1, - gcvAPI_OPENGL = 0x2, - gcvAPI_OPENVG = 0x3, - gcvAPI_OPENCL = 0x4, -} -gceAPI; - /* Depth modes. */ typedef enum _gceDEPTH_MODE { @@ -255,7 +415,23 @@ typedef enum _gceDEPTH_MODE gcvDEPTH_W, } gceDEPTH_MODE; -#endif /* VIVANTE_NO_3D */ +#endif /* gcdENABLE_3D */ + +#if (gcdENABLE_3D || gcdENABLE_VG) +/* API flags. */ +typedef enum _gceAPI +{ + gcvAPI_D3D = 1, + gcvAPI_OPENGL_ES11, + gcvAPI_OPENGL_ES20, + gcvAPI_OPENGL_ES30, + gcvAPI_OPENGL, + gcvAPI_OPENVG, + gcvAPI_OPENCL, +} +gceAPI; +#endif + typedef enum _gceWHERE { @@ -279,8 +455,6 @@ typedef enum _gceSignalHandlerType } gceSignalHandlerType; - -#if gcdENABLE_VG /* gcsHAL_Limits*/ typedef struct _gcsHAL_LIMITS { @@ -291,13 +465,12 @@ typedef struct _gcsHAL_LIMITS gctUINT32 *chipFeatures; /* target caps */ - gctUINT32 maxWidth; - gctUINT32 maxHeight; - gctUINT32 multiTargetCount; - gctUINT32 maxSamples; + gctUINT32 maxWidth; + gctUINT32 maxHeight; + gctUINT32 multiTargetCount; + gctUINT32 maxSamples; }gcsHAL_LIMITS; -#endif /******************************************************************************\ *********** Generic Memory Allocation Optimization Using Containers ************ @@ -367,7 +540,7 @@ gcsCONTAINER_FreeAll( /* Construct a new gcoHAL object. */ gceSTATUS -gcoHAL_Construct( +gcoHAL_ConstructEx( IN gctPOINTER Context, IN gcoOS Os, OUT gcoHAL * Hal @@ -375,16 +548,77 @@ gcoHAL_Construct( /* Destroy an gcoHAL object. */ gceSTATUS +gcoHAL_DestroyEx( + IN gcoHAL Hal + ); + +/* Empty function for compatibility. */ +gceSTATUS +gcoHAL_Construct( + IN gctPOINTER Context, + IN gcoOS Os, + OUT gcoHAL * Hal + ); + +/* Empty function for compatibility. */ +gceSTATUS gcoHAL_Destroy( IN gcoHAL Hal ); +/* Get HAL options */ +gceSTATUS +gcoHAL_GetOption( + IN gcoHAL Hal, + IN gceOPTION Option + ); + +gceSTATUS +gcoHAL_FrameInfoOps( + IN gcoHAL Hal, + IN gceFRAMEINFO FrameInfo, + IN gceFRAMEINFO_OP Op, + IN OUT gctUINT * Val + ); + + +gceSTATUS +gcoHAL_GetHardware( + IN gcoHAL Hal, + OUT gcoHARDWARE* Hw + ); + +#if gcdENABLE_2D /* Get pointer to gco2D object. */ gceSTATUS gcoHAL_Get2DEngine( IN gcoHAL Hal, OUT gco2D * Engine ); +#endif + +#if gcdENABLE_3D +gceSTATUS +gcoHAL_GetSpecialHintData( + IN gcoHAL Hal, + OUT gctINT * Hint + ); +/* +** Deprecated(Don't use it), keep it here for external library(libgcu.so) +*/ +gceSTATUS +gcoHAL_Get3DEngine( + IN gcoHAL Hal, + OUT gco3D * Engine + ); +#endif /* gcdEANBLE_3D */ + + +gceSTATUS +gcoHAL_GetProductName( + IN gcoHAL Hal, + OUT gctSTRING *ProductName + ); gceSTATUS gcoHAL_SetFscaleValue( @@ -403,44 +637,39 @@ gcoHAL_SetBltNP2Texture( gctBOOL enable ); -#ifndef VIVANTE_NO_3D -/* Get pointer to gco3D object. */ gceSTATUS -gcoHAL_Get3DEngine( - IN gcoHAL Hal, - OUT gco3D * Engine +gcoHAL_NameVideoMemory( + IN gctUINT32 Handle, + OUT gctUINT32 * Name ); gceSTATUS -gcoHAL_Query3DEngine( - IN gcoHAL Hal, - OUT gco3D * Engine +gcoHAL_ImportVideoMemory( + IN gctUINT32 Name, + OUT gctUINT32 * Handle ); gceSTATUS -gcoHAL_Set3DEngine( - IN gcoHAL Hal, - IN gco3D Engine +gcoHAL_GetVideoMemoryFd( + IN gctUINT32 Handle, + OUT gctINT * Fd ); +/* Verify whether the specified feature is available in hardware. */ gceSTATUS -gcoHAL_Get3DHardware( +gcoHAL_IsFeatureAvailable( IN gcoHAL Hal, - OUT gcoHARDWARE * Hardware + IN gceFEATURE Feature ); gceSTATUS -gcoHAL_Set3DHardware( +gcoHAL_IsSwwaNeeded( IN gcoHAL Hal, - IN gcoHARDWARE Hardware + IN gceSWWA Swwa ); - -#endif /* VIVANTE_NO_3D */ - -/* Verify whether the specified feature is available in hardware. */ gceSTATUS -gcoHAL_IsFeatureAvailable( +gcoHAL_IsFeatureAvailable1( IN gcoHAL Hal, IN gceFEATURE Feature ); @@ -462,6 +691,13 @@ gceSTATUS gcoHAL_QueryChipMinorFeatures( OUT gctUINT32* ChipMinorFeatures ); +gctINT32 +gcoOS_EndRecordAllocation(void); +void +gcoOS_RecordAllocation(void); +void +gcoOS_AddRecordAllocation(gctSIZE_T Size); + /* Query the amount of video memory. */ gceSTATUS gcoHAL_QueryVideoMemory( @@ -501,6 +737,36 @@ 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 + ); + +/* Lock video memory. */ +gceSTATUS +gcoOS_LockVideoMemory( + IN gcoOS Os, + IN gctPOINTER Handle, + IN gctBOOL InUserSpace, + IN gctBOOL InCacheable, + OUT gctUINT32 * Physical, + OUT gctPOINTER * Logical + ); + /* Map user memory. */ gceSTATUS gcoHAL_MapUserMemory( @@ -537,6 +803,14 @@ gcoHAL_Commit( IN gctBOOL Stall ); +#if gcdENABLE_3D +/* Sencd fence command. */ +gceSTATUS +gcoHAL_SendFence( + IN gcoHAL Hal + ); +#endif /* gcdENABLE_3D */ + /* Query the tile capabilities. */ gceSTATUS gcoHAL_QueryTiled( @@ -591,19 +865,33 @@ gcoHAL_GetDump( OUT gcoDUMP * Dump ); -/* Call the kernel HAL layer. */ +#if gcdENABLE_3D gceSTATUS -gcoHAL_Call( - IN gcoHAL Hal, - IN OUT gcsHAL_INTERFACE_PTR Interface +gcoHAL_SetPatchID( + IN gcoHAL Hal, + IN gcePATCH_ID PatchID ); +/* Get Patch ID based on process name */ gceSTATUS gcoHAL_GetPatchID( IN gcoHAL Hal, OUT gcePATCH_ID * PatchID ); +gceSTATUS +gcoHAL_SetGlobalPatchID( + IN gcoHAL Hal, + IN gcePATCH_ID PatchID + ); +#endif /* gcdENABLE_3D */ +/* Call the kernel HAL layer. */ +gceSTATUS +gcoHAL_Call( + IN gcoHAL Hal, + IN OUT gcsHAL_INTERFACE_PTR Interface + ); + /* Schedule an event. */ gceSTATUS gcoHAL_ScheduleEvent( @@ -660,18 +948,19 @@ gcoHAL_QueryChipCount( ); gceSTATUS -gcoHAL_QuerySeparated3D2D( - IN gcoHAL Hal +gcoHAL_Query3DCoreCount( + IN gcoHAL Hal, + OUT gctUINT32 *Count ); gceSTATUS -gcoHAL_QuerySpecialHint( - IN gceSPECIAL_HINT Hint +gcoHAL_QuerySeparated2D( + IN gcoHAL Hal ); gceSTATUS -gcoHAL_SetSpecialHintData( - IN gcoHARDWARE Hardware +gcoHAL_Is3DAvailable( + IN gcoHAL Hal ); /* Get pointer to gcoVG object. */ @@ -681,23 +970,91 @@ gcoHAL_GetVGEngine( OUT gcoVG * Engine ); -#if gcdENABLE_VG gceSTATUS gcoHAL_QueryChipLimits( IN gcoHAL Hal, IN gctINT32 Chip, + IN gctINT32 Mask, OUT gcsHAL_LIMITS *Limits); gceSTATUS gcoHAL_QueryChipFeature( IN gcoHAL Hal, IN gctINT32 Chip, + IN gctINT32 Mask, IN gceFEATURE Feature); +/*----------------------------------------------------------------------------*/ +/*----- 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 + ); + +/* Config power management to be enabled or disabled. */ +gceSTATUS +gcoHAL_ConfigPowerManagement( + IN gctBOOL Enable + ); + +#if gcdENABLE_3D || gcdENABLE_VG +/* Query the target capabilities. */ +gceSTATUS +gcoHAL_QueryTargetCaps( + IN gcoHAL Hal, + OUT gctUINT * MaxWidth, + OUT gctUINT * MaxHeight, + OUT gctUINT * MultiTargetCount, + OUT gctUINT * MaxSamples + ); #endif + /******************************************************************************\ ********************************** gcoOS Object ********************************* \******************************************************************************/ +/* Lock PLS access */ +gceSTATUS +gcoOS_LockPLS( + void + ); + +/* Unlock PLS access */ +gceSTATUS +gcoOS_UnLockPLS( + void + ); /* Get PLS value for given key */ gctPOINTER @@ -724,17 +1081,17 @@ gcoOS_GetTLS( /* Destroy the objects associated with the current thread. */ void gcoOS_FreeThreadData( - IN gctBOOL ProcessExiting + void ); -/* Construct a new gcoOS object. */ +/* Empty function for compatibility. */ gceSTATUS gcoOS_Construct( IN gctPOINTER Context, OUT gcoOS * Os ); -/* Destroy an gcoOS object. */ +/* Empty function for compatibility. */ gceSTATUS gcoOS_Destroy( IN gcoOS Os @@ -770,6 +1127,21 @@ gcoOS_Free( IN gctPOINTER Memory ); +/* Allocate memory. */ +gceSTATUS +gcoOS_AllocateSharedMemory( + IN gcoOS Os, + IN gctSIZE_T Bytes, + OUT gctPOINTER * Memory + ); + +/* Free memory. */ +gceSTATUS +gcoOS_FreeSharedMemory( + IN gcoOS Os, + IN gctPOINTER Memory + ); + /* Allocate memory. */ gceSTATUS gcoOS_AllocateMemory( @@ -804,33 +1176,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 - ); - -gceSTATUS -gcoSURF_GetBankOffsetBytes( - IN gcoSURF Surfce, - IN gceSURF_TYPE Type, - IN gctUINT32 Stride, - IN gctUINT32_PTR Bytes - ); - /* Map user memory. */ gceSTATUS gcoOS_MapUserMemory( @@ -893,12 +1238,16 @@ gcoOS_FreeNonPagedMemory( ); #define gcmOS_SAFE_FREE(os, mem) \ - gcoOS_Free(os, mem); \ - mem = gcvNULL + gcoOS_Free(os, mem); \ + mem = gcvNULL + +#define gcmOS_SAFE_FREE_SHARED_MEMORY(os, mem) \ + gcoOS_FreeSharedMemory(os, mem); \ + mem = gcvNULL #define gcmkOS_SAFE_FREE(os, mem) \ gckOS_Free(os, mem); \ - mem = gcvNULL + mem = gcvNULL typedef enum _gceFILE_MODE { @@ -1039,7 +1388,7 @@ gcoOS_SetEnv( gceSTATUS gcoOS_GetCwd( IN gcoOS Os, - IN gctINT SizeInBytes, + IN gctINT SizeInBytes, OUT gctSTRING Buffer ); @@ -1146,18 +1495,17 @@ gcoOS_StrToFloat( ); /* Convert hex string to integer. */ -gceSTATUS -gcoOS_HexStrToInt( - IN gctCONST_STRING String, - OUT gctINT * Int - ); +gceSTATUS gcoOS_HexStrToInt( + IN gctCONST_STRING String, + OUT gctINT * Int + ); /* Convert hex string to float. */ gceSTATUS gcoOS_HexStrToFloat( - IN gctCONST_STRING String, - OUT gctFLOAT * Float - ); + IN gctCONST_STRING String, + OUT gctFLOAT * Float + ); /* Convert string to integer. */ gceSTATUS @@ -1233,11 +1581,6 @@ gcoOS_SetProfileSetting( ); #endif -gctBOOL -gcoOS_IsNeededSupportNP2Texture( - IN gctCHAR* ProcName - ); - /* Query the video memory. */ gceSTATUS gcoOS_QueryVideoMemory( @@ -1292,6 +1635,22 @@ gcoOS_AtomDestroy( IN gcsATOM_PTR Atom ); +/* Get the 32-bit value protected by an atom. */ +gceSTATUS +gcoOS_AtomGet( + IN gcoOS Os, + IN gcsATOM_PTR Atom, + OUT gctINT32_PTR Value + ); + +/* Set the 32-bit value protected by an atom. */ +gceSTATUS +gcoOS_AtomSet( + IN gcoOS Os, + IN gcsATOM_PTR Atom, + IN gctINT32 Value + ); + /* Increment an atom. */ gceSTATUS gcoOS_AtomIncrement( @@ -1523,7 +1882,7 @@ gcoOS_ReadRegister( gceSTATUS gcoOS_CacheClean( IN gcoOS Os, - IN gctUINT64 Node, + IN gctUINT32 Node, IN gctPOINTER Logical, IN gctSIZE_T Bytes ); @@ -1531,7 +1890,7 @@ gcoOS_CacheClean( gceSTATUS gcoOS_CacheFlush( IN gcoOS Os, - IN gctUINT64 Node, + IN gctUINT32 Node, IN gctPOINTER Logical, IN gctSIZE_T Bytes ); @@ -1539,7 +1898,7 @@ gcoOS_CacheFlush( gceSTATUS gcoOS_CacheInvalidate( IN gcoOS Os, - IN gctUINT64 Node, + IN gctUINT32 Node, IN gctPOINTER Logical, IN gctSIZE_T Bytes ); @@ -1550,6 +1909,11 @@ gcoOS_MemoryBarrier( IN gctPOINTER Logical ); +gceSTATUS +gcoOS_CPUPhysicalToGPUPhysical( + IN gctUINT32 CPUPhysical, + OUT gctUINT32_PTR GPUPhysical + ); /*----------------------------------------------------------------------------*/ /*----- Profile --------------------------------------------------------------*/ @@ -1608,7 +1972,7 @@ gcoOS_QueryProfileTickRate( # define gcmPROFILE_QUERY(start, ticks) do { } while (gcvFALSE) # define gcmPROFILE_ONLY(x) do { } while (gcvFALSE) # define gcmPROFILE_ELSE(x) x -# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE) +# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE) # define gcmPROFILE_DECLARE_ELSE(x) x #endif @@ -1653,6 +2017,41 @@ gcoMATH_UInt8AsFloat16( IN gctUINT8 X ); +gctUINT32 +gcoMATH_Float16ToFloat( + IN gctUINT16 In + ); + +gctUINT16 +gcoMATH_FloatToFloat16( + IN gctUINT32 In + ); + +gctUINT32 +gcoMATH_Float11ToFloat( + IN gctUINT32 In + ); + +gctUINT16 +gcoMATH_FloatToFloat11( + IN gctUINT32 In + ); + +gctUINT32 +gcoMATH_Float10ToFloat( + IN gctUINT32 In + ); + +gctUINT16 +gcoMATH_FloatToFloat10( + IN gctUINT32 In + ); + +gctUINT32 +gcoMATH_Float14ToFloat( + IN gctUINT16 In + ); + /******************************************************************************\ **************************** Coordinate Structures ***************************** \******************************************************************************/ @@ -1702,7 +2101,6 @@ typedef union _gcsPIXEL } gcsPIXEL; - /******************************************************************************\ ********************************* gcoSURF Object ******************************** \******************************************************************************/ @@ -1719,9 +2117,28 @@ typedef enum _gceFORMAT_CLASS gcvFORMAT_CLASS_LUMINANCE, gcvFORMAT_CLASS_BUMP, gcvFORMAT_CLASS_DEPTH, + gcvFORMAT_CLASS_ASTC, + gcvFORMAT_CLASS_OTHER } gceFORMAT_CLASS; +/* Color format data type */ +typedef enum _gceFORMAT_DATATYPE +{ + gcvFORMAT_DATATYPE_UNSIGNED_NORMALIZED, + gcvFORMAT_DATATYPE_SIGNED_NORMALIZED, + gcvFORMAT_DATATYPE_UNSIGNED_INTEGER, + gcvFORMAT_DATATYPE_SIGNED_INTEGER, + gcvFORMAT_DATATYPE_FLOAT16, + gcvFORMAT_DATATYPE_FLOAT32, + gcvFORMAT_DATATYPE_FLOAT_E5B9G9R9, + gcvFORMAT_DATATYPE_FLOAT_B10G11R11F, + gcvFORMAT_DATATYPE_INDEX, + gcvFORMAT_DATATYPE_SRGB, + gcvFORMAT_DATATYPE_FLOAT32_UINT, +} +gceFORMAT_DATATYPE; + /* Special enums for width field in gcsFORMAT_COMPONENT. */ typedef enum _gceCOMPONENT_CONTROL { @@ -1794,34 +2211,74 @@ typedef struct _gcsFORMAT_CLASS_TYPE_DEPTH } gcsFORMAT_CLASS_TYPE_DEPTH; +typedef union _gcuPIXEL_FORMAT_CLASS +{ + gcsFORMAT_CLASS_TYPE_BUMP bump; + gcsFORMAT_CLASS_TYPE_RGBA rgba; + gcsFORMAT_CLASS_TYPE_YUV yuv; + gcsFORMAT_CLASS_TYPE_LUMINANCE lum; + gcsFORMAT_CLASS_TYPE_INDEX index; + gcsFORMAT_CLASS_TYPE_DEPTH depth; +} +gcuPIXEL_FORMAT_CLASS; + /* Format parameters. */ typedef struct _gcsSURF_FORMAT_INFO { + /* Name of the format */ + gctCONST_STRING formatName; + /* Format code and class. */ gceSURF_FORMAT format; gceFORMAT_CLASS fmtClass; + /* Format data type */ + gceFORMAT_DATATYPE fmtDataType; + /* The size of one pixel in bits. */ gctUINT8 bitsPerPixel; - /* Component swizzle. */ - gceSURF_SWIZZLE swizzle; + /* Pixel block dimensions. */ + gctUINT blockWidth; + gctUINT blockHeight; + + /* Pixel block size in bits. */ + gctUINT blockSize; + + /* Some formats are larger than what the GPU can support. */ + /* These formats are read in the number of layers specified. */ + gctUINT8 layers; + + /* The format is faked and software will interpret it differently + ** with HW. Most of them can't be blendable(PE) or filterable(TX). + */ + gctBOOL fakedFormat; /* Some formats have two neighbour pixels interleaved together. */ /* To describe such format, set the flag to 1 and add another */ /* like this one describing the odd pixel format. */ - gctUINT8 interleaved; + gctBOOL interleaved; + + /* sRGB format. */ + gctBOOL sRGB; /* Format components. */ - union - { - gcsFORMAT_CLASS_TYPE_BUMP bump; - gcsFORMAT_CLASS_TYPE_RGBA rgba; - gcsFORMAT_CLASS_TYPE_YUV yuv; - gcsFORMAT_CLASS_TYPE_LUMINANCE lum; - gcsFORMAT_CLASS_TYPE_INDEX index; - gcsFORMAT_CLASS_TYPE_DEPTH depth; - } u; + gcuPIXEL_FORMAT_CLASS u; + + /* Format components. */ + gcuPIXEL_FORMAT_CLASS uOdd; + + /* Render format. */ + gceSURF_FORMAT closestRenderFormat; + /*gctCLOSEST_FORMAT dynamicClosestRenderFormat;*/ + gctUINT renderFormat; + const gceTEXTURE_SWIZZLE * pixelSwizzle; + + /* Texture format. */ + gceSURF_FORMAT closestTXFormat; + gctUINT txFormat; + const gceTEXTURE_SWIZZLE * txSwizzle; + gctBOOL txIntFilter; } gcsSURF_FORMAT_INFO; @@ -1835,16 +2292,6 @@ typedef struct _gcsSURF_FRAMEBUFFER } gcsSURF_FRAMEBUFFER; -typedef struct _gcsVIDMEM_NODE_SHARED_INFO -{ - gctBOOL tileStatusDisabled; - gcsPOINT SrcOrigin; - gcsPOINT DestOrigin; - gcsSIZE RectSize; - gctUINT32 clearValue; -} -gcsVIDMEM_NODE_SHARED_INFO; - /* Generic pixel component descriptors. */ extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XXX8; extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XX8X; @@ -1887,13 +2334,23 @@ gcoSURF_MapUserSurface( IN gctUINT32 Physical ); +/* Wrapp surface with known logical/GPU address */ +gceSTATUS +gcoSURF_WrapSurface( + IN gcoSURF Surface, + IN gctUINT Alignment, + IN gctPOINTER Logical, + IN gctUINT32 Physical + ); + + /* Query vid mem node info. */ gceSTATUS gcoSURF_QueryVidMemNode( IN gcoSURF Surface, - OUT gctUINT64 * Node, + OUT gctUINT32 * Node, OUT gcePOOL * Pool, - OUT gctUINT_PTR Bytes + OUT gctSIZE_T_PTR Bytes ); /* Set the color type of the surface. */ @@ -1910,23 +2367,26 @@ gcoSURF_GetColorType( OUT gceSURF_COLOR_TYPE *ColorType ); -/* Set the surface ration angle. */ +/* Set the color space of the surface. */ gceSTATUS -gcoSURF_SetRotation( +gcoSURF_SetColorSpace( IN gcoSURF Surface, - IN gceSURF_ROTATION Rotation + IN gceSURF_COLOR_SPACE ColorSpace ); +/* Get the color space of the surface. */ gceSTATUS -gcoSURF_SetPreRotation( +gcoSURF_GetColorSpace( IN gcoSURF Surface, - IN gceSURF_ROTATION Rotation + OUT gceSURF_COLOR_SPACE *ColorSpace ); + +/* Set the surface ration angle. */ gceSTATUS -gcoSURF_GetPreRotation( +gcoSURF_SetRotation( IN gcoSURF Surface, - IN gceSURF_ROTATION *Rotation + IN gceSURF_ROTATION Rotation ); gceSTATUS @@ -1934,25 +2394,38 @@ gcoSURF_IsValid( IN gcoSURF Surface ); -#ifndef VIVANTE_NO_3D +#if gcdENABLE_3D /* Verify and return the state of the tile status mechanism. */ gceSTATUS gcoSURF_IsTileStatusSupported( IN gcoSURF Surface ); -/* Process tile status for the specified surface. */ +/* Verify if surface has tile status enabled. */ +gceSTATUS +gcoSURF_IsTileStatusEnabled( + IN gcoSURF Surface + ); + +/* Verify if surface is compressed. */ gceSTATUS -gcoSURF_SetTileStatus( +gcoSURF_IsCompressed( IN gcoSURF Surface ); -/* Enable tile status for the specified surface. */ +/* Enable tile status for the specified surface on zero slot. */ gceSTATUS gcoSURF_EnableTileStatus( IN gcoSURF Surface ); +/* Enable tile status for the specified surface on specified slot. */ +gceSTATUS +gcoSURF_EnableTileStatusEx( + IN gcoSURF Surface, + IN gctUINT RtIndex + ); + /* Disable tile status for the specified surface. */ gceSTATUS gcoSURF_DisableTileStatus( @@ -1960,15 +2433,13 @@ gcoSURF_DisableTileStatus( IN gctBOOL Decompress ); +/* Flush tile status cache for the specified surface. */ gceSTATUS -gcoSURF_AlignResolveRect( - IN gcoSURF Surf, - IN gcsPOINT_PTR RectOrigin, - IN gcsPOINT_PTR RectSize, - OUT gcsPOINT_PTR AlignedOrigin, - OUT gcsPOINT_PTR AlignedSize +gcoSURF_FlushTileStatus( + IN gcoSURF Surface, + IN gctBOOL Decompress ); -#endif /* VIVANTE_NO_3D */ +#endif /* gcdENABLE_3D */ /* Get surface size. */ gceSTATUS @@ -1998,11 +2469,34 @@ gcoSURF_GetAlignment( OUT gctUINT * YAlignment ); +gceSTATUS +gcoSURF_AlignResolveRect( + IN gcoSURF Surf, + IN gcsPOINT_PTR RectOrigin, + IN gcsPOINT_PTR RectSize, + OUT gcsPOINT_PTR AlignedOrigin, + OUT gcsPOINT_PTR AlignedSize + ); + /* Get surface type and format. */ gceSTATUS gcoSURF_GetFormat( IN gcoSURF Surface, - OUT gceSURF_TYPE * Type, + OUT OPTIONAL gceSURF_TYPE * Type, + OUT OPTIONAL gceSURF_FORMAT * Format + ); + +/* Get surface information */ +gceSTATUS +gcoSURF_GetFormatInfo( + IN gcoSURF Surface, + OUT gcsSURF_FORMAT_INFO_PTR * formatInfo + ); + +/* Get Surface pack format */ +gceSTATUS +gcoSURF_GetPackedFormat( + IN gcoSURF Surface, OUT gceSURF_FORMAT * Format ); @@ -2013,6 +2507,20 @@ gcoSURF_GetTiling( OUT gceTILING * Tiling ); +/* Get flip bitmap offset bytes. */ +gceSTATUS +gcoSURF_GetFlipBitmapOffset( + IN gcoSURF Surface, + OUT gctUINT_PTR FlipBitmapOffset + ); + +/* Get bottom buffer offset bytes. */ +gceSTATUS +gcoSURF_GetBottomBufferOffset( + IN gcoSURF Surface, + OUT gctUINT_PTR BottomBufferOffset + ); + /* Lock the surface. */ gceSTATUS gcoSURF_Lock( @@ -2028,7 +2536,16 @@ gcoSURF_Unlock( IN gctPOINTER Memory ); -/* Return pixel format parameters. */ +/*. Query surface flags.*/ +gceSTATUS +gcoSURF_QueryFlags( + IN gcoSURF Surface, + IN gceSURF_FLAG Flag + ); + +/* Return pixel format parameters; Info is required to be a pointer to an + * array of at least two items because some formats have up to two records + * of description. */ gceSTATUS gcoSURF_QueryFormat( IN gceSURF_FORMAT Format, @@ -2054,9 +2571,6 @@ gcoSURF_FillFromTile( IN gcoSURF Surface ); -/* Check if surface needs a filler. */ -gceSTATUS gcoSURF_NeedFiller(IN gcoSURF Surface); - /* Fill surface with a value. */ gceSTATUS gcoSURF_Fill( @@ -2085,6 +2599,14 @@ gcoSURF_ConstructWrapper( OUT gcoSURF * Surface ); +/* Set surface flags.*/ +gceSTATUS +gcoSURF_SetFlags( + IN gcoSURF Surface, + IN gceSURF_FLAG Flag, + IN gctBOOL Value + ); + /* Set the underlying buffer for the surface wrapper. */ gceSTATUS gcoSURF_SetBuffer( @@ -2157,13 +2679,7 @@ gcoSURF_QueryOrientation( gceSTATUS gcoSURF_SetOffset( IN gcoSURF Surface, - IN gctUINT Offset - ); - -gceSTATUS -gcoSURF_GetOffset( - IN gcoSURF Surface, - OUT gctUINT *Offset + IN gctSIZE_T Offset ); gceSTATUS @@ -2174,6 +2690,30 @@ gcoSURF_NODE_Cache( IN gceCACHEOPERATION Operation ); +/* Lock and unlock surface node */ +gceSTATUS +gcoSURF_LockNode( + IN gcsSURF_NODE_PTR Node, + OUT gctUINT32 * Address, + OUT gctPOINTER * Memory + ); + +gceSTATUS +gcoSURF_UnLockNode( + IN gcsSURF_NODE_PTR Node, + IN gceSURF_TYPE Type + ); + +/* Perform CPU cache operation on surface node */ +gceSTATUS +gcoSURF_NODE_CPUCacheOperation( + IN gcsSURF_NODE_PTR Node, + IN gceSURF_TYPE Type, + IN gctSIZE_T Offset, + IN gctSIZE_T Length, + IN gceCACHEOPERATION Operation + ); + /* Perform CPU cache operation on surface */ gceSTATUS gcoSURF_CPUCacheOperation( @@ -2183,14 +2723,85 @@ gcoSURF_CPUCacheOperation( gceSTATUS -gcoSURF_SetLinearResolveAddress( +gcoSURF_Swap( + IN gcoSURF Surface1, + IN gcoSURF Surface2 + ); + +gceSTATUS +gcoSURF_ResetSurWH( IN gcoSURF Surface, - IN gctUINT32 Address, - IN gctPOINTER Memory + IN gctUINT oriw, + IN gctUINT orih, + IN gctUINT alignw, + IN gctUINT alignh, + IN gceSURF_FORMAT fmt +); + +/* Update surface timestamp. */ +gceSTATUS +gcoSURF_UpdateTimeStamp( + IN gcoSURF Surface ); - gceSTATUS - gcoSURF_Swap(IN gcoSURF Surface1, IN gcoSURF Surface2); +/* 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 + ); + +#if (gcdENABLE_3D || gcdENABLE_VG) +/* Copy surface. */ +gceSTATUS +gcoSURF_Copy( + IN gcoSURF Surface, + IN gcoSURF Source + ); + +/* Set number of samples for a gcoSURF object. */ +gceSTATUS +gcoSURF_SetSamples( + IN gcoSURF Surface, + IN gctUINT Samples + ); + +/* Get the number of samples per pixel. */ +gceSTATUS +gcoSURF_GetSamples( + IN gcoSURF Surface, + OUT gctUINT_PTR Samples + ); +#endif /******************************************************************************\ ********************************* gcoDUMP Object ******************************** @@ -2455,7 +3066,16 @@ gcoOS_SetDebugFile( gctFILE gcoOS_ReplaceDebugFile( IN gctFILE fp - ); + ); + +void +gcoOS_SysTraceBegin( + IN gctCONST_STRING FuncName + ); + +void +gcoOS_SysTraceEnd( + IN void); /******************************************************************************* ** @@ -2484,7 +3104,7 @@ gcoOS_DebugFatal( #if gcmIS_DEBUG(gcdDEBUG_FATAL) # define gcmFATAL gcoOS_DebugFatal # define gcmkFATAL gckOS_DebugFatal -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmFATAL(...) # define gcmkFATAL(...) #else @@ -2546,7 +3166,7 @@ gcoOS_DebugTrace( # define gcmTRACE gcoOS_DebugTrace # define gcmkTRACE gckOS_DebugTrace # define gcmkTRACE_N gckOS_DebugTraceN -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmTRACE(...) # define gcmkTRACE(...) # define gcmkTRACE_N(...) @@ -2615,6 +3235,9 @@ gcoOS_DebugTrace( #define gcvZONE_IMAGE (1 << 19) #define gcvZONE_UTILITY (1 << 20) #define gcvZONE_PARAMETERS (1 << 21) +#define gcvZONE_BUFOBJ (1 << 22) +#define gcvZONE_SHADER (1 << 23) +#define gcvZONE_STREAM_OUT (1 << 24) /* API definitions. */ #define gcvZONE_API_HAL (1 << 28) @@ -2624,9 +3247,9 @@ gcoOS_DebugTrace( #define gcvZONE_API_VG11 (5 << 28) #define gcvZONE_API_GL (6 << 28) #define gcvZONE_API_DFB (7 << 28) -#define gcvZONE_API_GDI (8 << 28) -#define gcvZONE_API_D3D (9 << 28) -#define gcvZONE_API_ES30 (10 << 28) +#define gcvZONE_API_GDI ((gctUINT32)8 << 28) +#define gcvZONE_API_D3D ((gctUINT32)9 << 28) +#define gcvZONE_API_ES30 ((gctUINT32)10 << 28) #define gcmZONE_GET_API(zone) ((zone) >> 28) @@ -2685,7 +3308,7 @@ gcoOS_DebugTraceZone( # define gcmTRACE_ZONE gcoOS_DebugTraceZone # define gcmkTRACE_ZONE gckOS_DebugTraceZone # define gcmkTRACE_ZONE_N gckOS_DebugTraceZoneN -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmTRACE_ZONE(...) # define gcmkTRACE_ZONE(...) # define gcmkTRACE_ZONE_N(...) @@ -2748,28 +3371,20 @@ gcoOS_DebugTraceZone( ** ... Optional arguments for text. */ #if gcmIS_DEBUG(gcdDEBUG_STACK) - void - gcoOS_StackPush( - IN gctCONST_STRING Function, - IN gctINT Line, - IN gctCONST_STRING Text, - ... - ); - void - gcoOS_StackPop( - IN gctCONST_STRING Function - ); - void - gcoOS_StackDump( - void - ); + void gcoOS_StackPush(IN gctINT8_PTR Identity, IN gctCONST_STRING Function, IN gctINT Line, IN gctCONST_STRING Text, ...); + void gcoOS_StackPop(IN gctINT8_PTR Identity, IN gctCONST_STRING Function); + void gcoOS_StackDump(void); + void gcoOS_StackRemove(IN gctHANDLE Thread); + # define gcmSTACK_PUSH gcoOS_StackPush # define gcmSTACK_POP gcoOS_StackPop # define gcmSTACK_DUMP gcoOS_StackDump -#elif gcdHAS_ELLIPSES +# define gcmSTACK_REMOVE gcoOS_StackRemove +#elif gcdHAS_ELLIPSIS # define gcmSTACK_PUSH(...) do { } while (0) -# define gcmSTACK_POP(Function) do { } while (0) +# define gcmSTACK_POP(...) do { } while (0) # define gcmSTACK_DUMP() do { } while (0) +# define gcmSTACK_REMOVE(...) do { } while (0) #else gcmINLINE static void __dummy_stack_push( @@ -2780,8 +3395,62 @@ gcoOS_DebugTraceZone( { } # define gcmSTACK_PUSH __dummy_stack_push -# define gcmSTACK_POP(Function) do { } while (0) +# define gcmSTACK_POP(a,b) do { } while (0) # define gcmSTACK_DUMP() do { } while (0) +# define gcmSTACK_REMOVE(a) do { } while (0) +#endif + +/******************************************************************************\ +******************************** Binary Trace ********************************** +\******************************************************************************/ +typedef struct _gcsBINARY_TRACE_MESSAGE * gcsBINARY_TRACE_MESSAGE_PTR; +typedef struct _gcsBINARY_TRACE_MESSAGE +{ + gctUINT32 signature; + gctUINT32 pid; + gctUINT32 tid; + gctUINT32 line; + gctUINT32 numArguments; + gctUINT8 payload; +} +gcsBINARY_TRACE_MESSAGE; + +#define gcdBINARY_TRACE_MESSAGE_SIZE 240 + +#if gcdBINARY_TRACE + void + gcoOS_BinaryTrace( + IN gctCONST_STRING Function, + IN gctINT Line, + IN gctCONST_STRING Text OPTIONAL, + ... + ); + + void + gckOS_BinaryTrace( + IN gctCONST_STRING Function, + IN gctINT Line, + IN gctCONST_STRING Text OPTIONAL, + ... + ); + +# define gcmBINARY_TRACE gcoOS_BinaryTrace +# define gcmkBINARY_TRACE gckOS_BinaryTrace +#elif gcdHAS_ELLIPSIS +# define gcmBINARY_TRACE(Function, Line, Text, ...) +# define gcmkBINARY_TRACE(Function, Line, Text, ...) +#else + gcmINLINE static void + __dummy_binary_trace( + IN gctCONST_STRING Function, + IN gctINT Line, + IN gctCONST_STRING Text, + ) + { + } + +# define gcmBINARY_TRACE __dummy_binary_trace +# define gcmkBINARY_TRACE __dummy_binary_trace #endif /******************************************************************************\ @@ -2790,6 +3459,9 @@ gcoOS_DebugTraceZone( #define gcdHEADER_LEVEL gcvLEVEL_VERBOSE +#ifndef gcdEMPTY_HEADER_FOOTER +#define gcdEMPTY_HEADER_FOOTER 0 +#endif #if gcdENABLE_PROFILING void @@ -2799,33 +3471,40 @@ gcoOS_ProfileDB( ); #define gcmHEADER() \ + gctINT8 __user__ = 1; \ static gctBOOL __profile__initialized__ = gcvFALSE; \ - gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ + gcmSTACK_PUSH(&__user__, __FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__) #define gcmHEADER_ARG(...) \ + gctINT8 __user__ = 1; \ static gctBOOL __profile__initialized__ = gcvFALSE; \ - gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \ + gcmSTACK_PUSH(&__user__, __FUNCTION__, __LINE__, Text, __VA_ARGS__); \ gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__) #define gcmFOOTER() \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(&__user__, __FUNCTION__); \ gcoOS_ProfileDB(__FUNCTION__, gcvNULL) #define gcmFOOTER_NO() \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(&__user__, __FUNCTION__); \ gcoOS_ProfileDB(__FUNCTION__, gcvNULL) #define gcmFOOTER_ARG(...) \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(&__user__, __FUNCTION__); \ gcoOS_ProfileDB(__FUNCTION__, gcvNULL) #define gcmFOOTER_KILL() \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(&__user__, __FUNCTION__); \ gcoOS_ProfileDB(gcvNULL, gcvNULL) #else /* gcdENABLE_PROFILING */ -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmHEADER() +#elif gcdEMPTY_HEADER_FOOTER +# define gcmHEADER() +#elif gcdHAS_ELLIPSIS #define gcmHEADER() \ gctINT8 __user__ = 1; \ gctINT8_PTR __user_ptr__ = &__user__; \ - gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ + gcmSTACK_PUSH(__user_ptr__, __FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ + gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "++%s(%d)", __FUNCTION__, __LINE__) #else @@ -2836,13 +3515,20 @@ gcoOS_ProfileDB( # define gcmHEADER __dummy_header #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmHEADER_ARG(Text, ...) +#elif gcdHAS_ELLIPSIS +#if gcdEMPTY_HEADER_FOOTER +# define gcmHEADER_ARG(Text, ...) +#else # define gcmHEADER_ARG(Text, ...) \ gctINT8 __user__ = 1; \ gctINT8_PTR __user_ptr__ = &__user__; \ - gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \ + gcmSTACK_PUSH(__user_ptr__, __FUNCTION__, __LINE__, Text, __VA_ARGS__); \ + gcmBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__) +#endif #else gcmINLINE static void __dummy_header_arg( @@ -2854,18 +3540,18 @@ gcoOS_ProfileDB( # define gcmHEADER_ARG __dummy_header_arg #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +# define gcmFOOTER() +#elif gcdEMPTY_HEADER_FOOTER +# define gcmFOOTER() +#elif gcdHAS_ELLIPSIS # define gcmFOOTER() \ - gcmSTACK_POP(__FUNCTION__); \ - gcmPROFILE_ONLY(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ - "--%s(%d) [%llu,%llu]: status=%d(%s)", \ - __FUNCTION__, __LINE__, \ - __ticks__, __total__, \ - status, gcoOS_DebugStatus2Name(status))); \ - gcmPROFILE_ELSE(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ - "--%s(%d): status=%d(%s)", \ - __FUNCTION__, __LINE__, \ - status, gcoOS_DebugStatus2Name(status))); \ + gcmSTACK_POP(__user_ptr__, __FUNCTION__); \ + gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ + "--%s(%d): status=%d(%s)", \ + __FUNCTION__, __LINE__, \ + status, gcoOS_DebugStatus2Name(status)); \ *__user_ptr__ -= 1 #else gcmINLINE static void @@ -2875,9 +3561,14 @@ gcoOS_ProfileDB( # define gcmFOOTER __dummy_footer #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmFOOTER_NO() +#elif gcdEMPTY_HEADER_FOOTER +# define gcmFOOTER_NO() +#elif gcdHAS_ELLIPSIS #define gcmFOOTER_NO() \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(__user_ptr__, __FUNCTION__); \ + gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "--%s(%d)", __FUNCTION__, __LINE__); \ *__user_ptr__ -= 1 @@ -2889,9 +3580,14 @@ gcoOS_ProfileDB( # define gcmFOOTER_NO __dummy_footer_no #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmFOOTER_KILL() +#elif gcdEMPTY_HEADER_FOOTER +# define gcmFOOTER_KILL() +#elif gcdHAS_ELLIPSIS #define gcmFOOTER_KILL() \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(__user_ptr__, __FUNCTION__); \ + gcmBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "--%s(%d)", __FUNCTION__, __LINE__); \ *__user_ptr__ -= 1 @@ -2903,12 +3599,19 @@ gcoOS_ProfileDB( # define gcmFOOTER_KILL __dummy_footer_kill #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +# define gcmFOOTER_ARG(Text, ...) +#elif gcdHAS_ELLIPSIS +#if gcdEMPTY_HEADER_FOOTER +# define gcmFOOTER_ARG(Text, ...) +#else # define gcmFOOTER_ARG(Text, ...) \ - gcmSTACK_POP(__FUNCTION__); \ + gcmSTACK_POP(__user_ptr__, __FUNCTION__); \ + gcmBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \ gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "--%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__); \ *__user_ptr__ -= 1 +#endif #else gcmINLINE static void __dummy_footer_arg( @@ -2922,10 +3625,13 @@ gcoOS_ProfileDB( #endif /* gcdENABLE_PROFILING */ -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmkHEADER() +#elif gcdHAS_ELLIPSIS #define gcmkHEADER() \ gctINT8 __kernel__ = 1; \ gctINT8_PTR __kernel_ptr__ = &__kernel__; \ + gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "++%s(%d)", __FUNCTION__, __LINE__) #else @@ -2936,10 +3642,13 @@ gcoOS_ProfileDB( # define gcmkHEADER __dummy_kheader #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +# define gcmkHEADER_ARG(Text, ...) +#elif gcdHAS_ELLIPSIS # define gcmkHEADER_ARG(Text, ...) \ gctINT8 __kernel__ = 1; \ gctINT8_PTR __kernel_ptr__ = &__kernel__; \ + gcmkBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__) #else @@ -2953,8 +3662,11 @@ gcoOS_ProfileDB( # define gcmkHEADER_ARG __dummy_kheader_arg #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmkFOOTER() +#elif gcdHAS_ELLIPSIS #define gcmkFOOTER() \ + gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, status); \ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "--%s(%d): status=%d(%s)", \ __FUNCTION__, __LINE__, status, gckOS_DebugStatus2Name(status)); \ @@ -2967,8 +3679,11 @@ gcoOS_ProfileDB( # define gcmkFOOTER __dummy_kfooter #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +#define gcmkFOOTER_NO() +#elif gcdHAS_ELLIPSIS #define gcmkFOOTER_NO() \ + gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "--%s(%d)", __FUNCTION__, __LINE__); \ *__kernel_ptr__ -= 1 @@ -2980,8 +3695,11 @@ gcoOS_ProfileDB( # define gcmkFOOTER_NO __dummy_kfooter_no #endif -#if gcdHAS_ELLIPSES +#ifdef gcdFSL_REL_BUILD +# define gcmkFOOTER_ARG(Text, ...) +#elif gcdHAS_ELLIPSIS # define gcmkFOOTER_ARG(Text, ...) \ + gcmkBINARY_TRACE(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \ gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \ "--%s(%d): " Text, \ __FUNCTION__, __LINE__, __VA_ARGS__); \ @@ -3104,7 +3822,7 @@ gckOS_DebugFlush( void ); # define gcmDUMP_FRAMERATE gcfDumpFrameRate -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_FRAMERATE(...) #else gcmINLINE static void @@ -3137,7 +3855,7 @@ gckOS_DebugFlush( ... ); # define gcmDUMP gcfDump -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP(...) #else gcmINLINE static void @@ -3178,7 +3896,7 @@ gckOS_DebugFlush( IN gctSIZE_T Bytes ); # define gcmDUMP_DATA gcfDumpData -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_DATA(...) #else gcmINLINE static void @@ -3228,7 +3946,7 @@ gcfDumpBuffer( IN gctSIZE_T Bytes ); # define gcmDUMP_BUFFER gcfDumpBuffer -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_BUFFER(...) #else gcmINLINE static void @@ -3260,7 +3978,7 @@ gcfDumpBuffer( gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...); #if gcdDUMP_API # define gcmDUMP_API gcfDumpApi -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_API(...) #else gcmINLINE static void @@ -3287,7 +4005,7 @@ gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...); gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size); #if gcdDUMP_API # define gcmDUMP_API_ARRAY gcfDumpArray -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_API_ARRAY(...) #else gcmINLINE static void @@ -3314,7 +4032,7 @@ gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size); gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination); #if gcdDUMP_API # define gcmDUMP_API_ARRAY_TOKEN gcfDumpArrayToken -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_API_ARRAY_TOKEN(...) #else gcmINLINE static void @@ -3341,7 +4059,7 @@ gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination); gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size); #if gcdDUMP_API # define gcmDUMP_API_DATA gcfDumpApiData -#elif gcdHAS_ELLIPSES +#elif gcdHAS_ELLIPSIS # define gcmDUMP_API_DATA(...) #else gcmINLINE static void @@ -3354,6 +4072,115 @@ gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size); # define gcmDUMP_API_DATA __dummy_dump_api_data #endif +/******************************************************************************* +** gcmDUMP_2D_COMMAND +** +** Print the 2D command buffer. +** +** ARGUMENTS: +** +** gctUINT32_PTR Pointer to the command buffer. +** gctUINT32 Command buffer size. +*/ +gceSTATUS gcfDump2DCommand(IN gctUINT32_PTR Command, IN gctUINT32 Size); +#if gcdDUMP_2D +# define gcmDUMP_2D_COMMAND gcfDump2DCommand +#elif gcdHAS_ELLIPSIS +# define gcmDUMP_2D_COMMAND(...) +#else + gcmINLINE static void + __dummy_dump_2d_command( + IN gctUINT32_PTR Command, + IN gctUINT32 Size + ) + { + } +# define gcmDUMP_2D_COMMAND __dummy_dump_2d_command +#endif + +/******************************************************************************* +** gcmDUMP_2D_SURFACE +** +** Print the 2D surface memory. +** +** ARGUMENTS: +** +** gctBOOL Src. +** gctUINT32 Address. +*/ +gceSTATUS gcfDump2DSurface(IN gctBOOL Src, IN gctUINT32 Address); +#if gcdDUMP_2D +# define gcmDUMP_2D_SURFACE gcfDump2DSurface +#elif gcdHAS_ELLIPSIS +# define gcmDUMP_2D_SURFACE(...) +#else + gcmINLINE static void + __dummy_dump_2d_surface( + IN gctBOOL Src, + IN gctUINT32 Address + ) + { + } +# define gcmDUMP_2D_SURFACE __dummy_dump_2d_surface +#endif + +/******************************************************************************* +** gcmDUMP_ADD_MEMORY_INFO +** +** Record the memory info. +** +** ARGUMENTS: +** +** gctUINT32 Address. +** gctSIZE_T Size. +*/ +gceSTATUS gcfAddMemoryInfo(IN gctUINT32 GPUAddress, IN gctPOINTER Logical, IN gctUINT32 Physical, IN gctUINT32 Size); +#if gcdDUMP_2D +# define gcmDUMP_ADD_MEMORY_INFO gcfAddMemoryInfo +#elif gcdHAS_ELLIPSIS +# define gcmDUMP_ADD_MEMORY_INFO(...) +#else + gcmINLINE static void + __dummy_dump_add_memory_info( + IN gctUINT32 GPUAddress, + IN gctPOINTER Logical, + IN gctUINT32 Physical, + IN gctUINT32 Size + ) + { + } +# define gcmDUMP_ADD_MEMORY_INFO __dummy_dump_add_memory_info +#endif + +/******************************************************************************* +** gcmDUMP_DEL_MEMORY_INFO +** +** Record the memory info. +** +** ARGUMENTS: +** +** gctUINT32 Address. +*/ +gceSTATUS gcfDelMemoryInfo(IN gctUINT32 Address); +#if gcdDUMP_2D +# define gcmDUMP_DEL_MEMORY_INFO gcfDelMemoryInfo +#elif gcdHAS_ELLIPSIS +# define gcmDUMP_DEL_MEMORY_INFO(...) +#else + gcmINLINE static void + __dummy_dump_del_memory_info( + IN gctUINT32 Address + ) + { + } +# define gcmDUMP_DEL_MEMORY_INFO __dummy_dump_del_memory_info +#endif + +#if gcdDUMP_2D +extern gctPOINTER dumpMemInfoListMutex; +extern gctBOOL dump2DFlag; +#endif + /******************************************************************************* ** ** gcmTRACE_RELEASE @@ -3667,6 +4494,46 @@ gckOS_DebugStatus2Name( #define gcmONERROR(func) _gcmONERROR(gcm, func) #define gcmkONERROR(func) _gcmkONERROR(gcmk, func) +/******************************************************************************* +** +** gcmkSAFECASTSIZET +** +** Check wether value of a gctSIZE_T varible beyond the capability +** of 32bits GPU hardware. +** +** ASSUMPTIONS: +** +** +** +** ARGUMENTS: +** +** x A gctUINT32 variable +** y A gctSIZE_T variable +*/ +#define gcmkSAFECASTSIZET(x, y) \ + do \ + { \ + gctUINT32 tmp = (gctUINT32)(y); \ + if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \ + { \ + gcmkASSERT(tmp <= gcvMAXUINT32); \ + } \ + (x) = tmp; \ + } \ + while (gcvFALSE) + +#define gcmSAFECASTSIZET(x, y) \ + do \ + { \ + gctUINT32 tmp = (gctUINT32)(y); \ + if (gcmSIZEOF(gctSIZE_T) > gcmSIZEOF(gctUINT32)) \ + { \ + gcmASSERT(tmp <= gcvMAXUINT32); \ + } \ + (x) = tmp; \ + } \ + while (gcvFALSE) + /******************************************************************************* ** ** gcmVERIFY_LOCK @@ -3865,13 +4732,17 @@ gcGetUserDebugOption( void ); +#if defined(ANDROID) struct _gcoOS_SymbolsList { +#if gcdENABLE_3D gcePATCH_ID patchId; +#endif const char * symList[10]; }; +#endif -#if gcdHAS_ELLIPSES +#if gcdHAS_ELLIPSIS #define gcmUSER_DEBUG_MSG(level, ...) \ do \ { \ @@ -3889,6 +4760,759 @@ struct _gcoOS_SymbolsList #define gcmUSER_DEBUG_WARNING_MSG #endif +/******************************************************************************* +** +** A set of macros to aid state loading. +** +** ARGUMENTS: +** +** CommandBuffer Pointer to a gcoCMDBUF object. +** StateDelta Pointer to a gcsSTATE_DELTA state delta structure. +** Memory Destination memory pointer of gctUINT32_PTR type. +** PartOfContext Whether or not the state is a part of the context. +** FixedPoint Whether or not the state is of the fixed point format. +** Count Number of consecutive states to be loaded. +** Address State address. +** Data Data to be set to the state. +*/ + +/*----------------------------------------------------------------------------*/ + +#if gcmIS_DEBUG(gcdDEBUG_CODE) + +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \ + CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \ + CommandBuffer->lastLoadStateAddress = Address; \ + CommandBuffer->lastLoadStateCount = Count + +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \ + gcmASSERT( \ + (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \ + == \ + (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \ + ); \ + \ + gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \ + \ + CommandBuffer->lastLoadStateCount -= 1 + +# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \ + gcmASSERT(CommandBuffer->lastLoadStateCount == 0); + +# define gcmDEFINELOADSTATEBASE() \ + gctUINT32_PTR LoadStateBase; + +# define gcmSETLOADSTATEBASE(CommandBuffer, OutSide) \ + if (OutSide) \ + {\ + LoadStateBase = (gctUINT32_PTR)*OutSide; \ + }\ + else\ + {\ + LoadStateBase = (gctUINT_PTR)CommandBuffer->buffer;\ + } + + +# define gcmVERIFYLOADSTATEALIGNED(CommandBuffer, Memory) \ + gcmASSERT(((Memory - LoadStateBase) & 1) == 0); + +# define gcmUNSETLOADSTATEBASE() \ + LoadStateBase = LoadStateBase; + +#else + +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) +# define gcmVERIFYLOADSTATEDONE(CommandBuffer) + +# define gcmDEFINELOADSTATEBASE() +# define gcmSETLOADSTATEBASE(CommandBuffer, OutSide) +# define gcmVERIFYLOADSTATEALIGNED(CommandBuffer, Memory) +# define gcmUNSETLOADSTATEBASE() + +#endif + +#if gcdSECURE_USER + +# define gcmDEFINESECUREUSER() \ + gctUINT __secure_user_offset__; \ + gctUINT32_PTR __secure_user_hintArray__; + +# define gcmBEGINSECUREUSER() \ + __secure_user_offset__ = reserve->lastOffset; \ + \ + __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail) + +# define gcmENDSECUREUSER() \ + reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__) + +# define gcmSKIPSECUREUSER() \ + __secure_user_offset__ += gcmSIZEOF(gctUINT32) + +# define gcmUPDATESECUREUSER() \ + *__secure_user_hintArray__ = __secure_user_offset__; \ + \ + __secure_user_offset__ += gcmSIZEOF(gctUINT32); \ + __secure_user_hintArray__ += 1 + +#else + +# define gcmDEFINESECUREUSER() +# define gcmBEGINSECUREUSER() +# define gcmENDSECUREUSER() +# define gcmSKIPSECUREUSER() +# define gcmUPDATESECUREUSER() + +#endif + +/*----------------------------------------------------------------------------*/ + +#if gcdDUMP +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \ + if (FixedPoint) \ + { \ + gcmDUMP(gcvNULL, "#[state.x 0x%04X 0x%08X]", \ + Address, Data \ + ); \ + } \ + else \ + { \ + gcmDUMP(gcvNULL, "#[state 0x%04X 0x%08X]", \ + Address, Data \ + ); \ + } +#else +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) +#endif + +#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \ + gcmDEFINESECUREUSER() \ + gctSIZE_T ReserveSize; \ + gcoCMDBUF CommandBuffer; \ + gctUINT32_PTR Memory; \ + gcsSTATE_DELTA_PTR StateDelta + +#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \ +{ \ + gcmONERROR(gcoBUFFER_Reserve( \ + Hardware->buffer, ReserveSize, gcvTRUE, gcvCOMMAND_3D, &CommandBuffer \ + )); \ + \ + Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \ + \ + StateDelta = Hardware->delta; \ + \ + gcmBEGINSECUREUSER(); \ +} + +#define gcmENDSTATEBUFFER(Hardware, CommandBuffer, Memory, ReserveSize) \ +{ \ + gcmENDSECUREUSER(); \ + \ + gcmASSERT( \ + gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \ + == \ + (gctUINT8_PTR) Memory \ + ); \ +} + +/*----------------------------------------------------------------------------*/ + +#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \ +{ \ + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \ + gcmASSERT((gctUINT32)Count <= 1024); \ + \ + gcmVERIFYLOADSTATEDONE(CommandBuffer); \ + \ + gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \ + \ + *Memory++ \ + = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \ + \ + gcmSKIPSECUREUSER(); \ +} + +#define gcmENDSTATEBATCH(CommandBuffer, Memory) \ +{ \ + gcmVERIFYLOADSTATEDONE(CommandBuffer); \ + \ + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \ +} + +/*----------------------------------------------------------------------------*/ + +#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ + \ + gcmSAFECASTSIZET(__temp_data32__, Data); \ + \ + *Memory++ = __temp_data32__; \ + \ + gcoHARDWARE_UpdateDelta( \ + StateDelta, Address, 0, __temp_data32__ \ + ); \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + +#define gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcoHARDWARE_UpdateDelta( \ + StateDelta, Address, Mask, __temp_data32__ \ + ); \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + + +#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \ + \ + gcmSKIPSECUREUSER(); \ +} + +#define gcmSETFILLER(CommandBuffer, Memory) \ +{ \ + gcmVERIFYLOADSTATEDONE(CommandBuffer); \ + \ + Memory += 1; \ + \ + gcmSKIPSECUREUSER(); \ +} + +/*----------------------------------------------------------------------------*/ + +#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data); \ + gcmENDSTATEBATCH(CommandBuffer, Memory); \ +} + +#define gcmSETSINGLESTATEWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data); \ + gcmENDSTATEBATCH(CommandBuffer, Memory); \ +} + + +#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \ + gcmENDSTATEBATCH(CommandBuffer, Memory); \ +} + + + +#define gcmSETSEMASTALLPIPE(StateDelta, CommandBuffer, Memory, Data) \ +{ \ + gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, gcvFALSE, AQSemaphoreRegAddrs, Data); \ + \ + *Memory++ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \ + \ + *Memory++ = Data; \ + \ + gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \ + gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \ + gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \ + \ + gcmSKIPSECUREUSER(); \ +} + +/******************************************************************************* +** +** gcmSETSTARTDECOMMAND +** +** Form a START_DE command. +** +** ARGUMENTS: +** +** Memory Destination memory pointer of gctUINT32_PTR type. +** Count Number of the rectangles. +*/ + +#define gcmSETSTARTDECOMMAND(Memory, Count) \ +{ \ + *Memory++ \ + = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \ + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \ + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \ + \ + *Memory++ = 0xDEADDEED; \ +} + +/***************************************** +** Temp command buffer macro +*/ +#define gcmDEFINESTATEBUFFER_NEW(CommandBuffer, StateDelta, Memory) \ + gcmDEFINESECUREUSER() \ + gcmDEFINELOADSTATEBASE() \ + gcsTEMPCMDBUF CommandBuffer = gcvNULL; \ + gctUINT32_PTR Memory; \ + gcsSTATE_DELTA_PTR StateDelta + + +#define gcmBEGINSTATEBUFFER_NEW(Hardware, CommandBuffer, StateDelta, Memory, OutSide) \ +{ \ + if (OutSide) \ + {\ + Memory = (gctUINT32_PTR)*OutSide; \ + }\ + else \ + {\ + gcmONERROR(gcoBUFFER_StartTEMPCMDBUF( \ + Hardware->buffer, &CommandBuffer \ + ));\ + \ + Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \ + \ + }\ + StateDelta = Hardware->delta; \ + \ + gcmBEGINSECUREUSER(); \ + gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\ +} + +#define gcmENDSTATEBUFFER_NEW(Hardware, CommandBuffer, Memory, OutSide) \ +{ \ + gcmENDSECUREUSER(); \ + \ + if (OutSide) \ + {\ + *OutSide = Memory; \ + }\ + else \ + {\ + CommandBuffer->currentByteSize = (gctUINT32)((gctUINT8_PTR)Memory - \ + (gctUINT8_PTR)CommandBuffer->buffer); \ + \ + gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->buffer));\ + }\ + gcmUNSETLOADSTATEBASE()\ +} + +/*----------------------------------------------------------------------------*/ + +#define gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, Count) \ +{ \ + gcmVERIFYLOADSTATEALIGNED(CommandBuffer,Memory);\ + gcmASSERT((gctUINT32)Count <= 1024); \ + \ + *Memory++ \ + = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \ + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \ + \ + gcmSKIPSECUREUSER(); \ +} + +#define gcmENDSTATEBATCH_NEW(CommandBuffer, Memory) \ + gcmVERIFYLOADSTATEALIGNED(CommandBuffer,Memory); + +/*----------------------------------------------------------------------------*/ + +#define gcmSETSTATEDATA_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcoHARDWARE_UpdateDelta( \ + StateDelta, Address, 0, __temp_data32__ \ + ); \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + +#define gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcoHARDWARE_UpdateDelta( \ + StateDelta, Address, Mask, __temp_data32__ \ + ); \ + \ + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ + \ + gcmUPDATESECUREUSER(); \ +} + + +#define gcmSETCTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, Address, Data) \ +{ \ + gctUINT32 __temp_data32__; \ + \ + __temp_data32__ = Data; \ + \ + *Memory++ = __temp_data32__; \ + \ + gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \ + \ + gcmSKIPSECUREUSER(); \ +} + +#define gcmSETFILLER_NEW(CommandBuffer, Memory) \ +{ \ + Memory += 1; \ + \ + gcmSKIPSECUREUSER(); \ +} + +/*----------------------------------------------------------------------------*/ + +#define gcmSETSINGLESTATE_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATA_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data); \ + gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \ +} + +#define gcmSETSINGLESTATEWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data) \ +{ \ + gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Mask, Data); \ + gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \ +} + + +#define gcmSETSINGLECTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \ + Address, Data) \ +{ \ + gcmBEGINSTATEBATCH_NEW(CommandBuffer, Memory, FixedPoint, Address, 1); \ + gcmSETCTRLSTATE_NEW(StateDelta, CommandBuffer, Memory, Address, Data); \ + gcmENDSTATEBATCH_NEW(CommandBuffer, Memory); \ +} + + + +#define gcmSETSEMASTALLPIPE_NEW(StateDelta, CommandBuffer, Memory, Data) \ +{ \ + gcmSETSINGLESTATE_NEW(StateDelta, CommandBuffer, Memory, gcvFALSE, AQSemaphoreRegAddrs, Data); \ + \ + *Memory++ = gcmSETFIELDVALUE(0, STALL_COMMAND, OPCODE, STALL); \ + \ + *Memory++ = Data; \ + \ + gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \ + gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \ + gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \ + \ + gcmSKIPSECUREUSER(); \ +} + +#define gcmSETSTARTDECOMMAND_NEW(CommandBuffer, Memory, Count) \ +{ \ + *Memory++ \ + = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \ + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \ + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \ + \ + *Memory++ = 0xDEADDEED; \ + \ +} + +#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 +** +** Configure uniforms according to chip and numConstants. +*/ +#if !gcdENABLE_UNIFIED_CONSTANT +#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \ + UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \ +{ \ + if (ChipModel == gcv2000 && ChipRevision == 0x5118) \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 64; \ + ConstMax = 320; \ + } \ + else if (NumConstants == 320) \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 64; \ + ConstMax = 320; \ + } \ + /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */ \ + else if (NumConstants > 256 && ChipModel == gcv1000) \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 64; \ + ConstMax = 320; \ + } \ + else if (NumConstants > 256) \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 256; \ + ConstMax = 512; \ + } \ + else if (NumConstants == 256) \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 256; \ + ConstMax = 512; \ + } \ + else \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 168; \ + PsConstMax = 64; \ + ConstMax = 232; \ + } \ +} +#else +#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, NumConstants, \ + UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \ +{ \ + if (NumConstants > 256) \ + { \ + UnifiedConst = gcvTRUE; \ + VsConstBase = gcregSHUniformsRegAddrs; \ + PsConstBase = gcregSHUniformsRegAddrs; \ + ConstMax = NumConstants; \ + VsConstMax = 256; \ + PsConstMax = ConstMax - VsConstMax; \ + } \ + else if (NumConstants == 256) \ + { \ + if (ChipModel == gcv2000 && ChipRevision == 0x5118) \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 64; \ + ConstMax = 320; \ + } \ + else \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 256; \ + PsConstMax = 256; \ + ConstMax = 512; \ + } \ + } \ + else \ + { \ + UnifiedConst = gcvFALSE; \ + VsConstBase = AQVertexShaderConstRegAddrs; \ + PsConstBase = AQPixelShaderConstRegAddrs; \ + VsConstMax = 168; \ + PsConstMax = 64; \ + ConstMax = 232; \ + } \ +} +#endif + #ifdef __cplusplus } #endif diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h deleted file mode 100644 index f8413700031a..000000000000 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h +++ /dev/null @@ -1,4298 +0,0 @@ -/**************************************************************************** -* -* Copyright (C) 2005 - 2013 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 file the defines the front- and back-end compilers, as well as the -** objects they use. -*/ - -#ifndef __gc_hal_compiler_h_ -#define __gc_hal_compiler_h_ - -#ifndef VIVANTE_NO_3D -#include "gc_hal_types.h" -#include "gc_hal_engine.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef GC_ENABLE_LOADTIME_OPT -#define GC_ENABLE_LOADTIME_OPT 1 -#endif - -#define TEMP_OPT_CONSTANT_TEXLD_COORD 0 - -#define TEMP_SHADER_PATCH 1 - -#define TEMP_INLINE_ALL_EXPANSION 1 -/******************************* IR VERSION ******************/ -#define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1') - -/******************************************************************************\ -|******************************* SHADER LANGUAGE ******************************| -\******************************************************************************/ - - /* allocator/deallocator function pointer */ -typedef gceSTATUS (*gctAllocatorFunc)( - IN gctSIZE_T Bytes, - OUT gctPOINTER * Memory - ); - -typedef gceSTATUS (*gctDeallocatorFunc)( - IN gctPOINTER Memory - ); - -typedef gctBOOL (*compareFunc) ( - IN void * data, - IN void * key - ); - -typedef struct _gcsListNode gcsListNode; -struct _gcsListNode -{ - gcsListNode * next; - void * data; -}; - -typedef struct _gcsAllocator -{ - gctAllocatorFunc allocate; - gctDeallocatorFunc deallocate; -} gcsAllocator; - -/* simple map structure */ -typedef struct _SimpleMap SimpleMap; -struct _SimpleMap -{ - gctUINT32 key; - gctUINT32 val; - SimpleMap *next; - gcsAllocator *allocator; - -}; - -/* SimpleMap Operations */ -/* return -1 if not found, otherwise return the mapped value */ -gctUINT32 -gcSimpleMap_Find( - IN SimpleMap *Map, - IN gctUINT32 Key - ); - -gceSTATUS -gcSimpleMap_Destory( - IN SimpleMap * Map, - IN gcsAllocator * Allocator - ); - -/* Add a pair to the Map head, the user should be aware that the - * map pointer is always changed when adding a new node : - * - * gcSimpleMap_AddNode(&theMap, key, val, allocator); - * - */ -gceSTATUS -gcSimpleMap_AddNode( - IN SimpleMap ** Map, - IN gctUINT32 Key, - IN gctUINT32 Val, - IN gcsAllocator * Allocator - ); - -/* gcsList data structure and related operations */ -typedef struct _gcsList -{ - gcsListNode *head; - gcsListNode *tail; - gctINT count; - gcsAllocator *allocator; -} gcsList; - -/* List operations */ -void -gcList_Init( - IN gcsList *list, - IN gcsAllocator *allocator - ); - -gceSTATUS -gcList_CreateNode( - IN void * Data, - IN gctAllocatorFunc Allocator, - OUT gcsListNode ** ListNode - ); - -gceSTATUS -gcList_Clean( - IN gcsList * List, - IN gctBOOL FreeData - ); - -gcsListNode * -gcList_FindNode( - IN gcsList * List, - IN void * Key, - IN compareFunc compare - ); - -gceSTATUS -gcList_AddNode( - IN gcsList * List, - IN void * Data - ); - -gceSTATUS -gcList_RemoveNode( - IN gcsList * List, - IN gcsListNode * Node - ); - -/* link list structure for code list */ -typedef gcsList gcsCodeList; -typedef gcsCodeList * gctCodeList; -typedef gcsListNode gcsCodeListNode; - -/* Possible shader language opcodes. */ -typedef enum _gcSL_OPCODE -{ - gcSL_NOP, /* 0x00 */ - gcSL_MOV, /* 0x01 */ - gcSL_SAT, /* 0x02 */ - gcSL_DP3, /* 0x03 */ - gcSL_DP4, /* 0x04 */ - gcSL_ABS, /* 0x05 */ - gcSL_JMP, /* 0x06 */ - gcSL_ADD, /* 0x07 */ - gcSL_MUL, /* 0x08 */ - gcSL_RCP, /* 0x09 */ - gcSL_SUB, /* 0x0A */ - gcSL_KILL, /* 0x0B */ - gcSL_TEXLD, /* 0x0C */ - gcSL_CALL, /* 0x0D */ - gcSL_RET, /* 0x0E */ - gcSL_NORM, /* 0x0F */ - gcSL_MAX, /* 0x10 */ - gcSL_MIN, /* 0x11 */ - gcSL_POW, /* 0x12 */ - gcSL_RSQ, /* 0x13 */ - gcSL_LOG, /* 0x14 */ - gcSL_FRAC, /* 0x15 */ - gcSL_FLOOR, /* 0x16 */ - gcSL_CEIL, /* 0x17 */ - gcSL_CROSS, /* 0x18 */ - gcSL_TEXLDP, /* 0x19 */ - gcSL_TEXBIAS, /* 0x1A */ - gcSL_TEXGRAD, /* 0x1B */ - gcSL_TEXLOD, /* 0x1C */ - gcSL_SIN, /* 0x1D */ - gcSL_COS, /* 0x1E */ - gcSL_TAN, /* 0x1F */ - gcSL_EXP, /* 0x20 */ - gcSL_SIGN, /* 0x21 */ - gcSL_STEP, /* 0x22 */ - gcSL_SQRT, /* 0x23 */ - gcSL_ACOS, /* 0x24 */ - gcSL_ASIN, /* 0x25 */ - gcSL_ATAN, /* 0x26 */ - gcSL_SET, /* 0x27 */ - gcSL_DSX, /* 0x28 */ - gcSL_DSY, /* 0x29 */ - gcSL_FWIDTH, /* 0x2A */ - gcSL_DIV, /* 0x2B */ - gcSL_MOD, /* 0x2C */ - gcSL_AND_BITWISE, /* 0x2D */ - gcSL_OR_BITWISE, /* 0x2E */ - gcSL_XOR_BITWISE, /* 0x2F */ - gcSL_NOT_BITWISE, /* 0x30 */ - gcSL_LSHIFT, /* 0x31 */ - gcSL_RSHIFT, /* 0x32 */ - gcSL_ROTATE, /* 0x33 */ - gcSL_BITSEL, /* 0x34 */ - gcSL_LEADZERO, /* 0x35 */ - gcSL_LOAD, /* 0x36 */ - gcSL_STORE, /* 0x37 */ - gcSL_BARRIER, /* 0x38 */ - gcSL_STORE1, /* 0x39 */ - gcSL_ATOMADD, /* 0x3A */ - gcSL_ATOMSUB, /* 0x3B */ - gcSL_ATOMXCHG, /* 0x3C */ - gcSL_ATOMCMPXCHG, /* 0x3D */ - gcSL_ATOMMIN, /* 0x3E */ - gcSL_ATOMMAX, /* 0x3F */ - gcSL_ATOMOR, /* 0x40 */ - gcSL_ATOMAND, /* 0x41 */ - gcSL_ATOMXOR, /* 0x42 */ - /*gcSL_UNUSED, 0x43 */ - /*gcSL_UNUSED, 0x44 */ - /*gcSL_UNUSED, 0x45 */ - /*gcSL_UNUSED, 0x46 */ - /*gcSL_UNUSED, 0x47 */ - /*gcSL_UNUSED, 0x48 */ - /*gcSL_UNUSED, 0x49 */ - /*gcSL_UNUSED, 0x4A */ - /*gcSL_UNUSED, 0x4B */ - /*gcSL_UNUSED, 0x4C */ - /*gcSL_UNUSED, 0x4D */ - /*gcSL_UNUSED, 0x4E */ - /*gcSL_UNUSED, 0x4F */ - /*gcSL_UNUSED, 0x50 */ - /*gcSL_UNUSED, 0x51 */ - /*gcSL_UNUSED, 0x52 */ - gcSL_ADDLO = 0x53, /* 0x53 */ /* Float only. */ - gcSL_MULLO, /* 0x54 */ /* Float only. */ - gcSL_CONV, /* 0x55 */ - gcSL_GETEXP, /* 0x56 */ - gcSL_GETMANT, /* 0x57 */ - gcSL_MULHI, /* 0x58 */ /* Integer only. */ - gcSL_CMP, /* 0x59 */ - gcSL_I2F, /* 0x5A */ - gcSL_F2I, /* 0x5B */ - gcSL_ADDSAT, /* 0x5C */ /* Integer only. */ - gcSL_SUBSAT, /* 0x5D */ /* Integer only. */ - gcSL_MULSAT, /* 0x5E */ /* Integer only. */ - gcSL_DP2, /* 0x5F */ - gcSL_MAXOPCODE -} -gcSL_OPCODE; - -typedef enum _gcSL_FORMAT -{ - gcSL_FLOAT = 0, /* 0 */ - gcSL_INTEGER = 1, /* 1 */ - gcSL_INT32 = 1, /* 1 */ - gcSL_BOOLEAN = 2, /* 2 */ - gcSL_UINT32 = 3, /* 3 */ - gcSL_INT8, /* 4 */ - gcSL_UINT8, /* 5 */ - gcSL_INT16, /* 6 */ - gcSL_UINT16, /* 7 */ - gcSL_INT64, /* 8 */ /* Reserved for future enhancement. */ - gcSL_UINT64, /* 9 */ /* Reserved for future enhancement. */ - gcSL_INT128, /* 10 */ /* Reserved for future enhancement. */ - gcSL_UINT128, /* 11 */ /* Reserved for future enhancement. */ - gcSL_FLOAT16, /* 12 */ - gcSL_FLOAT64, /* 13 */ /* Reserved for future enhancement. */ - gcSL_FLOAT128, /* 14 */ /* Reserved for future enhancement. */ -} -gcSL_FORMAT; - -/* Destination write enable bits. */ -typedef enum _gcSL_ENABLE -{ - gcSL_ENABLE_NONE = 0x0, /* none is enabled, error/uninitialized state */ - gcSL_ENABLE_X = 0x1, - gcSL_ENABLE_Y = 0x2, - gcSL_ENABLE_Z = 0x4, - gcSL_ENABLE_W = 0x8, - /* Combinations. */ - gcSL_ENABLE_XY = gcSL_ENABLE_X | gcSL_ENABLE_Y, - gcSL_ENABLE_XYZ = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z, - gcSL_ENABLE_XYZW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W, - gcSL_ENABLE_XYW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_W, - gcSL_ENABLE_XZ = gcSL_ENABLE_X | gcSL_ENABLE_Z, - gcSL_ENABLE_XZW = gcSL_ENABLE_X | gcSL_ENABLE_Z | gcSL_ENABLE_W, - gcSL_ENABLE_XW = gcSL_ENABLE_X | gcSL_ENABLE_W, - gcSL_ENABLE_YZ = gcSL_ENABLE_Y | gcSL_ENABLE_Z, - gcSL_ENABLE_YZW = gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W, - gcSL_ENABLE_YW = gcSL_ENABLE_Y | gcSL_ENABLE_W, - gcSL_ENABLE_ZW = gcSL_ENABLE_Z | gcSL_ENABLE_W, -} -gcSL_ENABLE; - -/* Possible indices. */ -typedef enum _gcSL_INDEXED -{ - gcSL_NOT_INDEXED, /* 0 */ - gcSL_INDEXED_X, /* 1 */ - gcSL_INDEXED_Y, /* 2 */ - gcSL_INDEXED_Z, /* 3 */ - gcSL_INDEXED_W, /* 4 */ -} -gcSL_INDEXED; - -/* Opcode conditions. */ -typedef enum _gcSL_CONDITION -{ - gcSL_ALWAYS, /* 0x0 */ - gcSL_NOT_EQUAL, /* 0x1 */ - gcSL_LESS_OR_EQUAL, /* 0x2 */ - gcSL_LESS, /* 0x3 */ - gcSL_EQUAL, /* 0x4 */ - gcSL_GREATER, /* 0x5 */ - gcSL_GREATER_OR_EQUAL, /* 0x6 */ - gcSL_AND, /* 0x7 */ - gcSL_OR, /* 0x8 */ - gcSL_XOR, /* 0x9 */ - gcSL_NOT_ZERO, /* 0xA */ -} -gcSL_CONDITION; - -/* Possible source operand types. */ -typedef enum _gcSL_TYPE -{ - gcSL_NONE, /* 0x0 */ - gcSL_TEMP, /* 0x1 */ - gcSL_ATTRIBUTE, /* 0x2 */ - gcSL_UNIFORM, /* 0x3 */ - gcSL_SAMPLER, /* 0x4 */ - gcSL_CONSTANT, /* 0x5 */ - gcSL_OUTPUT, /* 0x6 */ - gcSL_PHYSICAL, /* 0x7 */ -} -gcSL_TYPE; - -/* Swizzle generator macro. */ -#define gcmSWIZZLE(Component1, Component2, Component3, Component4) \ -( \ - (gcSL_SWIZZLE_ ## Component1 << 0) | \ - (gcSL_SWIZZLE_ ## Component2 << 2) | \ - (gcSL_SWIZZLE_ ## Component3 << 4) | \ - (gcSL_SWIZZLE_ ## Component4 << 6) \ -) - -#define gcmExtractSwizzle(Swizzle, Index) \ - ((gcSL_SWIZZLE) ((((Swizzle) >> (Index * 2)) & 0x3))) - -#define gcmComposeSwizzle(SwizzleX, SwizzleY, SwizzleZ, SwizzleW) \ -( \ - ((SwizzleX) << 0) | \ - ((SwizzleY) << 2) | \ - ((SwizzleZ) << 4) | \ - ((SwizzleW) << 6) \ -) - -/* Possible swizzle values. */ -typedef enum _gcSL_SWIZZLE -{ - gcSL_SWIZZLE_X, /* 0x0 */ - gcSL_SWIZZLE_Y, /* 0x1 */ - gcSL_SWIZZLE_Z, /* 0x2 */ - gcSL_SWIZZLE_W, /* 0x3 */ - /* Combinations. */ - gcSL_SWIZZLE_XXXX = gcmSWIZZLE(X, X, X, X), - gcSL_SWIZZLE_YYYY = gcmSWIZZLE(Y, Y, Y, Y), - gcSL_SWIZZLE_ZZZZ = gcmSWIZZLE(Z, Z, Z, Z), - gcSL_SWIZZLE_WWWW = gcmSWIZZLE(W, W, W, W), - gcSL_SWIZZLE_XYYY = gcmSWIZZLE(X, Y, Y, Y), - gcSL_SWIZZLE_XZZZ = gcmSWIZZLE(X, Z, Z, Z), - gcSL_SWIZZLE_XWWW = gcmSWIZZLE(X, W, W, W), - gcSL_SWIZZLE_YZZZ = gcmSWIZZLE(Y, Z, Z, Z), - gcSL_SWIZZLE_YWWW = gcmSWIZZLE(Y, W, W, W), - gcSL_SWIZZLE_ZWWW = gcmSWIZZLE(Z, W, W, W), - gcSL_SWIZZLE_XYZZ = gcmSWIZZLE(X, Y, Z, Z), - gcSL_SWIZZLE_XYWW = gcmSWIZZLE(X, Y, W, W), - gcSL_SWIZZLE_XZWW = gcmSWIZZLE(X, Z, W, W), - gcSL_SWIZZLE_YZWW = gcmSWIZZLE(Y, Z, W, W), - gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z), - gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W), - gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y), - gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z), - gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W), - gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W), - gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W), - gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W), - - gcSL_SWIZZLE_INVALID = 0x7FFFFFFF -} -gcSL_SWIZZLE; - -typedef enum _gcSL_COMPONENT -{ - gcSL_COMPONENT_X, /* 0x0 */ - gcSL_COMPONENT_Y, /* 0x1 */ - gcSL_COMPONENT_Z, /* 0x2 */ - gcSL_COMPONENT_W, /* 0x3 */ - gcSL_COMPONENT_COUNT /* 0x4 */ -} gcSL_COMPONENT; - -#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0) - -/******************************************************************************\ -|*********************************** SHADERS **********************************| -\******************************************************************************/ - -/* Shader types. */ -typedef enum _gcSHADER_KIND { - gcSHADER_TYPE_UNKNOWN = 0, - gcSHADER_TYPE_VERTEX, - gcSHADER_TYPE_FRAGMENT, - gcSHADER_TYPE_CL, - gcSHADER_TYPE_PRECOMPILED, - gcSHADER_KIND_COUNT -} gcSHADER_KIND; - -typedef enum _gcGL_DRIVER_VERSION { - gcGL_DRIVER_ES11, /* OpenGL ES 1.1 */ - gcGL_DRIVER_ES20, /* OpenGL ES 2.0 */ - gcGL_DRIVER_ES30 /* OpenGL ES 3.0 */ -} gcGL_DRIVER_VERSION; - -/* gcSHADER objects. */ -typedef struct _gcSHADER * gcSHADER; -typedef struct _gcATTRIBUTE * gcATTRIBUTE; -typedef struct _gcUNIFORM * gcUNIFORM; -typedef struct _gcOUTPUT * gcOUTPUT; -typedef struct _gcsFUNCTION * gcFUNCTION; -typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION; -typedef struct _gcsHINT * gcsHINT_PTR; -typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER; -typedef struct _gcVARIABLE * gcVARIABLE; - -struct _gcsHINT -{ - /* Numbr of data transfers for Vertex Shader output. */ - gctUINT32 vsOutputCount; - - /* Flag whether the VS has point size or not. */ - gctBOOL vsHasPointSize; - -#if gcdUSE_WCLIP_PATCH - /* Flag whether the VS gl_position.z depends on gl_position.w - it's a hint for wclipping */ - gctBOOL vsPositionZDependsOnW; -#endif - - gctBOOL clipW; - - /* Flag whether or not the shader has a KILL instruction. */ - gctBOOL hasKill; - - /* Element count. */ - gctUINT32 elementCount; - - /* Component count. */ - gctUINT32 componentCount; - - /* Number of data transfers for Fragment Shader input. */ - gctUINT32 fsInputCount; - - /* Maximum number of temporary registers used in FS. */ - gctUINT32 fsMaxTemp; - - /* Maximum number of temporary registers used in VS. */ - gctUINT32 vsMaxTemp; - - /* Balance minimum. */ - gctUINT32 balanceMin; - - /* Balance maximum. */ - gctUINT32 balanceMax; - - /* Auto-shift balancing. */ - gctBOOL autoShift; - - /* Flag whether the PS outputs the depth value or not. */ - gctBOOL psHasFragDepthOut; - - /* Flag whether the ThreadWalker is in PS. */ - gctBOOL threadWalkerInPS; - - /* HW reg number for position of VS */ - gctUINT32 hwRegNoOfSIVPos; - -#if gcdALPHA_KILL_IN_SHADER - /* States to set when alpha kill is enabled. */ - gctUINT32 killStateAddress; - gctUINT32 alphaKillStateValue; - gctUINT32 colorKillStateValue; - - /* Shader instructiuon. */ - gctUINT32 killInstructionAddress; - gctUINT32 alphaKillInstruction[3]; - gctUINT32 colorKillInstruction[3]; -#endif - -#if TEMP_SHADER_PATCH - gctUINT32 pachedShaderIdentifier; -#endif -}; - -#if TEMP_SHADER_PATCH -#define INVALID_SHADER_IDENTIFIER 0xFFFFFFFF -#endif - -/* gcSHADER_TYPE enumeration. */ -typedef enum _gcSHADER_TYPE -{ - gcSHADER_FLOAT_X1 = 0, /* 0x00 */ - gcSHADER_FLOAT_X2, /* 0x01 */ - gcSHADER_FLOAT_X3, /* 0x02 */ - gcSHADER_FLOAT_X4, /* 0x03 */ - gcSHADER_FLOAT_2X2, /* 0x04 */ - gcSHADER_FLOAT_3X3, /* 0x05 */ - gcSHADER_FLOAT_4X4, /* 0x06 */ - gcSHADER_BOOLEAN_X1, /* 0x07 */ - gcSHADER_BOOLEAN_X2, /* 0x08 */ - gcSHADER_BOOLEAN_X3, /* 0x09 */ - gcSHADER_BOOLEAN_X4, /* 0x0A */ - gcSHADER_INTEGER_X1, /* 0x0B */ - gcSHADER_INTEGER_X2, /* 0x0C */ - gcSHADER_INTEGER_X3, /* 0x0D */ - gcSHADER_INTEGER_X4, /* 0x0E */ - gcSHADER_SAMPLER_1D, /* 0x0F */ - gcSHADER_SAMPLER_2D, /* 0x10 */ - gcSHADER_SAMPLER_3D, /* 0x11 */ - gcSHADER_SAMPLER_CUBIC, /* 0x12 */ - gcSHADER_FIXED_X1, /* 0x13 */ - gcSHADER_FIXED_X2, /* 0x14 */ - gcSHADER_FIXED_X3, /* 0x15 */ - gcSHADER_FIXED_X4, /* 0x16 */ - gcSHADER_IMAGE_2D, /* 0x17 */ /* For OCL. */ - gcSHADER_IMAGE_3D, /* 0x18 */ /* For OCL. */ - gcSHADER_SAMPLER, /* 0x19 */ /* For OCL. */ - gcSHADER_FLOAT_2X3, /* 0x1A */ - gcSHADER_FLOAT_2X4, /* 0x1B */ - gcSHADER_FLOAT_3X2, /* 0x1C */ - gcSHADER_FLOAT_3X4, /* 0x1D */ - gcSHADER_FLOAT_4X2, /* 0x1E */ - gcSHADER_FLOAT_4X3, /* 0x1F */ - gcSHADER_ISAMPLER_2D, /* 0x20 */ - gcSHADER_ISAMPLER_3D, /* 0x21 */ - gcSHADER_ISAMPLER_CUBIC, /* 0x22 */ - gcSHADER_USAMPLER_2D, /* 0x23 */ - gcSHADER_USAMPLER_3D, /* 0x24 */ - gcSHADER_USAMPLER_CUBIC, /* 0x25 */ - gcSHADER_SAMPLER_EXTERNAL_OES, /* 0x26 */ - - gcSHADER_UINT_X1, /* 0x27 */ - gcSHADER_UINT_X2, /* 0x28 */ - gcSHADER_UINT_X3, /* 0x29 */ - gcSHADER_UINT_X4, /* 0x2A */ - - gcSHADER_UNKONWN_TYPE, /* do not add type after this */ - gcSHADER_TYPE_COUNT /* must to change gcvShaderTypeInfo at the - * same time if you add any new type! */} -gcSHADER_TYPE; - -typedef enum _gcSHADER_TYPE_KIND -{ - gceTK_UNKOWN, - gceTK_FLOAT, - gceTK_INT, - gceTK_UINT, - gceTK_BOOL, - gceTK_FIXED, - gceTK_SAMPLER, - gceTK_IMAGE, - gceTK_OTHER -} gcSHADER_TYPE_KIND; - -typedef struct _gcSHADER_TYPEINFO -{ - gcSHADER_TYPE type; /* e.g. gcSHADER_FLOAT_2X4 */ - gctINT components; /* e.g. 4 components */ - gctINT rows; /* e.g. 2 rows */ - gcSHADER_TYPE componentType; /* e.g. gcSHADER_FLOAT_X4 */ - gcSHADER_TYPE_KIND kind; /* e.g. gceTK_FLOAT */ - gctCONST_STRING name; /* e.g. "FLOAT_2X4" */ -} gcSHADER_TYPEINFO; - -extern gcSHADER_TYPEINFO gcvShaderTypeInfo[]; - -#define gcmType_Comonents(Type) (gcvShaderTypeInfo[Type].components) -#define gcmType_Rows(Type) (gcvShaderTypeInfo[Type].rows) -#define gcmType_ComonentType(Type) (gcvShaderTypeInfo[Type].componentType) -#define gcmType_Kind(Type) (gcvShaderTypeInfo[Type].kind) -#define gcmType_Name(Type) (gcvShaderTypeInfo[Type].name) - -#define gcmType_isMatrix(type) (gcmType_Rows(type) > 1) - -typedef enum _gcSHADER_VAR_CATEGORY -{ - gcSHADER_VAR_CATEGORY_NORMAL = 0, /* primitive type and its array */ - gcSHADER_VAR_CATEGORY_STRUCT = 1 /* structure */ -} -gcSHADER_VAR_CATEGORY; - -typedef enum _gceTYPE_QUALIFIER -{ - gcvTYPE_QUALIFIER_NONE = 0x0, /* unqualified */ - gcvTYPE_QUALIFIER_VOLATILE = 0x1, /* volatile */ -}gceTYPE_QUALIFIER; - -typedef gctUINT16 gctTYPE_QUALIFIER; - -#if GC_ENABLE_LOADTIME_OPT -typedef struct _gcSHADER_TYPE_INFO -{ - gcSHADER_TYPE type; /* eg. gcSHADER_FLOAT_2X3 is the type */ - gctCONST_STRING name; /* the name of the type: "gcSHADER_FLOAT_2X3" */ - gcSHADER_TYPE baseType; /* its base type is gcSHADER_FLOAT_2 */ - gctINT components; /* it has 2 components */ - gctINT rows; /* and 3 rows */ - gctINT size; /* the size in byte */ -} gcSHADER_TYPE_INFO; - -extern gcSHADER_TYPE_INFO shader_type_info[]; - -enum gceLTCDumpOption { - gceLTC_DUMP_UNIFORM = 0x0001, - gceLTC_DUMP_EVALUATION = 0x0002, - gceLTC_DUMP_EXPESSION = 0x0004, - gceLTC_DUMP_COLLECTING = 0x0008, -}; - -gctBOOL gcDumpOption(gctINT Opt); - -#endif /* GC_ENABLE_LOADTIME_OPT */ - -#define IS_MATRIX_TYPE(type) \ - (((type >= gcSHADER_FLOAT_2X2) && (type <= gcSHADER_FLOAT_4X4)) || \ - ((type >= gcSHADER_FLOAT_2X3) && (type <= gcSHADER_FLOAT_4X3))) - -/* gcSHADER_PRECISION enumeration. */ -typedef enum _gcSHADER_PRECISION -{ - gcSHADER_PRECISION_DEFAULT, /* 0x00 */ - gcSHADER_PRECISION_HIGH, /* 0x01 */ - gcSHADER_PRECISION_MEDIUM, /* 0x02 */ - gcSHADER_PRECISION_LOW, /* 0x03 */ -} -gcSHADER_PRECISION; - -/* Shader flags. */ -typedef enum _gceSHADER_FLAGS -{ - gcvSHADER_NO_OPTIMIZATION = 0x00, - gcvSHADER_DEAD_CODE = 0x01, - gcvSHADER_RESOURCE_USAGE = 0x02, - gcvSHADER_OPTIMIZER = 0x04, - gcvSHADER_USE_GL_Z = 0x08, - /* - The GC family of GPU cores model GC860 and under require the Z - to be from 0 <= z <= w. - However, OpenGL specifies the Z to be from -w <= z <= w. So we - have to a conversion here: - - z = (z + w) / 2. - - So here we append two instructions to the vertex shader. - */ - gcvSHADER_USE_GL_POSITION = 0x10, - gcvSHADER_USE_GL_FACE = 0x20, - gcvSHADER_USE_GL_POINT_COORD = 0x40, - gcvSHADER_LOADTIME_OPTIMIZER = 0x80, -#if gcdALPHA_KILL_IN_SHADER - gcvSHADER_USE_ALPHA_KILL = 0x100, -#endif - -#if gcdPRE_ROTATION && (ANDROID_SDK_VERSION >= 14) - gcvSHADER_VS_PRE_ROTATION = 0x200, -#endif - -#if TEMP_INLINE_ALL_EXPANSION - gcvSHADER_INLINE_ALL_EXPANSION = 0x400, -#endif -} -gceSHADER_FLAGS; - -gceSTATUS -gcSHADER_CheckClipW( - IN gctCONST_STRING VertexSource, - IN gctCONST_STRING FragmentSource, - OUT gctBOOL * clipW); - -/******************************************************************************* -** gcSHADER_GetUniformVectorCount -** -** Get the number of vectors used by uniforms for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * Count -** Pointer to a variable receiving the number of vectors. -*/ -gceSTATUS -gcSHADER_GetUniformVectorCount( - IN gcSHADER Shader, - OUT gctSIZE_T * Count - ); - -/******************************************************************************* -** gcOptimizer Data Structures -*******************************************************************************/ -typedef enum _gceSHADER_OPTIMIZATION -{ - /* No optimization. */ - gcvOPTIMIZATION_NONE, - - /* Flow graph construction. */ - gcvOPTIMIZATION_CONSTRUCTION = 1 << 0, - - /* Dead code elimination. */ - gcvOPTIMIZATION_DEAD_CODE = 1 << 1, - - /* Redundant move instruction elimination. */ - gcvOPTIMIZATION_REDUNDANT_MOVE = 1 << 2, - - /* Inline expansion. */ - gcvOPTIMIZATION_INLINE_EXPANSION = 1 << 3, - - /* Constant propagation. */ - gcvOPTIMIZATION_CONSTANT_PROPAGATION = 1 << 4, - - /* Redundant bounds/checking elimination. */ - gcvOPTIMIZATION_REDUNDANT_CHECKING = 1 << 5, - - /* Loop invariant movement. */ - gcvOPTIMIZATION_LOOP_INVARIANT = 1 << 6, - - /* Induction variable removal. */ - gcvOPTIMIZATION_INDUCTION_VARIABLE = 1 << 7, - - /* Common subexpression elimination. */ - gcvOPTIMIZATION_COMMON_SUBEXPRESSION = 1 << 8, - - /* Control flow/banch optimization. */ - gcvOPTIMIZATION_CONTROL_FLOW = 1 << 9, - - /* Vector component operation merge. */ - gcvOPTIMIZATION_VECTOR_INSTRUCTION_MERGE = 1 << 10, - - /* Algebra simplificaton. */ - gcvOPTIMIZATION_ALGEBRAIC_SIMPLIFICATION = 1 << 11, - - /* Pattern matching and replacing. */ - gcvOPTIMIZATION_PATTERN_MATCHING = 1 << 12, - - /* Interprocedural constant propagation. */ - gcvOPTIMIZATION_IP_CONSTANT_PROPAGATION = 1 << 13, - - /* Interprecedural register optimization. */ - gcvOPTIMIZATION_IP_REGISTRATION = 1 << 14, - - /* Optimization option number. */ - gcvOPTIMIZATION_OPTION_NUMBER = 1 << 15, - - /* Loadtime constant. */ - gcvOPTIMIZATION_LOADTIME_CONSTANT = 1 << 16, - - /* MAD instruction optimization. */ - gcvOPTIMIZATION_MAD_INSTRUCTION = 1 << 17, - - /* Special optimization for LOAD SW workaround. */ - gcvOPTIMIZATION_LOAD_SW_WORKAROUND = 1 << 18, - - /* move code into conditional block if possile */ - gcvOPTIMIZATION_CONDITIONALIZE = 1 << 19, - - /* expriemental: power optimization mode - 1. add extra dummy texld to tune performance - 2. insert NOP after high power instrucitons - 3. split high power vec3/vec4 instruciton to vec2/vec1 operation - 4. ... - */ - gcvOPTIMIZATION_POWER_OPTIMIZATION = 1 << 20, - - /* optimize varying packing */ - gcvOPTIMIZATION_VARYINGPACKING = 1 << 22, - -#if TEMP_INLINE_ALL_EXPANSION - gcvOPTIMIZATION_INLINE_ALL_EXPANSION = 1 << 23, -#endif - - /* Full optimization. */ - /* Note that gcvOPTIMIZATION_LOAD_SW_WORKAROUND is off. */ - gcvOPTIMIZATION_FULL = 0x7FFFFFFF & - ~gcvOPTIMIZATION_LOAD_SW_WORKAROUND & - ~gcvOPTIMIZATION_INLINE_ALL_EXPANSION & - ~gcvOPTIMIZATION_POWER_OPTIMIZATION, - - /* Optimization Unit Test flag. */ - gcvOPTIMIZATION_UNIT_TEST = 1 << 31 -} -gceSHADER_OPTIMIZATION; - -typedef enum _gceOPTIMIZATION_VaryingPaking -{ - gcvOPTIMIZATION_VARYINGPACKING_NONE = 0, - gcvOPTIMIZATION_VARYINGPACKING_NOSPLIT, - gcvOPTIMIZATION_VARYINGPACKING_SPLIT -} gceOPTIMIZATION_VaryingPaking; - -typedef struct _gcOPTIMIZER_OPTION -{ - gceSHADER_OPTIMIZATION optFlags; - - /* debug & dump options: - - VC_OPTION=-DUMP:SRC:OPT|:OPTV|:CG|:CGV:|ALL|ALLV - - SRC: dump shader source code - OPT: dump incoming and final IR - OPTV: dump result IR in each optimization phase - CG: dump generated machine code - CGV: dump BE tree and optimization detail - - ALL = SRC|OPT|CG - ALLV = SRC|OPT|OPTV|CG|CGV - */ - gctBOOL dumpShaderSource; /* dump shader source code */ - gctBOOL dumpOptimizer; /* dump incoming and final IR */ - gctBOOL dumpOptimizerVerbose; /* dump result IR in each optimization phase */ - gctBOOL dumpBEGenertedCode; /* dump generated machine code */ - gctBOOL dumpBEVerbose; /* dump BE tree and optimization detail */ - gctBOOL dumpBEFinalIR; /* dump BE final IR */ - - /* Code generation */ - - /* Varying Packing: - - VC_OPTION=-PACKVARYING:[0-2]|:T[-]m[,n]|:LshaderIdx,min,max - - 0: turn off varying packing - 1: pack varyings, donot split any varying - 2: pack varyings, may split to make fully packed output - - Tm: only packing shader pair which vertex shader id is m - Tm,n: only packing shader pair which vertex shader id - is in range of [m, n] - T-m: do not packing shader pair which vertex shader id is m - T-m,n: do not packing shader pair which vertex shader id - is in range of [m, n] - - LshaderIdx,min,max : set load balance (min, max) for shaderIdx - if shaderIdx is -1, all shaders are impacted - newMin = origMin * (min/100.); - newMax = origMax * (max/100.); - */ - gceOPTIMIZATION_VaryingPaking packVarying; - gctINT _triageStart; - gctINT _triageEnd; - gctINT _loadBalanceShaderIdx; - gctINT _loadBalanceMin; - gctINT _loadBalanceMax; - - /* Do not generate immdeiate - - VC_OPTION=-NOIMM - - Force generate immediate even the machine model don't support it, - for testing purpose only - - VC_OPTION=-FORCEIMM - */ - gctBOOL noImmediate; - gctBOOL forceImmediate; - - /* Power reduction mode options */ - gctBOOL needPowerOptimization; - - /* Patch TEXLD instruction by adding dummy texld - (can be used to tune GPU power usage): - for every TEXLD we seen, add n dummy TEXLD - - it can be enabled by environment variable: - - VC_OPTION=-PATCH_TEXLD:M:N - - (for each M texld, add N dummy texld) - */ - gctINT patchEveryTEXLDs; - gctINT patchDummyTEXLDs; - - /* Insert NOP after high power consumption instructions - - VC_OPTION="-INSERTNOP:MUL:MULLO:DP3:DP4:SEENTEXLD" - */ - gctBOOL insertNOP; - gctBOOL insertNOPAfterMUL; - gctBOOL insertNOPAfterMULLO; - gctBOOL insertNOPAfterDP3; - gctBOOL insertNOPAfterDP4; - gctBOOL insertNOPOnlyWhenTexldSeen; - - /* split MAD to MUL and ADD: - - VC_OPTION=-SPLITMAD - */ - gctBOOL splitMAD; - - /* Convert vect3/vec4 operations to multiple vec2/vec1 operations - - VC_OPTION=-SPLITVEC:MUL:MULLO:DP3:DP4 - */ - gctBOOL splitVec; - gctBOOL splitVec4MUL; - gctBOOL splitVec4MULLO; - gctBOOL splitVec4DP3; - gctBOOL splitVec4DP4; - - /* turn/off features: - - VC_OPTION=-F:n,[0|1] - Note: n must be decimal number - */ - gctUINT featureBits; - - /* inline level (default 2 at O1): - - VC_OPTION=-INLINELEVEL:[0-3] - 0: no inline - 1: only inline the function only called once or small function - 2: inline functions be called less than 5 times or medium size function - 3: inline everything possible - */ - gctUINT inlineLevel; -} gcOPTIMIZER_OPTION; - -extern gcOPTIMIZER_OPTION theOptimizerOption; -#define gcmGetOptimizerOption() gcGetOptimizerOption() - -#define gcmOPT_DUMP_SHADER_SRC() \ - (gcmGetOptimizerOption()->dumpShaderSource != 0) -#define gcmOPT_DUMP_OPTIMIZER() \ - (gcmGetOptimizerOption()->dumpOptimizer != 0 || \ - gcmOPT_DUMP_OPTIMIZER_VERBOSE() ) -#define gcmOPT_DUMP_OPTIMIZER_VERBOSE() \ - (gcmGetOptimizerOption()->dumpOptimizerVerbose != 0) -#define gcmOPT_DUMP_CODEGEN() \ - (gcmGetOptimizerOption()->dumpBEGenertedCode != 0 || \ - gcmOPT_DUMP_CODEGEN_VERBOSE() ) -#define gcmOPT_DUMP_CODEGEN_VERBOSE() \ - (gcmGetOptimizerOption()->dumpBEVerbose != 0) -#define gcmOPT_DUMP_FINAL_IR() \ - (gcmGetOptimizerOption()->dumpBEFinalIR != 0) - -#define gcmOPT_SET_DUMP_SHADER_SRC(v) \ - gcmGetOptimizerOption()->dumpShaderSource = (v) - -#define gcmOPT_PATCH_TEXLD() (gcmGetOptimizerOption()->patchDummyTEXLDs != 0) -#define gcmOPT_INSERT_NOP() (gcmGetOptimizerOption()->insertNOP == gcvTRUE) -#define gcmOPT_SPLITMAD() (gcmGetOptimizerOption()->splitMAD == gcvTRUE) -#define gcmOPT_SPLITVEC() (gcmGetOptimizerOption()->splitVec == gcvTRUE) - -#define gcmOPT_NOIMMEDIATE() (gcmGetOptimizerOption()->noImmediate == gcvTRUE) -#define gcmOPT_FORCEIMMEDIATE() (gcmGetOptimizerOption()->forceImmediate == gcvTRUE) - -#define gcmOPT_PACKVARYING() (gcmGetOptimizerOption()->packVarying) -#define gcmOPT_PACKVARYING_triageStart() (gcmGetOptimizerOption()->_triageStart) -#define gcmOPT_PACKVARYING_triageEnd() (gcmGetOptimizerOption()->_triageEnd) - -#define gcmOPT_INLINELEVEL() (gcmGetOptimizerOption()->inlineLevel) - -/* Setters */ -#define gcmOPT_SetPatchTexld(m,n) (gcmGetOptimizerOption()->patchEveryTEXLDs = (m),\ - gcmGetOptimizerOption()->patchDummyTEXLDs = (n)) -#define gcmOPT_SetSplitVecMUL() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \ - gcmGetOptimizerOption()->splitVec4MUL = gcvTRUE) -#define gcmOPT_SetSplitVecMULLO() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \ - gcmGetOptimizerOption()->splitVec4MULLO = gcvTRUE) -#define gcmOPT_SetSplitVecDP3() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \ - gcmGetOptimizerOption()->splitVec4DP3 = gcvTRUE) -#define gcmOPT_SetSplitVecDP4() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \ - gcmGetOptimizerOption()->splitVec4DP4 = gcvTRUE) - -#define gcmOPT_SetPackVarying(v) (gcmGetOptimizerOption()->packVarying = v) - -#define FB_LIVERANGE_FIX1 0x0001 - - -#define PredefinedDummySamplerId 8 - -/* Function argument qualifier */ -typedef enum _gceINPUT_OUTPUT -{ - gcvFUNCTION_INPUT, - gcvFUNCTION_OUTPUT, - gcvFUNCTION_INOUT -} -gceINPUT_OUTPUT; - -/* Kernel function property flags. */ -typedef enum _gcePROPERTY_FLAGS -{ - gcvPROPERTY_REQD_WORK_GRP_SIZE = 0x01 -} -gceKERNEL_FUNCTION_PROPERTY_FLAGS; - -/* Uniform flags. */ -typedef enum _gceUNIFORM_FLAGS -{ - gcvUNIFORM_KERNEL_ARG = 0x01, - gcvUNIFORM_KERNEL_ARG_LOCAL = 0x02, - gcvUNIFORM_KERNEL_ARG_SAMPLER = 0x04, - gcvUNIFORM_LOCAL_ADDRESS_SPACE = 0x08, - gcvUNIFORM_PRIVATE_ADDRESS_SPACE = 0x10, - gcvUNIFORM_CONSTANT_ADDRESS_SPACE = 0x20, - gcvUNIFORM_GLOBAL_SIZE = 0x40, - gcvUNIFORM_LOCAL_SIZE = 0x80, - gcvUNIFORM_NUM_GROUPS = 0x100, - gcvUNIFORM_GLOBAL_OFFSET = 0x200, - gcvUNIFORM_WORK_DIM = 0x400, - gcvUNIFORM_KERNEL_ARG_CONSTANT = 0x800, - gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE = 0x1000, - gcvUNIFORM_KERNEL_ARG_PRIVATE = 0x2000, - gcvUNIFORM_LOADTIME_CONSTANT = 0x4000, - gcvUNIFORM_IS_ARRAY = 0x8000, -} -gceUNIFORM_FLAGS; - -#define gcdUNIFORM_KERNEL_ARG_MASK (gcvUNIFORM_KERNEL_ARG | \ - gcvUNIFORM_KERNEL_ARG_LOCAL | \ - gcvUNIFORM_KERNEL_ARG_SAMPLER | \ - gcvUNIFORM_KERNEL_ARG_PRIVATE | \ - gcvUNIFORM_KERNEL_ARG_CONSTANT) - -typedef enum _gceVARIABLE_UPDATE_FLAGS -{ - gcvVARIABLE_UPDATE_NOUPDATE = 0, - gcvVARIABLE_UPDATE_TEMPREG, - gcvVARIABLE_UPDATE_TYPE_QUALIFIER, -}gceVARIABLE_UPDATE_FLAGS; - -typedef struct _gcMACHINE_INST -{ - gctUINT state0; - gctUINT state1; - gctUINT state2; - gctUINT state3; -}gcMACHINE_INST, *gcMACHINE_INST_PTR; - -typedef struct _gcMACHINECODE -{ - gcMACHINE_INST_PTR pCode; /* machine code */ - gctUINT instCount; /* 128-bit count */ - gctUINT maxConstRegNo; - gctUINT maxTempRegNo; - gctUINT endPCOfMainRoutine; -}gcMACHINECODE, *gcMACHINECODE_PTR; - -typedef enum NP2_ADDRESS_MODE -{ - NP2_ADDRESS_MODE_CLAMP = 0, - NP2_ADDRESS_MODE_REPEAT = 1, - NP2_ADDRESS_MODE_MIRROR = 2 -}NP2_ADDRESS_MODE; - -typedef struct _gcNPOT_PATCH_PARAM -{ - gctINT samplerSlot; - NP2_ADDRESS_MODE addressMode[3]; - gctINT texDimension; /* 2 or 3 */ -}gcNPOT_PATCH_PARAM, *gcNPOT_PATCH_PARAM_PTR; - -typedef struct _gcZBIAS_PATCH_PARAM -{ - /* Driver uses this to program uniform that designating zbias */ - gctINT uniformAddr; - gctINT channel; -}gcZBIAS_PATCH_PARAM, *gcZBIAS_PATCH_PARAM_PTR; - -void -gcGetOptionFromEnv( - IN OUT gcOPTIMIZER_OPTION * Option - ); - -void -gcSetOptimizerOption( - IN gceSHADER_FLAGS Flags - ); - -gcOPTIMIZER_OPTION * -gcGetOptimizerOption(); - -/******************************************************************************* -** gcSHADER_SetCompilerVersion -** -** Set the compiler version of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to gcSHADER object -** -** gctINT *Version -** Pointer to a two word version -*/ -gceSTATUS -gcSHADER_SetCompilerVersion( - IN gcSHADER Shader, - IN gctUINT32 *Version - ); - -/******************************************************************************* -** gcSHADER_GetCompilerVersion -** -** Get the compiler version of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctUINT32_PTR *CompilerVersion. -** Pointer to holder of returned compilerVersion pointer -*/ -gceSTATUS -gcSHADER_GetCompilerVersion( - IN gcSHADER Shader, - OUT gctUINT32_PTR *CompilerVersion - ); - -/******************************************************************************* -** gcSHADER_GetType -** -** Get the gcSHADER object's type. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctINT *Type. -** Pointer to return shader type. -*/ -gceSTATUS -gcSHADER_GetType( - IN gcSHADER Shader, - OUT gctINT *Type - ); - -gctUINT -gcSHADER_NextId(); -/******************************************************************************* -** gcSHADER_Construct -******************************************************************************** -** -** Construct a new gcSHADER object. -** -** INPUT: -** -** gcoOS Hal -** Pointer to an gcoHAL object. -** -** gctINT ShaderType -** Type of gcSHADER object to cerate. 'ShaderType' can be one of the -** following: -** -** gcSHADER_TYPE_VERTEX Vertex shader. -** gcSHADER_TYPE_FRAGMENT Fragment shader. -** -** OUTPUT: -** -** gcSHADER * Shader -** Pointer to a variable receiving the gcSHADER object pointer. -*/ -gceSTATUS -gcSHADER_Construct( - IN gcoHAL Hal, - IN gctINT ShaderType, - OUT gcSHADER * Shader - ); - -/******************************************************************************* -** gcSHADER_Destroy -******************************************************************************** -** -** Destroy a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_Destroy( - IN gcSHADER Shader - ); - -/******************************************************************************* -** gcSHADER_Copy -******************************************************************************** -** -** Copy a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSHADER Source -** Pointer to a gcSHADER object that will be copied. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_Copy( - IN gcSHADER Shader, - IN gcSHADER Source - ); - -/******************************************************************************* -** gcSHADER_LoadHeader -** -** Load a gcSHADER object from a binary buffer. The binary buffer is layed out -** as follows: -** // Six word header -** // Signature, must be 'S','H','D','R'. -** gctINT8 signature[4]; -** gctUINT32 binFileVersion; -** gctUINT32 compilerVersion[2]; -** gctUINT32 gcSLVersion; -** gctUINT32 binarySize; -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** Shader type will be returned if type in shader object is not gcSHADER_TYPE_PRECOMPILED -** -** gctPOINTER Buffer -** Pointer to a binary buffer containing the shader data to load. -** -** gctSIZE_T BufferSize -** Number of bytes inside the binary buffer pointed to by 'Buffer'. -** -** OUTPUT: -** nothing -** -*/ -gceSTATUS -gcSHADER_LoadHeader( - IN gcSHADER Shader, - IN gctPOINTER Buffer, - IN gctSIZE_T BufferSize, - OUT gctUINT32 * ShaderVersion - ); - -/******************************************************************************* -** gcSHADER_LoadKernel -** -** Load a kernel function given by name into gcSHADER object -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSTRING KernelName -** Pointer to a kernel function name -** -** OUTPUT: -** nothing -** -*/ -gceSTATUS -gcSHADER_LoadKernel( - IN gcSHADER Shader, - IN gctSTRING KernelName - ); - -/******************************************************************************* -** gcSHADER_Load -******************************************************************************** -** -** Load a gcSHADER object from a binary buffer. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctPOINTER Buffer -** Pointer to a binary buffer containg the shader data to load. -** -** gctSIZE_T BufferSize -** Number of bytes inside the binary buffer pointed to by 'Buffer'. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_Load( - IN gcSHADER Shader, - IN gctPOINTER Buffer, - IN gctSIZE_T BufferSize - ); - -/******************************************************************************* -** gcSHADER_Save -******************************************************************************** -** -** Save a gcSHADER object to a binary buffer. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctPOINTER Buffer -** Pointer to a binary buffer to be used as storage for the gcSHADER -** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved, -** but the number of bytes required to hold the binary output for the -** gcSHADER object will be returned. -** -** gctSIZE_T * BufferSize -** Pointer to a variable holding the number of bytes allocated in -** 'Buffer'. Only valid if 'Buffer' is not gcvNULL. -** -** OUTPUT: -** -** gctSIZE_T * BufferSize -** Pointer to a variable receiving the number of bytes required to hold -** the binary form of the gcSHADER object. -*/ -gceSTATUS -gcSHADER_Save( - IN gcSHADER Shader, - IN gctPOINTER Buffer, - IN OUT gctSIZE_T * BufferSize - ); - -/******************************************************************************* -** gcSHADER_LoadEx -******************************************************************************** -** -** Load a gcSHADER object from a binary buffer. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctPOINTER Buffer -** Pointer to a binary buffer containg the shader data to load. -** -** gctSIZE_T BufferSize -** Number of bytes inside the binary buffer pointed to by 'Buffer'. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_LoadEx( - IN gcSHADER Shader, - IN gctPOINTER Buffer, - IN gctSIZE_T BufferSize - ); - -/******************************************************************************* -** gcSHADER_SaveEx -******************************************************************************** -** -** Save a gcSHADER object to a binary buffer. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctPOINTER Buffer -** Pointer to a binary buffer to be used as storage for the gcSHADER -** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved, -** but the number of bytes required to hold the binary output for the -** gcSHADER object will be returned. -** -** gctSIZE_T * BufferSize -** Pointer to a variable holding the number of bytes allocated in -** 'Buffer'. Only valid if 'Buffer' is not gcvNULL. -** -** OUTPUT: -** -** gctSIZE_T * BufferSize -** Pointer to a variable receiving the number of bytes required to hold -** the binary form of the gcSHADER object. -*/ -gceSTATUS -gcSHADER_SaveEx( - IN gcSHADER Shader, - IN gctPOINTER Buffer, - IN OUT gctSIZE_T * BufferSize - ); - -/******************************************************************************* -** gcSHADER_ReallocateAttributes -** -** Reallocate an array of pointers to gcATTRIBUTE objects. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcSHADER_ReallocateAttributes( - IN gcSHADER Shader, - IN gctSIZE_T Count - ); - -/******************************************************************************* -** gcSHADER_AddAttribute -******************************************************************************** -** -** Add an attribute to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the attribute to add. -** -** gcSHADER_TYPE Type -** Type of the attribute to add. -** -** gctSIZE_T Length -** Array length of the attribute to add. 'Length' must be at least 1. -** -** gctBOOL IsTexture -** gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not. -** -** OUTPUT: -** -** gcATTRIBUTE * Attribute -** Pointer to a variable receiving the gcATTRIBUTE object pointer. -*/ -gceSTATUS -gcSHADER_AddAttribute( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - IN gctBOOL IsTexture, - OUT gcATTRIBUTE * Attribute - ); - -/******************************************************************************* -** gcSHADER_GetAttributeCount -******************************************************************************** -** -** Get the number of attributes for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * Count -** Pointer to a variable receiving the number of attributes. -*/ -gceSTATUS -gcSHADER_GetAttributeCount( - IN gcSHADER Shader, - OUT gctSIZE_T * Count - ); - -/******************************************************************************* -** gcSHADER_GetAttribute -******************************************************************************** -** -** Get the gcATTRIBUTE object poniter for an indexed attribute for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Index -** Index of the attribute to retrieve. -** -** OUTPUT: -** -** gcATTRIBUTE * Attribute -** Pointer to a variable receiving the gcATTRIBUTE object pointer. -*/ -gceSTATUS -gcSHADER_GetAttribute( - IN gcSHADER Shader, - IN gctUINT Index, - OUT gcATTRIBUTE * Attribute - ); - -/******************************************************************************* -** gcSHADER_ReallocateUniforms -** -** Reallocate an array of pointers to gcUNIFORM objects. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcSHADER_ReallocateUniforms( - IN gcSHADER Shader, - IN gctSIZE_T Count - ); - -/******************************************************************************* -** gcSHADER_AddUniform -******************************************************************************** -** -** Add an uniform to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the uniform to add. -** -** gcSHADER_TYPE Type -** Type of the uniform to add. -** -** gctSIZE_T Length -** Array length of the uniform to add. 'Length' must be at least 1. -** -** OUTPUT: -** -** gcUNIFORM * Uniform -** Pointer to a variable receiving the gcUNIFORM object pointer. -*/ -gceSTATUS -gcSHADER_AddUniform( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - OUT gcUNIFORM * Uniform - ); - -/******************************************************************************* -** gcSHADER_AddPreRotationUniform -******************************************************************************** -** -** Add an uniform to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the uniform to add. -** -** gcSHADER_TYPE Type -** Type of the uniform to add. -** -** gctSIZE_T Length -** Array length of the uniform to add. 'Length' must be at least 1. -** -** gctINT col -** Which uniform. -** -** OUTPUT: -** -** gcUNIFORM * Uniform -** Pointer to a variable receiving the gcUNIFORM object pointer. -*/ -gceSTATUS -gcSHADER_AddPreRotationUniform( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - IN gctINT col, - OUT gcUNIFORM * Uniform - ); - -/******************************************************************************* -** gcSHADER_AddUniformEx -******************************************************************************** -** -** Add an uniform to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the uniform to add. -** -** gcSHADER_TYPE Type -** Type of the uniform to add. -** -** gcSHADER_PRECISION precision -** Precision of the uniform to add. -** -** gctSIZE_T Length -** Array length of the uniform to add. 'Length' must be at least 1. -** -** OUTPUT: -** -** gcUNIFORM * Uniform -** Pointer to a variable receiving the gcUNIFORM object pointer. -*/ -gceSTATUS -gcSHADER_AddUniformEx( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gcSHADER_PRECISION precision, - IN gctSIZE_T Length, - OUT gcUNIFORM * Uniform - ); - -/******************************************************************************* -** gcSHADER_AddUniformEx1 -******************************************************************************** -** -** Add an uniform to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the uniform to add. -** -** gcSHADER_TYPE Type -** Type of the uniform to add. -** -** gcSHADER_PRECISION precision -** Precision of the uniform to add. -** -** gctSIZE_T Length -** Array length of the uniform to add. 'Length' must be at least 1. -** -** gcSHADER_VAR_CATEGORY varCategory -** Variable category, normal or struct. -** -** gctUINT16 numStructureElement -** If struct, its element number. -** -** gctINT16 parent -** If struct, parent index in gcSHADER.variables. -** -** gctINT16 prevSibling -** If struct, previous sibling index in gcSHADER.variables. -** -** OUTPUT: -** -** gcUNIFORM * Uniform -** Pointer to a variable receiving the gcUNIFORM object pointer. -** -** gctINT16* ThisUniformIndex -** Returned value about uniform index in gcSHADER. -*/ -gceSTATUS -gcSHADER_AddUniformEx1( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gcSHADER_PRECISION precision, - IN gctSIZE_T Length, - IN gctINT IsArray, - IN gcSHADER_VAR_CATEGORY varCategory, - IN gctUINT16 numStructureElement, - IN gctINT16 parent, - IN gctINT16 prevSibling, - OUT gctINT16* ThisUniformIndex, - OUT gcUNIFORM * Uniform - ); - -/******************************************************************************* -** gcSHADER_GetUniformCount -******************************************************************************** -** -** Get the number of uniforms for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * Count -** Pointer to a variable receiving the number of uniforms. -*/ -gceSTATUS -gcSHADER_GetUniformCount( - IN gcSHADER Shader, - OUT gctSIZE_T * Count - ); - -/******************************************************************************* -** gcSHADER_GetPreRotationUniform -******************************************************************************** -** -** Get the preRotate Uniform. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gcUNIFORM ** pUniform -** Pointer to a preRotation uniforms array. -*/ -gceSTATUS -gcSHADER_GetPreRotationUniform( - IN gcSHADER Shader, - OUT gcUNIFORM ** pUniform - ); - -/******************************************************************************* -** gcSHADER_GetUniform -******************************************************************************** -** -** Get the gcUNIFORM object pointer for an indexed uniform for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Index -** Index of the uniform to retrieve. -** -** OUTPUT: -** -** gcUNIFORM * Uniform -** Pointer to a variable receiving the gcUNIFORM object pointer. -*/ -gceSTATUS -gcSHADER_GetUniform( - IN gcSHADER Shader, - IN gctUINT Index, - OUT gcUNIFORM * Uniform - ); - - -/******************************************************************************* -** gcSHADER_GetUniformIndexingRange -******************************************************************************** -** -** Get the gcUNIFORM object pointer for an indexed uniform for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctINT uniformIndex -** Index of the start uniform. -** -** gctINT offset -** Offset to indexing. -** -** OUTPUT: -** -** gctINT * LastUniformIndex -** Pointer to index of last uniform in indexing range. -** -** gctINT * OffsetUniformIndex -** Pointer to index of uniform that indexing at offset. -** -** gctINT * DeviationInOffsetUniform -** Pointer to offset in uniform picked up. -*/ -gceSTATUS -gcSHADER_GetUniformIndexingRange( - IN gcSHADER Shader, - IN gctINT uniformIndex, - IN gctINT offset, - OUT gctINT * LastUniformIndex, - OUT gctINT * OffsetUniformIndex, - OUT gctINT * DeviationInOffsetUniform - ); - -/******************************************************************************* -** gcSHADER_GetKernelFucntion -** -** Get the gcKERNEL_FUNCTION object pointer for an indexed kernel function for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Index -** Index of kernel function to retreive the name for. -** -** OUTPUT: -** -** gcKERNEL_FUNCTION * KernelFunction -** Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer. -*/ -gceSTATUS -gcSHADER_GetKernelFunction( - IN gcSHADER Shader, - IN gctUINT Index, - OUT gcKERNEL_FUNCTION * KernelFunction - ); - -gceSTATUS -gcSHADER_GetKernelFunctionByName( - IN gcSHADER Shader, - IN gctSTRING KernelName, - OUT gcKERNEL_FUNCTION * KernelFunction - ); -/******************************************************************************* -** gcSHADER_GetKernelFunctionCount -** -** Get the number of kernel functions for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * Count -** Pointer to a variable receiving the number of kernel functions. -*/ -gceSTATUS -gcSHADER_GetKernelFunctionCount( - IN gcSHADER Shader, - OUT gctSIZE_T * Count - ); - -/******************************************************************************* -** gcSHADER_ReallocateOutputs -** -** Reallocate an array of pointers to gcOUTPUT objects. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcSHADER_ReallocateOutputs( - IN gcSHADER Shader, - IN gctSIZE_T Count - ); - -/******************************************************************************* -** gcSHADER_AddOutput -******************************************************************************** -** -** Add an output to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the output to add. -** -** gcSHADER_TYPE Type -** Type of the output to add. -** -** gctSIZE_T Length -** Array length of the output to add. 'Length' must be at least 1. -** -** gctUINT16 TempRegister -** Temporary register index that holds the output value. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOutput( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - IN gctUINT16 TempRegister - ); - -gceSTATUS -gcSHADER_AddOutputIndexed( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gctSIZE_T Index, - IN gctUINT16 TempIndex - ); - -/******************************************************************************* -** gcSHADER_GetOutputCount -******************************************************************************** -** -** Get the number of outputs for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * Count -** Pointer to a variable receiving the number of outputs. -*/ -gceSTATUS -gcSHADER_GetOutputCount( - IN gcSHADER Shader, - OUT gctSIZE_T * Count - ); - -/******************************************************************************* -** gcSHADER_GetOutput -******************************************************************************** -** -** Get the gcOUTPUT object pointer for an indexed output for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Index -** Index of output to retrieve. -** -** OUTPUT: -** -** gcOUTPUT * Output -** Pointer to a variable receiving the gcOUTPUT object pointer. -*/ -gceSTATUS -gcSHADER_GetOutput( - IN gcSHADER Shader, - IN gctUINT Index, - OUT gcOUTPUT * Output - ); - - -/******************************************************************************* -** gcSHADER_GetOutputByName -******************************************************************************** -** -** Get the gcOUTPUT object pointer for this shader by output name. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSTRING name -** Name of output to retrieve. -** -** gctSIZE_T nameLength -** Length of name to retrieve -** -** OUTPUT: -** -** gcOUTPUT * Output -** Pointer to a variable receiving the gcOUTPUT object pointer. -*/ -gceSTATUS -gcSHADER_GetOutputByName( - IN gcSHADER Shader, - IN gctSTRING name, - IN gctSIZE_T nameLength, - OUT gcOUTPUT * Output - ); - -/******************************************************************************* -** gcSHADER_ReallocateVariables -** -** Reallocate an array of pointers to gcVARIABLE objects. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcSHADER_ReallocateVariables( - IN gcSHADER Shader, - IN gctSIZE_T Count - ); - -/******************************************************************************* -** gcSHADER_AddVariable -******************************************************************************** -** -** Add a variable to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the variable to add. -** -** gcSHADER_TYPE Type -** Type of the variable to add. -** -** gctSIZE_T Length -** Array length of the variable to add. 'Length' must be at least 1. -** -** gctUINT16 TempRegister -** Temporary register index that holds the variable value. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddVariable( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - IN gctUINT16 TempRegister - ); - - -/******************************************************************************* -** gcSHADER_AddVariableEx -******************************************************************************** -** -** Add a variable to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctCONST_STRING Name -** Name of the variable to add. -** -** gcSHADER_TYPE Type -** Type of the variable to add. -** -** gctSIZE_T Length -** Array length of the variable to add. 'Length' must be at least 1. -** -** gctUINT16 TempRegister -** Temporary register index that holds the variable value. -** -** gcSHADER_VAR_CATEGORY varCategory -** Variable category, normal or struct. -** -** gctUINT16 numStructureElement -** If struct, its element number. -** -** gctINT16 parent -** If struct, parent index in gcSHADER.variables. -** -** gctINT16 prevSibling -** If struct, previous sibling index in gcSHADER.variables. -** -** OUTPUT: -** -** gctINT16* ThisVarIndex -** Returned value about variable index in gcSHADER. -*/ -gceSTATUS -gcSHADER_AddVariableEx( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - IN gctUINT16 TempRegister, - IN gcSHADER_VAR_CATEGORY varCategory, - IN gctUINT16 numStructureElement, - IN gctINT16 parent, - IN gctINT16 prevSibling, - OUT gctINT16* ThisVarIndex - ); - -/******************************************************************************* -** gcSHADER_UpdateVariable -******************************************************************************** -** -** Update a variable to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Index -** Index of variable to retrieve. -** -** gceVARIABLE_UPDATE_FLAGS flag -** Flag which property of variable will be updated. -** -** gctUINT newValue -** New value to update. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_UpdateVariable( - IN gcSHADER Shader, - IN gctUINT Index, - IN gceVARIABLE_UPDATE_FLAGS flag, - IN gctUINT newValue - ); - -/******************************************************************************* -** gcSHADER_GetVariableCount -******************************************************************************** -** -** Get the number of variables for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * Count -** Pointer to a variable receiving the number of variables. -*/ -gceSTATUS -gcSHADER_GetVariableCount( - IN gcSHADER Shader, - OUT gctSIZE_T * Count - ); - -/******************************************************************************* -** gcSHADER_GetVariable -******************************************************************************** -** -** Get the gcVARIABLE object pointer for an indexed variable for this shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Index -** Index of variable to retrieve. -** -** OUTPUT: -** -** gcVARIABLE * Variable -** Pointer to a variable receiving the gcVARIABLE object pointer. -*/ -gceSTATUS -gcSHADER_GetVariable( - IN gcSHADER Shader, - IN gctUINT Index, - OUT gcVARIABLE * Variable - ); - -/******************************************************************************* -** gcSHADER_GetVariableIndexingRange -******************************************************************************** -** -** Get the gcVARIABLE indexing range. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcVARIABLE variable -** Start variable. -** -** gctBOOL whole -** Indicate whether maximum indexing range is queried -** -** OUTPUT: -** -** gctUINT *Start -** Pointer to range start (temp register index). -** -** gctUINT *End -** Pointer to range end (temp register index). -*/ -gceSTATUS -gcSHADER_GetVariableIndexingRange( - IN gcSHADER Shader, - IN gcVARIABLE variable, - IN gctBOOL whole, - OUT gctUINT *Start, - OUT gctUINT *End - ); - -/******************************************************************************* -** gcSHADER_AddOpcode -******************************************************************************** -** -** Add an opcode to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_OPCODE Opcode -** Opcode to add. -** -** gctUINT16 TempRegister -** Temporary register index that acts as the target of the opcode. -** -** gctUINT8 Enable -** Write enable bits for the temporary register that acts as the target -** of the opcode. -** -** gcSL_FORMAT Format -** Format of the temporary register. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOpcode( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gctUINT16 TempRegister, - IN gctUINT8 Enable, - IN gcSL_FORMAT Format - ); - -gceSTATUS -gcSHADER_AddOpcode2( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gcSL_CONDITION Condition, - IN gctUINT16 TempRegister, - IN gctUINT8 Enable, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_AddOpcodeIndexed -******************************************************************************** -** -** Add an opcode to a gcSHADER object that writes to an dynamically indexed -** target. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_OPCODE Opcode -** Opcode to add. -** -** gctUINT16 TempRegister -** Temporary register index that acts as the target of the opcode. -** -** gctUINT8 Enable -** Write enable bits for the temporary register that acts as the -** target of the opcode. -** -** gcSL_INDEXED Mode -** Location of the dynamic index inside the temporary register. Valid -** values can be: -** -** gcSL_INDEXED_X - Use x component of the temporary register. -** gcSL_INDEXED_Y - Use y component of the temporary register. -** gcSL_INDEXED_Z - Use z component of the temporary register. -** gcSL_INDEXED_W - Use w component of the temporary register. -** -** gctUINT16 IndexRegister -** Temporary register index that holds the dynamic index. -** -** gcSL_FORMAT Format -** Format of the temporary register. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOpcodeIndexed( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gctUINT16 TempRegister, - IN gctUINT8 Enable, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_AddOpcodeConditionIndexed -** -** Add an opcode to a gcSHADER object that writes to an dynamically indexed -** target. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_OPCODE Opcode -** Opcode to add. -** -** gcSL_CONDITION Condition -** Condition to check. -** -** gctUINT16 TempRegister -** Temporary register index that acts as the target of the opcode. -** -** gctUINT8 Enable -** Write enable bits for the temporary register that acts as the -** target of the opcode. -** -** gcSL_INDEXED Indexed -** Location of the dynamic index inside the temporary register. Valid -** values can be: -** -** gcSL_INDEXED_X - Use x component of the temporary register. -** gcSL_INDEXED_Y - Use y component of the temporary register. -** gcSL_INDEXED_Z - Use z component of the temporary register. -** gcSL_INDEXED_W - Use w component of the temporary register. -** -** gctUINT16 IndexRegister -** Temporary register index that holds the dynamic index. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOpcodeConditionIndexed( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gcSL_CONDITION Condition, - IN gctUINT16 TempRegister, - IN gctUINT8 Enable, - IN gcSL_INDEXED Indexed, - IN gctUINT16 IndexRegister, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_AddOpcodeConditional -******************************************************************************** -** -** Add an conditional opcode to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_OPCODE Opcode -** Opcode to add. -** -** gcSL_CONDITION Condition -** Condition that needs to evaluate to gcvTRUE in order for the opcode to -** execute. -** -** gctUINT Label -** Target label if 'Condition' evaluates to gcvTRUE. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOpcodeConditional( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gcSL_CONDITION Condition, - IN gctUINT Label - ); - -/******************************************************************************* -** gcSHADER_AddOpcodeConditionalFormatted -** -** Add an conditional jump or call opcode to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_OPCODE Opcode -** Opcode to add. -** -** gcSL_CONDITION Condition -** Condition that needs to evaluate to gcvTRUE in order for the opcode to -** execute. -** -** gcSL_FORMAT Format -** Format of conditional operands -** -** gctUINT Label -** Target label if 'Condition' evaluates to gcvTRUE. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOpcodeConditionalFormatted( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gcSL_CONDITION Condition, - IN gcSL_FORMAT Format, - IN gctUINT Label - ); - -/******************************************************************************* -** gcSHADER_AddOpcodeConditionalFormattedEnable -** -** Add an conditional jump or call opcode to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_OPCODE Opcode -** Opcode to add. -** -** gcSL_CONDITION Condition -** Condition that needs to evaluate to gcvTRUE in order for the opcode to -** execute. -** -** gcSL_FORMAT Format -** Format of conditional operands -** -** gctUINT8 Enable -** Write enable value for the target of the opcode. -** -** gctUINT Label -** Target label if 'Condition' evaluates to gcvTRUE. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddOpcodeConditionalFormattedEnable( - IN gcSHADER Shader, - IN gcSL_OPCODE Opcode, - IN gcSL_CONDITION Condition, - IN gcSL_FORMAT Format, - IN gctUINT8 Enable, - IN gctUINT Label - ); - -/******************************************************************************* -** gcSHADER_AddLabel -******************************************************************************** -** -** Define a label at the current instruction of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT Label -** Label to define. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddLabel( - IN gcSHADER Shader, - IN gctUINT Label - ); - -/******************************************************************************* -** gcSHADER_AddSource -******************************************************************************** -** -** Add a source operand to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_TYPE Type -** Type of the source operand. -** -** gctUINT16 SourceIndex -** Index of the source operand. -** -** gctUINT8 Swizzle -** x, y, z, and w swizzle values packed into one 8-bit value. -** -** gcSL_FORMAT Format -** Format of the source operand. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSource( - IN gcSHADER Shader, - IN gcSL_TYPE Type, - IN gctUINT16 SourceIndex, - IN gctUINT8 Swizzle, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_AddSourceIndexed -******************************************************************************** -** -** Add a dynamically indexed source operand to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcSL_TYPE Type -** Type of the source operand. -** -** gctUINT16 SourceIndex -** Index of the source operand. -** -** gctUINT8 Swizzle -** x, y, z, and w swizzle values packed into one 8-bit value. -** -** gcSL_INDEXED Mode -** Addressing mode for the index. -** -** gctUINT16 IndexRegister -** Temporary register index that holds the dynamic index. -** -** gcSL_FORMAT Format -** Format of the source operand. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceIndexed( - IN gcSHADER Shader, - IN gcSL_TYPE Type, - IN gctUINT16 SourceIndex, - IN gctUINT8 Swizzle, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_AddSourceAttribute -******************************************************************************** -** -** Add an attribute as a source operand to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcATTRIBUTE Attribute -** Pointer to a gcATTRIBUTE object. -** -** gctUINT8 Swizzle -** x, y, z, and w swizzle values packed into one 8-bit value. -** -** gctINT Index -** Static index into the attribute in case the attribute is a matrix -** or array. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceAttribute( - IN gcSHADER Shader, - IN gcATTRIBUTE Attribute, - IN gctUINT8 Swizzle, - IN gctINT Index - ); - -/******************************************************************************* -** gcSHADER_AddSourceAttributeIndexed -******************************************************************************** -** -** Add an indexed attribute as a source operand to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcATTRIBUTE Attribute -** Pointer to a gcATTRIBUTE object. -** -** gctUINT8 Swizzle -** x, y, z, and w swizzle values packed into one 8-bit value. -** -** gctINT Index -** Static index into the attribute in case the attribute is a matrix -** or array. -** -** gcSL_INDEXED Mode -** Addressing mode of the dynamic index. -** -** gctUINT16 IndexRegister -** Temporary register index that holds the dynamic index. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceAttributeIndexed( - IN gcSHADER Shader, - IN gcATTRIBUTE Attribute, - IN gctUINT8 Swizzle, - IN gctINT Index, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister - ); - -/******************************************************************************* -** gcSHADER_AddSourceUniform -******************************************************************************** -** -** Add a uniform as a source operand to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gctUINT8 Swizzle -** x, y, z, and w swizzle values packed into one 8-bit value. -** -** gctINT Index -** Static index into the uniform in case the uniform is a matrix or -** array. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceUniform( - IN gcSHADER Shader, - IN gcUNIFORM Uniform, - IN gctUINT8 Swizzle, - IN gctINT Index - ); - -/******************************************************************************* -** gcSHADER_AddSourceUniformIndexed -******************************************************************************** -** -** Add an indexed uniform as a source operand to a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gctUINT8 Swizzle -** x, y, z, and w swizzle values packed into one 8-bit value. -** -** gctINT Index -** Static index into the uniform in case the uniform is a matrix or -** array. -** -** gcSL_INDEXED Mode -** Addressing mode of the dynamic index. -** -** gctUINT16 IndexRegister -** Temporary register index that holds the dynamic index. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceUniformIndexed( - IN gcSHADER Shader, - IN gcUNIFORM Uniform, - IN gctUINT8 Swizzle, - IN gctINT Index, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister - ); - -gceSTATUS -gcSHADER_AddSourceSamplerIndexed( - IN gcSHADER Shader, - IN gctUINT8 Swizzle, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister - ); - -gceSTATUS -gcSHADER_AddSourceAttributeFormatted( - IN gcSHADER Shader, - IN gcATTRIBUTE Attribute, - IN gctUINT8 Swizzle, - IN gctINT Index, - IN gcSL_FORMAT Format - ); - -gceSTATUS -gcSHADER_AddSourceAttributeIndexedFormatted( - IN gcSHADER Shader, - IN gcATTRIBUTE Attribute, - IN gctUINT8 Swizzle, - IN gctINT Index, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister, - IN gcSL_FORMAT Format - ); - -gceSTATUS -gcSHADER_AddSourceUniformFormatted( - IN gcSHADER Shader, - IN gcUNIFORM Uniform, - IN gctUINT8 Swizzle, - IN gctINT Index, - IN gcSL_FORMAT Format - ); - -gceSTATUS -gcSHADER_AddSourceUniformIndexedFormatted( - IN gcSHADER Shader, - IN gcUNIFORM Uniform, - IN gctUINT8 Swizzle, - IN gctINT Index, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister, - IN gcSL_FORMAT Format - ); - -gceSTATUS -gcSHADER_AddSourceSamplerIndexedFormatted( - IN gcSHADER Shader, - IN gctUINT8 Swizzle, - IN gcSL_INDEXED Mode, - IN gctUINT16 IndexRegister, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_AddSourceConstant -******************************************************************************** -** -** Add a constant floating point value as a source operand to a gcSHADER -** object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctFLOAT Constant -** Floating point constant. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceConstant( - IN gcSHADER Shader, - IN gctFLOAT Constant - ); - -/******************************************************************************* -** gcSHADER_AddSourceConstantFormatted -******************************************************************************** -** -** Add a constant value as a source operand to a gcSHADER -** object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** void * Constant -** Pointer to constant. -** -** gcSL_FORMAT Format -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_AddSourceConstantFormatted( - IN gcSHADER Shader, - IN void *Constant, - IN gcSL_FORMAT Format - ); - -/******************************************************************************* -** gcSHADER_Pack -******************************************************************************** -** -** Pack a dynamically created gcSHADER object by trimming the allocated arrays -** and resolving all the labeling. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_Pack( - IN gcSHADER Shader - ); - -/******************************************************************************* -** gcSHADER_SetOptimizationOption -******************************************************************************** -** -** Set optimization option of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctUINT OptimizationOption -** Optimization option. Can be one of the following: -** -** 0 - No optimization. -** 1 - Full optimization. -** Other value - For optimizer testing. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcSHADER_SetOptimizationOption( - IN gcSHADER Shader, - IN gctUINT OptimizationOption - ); - -/******************************************************************************* -** gcSHADER_ReallocateFunctions -** -** Reallocate an array of pointers to gcFUNCTION objects. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcSHADER_ReallocateFunctions( - IN gcSHADER Shader, - IN gctSIZE_T Count - ); - -gceSTATUS -gcSHADER_AddFunction( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - OUT gcFUNCTION * Function - ); - -gceSTATUS -gcSHADER_ReallocateKernelFunctions( - IN gcSHADER Shader, - IN gctSIZE_T Count - ); - -gceSTATUS -gcSHADER_AddKernelFunction( - IN gcSHADER Shader, - IN gctCONST_STRING Name, - OUT gcKERNEL_FUNCTION * KernelFunction - ); - -gceSTATUS -gcSHADER_BeginFunction( - IN gcSHADER Shader, - IN gcFUNCTION Function - ); - -gceSTATUS -gcSHADER_EndFunction( - IN gcSHADER Shader, - IN gcFUNCTION Function - ); - -gceSTATUS -gcSHADER_BeginKernelFunction( - IN gcSHADER Shader, - IN gcKERNEL_FUNCTION KernelFunction - ); - -gceSTATUS -gcSHADER_EndKernelFunction( - IN gcSHADER Shader, - IN gcKERNEL_FUNCTION KernelFunction, - IN gctSIZE_T LocalMemorySize - ); - -gceSTATUS -gcSHADER_SetMaxKernelFunctionArgs( - IN gcSHADER Shader, - IN gctUINT32 MaxKernelFunctionArgs - ); - -/******************************************************************************* -** gcSHADER_SetConstantMemorySize -** -** Set the constant memory address space size of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T ConstantMemorySize -** Constant memory size in bytes -** -** gctCHAR *ConstantMemoryBuffer -** Constant memory buffer -*/ -gceSTATUS -gcSHADER_SetConstantMemorySize( - IN gcSHADER Shader, - IN gctSIZE_T ConstantMemorySize, - IN gctCHAR * ConstantMemoryBuffer - ); - -/******************************************************************************* -** gcSHADER_GetConstantMemorySize -** -** Set the constant memory address space size of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * ConstantMemorySize -** Pointer to a variable receiving constant memory size in bytes -** -** gctCHAR **ConstantMemoryBuffer. -** Pointer to a variable for returned shader constant memory buffer. -*/ -gceSTATUS -gcSHADER_GetConstantMemorySize( - IN gcSHADER Shader, - OUT gctSIZE_T * ConstantMemorySize, - OUT gctCHAR ** ConstantMemoryBuffer - ); - -/******************************************************************************* -** gcSHADER_SetPrivateMemorySize -** -** Set the private memory address space size of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T PrivateMemorySize -** Private memory size in bytes -*/ -gceSTATUS -gcSHADER_SetPrivateMemorySize( - IN gcSHADER Shader, - IN gctSIZE_T PrivateMemorySize - ); - -/******************************************************************************* -** gcSHADER_GetPrivateMemorySize -** -** Set the private memory address space size of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * PrivateMemorySize -** Pointer to a variable receiving private memory size in bytes -*/ -gceSTATUS -gcSHADER_GetPrivateMemorySize( - IN gcSHADER Shader, - OUT gctSIZE_T * PrivateMemorySize - ); - -/******************************************************************************* -** gcSHADER_SetLocalMemorySize -** -** Set the local memory address space size of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** gctSIZE_T LocalMemorySize -** Local memory size in bytes -*/ -gceSTATUS -gcSHADER_SetLocalMemorySize( - IN gcSHADER Shader, - IN gctSIZE_T LocalMemorySize - ); - -/******************************************************************************* -** gcSHADER_GetLocalMemorySize -** -** Set the local memory address space size of a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -** OUTPUT: -** -** gctSIZE_T * LocalMemorySize -** Pointer to a variable receiving lcoal memory size in bytes -*/ -gceSTATUS -gcSHADER_GetLocalMemorySize( - IN gcSHADER Shader, - OUT gctSIZE_T * LocalMemorySize - ); - - -/******************************************************************************* -** gcSHADER_CheckValidity -** -** Check validity for a gcSHADER object. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object. -** -*/ -gceSTATUS -gcSHADER_CheckValidity( - IN gcSHADER Shader - ); - -#if gcdUSE_WCLIP_PATCH -gceSTATUS -gcATTRIBUTE_IsPosition( - IN gcATTRIBUTE Attribute, - OUT gctBOOL * IsPosition - ); -#endif - -/******************************************************************************* -** gcATTRIBUTE_GetType -******************************************************************************** -** -** Get the type and array length of a gcATTRIBUTE object. -** -** INPUT: -** -** gcATTRIBUTE Attribute -** Pointer to a gcATTRIBUTE object. -** -** OUTPUT: -** -** gcSHADER_TYPE * Type -** Pointer to a variable receiving the type of the attribute. 'Type' -** can be gcvNULL, in which case no type will be returned. -** -** gctSIZE_T * ArrayLength -** Pointer to a variable receiving the length of the array if the -** attribute was declared as an array. If the attribute was not -** declared as an array, the array length will be 1. 'ArrayLength' can -** be gcvNULL, in which case no array length will be returned. -*/ -gceSTATUS -gcATTRIBUTE_GetType( - IN gcATTRIBUTE Attribute, - OUT gcSHADER_TYPE * Type, - OUT gctSIZE_T * ArrayLength - ); - -/******************************************************************************* -** gcATTRIBUTE_GetName -******************************************************************************** -** -** Get the name of a gcATTRIBUTE object. -** -** INPUT: -** -** gcATTRIBUTE Attribute -** Pointer to a gcATTRIBUTE object. -** -** OUTPUT: -** -** gctSIZE_T * Length -** Pointer to a variable receiving the length of the attribute name. -** 'Length' can be gcvNULL, in which case no length will be returned. -** -** gctCONST_STRING * Name -** Pointer to a variable receiving the pointer to the attribute name. -** 'Name' can be gcvNULL, in which case no name will be returned. -*/ -gceSTATUS -gcATTRIBUTE_GetName( - IN gcATTRIBUTE Attribute, - OUT gctSIZE_T * Length, - OUT gctCONST_STRING * Name - ); - -/******************************************************************************* -** gcATTRIBUTE_IsEnabled -******************************************************************************** -** -** Query the enabled state of a gcATTRIBUTE object. -** -** INPUT: -** -** gcATTRIBUTE Attribute -** Pointer to a gcATTRIBUTE object. -** -** OUTPUT: -** -** gctBOOL * Enabled -** Pointer to a variable receiving the enabled state of the attribute. -*/ -gceSTATUS -gcATTRIBUTE_IsEnabled( - IN gcATTRIBUTE Attribute, - OUT gctBOOL * Enabled - ); - -/******************************************************************************* -** gcUNIFORM_GetType -******************************************************************************** -** -** Get the type and array length of a gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** gcSHADER_TYPE * Type -** Pointer to a variable receiving the type of the uniform. 'Type' can -** be gcvNULL, in which case no type will be returned. -** -** gctSIZE_T * ArrayLength -** Pointer to a variable receiving the length of the array if the -** uniform was declared as an array. If the uniform was not declared -** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL, -** in which case no array length will be returned. -*/ -gceSTATUS -gcUNIFORM_GetType( - IN gcUNIFORM Uniform, - OUT gcSHADER_TYPE * Type, - OUT gctSIZE_T * ArrayLength - ); - -/******************************************************************************* -** gcUNIFORM_GetTypeEx -******************************************************************************** -** -** Get the type and array length of a gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** gcSHADER_TYPE * Type -** Pointer to a variable receiving the type of the uniform. 'Type' can -** be gcvNULL, in which case no type will be returned. -** -** gcSHADER_PRECISION * Precision -** Pointer to a variable receiving the precision of the uniform. 'Precision' can -** be gcvNULL, in which case no type will be returned. -** -** gctSIZE_T * ArrayLength -** Pointer to a variable receiving the length of the array if the -** uniform was declared as an array. If the uniform was not declared -** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL, -** in which case no array length will be returned. -*/ -gceSTATUS -gcUNIFORM_GetTypeEx( - IN gcUNIFORM Uniform, - OUT gcSHADER_TYPE * Type, - OUT gcSHADER_PRECISION * Precision, - OUT gctSIZE_T * ArrayLength - ); - -/******************************************************************************* -** gcUNIFORM_GetFlags -******************************************************************************** -** -** Get the flags of a gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** gceUNIFORM_FLAGS * Flags -** Pointer to a variable receiving the flags of the uniform. -** -*/ -gceSTATUS -gcUNIFORM_GetFlags( - IN gcUNIFORM Uniform, - OUT gceUNIFORM_FLAGS * Flags - ); - -/******************************************************************************* -** gcUNIFORM_SetFlags -******************************************************************************** -** -** Set the flags of a gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gceUNIFORM_FLAGS Flags -** Flags of the uniform to be set. -** -** OUTPUT: -** Nothing. -** -*/ -gceSTATUS -gcUNIFORM_SetFlags( - IN gcUNIFORM Uniform, - IN gceUNIFORM_FLAGS Flags - ); - -/******************************************************************************* -** gcUNIFORM_GetName -******************************************************************************** -** -** Get the name of a gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** gctSIZE_T * Length -** Pointer to a variable receiving the length of the uniform name. -** 'Length' can be gcvNULL, in which case no length will be returned. -** -** gctCONST_STRING * Name -** Pointer to a variable receiving the pointer to the uniform name. -** 'Name' can be gcvNULL, in which case no name will be returned. -*/ -gceSTATUS -gcUNIFORM_GetName( - IN gcUNIFORM Uniform, - OUT gctSIZE_T * Length, - OUT gctCONST_STRING * Name - ); - -/******************************************************************************* -** gcUNIFORM_GetSampler -******************************************************************************** -** -** Get the physical sampler number for a sampler gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** gctUINT32 * Sampler -** Pointer to a variable receiving the physical sampler. -*/ -gceSTATUS -gcUNIFORM_GetSampler( - IN gcUNIFORM Uniform, - OUT gctUINT32 * Sampler - ); - -/******************************************************************************* -** gcUNIFORM_GetFormat -** -** Get the type and array length of a gcUNIFORM object. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** gcSL_FORMAT * Format -** Pointer to a variable receiving the format of element of the uniform. -** 'Type' can be gcvNULL, in which case no type will be returned. -** -** gctBOOL * IsPointer -** Pointer to a variable receiving the state wheter the uniform is a pointer. -** 'IsPointer' can be gcvNULL, in which case no array length will be returned. -*/ -gceSTATUS -gcUNIFORM_GetFormat( - IN gcUNIFORM Uniform, - OUT gcSL_FORMAT * Format, - OUT gctBOOL * IsPointer - ); - -/******************************************************************************* -** gcUNIFORM_SetFormat -** -** Set the format and isPointer of a uniform. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gcSL_FORMAT Format -** Format of element of the uniform shaderType. -** -** gctBOOL IsPointer -** Wheter the uniform is a pointer. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcUNIFORM_SetFormat( - IN gcUNIFORM Uniform, - IN gcSL_FORMAT Format, - IN gctBOOL IsPointer - ); - -/******************************************************************************* -** gcUNIFORM_SetValue -******************************************************************************** -** -** Set the value of a uniform in integer. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gctSIZE_T Count -** Number of entries to program if the uniform has been declared as an -** array. -** -** const gctINT * Value -** Pointer to a buffer holding the integer values for the uniform. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcUNIFORM_SetValue( - IN gcUNIFORM Uniform, - IN gctSIZE_T Count, - IN const gctINT * Value - ); - -/******************************************************************************* -** gcUNIFORM_SetValueX -******************************************************************************** -** -** Set the value of a uniform in fixed point. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gctSIZE_T Count -** Number of entries to program if the uniform has been declared as an -** array. -** -** const gctFIXED_POINT * Value -** Pointer to a buffer holding the fixed point values for the uniform. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcUNIFORM_SetValueX( - IN gcUNIFORM Uniform, - IN gctSIZE_T Count, - IN gctFIXED_POINT * Value - ); - -/******************************************************************************* -** gcUNIFORM_SetValueF -******************************************************************************** -** -** Set the value of a uniform in floating point. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** gctSIZE_T Count -** Number of entries to program if the uniform has been declared as an -** array. -** -** const gctFLOAT * Value -** Pointer to a buffer holding the floating point values for the -** uniform. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcUNIFORM_SetValueF( - IN gcUNIFORM Uniform, - IN gctSIZE_T Count, - IN const gctFLOAT * Value - ); - -/******************************************************************************* -** gcUNIFORM_ProgramF -** -** Set the value of a uniform in floating point. -** -** INPUT: -** -** gctUINT32 Address -** Address of Uniform. -** -** gctSIZE_T Row/Col -** -** const gctFLOAT * Value -** Pointer to a buffer holding the floating point values for the -** uniform. -** -** OUTPUT: -** -** Nothing. -*/ -gceSTATUS -gcUNIFORM_ProgramF( - IN gctUINT32 Address, - IN gctSIZE_T Row, - IN gctSIZE_T Col, - IN const gctFLOAT * Value - ); - -/******************************************************************************* -** gcUNIFORM_GetModelViewProjMatrix -******************************************************************************** -** -** Get the value of uniform modelViewProjMatrix ID if present. -** -** INPUT: -** -** gcUNIFORM Uniform -** Pointer to a gcUNIFORM object. -** -** OUTPUT: -** -** Nothing. -*/ -gctUINT -gcUNIFORM_GetModelViewProjMatrix( - IN gcUNIFORM Uniform - ); - -/******************************************************************************* -** gcOUTPUT_GetType -******************************************************************************** -** -** Get the type and array length of a gcOUTPUT object. -** -** INPUT: -** -** gcOUTPUT Output -** Pointer to a gcOUTPUT object. -** -** OUTPUT: -** -** gcSHADER_TYPE * Type -** Pointer to a variable receiving the type of the output. 'Type' can -** be gcvNULL, in which case no type will be returned. -** -** gctSIZE_T * ArrayLength -** Pointer to a variable receiving the length of the array if the -** output was declared as an array. If the output was not declared -** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL, -** in which case no array length will be returned. -*/ -gceSTATUS -gcOUTPUT_GetType( - IN gcOUTPUT Output, - OUT gcSHADER_TYPE * Type, - OUT gctSIZE_T * ArrayLength - ); - -/******************************************************************************* -** gcOUTPUT_GetIndex -******************************************************************************** -** -** Get the index of a gcOUTPUT object. -** -** INPUT: -** -** gcOUTPUT Output -** Pointer to a gcOUTPUT object. -** -** OUTPUT: -** -** gctUINT * Index -** Pointer to a variable receiving the temporary register index of the -** output. 'Index' can be gcvNULL,. in which case no index will be -** returned. -*/ -gceSTATUS -gcOUTPUT_GetIndex( - IN gcOUTPUT Output, - OUT gctUINT * Index - ); - -/******************************************************************************* -** gcOUTPUT_GetName -******************************************************************************** -** -** Get the name of a gcOUTPUT object. -** -** INPUT: -** -** gcOUTPUT Output -** Pointer to a gcOUTPUT object. -** -** OUTPUT: -** -** gctSIZE_T * Length -** Pointer to a variable receiving the length of the output name. -** 'Length' can be gcvNULL, in which case no length will be returned. -** -** gctCONST_STRING * Name -** Pointer to a variable receiving the pointer to the output name. -** 'Name' can be gcvNULL, in which case no name will be returned. -*/ -gceSTATUS -gcOUTPUT_GetName( - IN gcOUTPUT Output, - OUT gctSIZE_T * Length, - OUT gctCONST_STRING * Name - ); - -/******************************************************************************* -*********************************************************** F U N C T I O N S ** -*******************************************************************************/ - -/******************************************************************************* -** gcFUNCTION_ReallocateArguments -** -** Reallocate an array of gcsFUNCTION_ARGUMENT objects. -** -** INPUT: -** -** gcFUNCTION Function -** Pointer to a gcFUNCTION object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcFUNCTION_ReallocateArguments( - IN gcFUNCTION Function, - IN gctSIZE_T Count - ); - -gceSTATUS -gcFUNCTION_AddArgument( - IN gcFUNCTION Function, - IN gctUINT16 TempIndex, - IN gctUINT8 Enable, - IN gctUINT8 Qualifier - ); - -gceSTATUS -gcFUNCTION_GetArgument( - IN gcFUNCTION Function, - IN gctUINT16 Index, - OUT gctUINT16_PTR Temp, - OUT gctUINT8_PTR Enable, - OUT gctUINT8_PTR Swizzle - ); - -gceSTATUS -gcFUNCTION_GetLabel( - IN gcFUNCTION Function, - OUT gctUINT_PTR Label - ); - -/******************************************************************************* -************************* K E R N E L P R O P E R T Y F U N C T I O N S ** -*******************************************************************************/ -/*******************************************************************************/ -gceSTATUS -gcKERNEL_FUNCTION_AddKernelFunctionProperties( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctINT propertyType, - IN gctSIZE_T propertySize, - IN gctINT * values - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetPropertyCount( - IN gcKERNEL_FUNCTION KernelFunction, - OUT gctSIZE_T * Count - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetProperty( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctUINT Index, - OUT gctSIZE_T * propertySize, - OUT gctINT * propertyType, - OUT gctINT * propertyValues - ); - - -/******************************************************************************* -*******************************I M A G E S A M P L E R F U N C T I O N S ** -*******************************************************************************/ -/******************************************************************************* -** gcKERNEL_FUNCTION_ReallocateImageSamplers -** -** Reallocate an array of pointers to image sampler pair. -** -** INPUT: -** -** gcKERNEL_FUNCTION KernelFunction -** Pointer to a gcKERNEL_FUNCTION object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcKERNEL_FUNCTION_ReallocateImageSamplers( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctSIZE_T Count - ); - -gceSTATUS -gcKERNEL_FUNCTION_AddImageSampler( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctUINT8 ImageNum, - IN gctBOOL IsConstantSamplerType, - IN gctUINT32 SamplerType - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetImageSamplerCount( - IN gcKERNEL_FUNCTION KernelFunction, - OUT gctSIZE_T * Count - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetImageSampler( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctUINT Index, - OUT gctUINT8 *ImageNum, - OUT gctBOOL *IsConstantSamplerType, - OUT gctUINT32 *SamplerType - ); - -/******************************************************************************* -*********************************************K E R N E L F U N C T I O N S ** -*******************************************************************************/ - -/******************************************************************************* -** gcKERNEL_FUNCTION_ReallocateArguments -** -** Reallocate an array of gcsFUNCTION_ARGUMENT objects. -** -** INPUT: -** -** gcKERNEL_FUNCTION Function -** Pointer to a gcKERNEL_FUNCTION object. -** -** gctSIZE_T Count -** Array count to reallocate. 'Count' must be at least 1. -*/ -gceSTATUS -gcKERNEL_FUNCTION_ReallocateArguments( - IN gcKERNEL_FUNCTION Function, - IN gctSIZE_T Count - ); - -gceSTATUS -gcKERNEL_FUNCTION_AddArgument( - IN gcKERNEL_FUNCTION Function, - IN gctUINT16 TempIndex, - IN gctUINT8 Enable, - IN gctUINT8 Qualifier - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetArgument( - IN gcKERNEL_FUNCTION Function, - IN gctUINT16 Index, - OUT gctUINT16_PTR Temp, - OUT gctUINT8_PTR Enable, - OUT gctUINT8_PTR Swizzle - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetLabel( - IN gcKERNEL_FUNCTION Function, - OUT gctUINT_PTR Label - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetName( - IN gcKERNEL_FUNCTION KernelFunction, - OUT gctSIZE_T * Length, - OUT gctCONST_STRING * Name - ); - -gceSTATUS -gcKERNEL_FUNCTION_ReallocateUniformArguments( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctSIZE_T Count - ); - -gceSTATUS -gcKERNEL_FUNCTION_AddUniformArgument( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctCONST_STRING Name, - IN gcSHADER_TYPE Type, - IN gctSIZE_T Length, - OUT gcUNIFORM * UniformArgument - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetUniformArgumentCount( - IN gcKERNEL_FUNCTION KernelFunction, - OUT gctSIZE_T * Count - ); - -gceSTATUS -gcKERNEL_FUNCTION_GetUniformArgument( - IN gcKERNEL_FUNCTION KernelFunction, - IN gctUINT Index, - OUT gcUNIFORM * UniformArgument - ); - -gceSTATUS -gcKERNEL_FUNCTION_SetCodeEnd( - IN gcKERNEL_FUNCTION KernelFunction - ); - -/******************************************************************************* -** gcCompileShader -******************************************************************************** -** -** Compile a shader. -** -** INPUT: -** -** gcoOS Hal -** Pointer to an gcoHAL object. -** -** gctINT ShaderType -** Shader type to compile. Can be one of the following values: -** -** gcSHADER_TYPE_VERTEX -** Compile a vertex shader. -** -** gcSHADER_TYPE_FRAGMENT -** Compile a fragment shader. -** -** gctSIZE_T SourceSize -** Size of the source buffer in bytes. -** -** gctCONST_STRING Source -** Pointer to the buffer containing the shader source code. -** -** OUTPUT: -** -** gcSHADER * Binary -** Pointer to a variable receiving the pointer to a gcSHADER object -** containg the compiled shader code. -** -** gctSTRING * Log -** Pointer to a variable receiving a string pointer containging the -** compile log. -*/ -gceSTATUS -gcCompileShader( - IN gcoHAL Hal, - IN gctINT ShaderType, - IN gctSIZE_T SourceSize, - IN gctCONST_STRING Source, - OUT gcSHADER * Binary, - OUT gctSTRING * Log - ); - -/******************************************************************************* -** gcOptimizeShader -******************************************************************************** -** -** Optimize a shader. -** -** INPUT: -** -** gcSHADER Shader -** Pointer to a gcSHADER object holding information about the compiled -** shader. -** -** gctFILE LogFile -** Pointer to an open FILE object. -*/ -gceSTATUS -gcOptimizeShader( - IN gcSHADER Shader, - IN gctFILE LogFile - ); - -/******************************************************************************* -** gcLinkShaders -******************************************************************************** -** -** Link two shaders and generate a harwdare specific state buffer by compiling -** the compiler generated code through the resource allocator and code -** generator. -** -** INPUT: -** -** gcSHADER VertexShader -** Pointer to a gcSHADER object holding information about the compiled -** vertex shader. -** -** gcSHADER FragmentShader -** Pointer to a gcSHADER object holding information about the compiled -** fragment shader. -** -** gceSHADER_FLAGS Flags -** Compiler flags. Can be any of the following: -** -** gcvSHADER_DEAD_CODE - Dead code elimination. -** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion. -** gcvSHADER_OPTIMIZER - Full optimization. -** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate. -** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position. -** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward. -** -** OUTPUT: -** -** gctSIZE_T * StateBufferSize -** Pointer to a variable receicing the number of bytes in the buffer -** returned in 'StateBuffer'. -** -** gctPOINTER * StateBuffer -** Pointer to a variable receiving a buffer pointer that contains the -** states required to download the shaders into the hardware. -** -** gcsHINT_PTR * Hints -** Pointer to a variable receiving a gcsHINT structure pointer that -** contains information required when loading the shader states. -*/ -gceSTATUS -gcLinkShaders( - IN gcSHADER VertexShader, - IN gcSHADER FragmentShader, - IN gceSHADER_FLAGS Flags, - OUT gctSIZE_T * StateBufferSize, - OUT gctPOINTER * StateBuffer, - OUT gcsHINT_PTR * Hints, - OUT gcMACHINECODE_PTR *ppVsMachineCode, - OUT gcMACHINECODE_PTR *ppFsMachineCode - ); - -/******************************************************************************* -** gcLoadShaders -******************************************************************************** -** -** Load a pre-compiled and pre-linked shader program into the hardware. -** -** INPUT: -** -** gcoHAL Hal -** Pointer to a gcoHAL object. -** -** gctSIZE_T StateBufferSize -** The number of bytes in the 'StateBuffer'. -** -** gctPOINTER StateBuffer -** Pointer to the states that make up the shader program. -** -** gcsHINT_PTR Hints -** Pointer to a gcsHINT structure that contains information required -** when loading the shader states. -*/ -gceSTATUS -gcLoadShaders( - IN gcoHAL Hal, - IN gctSIZE_T StateBufferSize, - IN gctPOINTER StateBuffer, - IN gcsHINT_PTR Hints - ); - -gceSTATUS -gcRecompileShaders( - IN gcoHAL Hal, - IN gcMACHINECODE_PTR pVsMachineCode, - IN gcMACHINECODE_PTR pPsMachineCode, - /*Recompile variables*/ - IN OUT gctPOINTER *ppRecompileStateBuffer, - IN OUT gctSIZE_T *pRecompileStateBufferSize, - IN OUT gcsHINT_PTR *ppRecompileHints, - /* natvie state*/ - IN gctPOINTER pNativeStateBuffer, - IN gctSIZE_T nativeStateBufferSize, - IN gcsHINT_PTR pNativeHints, - /* npt info */ - IN gctUINT32 Samplers, - IN gctUINT32 *SamplerWrapS, - IN gctUINT32 *SamplerWrapT - ); - -gceSTATUS -gcRecompileDepthBias( - IN gcoHAL Hal, - IN gcMACHINECODE_PTR pVsMachineCode, - /*Recompile variables*/ - IN OUT gctPOINTER *ppRecompileStateBuffer, - IN OUT gctSIZE_T *pRecompileStateBufferSize, - IN OUT gcsHINT_PTR *ppRecompileHints, - /* natvie state*/ - IN gctPOINTER pNativeStateBuffer, - IN gctSIZE_T nativeStateBufferSize, - IN gcsHINT_PTR pNativeHints, - OUT gctINT * uniformAddr, - OUT gctINT * uniformChannel - ); - -/******************************************************************************* -** gcSaveProgram -******************************************************************************** -** -** Save pre-compiled shaders and pre-linked programs to a binary file. -** -** INPUT: -** -** gcSHADER VertexShader -** Pointer to vertex shader object. -** -** gcSHADER FragmentShader -** Pointer to fragment shader object. -** -** gctSIZE_T ProgramBufferSize -** Number of bytes in 'ProgramBuffer'. -** -** gctPOINTER ProgramBuffer -** Pointer to buffer containing the program states. -** -** gcsHINT_PTR Hints -** Pointer to HINTS structure for program states. -** -** OUTPUT: -** -** gctPOINTER * Binary -** Pointer to a variable receiving the binary data to be saved. -** -** gctSIZE_T * BinarySize -** Pointer to a variable receiving the number of bytes inside 'Binary'. -*/ -gceSTATUS -gcSaveProgram( - IN gcSHADER VertexShader, - IN gcSHADER FragmentShader, - IN gctSIZE_T ProgramBufferSize, - IN gctPOINTER ProgramBuffer, - IN gcsHINT_PTR Hints, - OUT gctPOINTER * Binary, - OUT gctSIZE_T * BinarySize - ); - -/******************************************************************************* -** gcLoadProgram -******************************************************************************** -** -** Load pre-compiled shaders and pre-linked programs from a binary file. -** -** INPUT: -** -** gctPOINTER Binary -** Pointer to the binary data loaded. -** -** gctSIZE_T BinarySize -** Number of bytes in 'Binary'. -** -** OUTPUT: -** -** gcSHADER VertexShader -** Pointer to a vertex shader object. -** -** gcSHADER FragmentShader -** Pointer to a fragment shader object. -** -** gctSIZE_T * ProgramBufferSize -** Pointer to a variable receicing the number of bytes in the buffer -** returned in 'ProgramBuffer'. -** -** gctPOINTER * ProgramBuffer -** Pointer to a variable receiving a buffer pointer that contains the -** states required to download the shaders into the hardware. -** -** gcsHINT_PTR * Hints -** Pointer to a variable receiving a gcsHINT structure pointer that -** contains information required when loading the shader states. -*/ -gceSTATUS -gcLoadProgram( - IN gctPOINTER Binary, - IN gctSIZE_T BinarySize, - OUT gcSHADER VertexShader, - OUT gcSHADER FragmentShader, - OUT gctSIZE_T * ProgramBufferSize, - OUT gctPOINTER * ProgramBuffer, - OUT gcsHINT_PTR * Hints - ); - -/******************************************************************************* -** gcCompileKernel -******************************************************************************** -** -** Compile a OpenCL kernel shader. -** -** INPUT: -** -** gcoOS Hal -** Pointer to an gcoHAL object. -** -** gctSIZE_T SourceSize -** Size of the source buffer in bytes. -** -** gctCONST_STRING Source -** Pointer to the buffer containing the shader source code. -** -** OUTPUT: -** -** gcSHADER * Binary -** Pointer to a variable receiving the pointer to a gcSHADER object -** containg the compiled shader code. -** -** gctSTRING * Log -** Pointer to a variable receiving a string pointer containging the -** compile log. -*/ -gceSTATUS -gcCompileKernel( - IN gcoHAL Hal, - IN gctSIZE_T SourceSize, - IN gctCONST_STRING Source, - IN gctCONST_STRING Options, - OUT gcSHADER * Binary, - OUT gctSTRING * Log - ); - -/******************************************************************************* -** gcLinkKernel -******************************************************************************** -** -** Link OpenCL kernel and generate a harwdare specific state buffer by compiling -** the compiler generated code through the resource allocator and code -** generator. -** -** INPUT: -** -** gcSHADER Kernel -** Pointer to a gcSHADER object holding information about the compiled -** OpenCL kernel. -** -** gceSHADER_FLAGS Flags -** Compiler flags. Can be any of the following: -** -** gcvSHADER_DEAD_CODE - Dead code elimination. -** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion. -** gcvSHADER_OPTIMIZER - Full optimization. -** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate. -** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position. -** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward. -** -** OUTPUT: -** -** gctSIZE_T * StateBufferSize -** Pointer to a variable receiving the number of bytes in the buffer -** returned in 'StateBuffer'. -** -** gctPOINTER * StateBuffer -** Pointer to a variable receiving a buffer pointer that contains the -** states required to download the shaders into the hardware. -** -** gcsHINT_PTR * Hints -** Pointer to a variable receiving a gcsHINT structure pointer that -** contains information required when loading the shader states. -*/ -gceSTATUS -gcLinkKernel( - IN gcSHADER Kernel, - IN gceSHADER_FLAGS Flags, - OUT gctSIZE_T * StateBufferSize, - OUT gctPOINTER * StateBuffer, - OUT gcsHINT_PTR * Hints - ); - -/******************************************************************************* -** gcLoadKernel -******************************************************************************** -** -** Load a pre-compiled and pre-linked kernel program into the hardware. -** -** INPUT: -** -** gctSIZE_T StateBufferSize -** The number of bytes in the 'StateBuffer'. -** -** gctPOINTER StateBuffer -** Pointer to the states that make up the shader program. -** -** gcsHINT_PTR Hints -** Pointer to a gcsHINT structure that contains information required -** when loading the shader states. -*/ -gceSTATUS -gcLoadKernel( - IN gctSIZE_T StateBufferSize, - IN gctPOINTER StateBuffer, - IN gcsHINT_PTR Hints - ); - -gceSTATUS -gcInvokeThreadWalker( - IN gcsTHREAD_WALKER_INFO_PTR Info - ); - -void -gcTYPE_GetTypeInfo( - IN gcSHADER_TYPE Type, - OUT gctINT * Components, - OUT gctINT * Rows, - OUT gctCONST_STRING * Name - ); - -gctBOOL -gcOPT_doVaryingPackingForShader( - IN gcSHADER Shader - ); - -gceSTATUS -gcSHADER_PatchNPOTForMachineCode( - IN gcSHADER_KIND shaderType, - IN gcMACHINECODE_PTR pMachineCode, - IN gcNPOT_PATCH_PARAM_PTR pPatchParam, - IN gctUINT countOfPatchParam, - IN gctUINT hwSupportedInstCount, - OUT gctPOINTER* ppCmdBuffer, - OUT gctUINT32* pByteSizeOfCmdBuffer, - IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */ - ); - -gceSTATUS -gcSHADER_PatchZBiasForMachineCodeVS( - IN gcMACHINECODE_PTR pMachineCode, - IN OUT gcZBIAS_PATCH_PARAM_PTR pPatchParam, - IN gctUINT hwSupportedInstCount, - OUT gctPOINTER* ppCmdBuffer, - OUT gctUINT32* pByteSizeOfCmdBuffer, - IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */ - ); - -#ifdef __cplusplus -} -#endif - -#endif /* VIVANTE_NO_3D */ -#endif /* __gc_hal_compiler_h_ */ 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 ea86349dcf97..345b4eaca17b 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -18,7 +18,6 @@ * *****************************************************************************/ - #ifndef __gc_hal_driver_h_ #define __gc_hal_driver_h_ @@ -42,6 +41,7 @@ extern "C" { #define IOCTL_GCHAL_KERNEL_INTERFACE 30001 #define IOCTL_GCHAL_TERMINATE 30002 +#undef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT /******************************************************************************\ ********************************* Command Codes ******************************** \******************************************************************************/ @@ -61,7 +61,7 @@ typedef enum _gceHAL_COMMAND_CODES /* Video memory allocation. */ gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */ gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */ - gcvHAL_FREE_VIDEO_MEMORY, + gcvHAL_RELEASE_VIDEO_MEMORY, /* Physical-to-logical mapping. */ gcvHAL_MAP_MEMORY, @@ -145,9 +145,6 @@ typedef enum _gceHAL_COMMAND_CODES /* Frame database. */ gcvHAL_GET_FRAME_INFO, - /* Shared info for each process */ - gcvHAL_GET_SHARED_INFO, - gcvHAL_SET_SHARED_INFO, gcvHAL_QUERY_COMMAND_BUFFER, gcvHAL_COMMIT_DONE, @@ -164,17 +161,33 @@ typedef enum _gceHAL_COMMAND_CODES gcvHAL_SET_FSCALE_VALUE, gcvHAL_GET_FSCALE_VALUE, + gcvHAL_NAME_VIDEO_MEMORY, + gcvHAL_IMPORT_VIDEO_MEMORY, + /* Reset time stamp. */ gcvHAL_QUERY_RESET_TIME_STAMP, + /* Multi-GPU read/write. */ + gcvHAL_READ_REGISTER_EX, + gcvHAL_WRITE_REGISTER_EX, + /* Sync point operations. */ gcvHAL_SYNC_POINT, /* Create native fence and return its fd. */ gcvHAL_CREATE_NATIVE_FENCE, - /* Video memory database */ - gcvHAL_VIDMEM_DATABASE, + /* Destory MMU. */ + gcvHAL_DESTROY_MMU, + + /* Shared buffer. */ + gcvHAL_SHBUF, + + /* Config power management. */ + gcvHAL_CONFIG_POWER_MANAGEMENT, + + /* Connect a video node to an OS native fd. */ + gcvHAL_GET_VIDEO_MEMORY_FD, } gceHAL_COMMAND_CODES; @@ -222,6 +235,9 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY /* Supported minor feature 4 fields. */ gctUINT32 chipMinorFeatures4; + /* Supported minor feature 5 fields. */ + gctUINT32 chipMinorFeatures5; + /* Number of streams supported. */ gctUINT32 streamCount; @@ -257,6 +273,17 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY /* Supertile layout style in hardware */ gctUINT32 superTileMode; + +#if gcdMULTI_GPU + /* Number of 3D GPUs */ + gctUINT32 gpuCoreCount; +#endif + + /* Special control bits for 2D chip. */ + gctUINT32 chip2DControl; + + /* Product ID */ + gctUINT32 productID; } gcsHAL_QUERY_CHIP_IDENTITY; @@ -384,11 +411,14 @@ 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; - /* Allocated video memory in gcuVIDMEM_NODE. */ - OUT gctUINT64 node; + /* Allocated video memory. */ + OUT gctUINT32 node; } AllocateLinearVideoMemory; @@ -413,58 +443,64 @@ typedef struct _gcsHAL_INTERFACE /* Memory pool to allocate from. */ IN OUT gcePOOL pool; - /* Allocated video memory in gcuVIDMEM_NODE. */ - OUT gctUINT64 node; + /* Allocated video memory. */ + OUT gctUINT32 node; } AllocateVideoMemory; - /* gcvHAL_FREE_VIDEO_MEMORY */ - struct _gcsHAL_FREE_VIDEO_MEMORY + /* gcvHAL_RELEASE_VIDEO_MEMORY */ + struct _gcsHAL_RELEASE_VIDEO_MEMORY { - /* Allocated video memory in gcuVIDMEM_NODE. */ - IN gctUINT64 node; + /* Allocated video memory. */ + IN gctUINT32 node; #ifdef __QNXNTO__ /* TODO: This is part of the unlock - why is it here? */ /* Mapped logical address to unmap in user space. */ - OUT gctUINT64 memory; + OUT gctUINT64 memory; /* Number of bytes to allocated. */ - OUT gctUINT64 bytes; + OUT gctUINT64 bytes; #endif } - FreeVideoMemory; + ReleaseVideoMemory; /* gcvHAL_LOCK_VIDEO_MEMORY */ struct _gcsHAL_LOCK_VIDEO_MEMORY { - /* Allocated video memory gcuVIDMEM_NODE gcuVIDMEM_NODE. */ - IN gctUINT64 node; + /* Allocated video memory. */ + IN gctUINT32 node; /* Cache configuration. */ /* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL ** can be configured */ - IN gctBOOL cacheable; + IN gctBOOL cacheable; /* Hardware specific address. */ - OUT gctUINT32 address; + OUT gctUINT32 address; /* Mapped logical address. */ - OUT gctUINT64 memory; + OUT gctUINT64 memory; + + /* Customer priviate handle*/ + OUT gctUINT32 gid; + + /* Bus address of a contiguous video node. */ + OUT gctUINT64 physicalAddress; } LockVideoMemory; /* gcvHAL_UNLOCK_VIDEO_MEMORY */ struct _gcsHAL_UNLOCK_VIDEO_MEMORY { - /* Allocated video memory in gcuVIDMEM_NODE. */ - IN gctUINT64 node; + /* Allocated video memory. */ + IN gctUINT64 node; /* Type of surface. */ - IN gceSURF_TYPE type; + IN gceSURF_TYPE type; /* Flag to unlock surface asynchroneously. */ - IN OUT gctBOOL asynchroneous; + IN OUT gctBOOL asynchroneous; } UnlockVideoMemory; @@ -528,7 +564,13 @@ typedef struct _gcsHAL_INTERFACE struct _gcsHAL_EVENT_COMMIT { /* Event queue in gcsQUEUE. */ - IN gctUINT64 queue; + IN gctUINT64 queue; + +#if gcdMULTI_GPU + IN gceCORE_3D_MASK chipEnable; + + IN gceMULTI_GPU_MODE gpuMode; +#endif } Event; @@ -546,6 +588,12 @@ typedef struct _gcsHAL_INTERFACE /* Event queue in gcsQUEUE. */ IN gctUINT64 queue; + +#if gcdMULTI_GPU + IN gceCORE_3D_MASK chipEnable; + + IN gceMULTI_GPU_MODE gpuMode; +#endif } Commit; @@ -696,15 +744,40 @@ typedef struct _gcsHAL_INTERFACE } WriteRegisterData; +#if gcdMULTI_GPU + /* gcvHAL_READ_REGISTER_EX */ + struct _gcsHAL_READ_REGISTER_EX + { + /* Logical address of memory to write data to. */ + IN gctUINT32 address; + + IN gctUINT32 coreSelect; + + /* Data read. */ + OUT gctUINT32 data[gcdMULTI_GPU]; + } + ReadRegisterDataEx; + + /* gcvHAL_WRITE_REGISTER_EX */ + struct _gcsHAL_WRITE_REGISTER_EX + { + /* Logical address of memory to write data to. */ + IN gctUINT32 address; + + IN gctUINT32 coreSelect; + + /* Data read. */ + IN gctUINT32 data[gcdMULTI_GPU]; + } + WriteRegisterDataEx; +#endif + #if VIVANTE_PROFILER /* gcvHAL_GET_PROFILE_SETTING */ struct _gcsHAL_GET_PROFILE_SETTING { /* Enable profiling */ OUT gctBOOL enable; - - /* The profile file name */ - OUT gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME]; } GetProfileSetting; @@ -713,9 +786,6 @@ typedef struct _gcsHAL_INTERFACE { /* Enable profiling */ IN gctBOOL enable; - - /* The profile file name */ - IN gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME]; } SetProfileSetting; @@ -736,6 +806,7 @@ typedef struct _gcsHAL_INTERFACE /* Context buffer object gckCONTEXT. Just a name. */ IN gctUINT32 context; #endif + /* Data read. */ OUT gcsPROFILER_COUNTERS counters; } @@ -749,6 +820,7 @@ typedef struct _gcsHAL_INTERFACE } RegisterProfileData2D; #endif + /* Power management. */ /* gcvHAL_SET_POWER_MANAGEMENT_STATE */ struct _gcsHAL_SET_POWER_MANAGEMENT @@ -809,12 +881,10 @@ typedef struct _gcsHAL_INTERFACE struct _gcsHAL_CACHE { IN gceCACHEOPERATION operation; - /* gctHANDLE */ IN gctUINT64 process; IN gctUINT64 logical; IN gctUINT64 bytes; - /* gcuVIDMEM_NODE_PTR */ - IN gctUINT64 node; + IN gctUINT32 node; } Cache; @@ -847,25 +917,11 @@ typedef struct _gcsHAL_INTERFACE OUT gcuDATABASE_INFO nonPaged; OUT gcuDATABASE_INFO contiguous; OUT gcuDATABASE_INFO gpuIdle; - } - Database; - /* gcvHAL_VIDMEM_DATABASE */ - struct _gcsHAL_VIDMEM_DATABASE - { - /* Set to gcvTRUE if you want to query a particular process ID. - ** Set to gcvFALSE to query the last detached process. */ - IN gctBOOL validProcessID; - - /* Process ID to query. */ - IN gctUINT32 processID; - - /* Information. */ - OUT gcuDATABASE_INFO vidMemResv; - OUT gcuDATABASE_INFO vidMemCont; - OUT gcuDATABASE_INFO vidMemVirt; + /* Detail information about video memory. */ + OUT gcuDATABASE_INFO vidMemPool[3]; } - VidMemDatabase; + Database; /* gcvHAL_VERSION */ struct _gcsHAL_VERSION @@ -898,11 +954,23 @@ typedef struct _gcsHAL_INTERFACE /* gcvHAL_ATTACH */ struct _gcsHAL_ATTACH { - /* Context buffer object gckCONTEXT. Just a name. */ + /* Handle of context buffer object. */ OUT gctUINT32 context; /* Number of states in the buffer. */ OUT gctUINT64 stateCount; + + /* Map context buffer to user or not. */ + IN gctBOOL map; + + /* Physical of context buffer. */ + OUT gctUINT32 physicals[2]; + + /* Physical of context buffer. */ + OUT gctUINT64 logicals[2]; + + /* Bytes of context buffer. */ + OUT gctUINT32 bytes; } Attach; @@ -933,61 +1001,32 @@ typedef struct _gcsHAL_INTERFACE SetTimeOut; #if gcdENABLE_VG - /* gcvHAL_COMMIT */ - struct _gcsHAL_VGCOMMIT - { - /* Context buffer in gcsVGCONTEXT. */ - IN gctUINT64 context; - - /* Command queue in gcsVGCMDQUEUE. */ - IN gctUINT64 queue; - - /* Number of entries in the queue. */ - IN gctUINT entryCount; - - /* Task table in gcsTASK_MASTER_TABLE. */ - IN gctUINT64 taskTable; - } - VGCommit; - - /* gcvHAL_QUERY_COMMAND_BUFFER */ - struct _gcsHAL_QUERY_COMMAND_BUFFER - { - /* Command buffer attributes. */ - OUT gcsCOMMAND_BUFFER_INFO information; - } - QueryCommandBuffer; - -#endif - - struct _gcsHAL_GET_SHARED_INFO + /* gcvHAL_COMMIT */ + struct _gcsHAL_VGCOMMIT { - /* Process id. */ - IN gctUINT32 pid; + /* Context buffer. gcsVGCONTEXT_PTR */ + IN gctUINT64 context; - /* Data id. */ - IN gctUINT32 dataId; + /* Command queue. gcsVGCMDQUEUE_PTR */ + IN gctUINT64 queue; - /* Data size. */ - IN gctSIZE_T bytes; + /* Number of entries in the queue. */ + IN gctUINT entryCount; - /* Pointer to save the shared data. */ - OUT gctPOINTER data; + /* Task table. gcsTASK_MASTER_TABLE_PTR */ + IN gctUINT64 taskTable; } - GetSharedInfo; + VGCommit; - struct _gcsHAL_SET_SHARED_INFO + /* gcvHAL_QUERY_COMMAND_BUFFER */ + struct _gcsHAL_QUERY_COMMAND_BUFFER { - /* Data id. */ - IN gctUINT32 dataId; - - /* Data to be shared. */ - IN gctPOINTER data; - - /* Data size. */ - IN gctSIZE_T bytes; + /* Command buffer attributes. */ + OUT gcsCOMMAND_BUFFER_INFO information; } - SetSharedInfo; + QueryCommandBuffer; + +#endif struct _gcsHAL_SET_FSCALE_VALUE { @@ -1003,6 +1042,20 @@ typedef struct _gcsHAL_INTERFACE } GetFscaleValue; + struct _gcsHAL_NAME_VIDEO_MEMORY + { + IN gctUINT32 handle; + OUT gctUINT32 name; + } + NameVideoMemory; + + struct _gcsHAL_IMPORT_VIDEO_MEMORY + { + IN gctUINT32 name; + OUT gctUINT32 handle; + } + ImportVideoMemory; + struct _gcsHAL_QUERY_RESET_TIME_STAMP { OUT gctUINT64 timeStamp; @@ -1035,6 +1088,41 @@ typedef struct _gcsHAL_INTERFACE } CreateNativeFence; + + struct _gcsHAL_DESTROY_MMU + { + /* Mmu object. */ + 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; + + struct _gcsHAL_CONFIG_POWER_MANAGEMENT + { + IN gctBOOL enable; + } + ConfigPowerManagement; + + struct _gcsHAL_GET_VIDEO_MEMORY_FD + { + IN gctUINT32 handle; + OUT gctINT fd; + } + GetVideoMemoryFd; } u; } diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h index b54752f8be6e..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -56,37 +56,37 @@ typedef struct _gcsCOMMAND_BUFFER_INFO /* Alignment and mask for the buffer address. */ gctUINT addressMask; - gctSIZE_T addressAlignment; + gctUINT32 addressAlignment; /* Alignment for each command. */ - gctSIZE_T commandAlignment; + gctUINT32 commandAlignment; /* Number of bytes required by the STATE command. */ - gctSIZE_T stateCommandSize; + gctUINT32 stateCommandSize; /* Number of bytes required by the RESTART command. */ - gctSIZE_T restartCommandSize; + gctUINT32 restartCommandSize; /* Number of bytes required by the FETCH command. */ - gctSIZE_T fetchCommandSize; + gctUINT32 fetchCommandSize; /* Number of bytes required by the CALL command. */ - gctSIZE_T callCommandSize; + gctUINT32 callCommandSize; /* Number of bytes required by the RETURN command. */ - gctSIZE_T returnCommandSize; + gctUINT32 returnCommandSize; /* Number of bytes required by the EVENT command. */ - gctSIZE_T eventCommandSize; + gctUINT32 eventCommandSize; /* Number of bytes required by the END command. */ - gctSIZE_T endCommandSize; + gctUINT32 endCommandSize; /* Number of bytes reserved at the tail of a static command buffer. */ - gctSIZE_T staticTailSize; + gctUINT32 staticTailSize; /* Number of bytes reserved at the tail of a dynamic command buffer. */ - gctSIZE_T dynamicTailSize; + gctUINT32 dynamicTailSize; } gcsCOMMAND_BUFFER_INFO; @@ -221,7 +221,7 @@ typedef struct _gcsTASK_FREE_VIDEO_MEMORY IN gceTASK id; /* Allocated video memory. */ - IN gctUINT64 node; + IN gctUINT32 node; } gcsTASK_FREE_VIDEO_MEMORY; 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 ffd45e8f677b..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -27,56 +27,57 @@ extern "C" { #endif /* -** FILE LAYOUT: +** FILE LAYOUT: ** -** gcsDUMP_FILE structure +** gcsDUMP_FILE structure ** -** gcsDUMP_DATA frame -** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame -** gctUINT8 data[length] +** gcsDUMP_DATA frame +** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame +** gctUINT8 data[length] */ -#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B') +#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B') typedef struct _gcsDUMP_FILE { - gctUINT32 signature; /* File signature */ - gctSIZE_T length; /* Length of file */ - gctUINT32 frames; /* Number of frames in file */ + gctUINT32 signature; /* File signature */ + gctSIZE_T length; /* Length of file */ + gctUINT32 frames; /* Number of frames in file */ } gcsDUMP_FILE; typedef enum _gceDUMP_TAG { - gcvTAG_SURFACE = gcmCC('s','u','r','f'), - gcvTAG_FRAME = gcmCC('f','r','m',' '), - gcvTAG_COMMAND = gcmCC('c','m','d',' '), - gcvTAG_INDEX = gcmCC('i','n','d','x'), - gcvTAG_STREAM = gcmCC('s','t','r','m'), - gcvTAG_TEXTURE = gcmCC('t','e','x','t'), - gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'), - gcvTAG_DEPTH = gcmCC('z','b','u','f'), - gcvTAG_RESOLVE = gcmCC('r','s','l','v'), - gcvTAG_DELETE = gcmCC('d','e','l',' '), + gcvTAG_SURFACE = gcmCC('s','u','r','f'), + gcvTAG_FRAME = gcmCC('f','r','m',' '), + gcvTAG_COMMAND = gcmCC('c','m','d',' '), + gcvTAG_INDEX = gcmCC('i','n','d','x'), + gcvTAG_STREAM = gcmCC('s','t','r','m'), + gcvTAG_TEXTURE = gcmCC('t','e','x','t'), + gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'), + gcvTAG_DEPTH = gcmCC('z','b','u','f'), + gcvTAG_RESOLVE = gcmCC('r','s','l','v'), + gcvTAG_DELETE = gcmCC('d','e','l',' '), + gcvTAG_BUFOBJ = gcmCC('b','u','f','o'), } gceDUMP_TAG; typedef struct _gcsDUMP_SURFACE { - gceDUMP_TAG type; /* Type of record. */ - gctUINT32 address; /* Address of the surface. */ - gctINT16 width; /* Width of surface. */ - gctINT16 height; /* Height of surface. */ - gceSURF_FORMAT format; /* Surface pixel format. */ - gctSIZE_T length; /* Number of bytes inside the surface. */ + gceDUMP_TAG type; /* Type of record. */ + gctUINT32 address; /* Address of the surface. */ + gctINT16 width; /* Width of surface. */ + gctINT16 height; /* Height of surface. */ + gceSURF_FORMAT format; /* Surface pixel format. */ + gctSIZE_T length; /* Number of bytes inside the surface. */ } gcsDUMP_SURFACE; typedef struct _gcsDUMP_DATA { - gceDUMP_TAG type; /* Type of record. */ - gctSIZE_T length; /* Number of bytes of data. */ - gctUINT32 address; /* Address for the data. */ + gceDUMP_TAG type; /* Type of record. */ + gctSIZE_T length; /* Number of bytes of data. */ + gctUINT32 address; /* Address for the data. */ } gcsDUMP_DATA; 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 c4347e1e0bbc..1f35873601d2 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -18,6 +18,7 @@ * *****************************************************************************/ + #ifndef __gc_hal_eglplatform_h_ #define __gc_hal_eglplatform_h_ @@ -51,22 +52,30 @@ typedef struct _DFBPixmap * HALNativePixmapType; #elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__) #if defined(EGL_API_WL) + +#if defined(__GNUC__) +# define inline __inline__ /* GNU keyword. */ +#endif + /* Wayland platform. */ -#include "wayland-server.h" #include -#define WL_EGL_NUM_BACKBUFFERS 2 +#define WL_EGL_NUM_BACKBUFFERS 3 typedef struct _gcsWL_VIV_BUFFER { - struct wl_buffer wl_buffer; + struct wl_resource *wl_buffer; gcoSURF surface; + gctINT32 width, height; } gcsWL_VIV_BUFFER; typedef struct _gcsWL_EGL_DISPLAY { struct wl_display* wl_display; struct wl_viv* wl_viv; + struct wl_registry *registry; + struct wl_event_queue *wl_queue; + gctINT swapInterval; } gcsWL_EGL_DISPLAY; typedef struct _gcsWL_EGL_BUFFER_INFO @@ -79,6 +88,9 @@ typedef struct _gcsWL_EGL_BUFFER_INFO gcePOOL pool; gctUINT bytes; gcoSURF surface; + gcoSURF attached_surface; + gctINT32 invalidate; + gctBOOL locked; } gcsWL_EGL_BUFFER_INFO; typedef struct _gcsWL_EGL_BUFFER @@ -89,19 +101,24 @@ typedef struct _gcsWL_EGL_BUFFER typedef struct _gcsWL_EGL_WINDOW_INFO { + gctINT32 dx; + gctINT32 dy; gctUINT width; gctUINT height; + gctINT32 attached_width; + gctINT32 attached_height; gceSURF_FORMAT format; gctUINT bpp; } gcsWL_EGL_WINDOW_INFO; struct wl_egl_window { + gcsWL_EGL_DISPLAY* display; gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS]; gcsWL_EGL_WINDOW_INFO info; gctUINT current; struct wl_surface* surface; - struct wl_callback* pending; + struct wl_callback* frame_callback; }; typedef void* HALNativeDisplayType; @@ -278,6 +295,12 @@ gcoOS_SetSwapInterval( IN gctINT Interval ); +gceSTATUS +gcoOS_SetSwapIntervalEx( + IN HALNativeDisplayType Display, + IN gctINT Interval, + IN gctPOINTER localDisplay); + gceSTATUS gcoOS_GetSwapInterval( IN HALNativeDisplayType Display, @@ -609,8 +632,41 @@ gcoOS_SwapBuffers( OUT gctUINT *Width, OUT gctUINT *Height ); + +#ifdef EGL_API_DRI +gceSTATUS +gcoOS_ResizeWindow( + IN gctPOINTER localDisplay, + IN HALNativeWindowType Drawable, + IN gctUINT Width, + IN gctUINT Height) + ; + +#ifdef USE_FREESCALE_EGL_ACCEL +gceSTATUS +gcoOS_SwapBuffersGeneric_Async( + IN gctPOINTER localDisplay, + IN HALNativeWindowType Drawable, + IN gcoSURF RenderTarget, + IN gcoSURF ResolveTarget, + IN gctPOINTER ResolveBits, + OUT gctUINT *Width, + OUT gctUINT *Height, + IN void * resolveRect + ); + +gceSTATUS +gcoOS_DrawSurface( + IN gctPOINTER localDisplay, + IN HALNativeWindowType Drawable + ); +#endif + +#endif + #ifdef __cplusplus } #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 4f5c3cea4c2c..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -32,20 +32,20 @@ extern "C" { typedef enum _halEventType { - /* Keyboard event. */ + /* Keyboard event. */ HAL_KEYBOARD, - /* Mouse move event. */ + /* Mouse move event. */ HAL_POINTER, - /* Mouse button event. */ + /* Mouse button event. */ HAL_BUTTON, - /* Application close event. */ - HAL_CLOSE, + /* Application close event. */ + HAL_CLOSE, - /* Application window has been updated. */ - HAL_WINDOW_UPDATE + /* Application window has been updated. */ + HAL_WINDOW_UPDATE } halEventType; @@ -171,10 +171,10 @@ halKeys; /* Structure that defined keyboard mapping. */ typedef struct _halKeyMap { - /* Normal key. */ + /* Normal key. */ halKeys normal; - /* Extended key. */ + /* Extended key. */ halKeys extended; } halKeyMap; @@ -182,50 +182,50 @@ halKeyMap; /* Event structure. */ typedef struct _halEvent { - /* Event type. */ + /* Event type. */ halEventType type; - /* Event data union. */ + /* Event data union. */ union _halEventData { - /* Event data for keyboard. */ + /* Event data for keyboard. */ struct _halKeyboard { - /* Scancode. */ - halKeys scancode; + /* Scancode. */ + halKeys scancode; - /* ASCII characte of the key pressed. */ - char key; + /* ASCII characte of the key pressed. */ + char key; - /* Flag whether the key was pressed (1) or released (0). */ - char pressed; + /* Flag whether the key was pressed (1) or released (0). */ + char pressed; } keyboard; - /* Event data for pointer. */ + /* Event data for pointer. */ struct _halPointer { - /* Current pointer coordinate. */ - int x; - int y; + /* Current pointer coordinate. */ + int x; + int y; } pointer; - /* Event data for mouse buttons. */ + /* Event data for mouse buttons. */ struct _halButton { - /* Left button state. */ - int left; + /* Left button state. */ + int left; - /* Middle button state. */ - int middle; + /* Middle button state. */ + int middle; - /* Right button state. */ - int right; + /* Right button state. */ + int right; - /* Current pointer coordinate. */ - int x; - int y; + /* Current pointer coordinate. */ + int x; + int y; } button; } 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 3fb2fe4c2709..700f7eb6d76a 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,10 +22,10 @@ #ifndef __gc_hal_engine_h_ #define __gc_hal_engine_h_ -#ifndef VIVANTE_NO_3D #include "gc_hal_types.h" #include "gc_hal_enum.h" +#if gcdENABLE_3D #if gcdENABLE_VG #include "gc_hal_engine_vg.h" #endif @@ -44,160 +44,40 @@ typedef struct _gcoTEXTURE * gcoTEXTURE; typedef struct _gcoINDEX * gcoINDEX; typedef struct _gcsVERTEX_ATTRIBUTES * gcsVERTEX_ATTRIBUTES_PTR; typedef struct _gcoVERTEXARRAY * gcoVERTEXARRAY; +typedef struct _gcoBUFOBJ * gcoBUFOBJ; #define gcdATTRIBUTE_COUNT 16 -/******************************************************************************\ -********************************* Enumerations ********************************* -\******************************************************************************/ - -/* Shading format. */ -typedef enum _gceSHADING -{ - gcvSHADING_SMOOTH, - gcvSHADING_FLAT_D3D, - gcvSHADING_FLAT_OPENGL, -} -gceSHADING; - -/* Culling modes. */ -typedef enum _gceCULL -{ - gcvCULL_NONE, - gcvCULL_CCW, - gcvCULL_CW, -} -gceCULL; - -/* Fill modes. */ -typedef enum _gceFILL -{ - gcvFILL_POINT, - gcvFILL_WIRE_FRAME, - gcvFILL_SOLID, -} -gceFILL; - -/* Compare modes. */ -typedef enum _gceCOMPARE -{ - gcvCOMPARE_NEVER, - gcvCOMPARE_NOT_EQUAL, - gcvCOMPARE_LESS, - gcvCOMPARE_LESS_OR_EQUAL, - gcvCOMPARE_EQUAL, - gcvCOMPARE_GREATER, - gcvCOMPARE_GREATER_OR_EQUAL, - gcvCOMPARE_ALWAYS, - gcvCOMPARE_INVALID = -1 -} -gceCOMPARE; - -/* Stencil modes. */ -typedef enum _gceSTENCIL_MODE -{ - gcvSTENCIL_NONE, - gcvSTENCIL_SINGLE_SIDED, - gcvSTENCIL_DOUBLE_SIDED, -} -gceSTENCIL_MODE; - -/* Stencil operations. */ -typedef enum _gceSTENCIL_OPERATION -{ - gcvSTENCIL_KEEP, - gcvSTENCIL_REPLACE, - gcvSTENCIL_ZERO, - gcvSTENCIL_INVERT, - gcvSTENCIL_INCREMENT, - gcvSTENCIL_DECREMENT, - gcvSTENCIL_INCREMENT_SATURATE, - gcvSTENCIL_DECREMENT_SATURATE, - gcvSTENCIL_OPERATION_INVALID = -1 -} -gceSTENCIL_OPERATION; - -/* Stencil selection. */ -typedef enum _gceSTENCIL_WHERE -{ - gcvSTENCIL_FRONT, - gcvSTENCIL_BACK, -} -gceSTENCIL_WHERE; - -/* Texture addressing selection. */ -typedef enum _gceTEXTURE_WHICH +typedef enum _gcePROGRAM_STAGE { - gcvTEXTURE_S, - gcvTEXTURE_T, - gcvTEXTURE_R, + gcvPROGRAM_STAGE_VERTEX = 0x0, + gcvPROGRAM_STAGE_TES = 0x1, + gcvPROGRAM_STAGE_TCS = 0x2, + gcvPROGRAM_STAGE_GEOMETRY = 0x3, + gcvPROGRAM_STAGE_FRAGMENT = 0x4, + gcvPROGRAM_STAGE_COMPUTE = 0x5, + gcvPROGRAM_STAGE_OPENCL = 0x6, + gcvPROGRAM_STAGE_LAST } -gceTEXTURE_WHICH; +gcePROGRAM_STAGE; -/* Texture addressing modes. */ -typedef enum _gceTEXTURE_ADDRESSING +typedef enum _gcePROGRAM_STAGE_BIT { - gcvTEXTURE_WRAP, - gcvTEXTURE_CLAMP, - gcvTEXTURE_BORDER, - gcvTEXTURE_MIRROR, - gcvTEXTURE_MIRROR_ONCE, + gcvPROGRAM_STAGE_VERTEX_BIT = 1 << gcvPROGRAM_STAGE_VERTEX, + gcvPROGRAM_STAGE_TES_BIT = 1 << gcvPROGRAM_STAGE_TES, + gcvPROGRAM_STAGE_TCS_BIT = 1 << gcvPROGRAM_STAGE_TCS, + gcvPROGRAM_STAGE_GEOMETRY_BIT = 1 << gcvPROGRAM_STAGE_GEOMETRY, + gcvPROGRAM_STAGE_FRAGMENT_BIT = 1 << gcvPROGRAM_STAGE_FRAGMENT, + gcvPROGRAM_STAGE_COMPUTE_BIT = 1 << gcvPROGRAM_STAGE_COMPUTE, + gcvPROGRAM_STAGE_OPENCL_BIT = 1 << gcvPROGRAM_STAGE_OPENCL, } -gceTEXTURE_ADDRESSING; +gcePROGRAM_STAGE_BIT; -/* Texture filters. */ -typedef enum _gceTEXTURE_FILTER -{ - gcvTEXTURE_NONE, - gcvTEXTURE_POINT, - gcvTEXTURE_LINEAR, - gcvTEXTURE_ANISOTROPIC, -} -gceTEXTURE_FILTER; - -/* Primitive types. */ -typedef enum _gcePRIMITIVE -{ - gcvPRIMITIVE_POINT_LIST, - gcvPRIMITIVE_LINE_LIST, - gcvPRIMITIVE_LINE_STRIP, - gcvPRIMITIVE_LINE_LOOP, - gcvPRIMITIVE_TRIANGLE_LIST, - gcvPRIMITIVE_TRIANGLE_STRIP, - gcvPRIMITIVE_TRIANGLE_FAN, - gcvPRIMITIVE_RECTANGLE, -} -gcePRIMITIVE; - -/* Index types. */ -typedef enum _gceINDEX_TYPE -{ - gcvINDEX_8, - gcvINDEX_16, - gcvINDEX_32, -} -gceINDEX_TYPE; /******************************************************************************\ ********************************* gcoHAL Object ********************************* \******************************************************************************/ -/* Query the target capabilities. */ -gceSTATUS -gcoHAL_QueryTargetCaps( - IN gcoHAL Hal, - OUT gctUINT * MaxWidth, - OUT gctUINT * MaxHeight, - OUT gctUINT * MultiTargetCount, - OUT gctUINT * MaxSamples - ); - -gceSTATUS -gcoHAL_SetDepthOnly( - IN gcoHAL Hal, - IN gctBOOL Enable - ); - gceSTATUS gcoHAL_QueryShaderCaps( IN gcoHAL Hal, @@ -206,6 +86,31 @@ gcoHAL_QueryShaderCaps( OUT gctUINT * Varyings ); +gceSTATUS +gcoHAL_QueryShaderCapsEx( + IN gcoHAL Hal, + OUT gctUINT * ShaderCoreCount, + OUT gctUINT * ThreadCount, + OUT gctUINT * VertexInstructionCount, + OUT gctUINT * FragmentInstructionCount + ); + +gceSTATUS +gcoHAL_QuerySamplerBase( + IN gcoHAL Hal, + OUT gctUINT32 * VertexCount, + OUT gctINT_PTR VertexBase, + OUT gctUINT32 * FragmentCount, + OUT gctINT_PTR FragmentBase + ); + +gceSTATUS +gcoHAL_QueryUniformBase( + IN gcoHAL Hal, + OUT gctUINT32 * VertexBase, + OUT gctUINT32 * FragmentBase + ); + gceSTATUS gcoHAL_QueryTextureCaps( IN gcoHAL Hal, @@ -239,46 +144,198 @@ gcoHAL_QueryStreamCaps( /*----------------------------------------------------------------------------*/ /*--------------------------------- gcoSURF 3D --------------------------------*/ +typedef enum _gceBLIT_FLAG +{ + gcvBLIT_FLAG_SKIP_DEPTH_WRITE = 0x1, + gcvBLIT_FLAG_SKIP_STENCIL_WRITE = 0x2, +} gceBLIT_FLAG; -/* Copy surface. */ -gceSTATUS -gcoSURF_Copy( - IN gcoSURF Surface, - IN gcoSURF Source - ); +typedef struct _gcsSURF_BLIT_ARGS +{ + gcoSURF srcSurface; + gctINT srcX, srcY, srcZ; + gctINT srcWidth, srcHeight, srcDepth; + gcoSURF dstSurface; + gctINT dstX, dstY, dstZ; + gctINT dstWidth, dstHeight, dstDepth; + gctBOOL xReverse; + gctBOOL yReverse; + gctBOOL scissorTest; + gcsRECT scissor; + gctUINT flags; +} +gcsSURF_BLIT_ARGS; + + + + +/* Clear flags. */ +typedef enum _gceCLEAR +{ + gcvCLEAR_COLOR = 0x1, + gcvCLEAR_DEPTH = 0x2, + gcvCLEAR_STENCIL = 0x4, + gcvCLEAR_HZ = 0x8, + gcvCLEAR_HAS_VAA = 0x10, + gcvCLEAR_WITH_GPU_ONLY = 0x100, + gcvCLEAR_WITH_CPU_ONLY = 0x200, +} +gceCLEAR; + +typedef struct _gcsSURF_CLEAR_ARGS +{ + /* + ** Color to fill the color portion of the framebuffer when clear + ** is called. + */ + struct { + gcuVALUE r; + gcuVALUE g; + gcuVALUE b; + gcuVALUE a; + /* + ** Color has multiple value type so we must specify it. + */ + gceVALUE_TYPE valueType; + } color; + + gcuVALUE depth; + + gctUINT stencil; + + + + /* + ** stencil bit-wise mask + */ + gctUINT8 stencilMask; + /* + ** Depth Write Mask + */ + gctBOOL depthMask; + /* + ** 4-bit channel Mask: ABGR:MSB->LSB + */ + gctUINT8 colorMask; + /* + ** If ClearRect is NULL, it means full clear + */ + gcsRECT_PTR clearRect; + /* + ** clear flags + */ + gceCLEAR flags; + + /* + ** Offset in surface to cube/array/3D + */ + gctUINT32 offset; + +} gcsSURF_CLEAR_ARGS; + + +typedef gcsSURF_CLEAR_ARGS* gcsSURF_CLEAR_ARGS_PTR; + +typedef struct _gscSURF_BLITDRAW_BLIT +{ + gcoSURF srcSurface; + gcoSURF dstSurface; + gcsRECT srcRect; + gcsRECT dstRect; + gceTEXTURE_FILTER filterMode; + gctBOOL xReverse; + gctBOOL yReverse; + gctBOOL scissorEnabled; + gcsRECT scissor; +}gscSURF_BLITDRAW_BLIT; + + +typedef enum _gceBLITDRAW_TYPE +{ + gcvBLITDRAW_CLEAR = 0, + gcvBLITDRAW_BLIT = 1, + + /* last number, not a real type */ + gcvBLITDRAW_NUM_TYPE + } +gceBLITDRAW_TYPE; + + +typedef struct _gscSURF_BLITDRAW_ARGS +{ + /* always the fist member */ + gceHAL_ARG_VERSION version; + + union _gcsSURF_BLITDRAW_ARGS_UNION + { + struct _gscSURF_BLITDRAW_ARG_v1 + { + /* Whether it's clear or blit operation, can be extended. */ + gceBLITDRAW_TYPE type; + + union _gscSURF_BLITDRAW_UNION + { + gscSURF_BLITDRAW_BLIT blit; + + struct _gscSURF_BLITDRAW_CLEAR + { + gcsSURF_CLEAR_ARGS clearArgs; + gcoSURF rtSurface; + gcoSURF dsSurface; + } clear; + } u; + } v1; + } uArgs; +} +gcsSURF_BLITDRAW_ARGS; + + +typedef struct _gcsSURF_RESOLVE_ARGS +{ + gceHAL_ARG_VERSION version; + union _gcsSURF_RESOLVE_ARGS_UNION + { + struct _gcsSURF_RESOLVE_ARG_v1 + { + gctBOOL yInverted; + }v1; + } uArgs; +} +gcsSURF_RESOLVE_ARGS; -/* Clear surface. */ + +/* CPU Blit with format (including linear <-> tile) conversion*/ gceSTATUS -gcoSURF_Clear( - IN gcoSURF Surface, - IN gctUINT Flags +gcoSURF_BlitCPU( + gcsSURF_BLIT_ARGS* args ); -/* Set number of samples for a gcoSURF object. */ + gceSTATUS -gcoSURF_SetSamples( - IN gcoSURF Surface, - IN gctUINT Samples +gcoSURF_BlitDraw( + IN gcsSURF_BLITDRAW_ARGS *args ); +#endif /* gcdENABLE_3D */ + -/* Get the number of samples per pixel. */ + +#if gcdENABLE_3D +/* Clear surface function. */ gceSTATUS -gcoSURF_GetSamples( +gcoSURF_Clear( IN gcoSURF Surface, - OUT gctUINT_PTR Samples + IN gcsSURF_CLEAR_ARGS_PTR clearArg ); -/* Clear rectangular surface. */ +/* Preserve pixels from source. */ gceSTATUS -gcoSURF_ClearRect( - IN gcoSURF Surface, - IN gctINT Left, - IN gctINT Top, - IN gctINT Right, - IN gctINT Bottom, - IN gctUINT Flags +gcoSURF_Preserve( + IN gcoSURF Source, + IN gcoSURF Dest, + IN gcsRECT_PTR MaskRect ); + /* TO BE REMOVED */ gceSTATUS depr_gcoSURF_Resolve( @@ -324,7 +381,16 @@ gcoSURF_Resolve( ); gceSTATUS -gcoSURF_IsHWResolveable( +gcoSURF_ResolveEx( + IN gcoSURF SrcSurface, + IN gcoSURF DestSurface, + IN gcsSURF_RESOLVE_ARGS *args + ); + + +/* Resolve rectangular area of a surface. */ +gceSTATUS +gcoSURF_ResolveRect( IN gcoSURF SrcSurface, IN gcoSURF DestSurface, IN gcsPOINT_PTR SrcOrigin, @@ -334,7 +400,27 @@ gcoSURF_IsHWResolveable( /* Resolve rectangular area of a surface. */ gceSTATUS -gcoSURF_ResolveRect( +gcoSURF_ResolveRectEx( + IN gcoSURF SrcSurface, + IN gcoSURF DestSurface, + IN gcsPOINT_PTR SrcOrigin, + IN gcsPOINT_PTR DestOrigin, + IN gcsPOINT_PTR RectSize, + IN gcsSURF_RESOLVE_ARGS *args + ); + + +gceSTATUS +gcoSURF_GetResolveAlignment( + IN gcoSURF Surface, + OUT gctUINT *originX, + OUT gctUINT *originY, + OUT gctUINT *sizeX, + OUT gctUINT *sizeY + ); + +gceSTATUS +gcoSURF_IsHWResolveable( IN gcoSURF SrcSurface, IN gcoSURF DestSurface, IN gcsPOINT_PTR SrcOrigin, @@ -359,11 +445,26 @@ gcoSURF_IsFormatRenderableAsRT( IN gcoSURF Surface ); -#if gcdSYNC gceSTATUS gcoSURF_GetFence( IN gcoSURF Surface ); + +gceSTATUS +gcoBUFOBJ_GetFence( + IN gcoBUFOBJ bufObj + ); + +gceSTATUS +gcoBUFOBJ_WaitFence( + IN gcoBUFOBJ bufObj + ); + +gceSTATUS +gcoBUFOBJ_IsFenceEnabled( + IN gcoBUFOBJ bufObj + ); + gceSTATUS gcoSURF_WaitFence( IN gcoSURF Surface @@ -388,7 +489,30 @@ gceSTATUS gcoINDEX_WaitFence( IN gcoINDEX index ); -#endif + +gceSTATUS +gcoSURF_3DBlitClearRect( + IN gcoSURF Surface, + IN gcsSURF_CLEAR_ARGS_PTR ClearArgs + ); + + +gceSTATUS +gcoSURF_3DBlitBltRect( + IN gcoSURF SrcSurf, + IN gcoSURF DestSurf, + IN gcsPOINT_PTR SrcOrigin, + IN gcsPOINT_PTR DestOrigin, + IN gcsPOINT_PTR RectSize + ); + +gceSTATUS +gcoSURF_3DBlitCopy( + IN gctUINT32 SrcAddress, + IN gctUINT32 DestAddress, + IN gctUINT32 Bytes + ); + /******************************************************************************\ ******************************** gcoINDEX Object ******************************* @@ -463,7 +587,7 @@ gcoINDEX_Upload( gceSTATUS gcoINDEX_UploadOffset( IN gcoINDEX Index, - IN gctUINT32 Offset, + IN gctSIZE_T Offset, IN gctCONST_POINTER Buffer, IN gctSIZE_T Bytes ); @@ -512,28 +636,10 @@ gcoINDEX_SetDynamic( IN gctUINT Buffers ); -gceSTATUS -gcoINDEX_UploadDynamic( - IN gcoINDEX Index, - IN gctCONST_POINTER Data, - IN gctSIZE_T Bytes - ); - /******************************************************************************\ ********************************** gco3D Object ********************************* \******************************************************************************/ -/* Clear flags. */ -typedef enum _gceCLEAR -{ - gcvCLEAR_COLOR = 0x1, - gcvCLEAR_DEPTH = 0x2, - gcvCLEAR_STENCIL = 0x4, - gcvCLEAR_HZ = 0x8, - gcvCLEAR_HAS_VAA = 0x10, -} -gceCLEAR; - /* Blending targets. */ typedef enum _gceBLEND_UNIT { @@ -562,6 +668,13 @@ gco3D_SetAPI( IN gceAPI ApiType ); +/* Get 3D API type. */ +gceSTATUS +gco3D_GetAPI( + IN gco3D Engine, + OUT gceAPI * ApiType + ); + /* Set render target. */ gceSTATUS gco3D_SetTarget( @@ -576,6 +689,36 @@ gco3D_UnsetTarget( IN gcoSURF Surface ); +gceSTATUS +gco3D_SetTargetEx( + IN gco3D Engine, + IN gctUINT32 TargetIndex, + IN gcoSURF Surface, + IN gctUINT32 LayerIndex + ); + +gceSTATUS +gco3D_UnsetTargetEx( + IN gco3D Engine, + IN gctUINT32 TargetIndex, + IN gcoSURF Surface + ); + +gceSTATUS +gco3D_SetTargetOffsetEx( + IN gco3D Engine, + IN gctUINT32 TargetIndex, + IN gctSIZE_T Offset + ); + + +gceSTATUS +gco3D_SetPSOutputMapping( + IN gco3D Engine, + IN gctINT32 * psOutputMapping + ); + + /* Set depth buffer. */ gceSTATUS gco3D_SetDepth( @@ -583,6 +726,12 @@ gco3D_SetDepth( IN gcoSURF Surface ); +gceSTATUS +gco3D_SetDepthBufferOffset( + IN gco3D Engine, + IN gctSIZE_T Offset + ); + /* Unset depth buffer. */ gceSTATUS gco3D_UnsetDepth( @@ -661,45 +810,6 @@ gco3D_SetClearStencil( IN gctUINT32 Stencil ); -/* Clear a Rect sub-surface. */ -gceSTATUS -gco3D_ClearRect( - IN gco3D Engine, - IN gctUINT32 Address, - IN gctPOINTER Memory, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gctINT32 Left, - IN gctINT32 Top, - IN gctINT32 Right, - IN gctINT32 Bottom, - IN gctUINT32 Width, - IN gctUINT32 Height, - IN gctUINT32 Flags - ); - -/* Clear surface. */ -gceSTATUS -gco3D_Clear( - IN gco3D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gctUINT32 Width, - IN gctUINT32 Height, - IN gctUINT32 Flags - ); - - -/* Clear tile status. */ -gceSTATUS -gco3D_ClearTileStatus( - IN gco3D Engine, - IN gcsSURF_INFO_PTR Surface, - IN gctUINT32 TileStatusAddress, - IN gctUINT32 Flags - ); - /* Set shading mode. */ gceSTATUS gco3D_SetShading( @@ -879,13 +989,22 @@ gco3D_SetEarlyDepth( IN gctBOOL Enable ); -/* Enable or disable all early depth operations. */ +/* Deprecated: Enable or disable all early depth operations. */ gceSTATUS gco3D_SetAllEarlyDepthModes( IN gco3D Engine, IN gctBOOL Disable ); +/* Enable or disable all early depth operations. */ +gceSTATUS +gco3D_SetAllEarlyDepthModesEx( + IN gco3D Engine, + IN gctBOOL Disable, + IN gctBOOL DisableModify, + IN gctBOOL DisablePassZ + ); + /* Switch dynamic early mode */ gceSTATUS gco3D_SwitchDynamicEarlyDepthMode( @@ -912,7 +1031,7 @@ typedef struct _gcsSTENCIL_INFO gceSTENCIL_MODE mode; gctUINT8 maskFront; - gctUINT8 maskBack; + gctUINT8 maskBack; gctUINT8 writeMaskFront; gctUINT8 writeMaskBack; @@ -1099,10 +1218,22 @@ gceSTATUS gco3D_DrawPrimitives( IN gco3D Engine, IN gcePRIMITIVE Type, - IN gctINT StartVertex, + IN gctSIZE_T StartVertex, IN gctSIZE_T PrimitiveCount ); +gceSTATUS +gco3D_DrawInstancedPrimitives( + IN gco3D Engine, + IN gcePRIMITIVE Type, + IN gctBOOL DrawIndex, + IN gctSIZE_T StartVertex, + IN gctSIZE_T StartIndex, + IN gctSIZE_T PrimitiveCount, + IN gctSIZE_T VertexCount, + IN gctSIZE_T InstanceCount + ); + gceSTATUS gco3D_DrawPrimitivesCount( IN gco3D Engine, @@ -1127,8 +1258,8 @@ gceSTATUS gco3D_DrawIndexedPrimitives( IN gco3D Engine, IN gcePRIMITIVE Type, - IN gctINT BaseVertex, - IN gctINT StartIndex, + IN gctSIZE_T BaseVertex, + IN gctSIZE_T StartIndex, IN gctSIZE_T PrimitiveCount ); @@ -1142,6 +1273,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( @@ -1166,6 +1304,12 @@ gco3D_Semaphore( IN gceWHERE To, IN gceHOW How); +/* Explicitly flush shader L1 cache */ +gceSTATUS +gco3D_FlushSHL1Cache( + IN gco3D Engine + ); + /* Set the subpixels center. */ gceSTATUS gco3D_SetCentroids( @@ -1180,6 +1324,48 @@ gco3D_SetLogicOp( IN gctUINT8 Rop ); +gceSTATUS +gco3D_SetOQ( + IN gco3D Engine, + INOUT gctPOINTER * Result, + IN gctBOOL Enable + ); + +gceSTATUS +gco3D_GetOQ( + IN gco3D Engine, + IN gctPOINTER Result, + OUT gctINT64 * Logical + ); + +gceSTATUS +gco3D_DeleteOQ( + IN gco3D Engine, + INOUT gctPOINTER Result + ); + +gceSTATUS +gco3D_SetColorOutCount( + IN gco3D Engine, + IN gctUINT32 ColorOutCount + ); + +gceSTATUS +gco3D_Set3DEngine( + IN gco3D Engine + ); + +gceSTATUS +gco3D_UnSet3DEngine( + IN gco3D Engine + ); + +gceSTATUS +gco3D_Get3DEngine( + OUT gco3D * Engine + ); + + /* OCL thread walker information. */ typedef struct _gcsTHREAD_WALKER_INFO * gcsTHREAD_WALKER_INFO_PTR; typedef struct _gcsTHREAD_WALKER_INFO @@ -1219,11 +1405,18 @@ gco3D_InvokeThreadWalker( IN gcsTHREAD_WALKER_INFO_PTR Info ); -/* Set w clip and w plane limit value. */ gceSTATUS -gco3D_SetWClipEnable( - IN gco3D Engine, - IN gctBOOL Enable +gco3D_GetClosestRenderFormat( + IN gco3D Engine, + IN gceSURF_FORMAT InFormat, + OUT gceSURF_FORMAT* OutFormat + ); + +/* Set w clip and w plane limit value. */ +gceSTATUS +gco3D_SetWClipEnable( + IN gco3D Engine, + IN gctBOOL Enable ); gceSTATUS @@ -1234,23 +1427,67 @@ gco3D_GetWClipEnable( gceSTATUS gco3D_SetWPlaneLimitF( - IN gco3D Engine, - IN gctFLOAT Value + IN gco3D Engine, + IN gctFLOAT Value ); gceSTATUS gco3D_SetWPlaneLimitX( - IN gco3D Engine, - IN gctFIXED_POINT Value + IN gco3D Engine, + IN gctFIXED_POINT Value ); - gceSTATUS gco3D_SetWPlaneLimit( IN gco3D Engine, IN gctFLOAT Value ); +gceSTATUS +gco3D_PrimitiveRestart( + IN gco3D Engine, + IN gctBOOL PrimitiveRestart); + +#if gcdSTREAM_OUT_BUFFER + +gceSTATUS +gco3D_QueryStreamOut( + IN gco3D Engine, + IN gctUINT32 OriginalIndexAddress, + IN gctUINT32 OriginalIndexOffset, + IN gctUINT32 OriginalIndexCount, + OUT gctBOOL_PTR Found + ); + +gceSTATUS +gco3D_StartStreamOut( + IN gco3D Engine, + IN gctINT StreamOutStatus, + IN gctUINT32 IndexAddress, + IN gctUINT32 IndexOffset, + IN gctUINT32 IndexCount + ); + +gceSTATUS +gco3D_StopStreamOut( + IN gco3D Engine + ); + +gceSTATUS +gco3D_ReplayStreamOut( + IN gco3D Engine, + IN gctUINT32 IndexAddress, + IN gctUINT32 IndexOffset, + IN gctUINT32 IndexCount + ); + +gceSTATUS +gco3D_EndStreamOut( + IN gco3D Engine + ); + +#endif + /*----------------------------------------------------------------------------*/ /*-------------------------- gco3D Fragment Processor ------------------------*/ @@ -1379,12 +1616,6 @@ gco3D_SetAlphaTextureFunction( IN gctINT Scale ); -/* Invoke OCL thread walker. */ -gceSTATUS -gcoHARDWARE_InvokeThreadWalker( - IN gcsTHREAD_WALKER_INFO_PTR Info - ); - /******************************************************************************\ ******************************* gcoTEXTURE Object ******************************* \******************************************************************************/ @@ -1402,16 +1633,6 @@ typedef enum _gceTEXTURE_FACE } gceTEXTURE_FACE; -#if gcdFORCE_MIPMAP -typedef enum -{ - gcvForceMipDisabled = 0, - gcvForceMipEnable = 1, - gcvForceMipGenerated = 2, - gcvForceMipNever = 3, -}gceFORCE_MIPMAP; -#endif - typedef struct _gcsTEXTURE { /* Addressing modes. */ @@ -1419,23 +1640,30 @@ typedef struct _gcsTEXTURE gceTEXTURE_ADDRESSING t; gceTEXTURE_ADDRESSING r; + gceTEXTURE_SWIZZLE swizzle[gcvTEXTURE_COMPONENT_NUM]; + /* Border color. */ - gctUINT8 border[4]; + gctUINT8 border[gcvTEXTURE_COMPONENT_NUM]; /* Filters. */ gceTEXTURE_FILTER minFilter; gceTEXTURE_FILTER magFilter; gceTEXTURE_FILTER mipFilter; gctUINT anisoFilter; - gctBOOL forceTopLevel; - gctBOOL autoMipmap; -#if gcdFORCE_MIPMAP - gceFORCE_MIPMAP forceMipmap; -#endif + /* Level of detail. */ - gctFIXED_POINT lodBias; - gctFIXED_POINT lodMin; - gctFIXED_POINT lodMax; + gctFLOAT lodBias; + gctFLOAT lodMin; + gctFLOAT lodMax; + + /* base/max level */ + gctINT32 baseLevel; + gctINT32 maxLevel; + + /* depth texture comparison */ + gceTEXTURE_COMPARE_MODE compareMode; + gceCOMPARE compareFunc; + } gcsTEXTURE, * gcsTEXTURE_PTR; @@ -1446,6 +1674,15 @@ gcoTEXTURE_Construct( OUT gcoTEXTURE * Texture ); +/* Construct a new gcoTEXTURE object with type information. */ +gceSTATUS +gcoTEXTURE_ConstructEx( + IN gcoHAL Hal, + IN gceTEXTURE_TYPE Type, + OUT gcoTEXTURE * Texture + ); + + /* Construct a new sized gcoTEXTURE object. */ gceSTATUS gcoTEXTURE_ConstructSized( @@ -1465,61 +1702,41 @@ gceSTATUS gcoTEXTURE_Destroy( IN gcoTEXTURE Texture ); -#if gcdFORCE_MIPMAP -gceSTATUS -gcoTEXTURE_DestroyForceMipmap( - IN gcoTEXTURE Texture - ); - -gceSTATUS -gcoTEXTURE_GetMipLevels( - IN gcoTEXTURE Texture, - OUT gctINT * levels - ); -#endif -/* Replace a mipmap in gcoTEXTURE object. */ -gceSTATUS -gcoTEXTURE_ReplaceMipMap( - IN gcoTEXTURE Texture, - IN gctUINT Level, - IN gctUINT Width, - IN gctUINT Height, - IN gctINT imageFormat, - IN gceSURF_FORMAT Format, - IN gctUINT Depth, - IN gctUINT Faces, - IN gcePOOL Pool - ); /* Upload data to an gcoTEXTURE object. */ gceSTATUS gcoTEXTURE_Upload( IN gcoTEXTURE Texture, + IN gctINT MipMap, IN gceTEXTURE_FACE Face, - IN gctUINT Width, - IN gctUINT Height, + IN gctSIZE_T Width, + IN gctSIZE_T Height, IN gctUINT Slice, IN gctCONST_POINTER Memory, - IN gctINT Stride, - IN gceSURF_FORMAT Format + IN gctSIZE_T Stride, + IN gceSURF_FORMAT Format, + IN gceSURF_COLOR_SPACE SrcColorSpace ); /* Upload data to an gcoTEXTURE object. */ gceSTATUS gcoTEXTURE_UploadSub( IN gcoTEXTURE Texture, - IN gctUINT MipMap, + IN gctINT MipMap, IN gceTEXTURE_FACE Face, - IN gctUINT X, - IN gctUINT Y, - IN gctUINT Width, - IN gctUINT Height, + IN gctSIZE_T X, + IN gctSIZE_T Y, + IN gctSIZE_T Width, + IN gctSIZE_T Height, IN gctUINT Slice, IN gctCONST_POINTER Memory, - IN gctINT Stride, - IN gceSURF_FORMAT Format + IN gctSIZE_T Stride, + IN gceSURF_FORMAT Format, + IN gceSURF_COLOR_SPACE SrcColorSpace, + IN gctUINT32 PhysicalAddress ); + /* Upload YUV data to an gcoTEXTURE object. */ gceSTATUS gcoTEXTURE_UploadYUV( @@ -1537,9 +1754,10 @@ gcoTEXTURE_UploadYUV( gceSTATUS gcoTEXTURE_UploadCompressed( IN gcoTEXTURE Texture, + IN gctINT MipMap, IN gceTEXTURE_FACE Face, - IN gctUINT Width, - IN gctUINT Height, + IN gctSIZE_T Width, + IN gctSIZE_T Height, IN gctUINT Slice, IN gctCONST_POINTER Memory, IN gctSIZE_T Bytes @@ -1549,25 +1767,17 @@ gcoTEXTURE_UploadCompressed( gceSTATUS gcoTEXTURE_UploadCompressedSub( IN gcoTEXTURE Texture, - IN gctUINT MipMap, + IN gctINT MipMap, IN gceTEXTURE_FACE Face, - IN gctUINT XOffset, - IN gctUINT YOffset, - IN gctUINT Width, - IN gctUINT Height, + IN gctSIZE_T XOffset, + IN gctSIZE_T YOffset, + IN gctSIZE_T Width, + IN gctSIZE_T Height, IN gctUINT Slice, IN gctCONST_POINTER Memory, IN gctSIZE_T Size ); -/* GetImageFormat of texture. */ -gceSTATUS -gcoTEXTURE_GetImageFormat( - IN gcoTEXTURE Texture, - IN gctUINT MipMap, - OUT gctINT * ImageFormat - ); - /* Get gcoSURF object for a mipmap level. */ gceSTATUS gcoTEXTURE_GetMipMap( @@ -1583,41 +1793,59 @@ gcoTEXTURE_GetMipMapFace( IN gctUINT MipMap, IN gceTEXTURE_FACE Face, OUT gcoSURF * Surface, - OUT gctUINT32_PTR Offset + OUT gctSIZE_T_PTR Offset + ); + +gceSTATUS +gcoTEXTURE_GetMipMapSlice( + IN gcoTEXTURE Texture, + IN gctUINT MipMap, + IN gctUINT Slice, + OUT gcoSURF * Surface, + OUT gctSIZE_T_PTR Offset ); gceSTATUS gcoTEXTURE_AddMipMap( IN gcoTEXTURE Texture, IN gctINT Level, - IN gctINT imageFormat, + IN gctINT InternalFormat, IN gceSURF_FORMAT Format, - IN gctUINT Width, - IN gctUINT Height, - IN gctUINT Depth, + IN gctSIZE_T Width, + IN gctSIZE_T Height, + IN gctSIZE_T Depth, IN gctUINT Faces, IN gcePOOL Pool, OUT gcoSURF * Surface ); gceSTATUS -gcoTEXTURE_AddMipMapFromClient( +gcoTEXTURE_AddMipMapWithFlag( IN gcoTEXTURE Texture, - IN gctINT Level, - IN gcoSURF Surface + IN gctINT Level, + IN gctINT InternalFormat, + IN gceSURF_FORMAT Format, + IN gctSIZE_T Width, + IN gctSIZE_T Height, + IN gctSIZE_T Depth, + IN gctUINT Faces, + IN gcePOOL Pool, + IN gctBOOL Protected, + OUT gcoSURF * Surface ); gceSTATUS -gcoTEXTURE_AddMipMapFromSurface( +gcoTEXTURE_AddMipMapFromClient( IN gcoTEXTURE Texture, IN gctINT Level, IN gcoSURF Surface ); gceSTATUS -gcoTEXTURE_SetMaxLevel( +gcoTEXTURE_AddMipMapFromSurface( IN gcoTEXTURE Texture, - IN gctUINT Levels + IN gctINT Level, + IN gcoSURF Surface ); gceSTATUS @@ -1637,6 +1865,11 @@ gcoTEXTURE_Flush( IN gcoTEXTURE Texture ); +gceSTATUS +gcoTEXTURE_FlushVS( + IN gcoTEXTURE Texture + ); + gceSTATUS gcoTEXTURE_QueryCaps( IN gcoHAL Hal, @@ -1650,19 +1883,33 @@ gcoTEXTURE_QueryCaps( ); gceSTATUS -gcoTEXTURE_GetTiling( - IN gcoTEXTURE Texture, - IN gctINT preferLevel, - OUT gceTILING * Tiling +gcoTEXTURE_GetClosestFormat( + IN gcoHAL Hal, + IN gceSURF_FORMAT InFormat, + OUT gceSURF_FORMAT* OutFormat ); gceSTATUS -gcoTEXTURE_GetClosestFormat( +gcoTEXTURE_GetClosestFormatEx( IN gcoHAL Hal, IN gceSURF_FORMAT InFormat, + IN gceTEXTURE_TYPE TextureType, OUT gceSURF_FORMAT* OutFormat ); +gceSTATUS +gcoTEXTURE_GetFormatInfo( + IN gcoTEXTURE Texture, + IN gctINT preferLevel, + OUT gcsSURF_FORMAT_INFO_PTR * TxFormatInfo + ); + +gceSTATUS +gcoTEXTURE_GetTextureFormatName( + IN gcsSURF_FORMAT_INFO_PTR TxFormatInfo, + OUT gctCONST_STRING * TxName + ); + gceSTATUS gcoTEXTURE_RenderIntoMipMap( IN gcoTEXTURE Texture, @@ -1670,13 +1917,14 @@ gcoTEXTURE_RenderIntoMipMap( ); gceSTATUS -gcoTEXTURE_IsRenderable( +gcoTEXTURE_RenderIntoMipMap2( IN gcoTEXTURE Texture, - IN gctUINT Level + IN gctINT Level, + IN gctBOOL Sync ); gceSTATUS -gcoTEXTURE_IsRenderableEx( +gcoTEXTURE_IsRenderable( IN gcoTEXTURE Texture, IN gctUINT Level ); @@ -1684,6 +1932,8 @@ gcoTEXTURE_IsRenderableEx( gceSTATUS gcoTEXTURE_IsComplete( IN gcoTEXTURE Texture, + IN gcsTEXTURE_PTR Info, + IN gctINT BaseLevel, IN gctINT MaxLevel ); @@ -1695,6 +1945,28 @@ gcoTEXTURE_BindTexture( IN gcsTEXTURE_PTR Info ); +gceSTATUS +gcoTEXTURE_BindTextureEx( + IN gcoTEXTURE Texture, + IN gctINT Target, + IN gctINT Sampler, + IN gcsTEXTURE_PTR Info, + IN gctINT textureLayer + ); + +gceSTATUS +gcoTEXTURE_InitParams( + IN gcoHAL Hal, + IN gcsTEXTURE_PTR TexParams + ); + +gceSTATUS +gcoTEXTURE_SetDepthTextureFlag( + IN gcoTEXTURE Texture, + IN gctBOOL unsized + ); + + /******************************************************************************\ ******************************* gcoSTREAM Object ****************************** \******************************************************************************/ @@ -1712,9 +1984,26 @@ typedef enum _gceVERTEX_FORMAT gcvVERTEX_FLOAT, gcvVERTEX_UNSIGNED_INT_10_10_10_2, gcvVERTEX_INT_10_10_10_2, + gcvVERTEX_UNSIGNED_INT_2_10_10_10_REV, + gcvVERTEX_INT_2_10_10_10_REV, + /* integer format */ + gcvVERTEX_INT8, + gcvVERTEX_INT16, + gcvVERTEX_INT32, } gceVERTEX_FORMAT; +/* What the SW converting scheme to create temp attrib */ +typedef enum _gceATTRIB_SCHEME +{ + gcvATTRIB_SCHEME_KEEP = 0, + gcvATTRIB_SCHEME_2_10_10_10_REV_TO_FLOAT, + gcvATTRIB_SCHEME_BYTE_TO_INT, + gcvATTRIB_SCHEME_SHORT_TO_INT, + gcvATTRIB_SCHEME_UBYTE_TO_UINT, + gcvATTRIB_SCHEME_USHORT_TO_UINT, +} gceATTRIB_SCHEME; + gceSTATUS gcoSTREAM_Construct( IN gcoHAL Hal, @@ -1730,7 +2019,7 @@ gceSTATUS gcoSTREAM_Upload( IN gcoSTREAM Stream, IN gctCONST_POINTER Buffer, - IN gctUINT32 Offset, + IN gctSIZE_T Offset, IN gctSIZE_T Bytes, IN gctBOOL Dynamic ); @@ -1741,6 +2030,18 @@ gcoSTREAM_SetStride( IN gctUINT32 Stride ); +gceSTATUS +gcoSTREAM_Size( + IN gcoSTREAM Stream, + OUT gctSIZE_T *Size + ); + +gceSTATUS +gcoSTREAM_Node( + IN gcoSTREAM Stream, + OUT gcsSURF_NODE_PTR * Node + ); + gceSTATUS gcoSTREAM_Lock( IN gcoSTREAM Stream, @@ -1799,6 +2100,14 @@ gcoSTREAM_CPUCacheOperation( IN gceCACHEOPERATION Operation ); +gceSTATUS +gcoSTREAM_CPUCacheOperation_Range( + IN gcoSTREAM Stream, + IN gctSIZE_T Offset, + IN gctSIZE_T Length, + IN gceCACHEOPERATION Operation + ); + /******************************************************************************\ ******************************** gcoVERTEX Object ****************************** \******************************************************************************/ @@ -1857,6 +2166,61 @@ gcoVERTEX_Bind( /******************************************************************************* ***** gcoVERTEXARRAY Object ***************************************************/ +typedef struct _gcsATTRIBUTE +{ + /* Enabled. */ + gctBOOL enable; + + /* Number of components. */ + gctINT size; + + /* Attribute format. */ + gceVERTEX_FORMAT format; + + /* Flag whether the attribute is normalized or not. */ + gctBOOL normalized; + + /* Stride of the component. */ + gctSIZE_T stride; + + /* Divisor of the attribute */ + gctUINT divisor; + + /* Pointer to the attribute data. */ + gctCONST_POINTER pointer; + + /* Stream object owning the attribute data. */ + gcoBUFOBJ stream; + + /* Generic values for attribute. */ + gctFLOAT genericValue[4]; + + /* Generic size for attribute. */ + gctINT genericSize; + + /* Vertex shader linkage. */ + gctUINT linkage; + +#if gcdUSE_WCLIP_PATCH + /* Does it hold positions? */ + gctBOOL isPosition; +#endif + + /* Index to vertex array */ + gctINT arrayIdx; + + gceATTRIB_SCHEME convertScheme; + + /* Pointer to the temporary buffer to be freed */ + gcoBUFOBJ tempStream; + + /* Pointer to the temporary memory to be freed */ + gctCONST_POINTER tempMemory; +} +gcsATTRIBUTE, +* gcsATTRIBUTE_PTR; + + typedef struct _gcsVERTEXARRAY { /* Enabled. */ @@ -1874,6 +2238,9 @@ typedef struct _gcsVERTEXARRAY /* Stride of the component. */ gctUINT stride; + /* Divisor of the attribute */ + gctUINT divisor; + /* Pointer to the attribute data. */ gctCONST_POINTER pointer; @@ -1889,9 +2256,7 @@ typedef struct _gcsVERTEXARRAY /* Vertex shader linkage. */ gctUINT linkage; -#if gcdUSE_WCLIP_PATCH gctBOOL isPosition; -#endif } gcsVERTEXARRAY, * gcsVERTEXARRAY_PTR; @@ -1908,12 +2273,14 @@ gcoVERTEXARRAY_Destroy( ); gceSTATUS -gcoVERTEXARRAY_Bind( +gcoVERTEXARRAY_Bind_Ex( IN gcoVERTEXARRAY Vertex, IN gctUINT32 EnableBits, IN gcsVERTEXARRAY_PTR VertexArray, IN gctUINT First, IN gctSIZE_T Count, + IN gctBOOL DrawArraysInstanced, + IN gctSIZE_T InstanceCount, IN gceINDEX_TYPE IndexType, IN gcoINDEX IndexObject, IN gctPOINTER IndexMemory, @@ -1927,16 +2294,49 @@ gcoVERTEXARRAY_Bind( #endif ); -gctUINT -gcoVERTEXARRAY_GetMaxStream( - IN gcoVERTEXARRAY Vertex -); +gceSTATUS +gcoVERTEXARRAY_Bind_Ex2( + IN gcoVERTEXARRAY Vertex, + IN gctUINT32 EnableBits, + IN gcsATTRIBUTE_PTR VertexArray, + IN gctSIZE_T First, + IN gctSIZE_T Count, + IN gctBOOL DrawArraysInstanced, + IN gctSIZE_T InstanceCount, + IN gceINDEX_TYPE IndexType, + IN gcoBUFOBJ IndexObject, + IN gctPOINTER IndexMemory, + IN OUT gcePRIMITIVE * PrimitiveType, +#if gcdUSE_WCLIP_PATCH + IN OUT gctSIZE_T * PrimitiveCount, + IN OUT gctFLOAT * wLimitRms, + IN OUT gctBOOL * wLimitDirty, +#else + IN OUT gctUINT * PrimitiveCount, +#endif + IN gctINT VertexInstanceIdLinkage + ); gceSTATUS -gcoVERTEXARRAY_SetMaxStream( +gcoVERTEXARRAY_Bind( IN gcoVERTEXARRAY Vertex, - gctUINT maxStreams -); + IN gctUINT32 EnableBits, + IN gcsVERTEXARRAY_PTR VertexArray, + IN gctUINT First, + IN gctSIZE_T Count, + IN gceINDEX_TYPE IndexType, + IN gcoINDEX IndexObject, + IN gctPOINTER IndexMemory, + IN OUT gcePRIMITIVE * PrimitiveType, +#if gcdUSE_WCLIP_PATCH + IN OUT gctUINT * PrimitiveCount, + IN OUT gctFLOAT * wLimitRms, + IN OUT gctBOOL * wLimitDirty +#else + IN OUT gctUINT * PrimitiveCount +#endif + ); + /******************************************************************************* ***** Composition *************************************************************/ @@ -1985,21 +2385,24 @@ gcsCOMPOSITION; gceSTATUS gco3D_ProbeComposition( - gctBOOL ResetIfEmpty + IN gcoHARDWARE Hardware, + IN gctBOOL ResetIfEmpty ); gceSTATUS gco3D_CompositionBegin( - void + IN gcoHARDWARE Hardware ); gceSTATUS gco3D_ComposeLayer( + IN gcoHARDWARE Hardware, IN gcsCOMPOSITION_PTR Layer ); gceSTATUS gco3D_CompositionSignals( + IN gcoHARDWARE Hardware, IN gctHANDLE Process, IN gctSIGNAL Signal1, IN gctSIGNAL Signal2 @@ -2007,6 +2410,7 @@ gco3D_CompositionSignals( gceSTATUS gco3D_CompositionEnd( + IN gcoHARDWARE Hardware, IN gcoSURF Target, IN gctBOOL Synchronous ); @@ -2022,32 +2426,162 @@ gcoHAL_DumpFrameDB( gctCONST_STRING Filename OPTIONAL ); +/****************************************************************************** +**********************gcoBUFOBJ object***************************************** +*******************************************************************************/ +typedef enum _gceBUFOBJ_TYPE +{ + gcvBUFOBJ_TYPE_ARRAY_BUFFER = 1, + gcvBUFOBJ_TYPE_ELEMENT_ARRAY_BUFFER = 2, + gcvBUFOBJ_TYPE_GENERIC_BUFFER = 100 + +} gceBUFOBJ_TYPE; + +typedef enum _gceBUFOBJ_USAGE +{ + gcvBUFOBJ_USAGE_STREAM_DRAW = 1, + gcvBUFOBJ_USAGE_STREAM_READ, + gcvBUFOBJ_USAGE_STREAM_COPY, + gcvBUFOBJ_USAGE_STATIC_DRAW, + gcvBUFOBJ_USAGE_STATIC_READ, + gcvBUFOBJ_USAGE_STATIC_COPY, + gcvBUFOBJ_USAGE_DYNAMIC_DRAW, + gcvBUFOBJ_USAGE_DYNAMIC_READ, + gcvBUFOBJ_USAGE_DYNAMIC_COPY, + +} gceBUFOBJ_USAGE; + +/* Construct a new gcoBUFOBJ object. */ +gceSTATUS +gcoBUFOBJ_Construct( + IN gcoHAL Hal, + IN gceBUFOBJ_TYPE Type, + OUT gcoBUFOBJ * BufObj + ); + +/* Destroy a gcoBUFOBJ object. */ +gceSTATUS +gcoBUFOBJ_Destroy( + IN gcoBUFOBJ BufObj + ); + +/* Lock pbo in memory. */ +gceSTATUS +gcoBUFOBJ_Lock( + IN gcoBUFOBJ BufObj, + OUT gctUINT32 * Address, + OUT gctPOINTER * Memory + ); + +/* Lock pbo in memory. */ +gceSTATUS +gcoBUFOBJ_FastLock( + IN gcoBUFOBJ BufObj, + OUT gctUINT32 * Address, + OUT gctPOINTER * Memory + ); + +/* Unlock pbo that was previously locked with gcoBUFOBJ_Lock. */ gceSTATUS -gcoHAL_GetSharedInfo( - IN gctUINT32 Pid, - IN gctUINT32 DataId, +gcoBUFOBJ_Unlock( + IN gcoBUFOBJ BufObj + ); + +/* Free existing pbo buffer. */ +gceSTATUS +gcoBUFOBJ_Free( + IN gcoBUFOBJ BufObj + ); + +/* Upload data into an pbo buffer. */ +gceSTATUS +gcoBUFOBJ_Upload( + IN gcoBUFOBJ BufObj, + IN gctCONST_POINTER Buffer, + IN gctSIZE_T Offset, IN gctSIZE_T Bytes, - OUT gctPOINTER Data + IN gceBUFOBJ_USAGE Usage ); +/* Bind an index object to the hardware. */ gceSTATUS -gcoHAL_SetSharedInfo( - IN gctUINT32 DataId, - IN gctPOINTER Data, - IN gctSIZE_T Bytes +gcoBUFOBJ_IndexBind ( + IN gcoBUFOBJ Index, + IN gceINDEX_TYPE Type, + IN gctUINT32 Offset, + IN gctSIZE_T Count ); -#if VIVANTE_PROFILER_CONTEXT +/* Find min and max index for the index buffer */ gceSTATUS -gcoHARDWARE_GetContext( - IN gcoHARDWARE Hardware, - OUT gctUINT32 * Context +gcoBUFOBJ_IndexGetRange( + IN gcoBUFOBJ Index, + IN gceINDEX_TYPE Type, + IN gctUINT32 Offset, + IN gctUINT32 Count, + OUT gctUINT32 * MinimumIndex, + OUT gctUINT32 * MaximumIndex + ); + +/* Sets a buffer object as dirty */ +gceSTATUS +gcoBUFOBJ_SetDirty( + IN gcoBUFOBJ BufObj + ); + +/* Creates a new buffer if needed */ +gceSTATUS +gcoBUFOBJ_AlignIndexBufferWhenNeeded( + IN gcoBUFOBJ BufObj, + IN gctSIZE_T Offset, + OUT gcoBUFOBJ * AlignedBufObj + ); + +/* Cache operations on whole range */ +gceSTATUS +gcoBUFOBJ_CPUCacheOperation( + IN gcoBUFOBJ BufObj, + IN gceCACHEOPERATION Operation + ); + +/* Cache operations on a specified range */ +gceSTATUS +gcoBUFOBJ_CPUCacheOperation_Range( + IN gcoBUFOBJ BufObj, + IN gctSIZE_T Offset, + IN gctSIZE_T Length, + IN gceCACHEOPERATION Operation + ); + +/* Return size of the bufobj */ +gceSTATUS +gcoBUFOBJ_GetSize( + IN gcoBUFOBJ BufObj, + OUT gctSIZE_T_PTR Size + ); + +/* Return memory node of the bufobj */ +gceSTATUS +gcoBUFOBJ_GetNode( + IN gcoBUFOBJ BufObj, + OUT gcsSURF_NODE_PTR * Node + ); + +/* Handle GPU cache operations */ +gceSTATUS +gcoBUFOBJ_GPUCacheOperation( + gcoBUFOBJ BufObj + ); + +/* Dump buffer. */ +void +gcoBUFOBJ_Dump( + IN gcoBUFOBJ BufObj ); -#endif #ifdef __cplusplus } #endif -#endif /* VIVANTE_NO_3D */ +#endif /* gcdENABLE_3D */ #endif /* __gc_hal_engine_h_ */ 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 4bb6772549ff..7e98d054c341 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -465,6 +465,12 @@ gcsPATH_DATA; gceSTATUS gcoHAL_QueryPathStorage( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif OUT gcsPATH_BUFFER_INFO_PTR Information ); @@ -472,6 +478,12 @@ gcoHAL_QueryPathStorage( gceSTATUS gcoHAL_AssociateCompletion( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcsPATH_DATA_PTR PathData ); @@ -479,6 +491,12 @@ gcoHAL_AssociateCompletion( gceSTATUS gcoHAL_DeassociateCompletion( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcsPATH_DATA_PTR PathData ); @@ -486,6 +504,12 @@ gcoHAL_DeassociateCompletion( gceSTATUS gcoHAL_CheckCompletion( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcsPATH_DATA_PTR PathData ); @@ -493,6 +517,12 @@ gcoHAL_CheckCompletion( gceSTATUS gcoHAL_WaitCompletion( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcsPATH_DATA_PTR PathData ); @@ -500,12 +530,25 @@ gcoHAL_WaitCompletion( gceSTATUS gcoHAL_Flush( IN gcoHAL Hal +#if GC355_PROFILER + , + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth +#endif ); /* Split a harwdare address into pool and offset. */ gceSTATUS gcoHAL_SplitAddress( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctUINT32 Address, OUT gcePOOL * Pool, OUT gctUINT32 * Offset @@ -515,6 +558,12 @@ gcoHAL_SplitAddress( gceSTATUS gcoHAL_CombineAddress( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcePOOL Pool, IN gctUINT32 Offset, OUT gctUINT32 * Address @@ -524,30 +573,54 @@ gcoHAL_CombineAddress( gceSTATUS gcoHAL_ScheduleVideoMemory( IN gcoHAL Hal, - IN gctUINT64 Node +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif + IN gctUINT32 Node ); /* Free linear video memory allocated with gcoHAL_AllocateLinearVideoMemory. */ gceSTATUS gcoHAL_FreeVideoMemory( IN gcoHAL Hal, - IN gctUINT64 Node +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif + IN gctUINT32 Node ); /* Query command buffer attributes. */ gceSTATUS gcoHAL_QueryCommandBuffer( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif OUT gcsCOMMAND_BUFFER_INFO_PTR Information ); /* Allocate and lock linear video memory. */ gceSTATUS gcoHAL_AllocateLinearVideoMemory( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctUINT Size, IN gctUINT Alignment, IN gcePOOL Pool, - OUT gctUINT64 * Node, + OUT gctUINT32 * Node, OUT gctUINT32 * Address, OUT gctPOINTER * Memory ); @@ -556,6 +629,12 @@ gcoHAL_AllocateLinearVideoMemory( gceSTATUS gcoHAL_GetAlignedSurfaceSize( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceSURF_TYPE Type, IN OUT gctUINT32_PTR Width, IN OUT gctUINT32_PTR Height @@ -564,9 +643,15 @@ gcoHAL_GetAlignedSurfaceSize( gceSTATUS gcoHAL_ReserveTask( IN gcoHAL Hal, +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceBLOCK Block, IN gctUINT TaskCount, - IN gctSIZE_T Bytes, + IN gctUINT32 Bytes, OUT gctPOINTER * Memory ); /******************************************************************************\ @@ -577,23 +662,69 @@ gcoHAL_ReserveTask( ** ** The gcoVG object abstracts the VG hardware pipe. */ +#if GC355_PROFILER +void +gcoVG_ProfilerEnableDisable( + IN gcoVG Vg, + IN gctUINT enableGetAPITimes, + IN gctFILE apiTimeFile + ); + +void +gcoVG_ProfilerTreeDepth( + IN gcoVG Vg, + IN gctUINT TreeDepth + ); + +void +gcoVG_ProfilerSetStates( + IN gcoVG Vg, + IN gctUINT treeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth + ); +#endif gctBOOL gcoVG_IsMaskSupported( +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceSURF_FORMAT Format ); gctBOOL gcoVG_IsTargetSupported( +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceSURF_FORMAT Format ); gctBOOL gcoVG_IsImageSupported( +#if GC355_PROFILER + IN gcoVG Vg, + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceSURF_FORMAT Format ); gctUINT8 gcoVG_PackColorComponent( +#if GC355_PROFILER + gcoVG Vg, + gctUINT TreeDepth, + gctUINT saveLayerTreeDepth, + gctUINT varTreeDepth, +#endif gctFLOAT Value ); @@ -606,64 +737,121 @@ gcoVG_Construct( gceSTATUS gcoVG_Destroy( IN gcoVG Vg +#if GC355_PROFILER + , + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth +#endif ); gceSTATUS gcoVG_SetTarget( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Target ); gceSTATUS gcoVG_UnsetTarget( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Surface ); gceSTATUS gcoVG_SetUserToSurface( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT UserToSurface[9] ); gceSTATUS gcoVG_SetSurfaceToImage( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT SurfaceToImage[9] ); gceSTATUS gcoVG_EnableMask( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctBOOL Enable ); gceSTATUS gcoVG_SetMask( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Mask ); gceSTATUS gcoVG_UnsetMask( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Surface ); gceSTATUS gcoVG_FlushMask( IN gcoVG Vg +#if GC355_PROFILER + , + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth +#endif ); gceSTATUS gcoVG_EnableScissor( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctBOOL Enable ); gceSTATUS gcoVG_SetScissor( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctSIZE_T RectangleCount, IN gcsVG_RECT_PTR Rectangles ); @@ -671,18 +859,33 @@ gcoVG_SetScissor( gceSTATUS gcoVG_EnableColorTransform( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctBOOL Enable ); gceSTATUS gcoVG_SetColorTransform( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT ColorTransform[8] ); gceSTATUS gcoVG_SetTileFillColor( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT Red, IN gctFLOAT Green, IN gctFLOAT Blue, @@ -692,6 +895,11 @@ gcoVG_SetTileFillColor( gceSTATUS gcoVG_SetSolidPaint( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctUINT8 Red, IN gctUINT8 Green, IN gctUINT8 Blue, @@ -701,6 +909,11 @@ gcoVG_SetSolidPaint( gceSTATUS gcoVG_SetLinearPaint( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT Constant, IN gctFLOAT StepX, IN gctFLOAT StepY @@ -709,6 +922,11 @@ gcoVG_SetLinearPaint( gceSTATUS gcoVG_SetRadialPaint( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT LinConstant, IN gctFLOAT LinStepX, IN gctFLOAT LinStepY, @@ -723,6 +941,11 @@ gcoVG_SetRadialPaint( gceSTATUS gcoVG_SetPatternPaint( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctFLOAT UConstant, IN gctFLOAT UStepX, IN gctFLOAT UStepY, @@ -735,6 +958,11 @@ gcoVG_SetPatternPaint( gceSTATUS gcoVG_SetColorRamp( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF ColorRamp, IN gceTILE_MODE ColorRampSpreadMode ); @@ -742,6 +970,13 @@ gcoVG_SetColorRamp( gceSTATUS gcoVG_SetPattern( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif + IN gctINT32 width, + IN gctINT32 height, IN gcoSURF Pattern, IN gceTILE_MODE TileMode, IN gceIMAGE_FILTER Filter @@ -750,24 +985,44 @@ gcoVG_SetPattern( gceSTATUS gcoVG_SetImageMode( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceVG_IMAGE Mode ); gceSTATUS gcoVG_SetBlendMode( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceVG_BLEND Mode ); gceSTATUS gcoVG_SetRenderingQuality( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceRENDER_QUALITY Quality ); gceSTATUS gcoVG_SetFillRule( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gceFILL_RULE FillRule ); @@ -780,6 +1035,11 @@ gcoVG_FinalizePath( gceSTATUS gcoVG_Clear( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctINT X, IN gctINT Y, IN gctINT Width, @@ -789,15 +1049,30 @@ gcoVG_Clear( gceSTATUS gcoVG_DrawPath( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcsPATH_DATA_PTR PathData, IN gctFLOAT Scale, IN gctFLOAT Bias, +#if gcdMOVG + IN gctUINT32 Width, + IN gctUINT32 Height, + IN gctFLOAT *Bounds, +#endif IN gctBOOL SoftwareTesselation ); gceSTATUS gcoVG_DrawImage( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Source, IN gcsPOINT_PTR SourceOrigin, IN gcsPOINT_PTR TargetOrigin, @@ -808,22 +1083,38 @@ gcoVG_DrawImage( IN gctINT TargetY, IN gctINT Width, IN gctINT Height, - IN gctBOOL Mask + IN gctBOOL Mask, + IN gctBOOL isDrawImage ); gceSTATUS gcoVG_TesselateImage( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Image, IN gcsVG_RECT_PTR Rectangle, IN gceIMAGE_FILTER Filter, IN gctBOOL Mask, +#if gcdMOVG + IN gctBOOL SoftwareTesselation, + IN gceVG_BLEND BlendMode +#else IN gctBOOL SoftwareTesselation +#endif ); gceSTATUS gcoVG_Blit( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Source, IN gcoSURF Target, IN gcsVG_RECT_PTR SrcRect, @@ -835,6 +1126,11 @@ gcoVG_Blit( gceSTATUS gcoVG_ColorMatrix( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Source, IN gcoSURF Target, IN const gctFLOAT * Matrix, @@ -850,6 +1146,11 @@ gcoVG_ColorMatrix( gceSTATUS gcoVG_SeparableConvolve( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Source, IN gcoSURF Target, IN gctINT KernelWidth, @@ -875,6 +1176,11 @@ gcoVG_SeparableConvolve( gceSTATUS gcoVG_GaussianBlur( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gcoSURF Source, IN gcoSURF Target, IN gctFLOAT StdDeviationX, @@ -894,6 +1200,11 @@ gcoVG_GaussianBlur( gceSTATUS gcoVG_EnableDither( IN gcoVG Vg, +#if GC355_PROFILER + IN gctUINT TreeDepth, + IN gctUINT saveLayerTreeDepth, + IN gctUINT varTreeDepth, +#endif IN gctBOOL Enable ); 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 1d19882217de..d20f00774b98 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -29,15 +29,19 @@ extern "C" { /* Chip models. */ typedef enum _gceCHIPMODEL { + gcv200 = 0x0200, gcv300 = 0x0300, gcv320 = 0x0320, + gcv328 = 0x0328, gcv350 = 0x0350, gcv355 = 0x0355, gcv400 = 0x0400, gcv410 = 0x0410, gcv420 = 0x0420, + gcv428 = 0x0428, gcv450 = 0x0450, gcv500 = 0x0500, + gcv520 = 0x0520, gcv530 = 0x0530, gcv600 = 0x0600, gcv700 = 0x0700, @@ -45,9 +49,16 @@ typedef enum _gceCHIPMODEL gcv860 = 0x0860, gcv880 = 0x0880, gcv1000 = 0x1000, + gcv1500 = 0x1500, gcv2000 = 0x2000, gcv2100 = 0x2100, + gcv2200 = 0x2200, + gcv2500 = 0x2500, + gcv3000 = 0x3000, gcv4000 = 0x4000, + gcv5000 = 0x5000, + gcv5200 = 0x5200, + gcv6400 = 0x6400, } gceCHIPMODEL; @@ -74,7 +85,7 @@ typedef enum _gceFEATURE gcvFEATURE_YUY2_AVERAGING, gcvFEATURE_FLIP_Y, gcvFEATURE_EARLY_Z, - gcvFEATURE_Z_COMPRESSION, + gcvFEATURE_COMPRESSION, gcvFEATURE_MSAA, gcvFEATURE_SPECIAL_ANTI_ALIASING, gcvFEATURE_SPECIAL_MSAA_LOD, @@ -100,9 +111,11 @@ typedef enum _gceFEATURE gcvFEATURE_VG_DOUBLE_BUFFER, gcvFEATURE_MC20, gcvFEATURE_SUPER_TILED, + gcvFEATURE_FAST_CLEAR_FLUSH, gcvFEATURE_2D_FILTERBLIT_PLUS_ALPHABLEND, gcvFEATURE_2D_DITHER, gcvFEATURE_2D_A8_TARGET, + gcvFEATURE_2D_A8_NO_ALPHA, gcvFEATURE_2D_FILTERBLIT_FULLROTATION, gcvFEATURE_2D_BITBLIT_FULLROTATION, gcvFEATURE_WIDE_LINE, @@ -125,51 +138,198 @@ typedef enum _gceFEATURE gcvFEATURE_TEXTURE_10_10_10_2, gcvFEATURE_TEXTURE_ANISOTROPIC_FILTERING, gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT, - gcvFEATURE_2D_ROTATION_STALL_FIX, + gcvFEATURE_2D_ROTATION_STALL_FIX, gcvFEATURE_2D_MULTI_SOURCE_BLT_EX, - gcvFEATURE_BUG_FIXES10, + gcvFEATURE_BUG_FIXES10, gcvFEATURE_2D_MINOR_TILING, /* Supertiled compressed textures are supported. */ gcvFEATURE_TEX_COMPRRESSION_SUPERTILED, gcvFEATURE_FAST_MSAA, gcvFEATURE_BUG_FIXED_INDEXED_TRIANGLE_STRIP, - gcvFEATURE_TEXTURE_TILED_READ, + gcvFEATURE_TEXTURE_TILE_STATUS_READ, gcvFEATURE_DEPTH_BIAS_FIX, gcvFEATURE_RECT_PRIMITIVE, - gcvFEATURE_BUG_FIXES11, - gcvFEATURE_SUPERTILED_TEXTURE, + gcvFEATURE_BUG_FIXES11, + gcvFEATURE_SUPERTILED_TEXTURE, gcvFEATURE_2D_NO_COLORBRUSH_INDEX8, gcvFEATURE_RS_YUV_TARGET, gcvFEATURE_2D_FC_SOURCE, - gcvFEATURE_PE_DITHER_FIX, + gcvFEATURE_2D_CC_NOAA_SOURCE, + gcvFEATURE_PE_DITHER_FIX, gcvFEATURE_2D_YUV_SEPARATE_STRIDE, gcvFEATURE_FRUSTUM_CLIP_FIX, + gcvFEATURE_TEXTURE_SWIZZLE, + gcvFEATURE_PRIMITIVE_RESTART, gcvFEATURE_TEXTURE_LINEAR, gcvFEATURE_TEXTURE_YUV_ASSEMBLER, + gcvFEATURE_LINEAR_RENDER_TARGET, + gcvFEATURE_SHADER_HAS_ATOMIC, gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE, + gcvFEATURE_SHADER_ENHANCEMENTS2, + gcvFEATURE_BUG_FIXES7, + gcvFEATURE_SHADER_HAS_RTNE, + gcvFEATURE_SHADER_HAS_EXTRA_INSTRUCTIONS2, + gcvFEATURE_SHADER_ENHANCEMENTS3, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING, - gcvFEATURE_BUGFIX15, + gcvFEATURE_SINGLE_BUFFER, + gcvFEATURE_OCCLUSION_QUERY, gcvFEATURE_2D_GAMMA, gcvFEATURE_2D_COLOR_SPACE_CONVERSION, gcvFEATURE_2D_SUPER_TILE_VERSION, + gcvFEATURE_HALTI0, + gcvFEATURE_HALTI1, + gcvFEATURE_HALTI2, gcvFEATURE_2D_MIRROR_EXTENSION, + gcvFEATURE_TEXTURE_ASTC, gcvFEATURE_2D_SUPER_TILE_V1, gcvFEATURE_2D_SUPER_TILE_V2, gcvFEATURE_2D_SUPER_TILE_V3, gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2, - gcvFEATURE_ELEMENT_INDEX_UINT, + gcvFEATURE_NEW_RA, + gcvFEATURE_BUG_FIXED_IMPLICIT_PRIMITIVE_RESTART, + gcvFEATURE_PE_MULTI_RT_BLEND_ENABLE_CONTROL, + gcvFEATURE_SMALL_MSAA, /* An upgraded version of Fast MSAA */ + gcvFEATURE_VERTEX_INST_ID_AS_ATTRIBUTE, + gcvFEATURE_DUAL_16, + gcvFEATURE_BRANCH_ON_IMMEDIATE_REG, gcvFEATURE_2D_COMPRESSION, + gcvFEATURE_TPC_COMPRESSION, gcvFEATURE_2D_OPF_YUV_OUTPUT, + gcvFEATURE_2D_FILTERBLIT_A8_ALPHA, gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT, + gcvFEATURE_V2_COMPRESSION_Z16_FIX, + + gcvFEATURE_VERTEX_INST_ID_AS_INTEGER, gcvFEATURE_2D_YUV_MODE, - gcvFEATURE_DECOMPRESS_Z16, - gcvFEATURE_LINEAR_RENDER_TARGET, - gcvFEATURE_BUG_FIXES8, - gcvFEATURE_HALTI2, + gcvFEATURE_ACE, + gcvFEATURE_COLOR_COMPRESSION, + + gcvFEATURE_32BPP_COMPONENT_TEXTURE_CHANNEL_SWIZZLE, + gcvFEATURE_64BPP_HW_CLEAR_SUPPORT, + gcvFEATURE_TX_LERP_PRECISION_FIX, + gcvFEATURE_COMPRESSION_V2, gcvFEATURE_MMU, + gcvFEATURE_COMPRESSION_V3, + gcvFEATURE_TX_DECOMPRESSOR, + gcvFEATURE_MRT_TILE_STATUS_BUFFER, + gcvFEATURE_COMPRESSION_V1, + gcvFEATURE_V1_COMPRESSION_Z16_DECOMPRESS_FIX, + gcvFEATURE_RTT, + gcvFEATURE_GENERICS, + gcvFEATURE_2D_ONE_PASS_FILTER, + gcvFEATURE_2D_ONE_PASS_FILTER_TAP, + gcvFEATURE_2D_POST_FLIP, + gcvFEATURE_2D_PIXEL_ALIGNMENT, + gcvFEATURE_CORRECT_AUTO_DISABLE_COUNT, + gcvFEATURE_CORRECT_AUTO_DISABLE_COUNT_WIDTH, + + gcvFEATURE_HALTI3, + gcvFEATURE_EEZ, + gcvFEATURE_INTEGER_PIPE_FIX, + gcvFEATURE_PSOUTPUT_MAPPING, + gcvFEATURE_8K_RT_FIX, + gcvFEATURE_TX_TILE_STATUS_MAPPING, + gcvFEATURE_SRGB_RT_SUPPORT, + gcvFEATURE_UNIFORM_APERTURE, + gcvFEATURE_TEXTURE_16K, + gcvFEATURE_PA_FARZCLIPPING_FIX, + gcvFEATURE_PE_DITHER_COLORMASK_FIX, + gcvFEATURE_ZSCALE_FIX, + + gcvFEATURE_MULTI_PIXELPIPES, + gcvFEATURE_PIPE_CL, + + gcvFEATURE_BUG_FIXES18, + + gcvFEATURE_UNIFIED_SAMPLERS, + gcvFEATURE_CL_PS_WALKER, + gcvFEATURE_NEW_HZ, + + gcvFEATURE_TX_FRAC_PRECISION_6BIT, + gcvFEATURE_SH_INSTRUCTION_PREFETCH, + gcvFEATURE_PROBE, + + gcvFEATURE_BUG_FIXES8, + gcvFEATURE_2D_ALL_QUAD, + + gcvFEATURE_SINGLE_PIPE_HALTI1, + + gcvFEATURE_BLOCK_SIZE_16x16, + + gcvFEATURE_NO_USER_CSC, + gcvFEATURE_ANDROID_ONLY, + gcvFEATURE_HAS_PRODUCTID, + + gcvFEATURE_V2_MSAA_COMP_FIX, + + gcvFEATURE_S8_ONLY_RENDERING, + + gcvFEATURE_SEPARATE_SRC_DST, + + gcvFEATURE_FE_START_VERTEX_SUPPORT, + gcvFEATURE_RS_DEPTHSTENCIL_NATIVE_SUPPORT, + + /* Insert features above this comment only. */ + gcvFEATURE_COUNT /* Not a feature. */ } gceFEATURE; +/* Chip SWWA. */ +typedef enum _gceSWWA +{ + gcvSWWA_601 = 0, + gcvSWWA_706, + gcvSWWA_1163, + gcvSWWA_1165, + /* Insert SWWA above this comment only. */ + gcvSWWA_COUNT /* Not a SWWA. */ +} +gceSWWA; + + +/* Option Set*/ +typedef enum _gceOPITON +{ + /* HW setting we take PREFER */ + gcvOPTION_PREFER_MULTIPIPE_RS = 0, + gcvOPTION_PREFER_ZCONVERT_BYPASS =1, + + + gcvOPTION_HW_NULL = 50, + gcvOPTION_PRINT_OPTION = 51, + + gcvOPTION_FBO_PREFER_MEM = 80, + + /* Insert option above this comment only */ + gcvOPTION_COUNT /* Not a OPTION*/ +} +gceOPTION; + +typedef enum _gceFRAMEINFO +{ + gcvFRAMEINFO_FRAME_NUM = 0, + gcvFRAMEINFO_DRAW_NUM = 1, + gcvFRAMEINFO_DRAW_DUAL16_NUM = 2, + gcvFRAMEINFO_DRAW_FL32_NUM = 3, + + + gcvFRAMEINFO_COUNT, +} +gceFRAMEINFO; + +typedef enum _gceFRAMEINFO_OP +{ + gcvFRAMEINFO_OP_INC = 0, + gcvFRAMEINFO_OP_DEC = 1, + gcvFRAMEINFO_OP_ZERO = 2, + gcvFRAMEINFO_OP_GET = 3, + + + gcvFRAMEINFO_OP_COUNT, +} +gceFRAMEINFO_OP; + + /* Chip Power Status. */ typedef enum _gceCHIPPOWERSTATE { @@ -209,7 +369,7 @@ typedef enum _gceSURF_TYPE gcvSURF_DEPTH, gcvSURF_BITMAP, gcvSURF_TILE_STATUS, - gcvSURF_IMAGE, + gcvSURF_IMAGE, gcvSURF_MASK, gcvSURF_SCISSOR, gcvSURF_HIERARCHICAL_DEPTH, @@ -220,15 +380,28 @@ typedef enum _gceSURF_TYPE gcvSURF_NO_VIDMEM = 0x200, /* Used to allocate surfaces with no underlying vidmem node. In Android, vidmem node is allocated by another process. */ gcvSURF_CACHEABLE = 0x400, /* Used to allocate a cacheable surface */ + gcvSURF_FLIP = 0x800, /* The Resolve Target the will been flip resolve from RT */ + gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */ gcvSURF_LINEAR = 0x2000, - gcvSURF_VG = 0x4000, + + gcvSURF_CREATE_AS_TEXTURE = 0x4000, /* create it as a texture */ + + gcvSURF_PROTECTED_CONTENT = 0x8000, /* create it as content protected */ + + /* Create it as no compression, valid on when it has tile status. */ + gcvSURF_NO_COMPRESSION = 0x40000, + + gcvSURF_CONTIGUOUS = 0x20000, /*create it as contiguous */ gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE | gcvSURF_LINEAR, + gcvSURF_RENDER_TARGET_LINEAR = gcvSURF_RENDER_TARGET + | gcvSURF_LINEAR, + gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET | gcvSURF_NO_TILE_STATUS, @@ -268,6 +441,14 @@ typedef enum _gceSURF_USAGE } gceSURF_USAGE; +typedef enum _gceSURF_COLOR_SPACE +{ + gcvSURF_COLOR_SPACE_UNKNOWN, + gcvSURF_COLOR_SPACE_LINEAR, + gcvSURF_COLOR_SPACE_NONLINEAR, +} +gceSURF_COLOR_SPACE; + typedef enum _gceSURF_COLOR_TYPE { gcvSURF_COLOR_UNKNOWN = 0, @@ -286,18 +467,35 @@ typedef enum _gceSURF_ROTATION gcvSURF_FLIP_X, gcvSURF_FLIP_Y, - gcvSURF_POST_FLIP_X = 0x40000000, + gcvSURF_POST_FLIP_X = 0x40000000, gcvSURF_POST_FLIP_Y = 0x80000000, } gceSURF_ROTATION; +/* Surface flag */ +typedef enum _gceSURF_FLAG +{ + /* None flag */ + gcvSURF_FLAG_NONE = 0x0, + /* content is preserved after swap */ + gcvSURF_FLAG_CONTENT_PRESERVED = 0x1, + /* content is updated after swap*/ + gcvSURF_FLAG_CONTENT_UPDATED = 0x2, + /* content is y inverted */ + gcvSURF_FLAG_CONTENT_YINVERTED = 0x4, + /* content is protected */ + gcvSURF_FLAG_CONTENT_PROTECTED = 0x8, + /* surface is contiguous. */ + gcvSURF_FLAG_CONTIGUOUS = (1 << 4), +} +gceSURF_FLAG; + typedef enum _gceMIPMAP_IMAGE_FORMAT { gcvUNKNOWN_MIPMAP_IMAGE_FORMAT = -2 } gceMIPMAP_IMAGE_FORMAT; - /* Surface formats. */ typedef enum _gceSURF_FORMAT { @@ -336,6 +534,10 @@ typedef enum _gceSURF_FORMAT gcvSURF_R8G8B8X8, gcvSURF_R5G5B5X1, gcvSURF_R4G4B4X4, + gcvSURF_X16R16G16B16_2_A8R8G8B8, + gcvSURF_A16R16G16B16_2_A8R8G8B8, + gcvSURF_A32R32G32B32_2_G32R32F, + gcvSURF_A32R32G32B32_4_A8R8G8B8, /* BGR formats. */ gcvSURF_A4B4G4R4 = 300, @@ -360,6 +562,10 @@ typedef enum _gceSURF_FORMAT gcvSURF_B4G4R4X4, gcvSURF_B5G5R5X1, gcvSURF_X2B10G10R10, + gcvSURF_B8G8R8_SNORM, + gcvSURF_X8B8G8R8_SNORM, + gcvSURF_A8B8G8R8_SNORM, + gcvSURF_A8B12G12R12_2_A8R8G8B8, /* Compressed formats. */ gcvSURF_DXT1 = 400, @@ -397,6 +603,12 @@ typedef enum _gceSURF_FORMAT gcvSURF_D24S8, gcvSURF_D32, gcvSURF_D24X8, + gcvSURF_D32F, + gcvSURF_S8D32F, + gcvSURF_S8D32F_1_G32R32F, + gcvSURF_S8D32F_2_A8R8G8B8, + gcvSURF_D24S8_1_A8R8G8B8, + gcvSURF_S8, /* Alpha formats. */ gcvSURF_A4 = 700, @@ -448,6 +660,11 @@ typedef enum _gceSURF_FORMAT gcvSURF_X32G32R32, gcvSURF_A32R32, gcvSURF_RG16, + gcvSURF_R8_SNORM, + gcvSURF_G8R8_SNORM, + + gcvSURF_R8_1_X8R8G8B8, + gcvSURF_G8R8_1_X8R8G8B8, /* Floating point formats. */ gcvSURF_R16F = 1200, @@ -472,10 +689,159 @@ typedef enum _gceSURF_FORMAT gcvSURF_L32F, gcvSURF_A32L32F, gcvSURF_A32R32F, - + gcvSURF_E5B9G9R9, + gcvSURF_B10G11R11F, + + gcvSURF_X16B16G16R16F_2_A8R8G8B8, + gcvSURF_A16B16G16R16F_2_A8R8G8B8, + gcvSURF_G32R32F_2_A8R8G8B8, + gcvSURF_X32B32G32R32F_2_G32R32F, + gcvSURF_A32B32G32R32F_2_G32R32F, + gcvSURF_X32B32G32R32F_4_A8R8G8B8, + gcvSURF_A32B32G32R32F_4_A8R8G8B8, + + gcvSURF_R16F_1_A4R4G4B4, + gcvSURF_G16R16F_1_A8R8G8B8, + gcvSURF_B16G16R16F_2_A8R8G8B8, + + gcvSURF_R32F_1_A8R8G8B8, + gcvSURF_B32G32R32F_3_A8R8G8B8, + + gcvSURF_B10G11R11F_1_A8R8G8B8, + + + /* sRGB format. */ + gcvSURF_SBGR8 = 1400, + gcvSURF_A8_SBGR8, + gcvSURF_X8_SBGR8, + + /* Integer formats. */ + gcvSURF_R8I = 1500, + gcvSURF_R8UI, + gcvSURF_R16I, + gcvSURF_R16UI, + gcvSURF_R32I, + gcvSURF_R32UI, + gcvSURF_X8R8I, + gcvSURF_G8R8I, + gcvSURF_X8R8UI, + gcvSURF_G8R8UI, + gcvSURF_X16R16I, + gcvSURF_G16R16I, + gcvSURF_X16R16UI, + gcvSURF_G16R16UI, + gcvSURF_X32R32I, + gcvSURF_G32R32I, + gcvSURF_X32R32UI, + gcvSURF_G32R32UI, + gcvSURF_X8G8R8I, + gcvSURF_B8G8R8I, + gcvSURF_X8G8R8UI, + gcvSURF_B8G8R8UI, + gcvSURF_X16G16R16I, + gcvSURF_B16G16R16I, + gcvSURF_X16G16R16UI, + gcvSURF_B16G16R16UI, + gcvSURF_X32G32R32I, + gcvSURF_B32G32R32I, + gcvSURF_X32G32R32UI, + gcvSURF_B32G32R32UI, + gcvSURF_X8B8G8R8I, + gcvSURF_A8B8G8R8I, + gcvSURF_X8B8G8R8UI, + gcvSURF_A8B8G8R8UI, + gcvSURF_X16B16G16R16I, + gcvSURF_A16B16G16R16I, + gcvSURF_X16B16G16R16UI, + gcvSURF_A16B16G16R16UI, + gcvSURF_X32B32G32R32I, + gcvSURF_A32B32G32R32I, + gcvSURF_X32B32G32R32UI, + gcvSURF_A32B32G32R32UI, + gcvSURF_A2B10G10R10UI, + gcvSURF_G32R32I_2_A8R8G8B8, + gcvSURF_G32R32UI_2_A8R8G8B8, + gcvSURF_X16B16G16R16I_2_A8R8G8B8, + gcvSURF_A16B16G16R16I_2_A8R8G8B8, + gcvSURF_X16B16G16R16UI_2_A8R8G8B8, + gcvSURF_A16B16G16R16UI_2_A8R8G8B8, + gcvSURF_X32B32G32R32I_2_G32R32I, + gcvSURF_A32B32G32R32I_2_G32R32I, + gcvSURF_X32B32G32R32I_3_A8R8G8B8, + gcvSURF_A32B32G32R32I_4_A8R8G8B8, + gcvSURF_X32B32G32R32UI_2_G32R32UI, + gcvSURF_A32B32G32R32UI_2_G32R32UI, + gcvSURF_X32B32G32R32UI_3_A8R8G8B8, + gcvSURF_A32B32G32R32UI_4_A8R8G8B8, + gcvSURF_A2B10G10R10UI_1_A8R8G8B8, + gcvSURF_A8B8G8R8I_1_A8R8G8B8, + gcvSURF_A8B8G8R8UI_1_A8R8G8B8, + gcvSURF_R8I_1_A4R4G4B4, + gcvSURF_R8UI_1_A4R4G4B4, + gcvSURF_R16I_1_A4R4G4B4, + gcvSURF_R16UI_1_A4R4G4B4, + gcvSURF_R32I_1_A8R8G8B8, + gcvSURF_R32UI_1_A8R8G8B8, + gcvSURF_X8R8I_1_A4R4G4B4, + gcvSURF_X8R8UI_1_A4R4G4B4, + gcvSURF_G8R8I_1_A4R4G4B4, + gcvSURF_G8R8UI_1_A4R4G4B4, + gcvSURF_X16R16I_1_A4R4G4B4, + gcvSURF_X16R16UI_1_A4R4G4B4, + gcvSURF_G16R16I_1_A8R8G8B8, + gcvSURF_G16R16UI_1_A8R8G8B8, + gcvSURF_X32R32I_1_A8R8G8B8, + gcvSURF_X32R32UI_1_A8R8G8B8, + gcvSURF_X8G8R8I_1_A4R4G4B4, + gcvSURF_X8G8R8UI_1_A4R4G4B4, + gcvSURF_B8G8R8I_1_A8R8G8B8, + gcvSURF_B8G8R8UI_1_A8R8G8B8, + gcvSURF_B16G16R16I_2_A8R8G8B8, + gcvSURF_B16G16R16UI_2_A8R8G8B8, + gcvSURF_B32G32R32I_3_A8R8G8B8, + gcvSURF_B32G32R32UI_3_A8R8G8B8, + + /* ASTC formats. */ + gcvSURF_ASTC4x4 = 1600, + gcvSURF_ASTC5x4, + gcvSURF_ASTC5x5, + gcvSURF_ASTC6x5, + gcvSURF_ASTC6x6, + gcvSURF_ASTC8x5, + gcvSURF_ASTC8x6, + gcvSURF_ASTC8x8, + gcvSURF_ASTC10x5, + gcvSURF_ASTC10x6, + gcvSURF_ASTC10x8, + gcvSURF_ASTC10x10, + gcvSURF_ASTC12x10, + gcvSURF_ASTC12x12, + gcvSURF_ASTC4x4_SRGB, + gcvSURF_ASTC5x4_SRGB, + gcvSURF_ASTC5x5_SRGB, + gcvSURF_ASTC6x5_SRGB, + gcvSURF_ASTC6x6_SRGB, + gcvSURF_ASTC8x5_SRGB, + gcvSURF_ASTC8x6_SRGB, + gcvSURF_ASTC8x8_SRGB, + gcvSURF_ASTC10x5_SRGB, + gcvSURF_ASTC10x6_SRGB, + gcvSURF_ASTC10x8_SRGB, + gcvSURF_ASTC10x10_SRGB, + gcvSURF_ASTC12x10_SRGB, + gcvSURF_ASTC12x12_SRGB, + + gcvSURF_FORMAT_COUNT } gceSURF_FORMAT; +/* Format modifiers. */ +typedef enum _gceSURF_FORMAT_MODE +{ + gcvSURF_FORMAT_OCL = 0x80000000 +} +gceSURF_FORMAT_MODE; + /* Pixel swizzle modes. */ typedef enum _gceSURF_SWIZZLE { @@ -505,11 +871,10 @@ typedef enum _gceSURF_ALIGNMENT gcvSURF_SIXTEEN, gcvSURF_SUPER_TILED, gcvSURF_SPLIT_TILED, - gcvSURF_SPLIT_SUPER_TILED, + gcvSURF_SPLIT_SUPER_TILED } gceSURF_ALIGNMENT; - /* Surface Addressing. */ typedef enum _gceSURF_ADDRESSING { @@ -667,6 +1032,7 @@ typedef enum _gce2D_COMMAND gcv2D_HOR_FILTER, gcv2D_VER_FILTER, gcv2D_MULTI_SOURCE_BLT, + gcv2D_FILTER_BLT, } gce2D_COMMAND; @@ -677,6 +1043,7 @@ typedef enum _gce2D_TILE_STATUS_CONFIG gcv2D_TSC_COMPRESSED = 0x00000002, gcv2D_TSC_DOWN_SAMPLER = 0x00000004, gcv2D_TSC_2D_COMPRESSED = 0x00000008, + gcv2D_TSC_TPC_COMPRESSED = 0x00000010, } gce2D_TILE_STATUS_CONFIG; @@ -704,6 +1071,8 @@ typedef enum _gce2D_STATE gcv2D_STATE_EN_GAMMA, gcv2D_STATE_DE_GAMMA, gcv2D_STATE_MULTI_SRC_BLIT_UNIFIED_DST_RECT, + gcv2D_STATE_PROFILE_ENABLE, + gcv2D_STATE_XRGB_ENABLE, gcv2D_STATE_ARRAY_EN_GAMMA = 0x10001, gcv2D_STATE_ARRAY_DE_GAMMA, @@ -712,7 +1081,30 @@ typedef enum _gce2D_STATE } gce2D_STATE; -#ifndef VIVANTE_NO_3D +typedef enum _gce2D_STATE_PROFILE +{ + gcv2D_STATE_PROFILE_NONE = 0x0, + gcv2D_STATE_PROFILE_COMMAND = 0x1, + gcv2D_STATE_PROFILE_SURFACE = 0x2, + gcv2D_STATE_PROFILE_ALL = 0xFFFF, +} +gce2D_STATE_PROFILE; + +/* Texture object types */ +typedef enum _gceTEXTURE_TYPE +{ + gcvTEXTURE_UNKNOWN = 0, + gcvTEXTURE_1D, + gcvTEXTURE_2D, + gcvTEXTURE_3D, + gcvTEXTURE_CUBEMAP, + gcvTEXTURE_1D_ARRAY, + gcvTEXTURE_2D_ARRAY, + gcvTEXTURE_EXTERNAL +} +gceTEXTURE_TYPE; + +#if gcdENABLE_3D /* Texture functions. */ typedef enum _gceTEXTURE_FUNCTION { @@ -746,7 +1138,7 @@ typedef enum _gceTEXTURE_CHANNEL gcvFROM_ONE_MINUS_ALPHA } gceTEXTURE_CHANNEL; -#endif /* VIVANTE_NO_3D */ +#endif /* gcdENABLE_3D */ /* Filter types. */ typedef enum _gceFILTER_TYPE @@ -777,12 +1169,22 @@ gceENDIAN_HINT; /* Tiling modes. */ typedef enum _gceTILING { - gcvLINEAR = 0, - gcvTILED, - gcvSUPERTILED, - gcvMULTI_TILED, - gcvMULTI_SUPERTILED, - gcvMINORTILED, + gcvINVALIDTILED = 0x0, /* Invalid tiling */ + /* Tiling basic modes enum'ed in power of 2. */ + gcvLINEAR = 0x1, /* No tiling. */ + gcvTILED = 0x2, /* 4x4 tiling. */ + gcvSUPERTILED = 0x4, /* 64x64 tiling. */ + gcvMINORTILED = 0x8, /* 2x2 tiling. */ + + /* Tiling special layouts. */ + gcvTILING_SPLIT_BUFFER = 0x100, + + /* Tiling combination layouts. */ + gcvMULTI_TILED = gcvTILED + | gcvTILING_SPLIT_BUFFER, + + gcvMULTI_SUPERTILED = gcvSUPERTILED + | gcvTILING_SPLIT_BUFFER, } gceTILING; @@ -822,7 +1224,9 @@ typedef enum _gceHARDWARE_TYPE gcvHARDWARE_3D = 0x01, gcvHARDWARE_2D = 0x02, gcvHARDWARE_VG = 0x04, - +#if gcdMULTI_GPU_AFFINITY + gcvHARDWARE_OCL = 0x05, +#endif gcvHARDWARE_3D2D = gcvHARDWARE_3D | gcvHARDWARE_2D } gceHARDWARE_TYPE; @@ -856,6 +1260,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 { @@ -871,18 +1286,18 @@ gceKERNEL_WHERE; /* Hardware blocks. */ typedef enum _gceBLOCK { - gcvBLOCK_COMMAND, - gcvBLOCK_TESSELLATOR, - gcvBLOCK_TESSELLATOR2, - gcvBLOCK_TESSELLATOR3, - gcvBLOCK_RASTER, - gcvBLOCK_VG, - gcvBLOCK_VG2, - gcvBLOCK_VG3, - gcvBLOCK_PIXEL, - - /* Number of defined blocks. */ - gcvBLOCK_COUNT + gcvBLOCK_COMMAND, + gcvBLOCK_TESSELLATOR, + gcvBLOCK_TESSELLATOR2, + gcvBLOCK_TESSELLATOR3, + gcvBLOCK_RASTER, + gcvBLOCK_VG, + gcvBLOCK_VG2, + gcvBLOCK_VG3, + gcvBLOCK_PIXEL, + + /* Number of defined blocks. */ + gcvBLOCK_COUNT } gceBLOCK; #endif @@ -895,43 +1310,271 @@ typedef enum _gceDEBUG_MESSAGE_TYPE } gceDEBUG_MESSAGE_TYPE; -typedef enum _gceSPECIAL_HINT +/* Shading format. */ +typedef enum _gceSHADING { - gceSPECIAL_HINT0, - gceSPECIAL_HINT1, - gceSPECIAL_HINT2, - gceSPECIAL_HINT3, - /* For disable dynamic stream/index */ - gceSPECIAL_HINT4 + gcvSHADING_SMOOTH, + gcvSHADING_FLAT_D3D, + gcvSHADING_FLAT_OPENGL, } -gceSPECIAL_HINT; +gceSHADING; -typedef enum _gceMACHINECODE +/* Culling modes. */ +typedef enum _gceCULL { - gcvMACHINECODE_HOVERJET0 = 0x0, - gcvMACHINECODE_HOVERJET1 , + gcvCULL_NONE, + gcvCULL_CCW, + gcvCULL_CW, +} +gceCULL; - gcvMACHINECODE_TAIJI0 , - gcvMACHINECODE_TAIJI1 , - gcvMACHINECODE_TAIJI2 , +/* Fill modes. */ +typedef enum _gceFILL +{ + gcvFILL_POINT, + gcvFILL_WIRE_FRAME, + gcvFILL_SOLID, +} +gceFILL; - gcvMACHINECODE_ANTUTU0 , +/* Compare modes. */ +typedef enum _gceCOMPARE +{ + gcvCOMPARE_INVALID = 0, + gcvCOMPARE_NEVER, + gcvCOMPARE_NOT_EQUAL, + gcvCOMPARE_LESS, + gcvCOMPARE_LESS_OR_EQUAL, + gcvCOMPARE_EQUAL, + gcvCOMPARE_GREATER, + gcvCOMPARE_GREATER_OR_EQUAL, + gcvCOMPARE_ALWAYS, +} +gceCOMPARE; - gcvMACHINECODE_GLB27_RELEASE_0, - gcvMACHINECODE_GLB27_RELEASE_1, +/* Stencil modes. */ +typedef enum _gceSTENCIL_MODE +{ + gcvSTENCIL_NONE, + gcvSTENCIL_SINGLE_SIDED, + gcvSTENCIL_DOUBLE_SIDED, +} +gceSTENCIL_MODE; + +/* Stencil operations. */ +typedef enum _gceSTENCIL_OPERATION +{ + gcvSTENCIL_KEEP, + gcvSTENCIL_REPLACE, + gcvSTENCIL_ZERO, + gcvSTENCIL_INVERT, + gcvSTENCIL_INCREMENT, + gcvSTENCIL_DECREMENT, + gcvSTENCIL_INCREMENT_SATURATE, + gcvSTENCIL_DECREMENT_SATURATE, + gcvSTENCIL_OPERATION_INVALID = -1 +} +gceSTENCIL_OPERATION; + +/* Stencil selection. */ +typedef enum _gceSTENCIL_WHERE +{ + gcvSTENCIL_FRONT, + gcvSTENCIL_BACK, +} +gceSTENCIL_WHERE; + +/* Texture addressing selection. */ +typedef enum _gceTEXTURE_WHICH +{ + gcvTEXTURE_S, + gcvTEXTURE_T, + gcvTEXTURE_R, +} +gceTEXTURE_WHICH; + +/* Texture addressing modes. */ +typedef enum _gceTEXTURE_ADDRESSING +{ + gcvTEXTURE_INVALID = 0, + gcvTEXTURE_CLAMP, + gcvTEXTURE_WRAP, + gcvTEXTURE_MIRROR, + gcvTEXTURE_BORDER, + gcvTEXTURE_MIRROR_ONCE, +} +gceTEXTURE_ADDRESSING; + +/* Texture filters. */ +typedef enum _gceTEXTURE_FILTER +{ + gcvTEXTURE_NONE, + gcvTEXTURE_POINT, + gcvTEXTURE_LINEAR, + gcvTEXTURE_ANISOTROPIC, +} +gceTEXTURE_FILTER; + +typedef enum _gceTEXTURE_COMPONENT +{ + gcvTEXTURE_COMPONENT_R, + gcvTEXTURE_COMPONENT_G, + gcvTEXTURE_COMPONENT_B, + gcvTEXTURE_COMPONENT_A, + + gcvTEXTURE_COMPONENT_NUM, +} gceTEXTURE_COMPONENT; + +/* Texture swizzle modes. */ +typedef enum _gceTEXTURE_SWIZZLE +{ + gcvTEXTURE_SWIZZLE_R = 0, + gcvTEXTURE_SWIZZLE_G, + gcvTEXTURE_SWIZZLE_B, + gcvTEXTURE_SWIZZLE_A, + gcvTEXTURE_SWIZZLE_0, + gcvTEXTURE_SWIZZLE_1, + + gcvTEXTURE_SWIZZLE_INVALID, +} gceTEXTURE_SWIZZLE; + +typedef enum _gceTEXTURE_COMPARE_MODE +{ + gcvTEXTURE_COMPARE_MODE_INVALID = 0, + gcvTEXTURE_COMPARE_MODE_NONE, + gcvTEXTURE_COMPARE_MODE_REF, +} gceTEXTURE_COMPARE_MODE; - gcvMACHINECODE_WAVESCAPE0 , - gcvMACHINECODE_WAVESCAPE1 , +/* Pixel output swizzle modes. */ +typedef enum _gcePIXEL_SWIZZLE +{ + gcvPIXEL_SWIZZLE_R = gcvTEXTURE_SWIZZLE_R, + gcvPIXEL_SWIZZLE_G = gcvTEXTURE_SWIZZLE_G, + gcvPIXEL_SWIZZLE_B = gcvTEXTURE_SWIZZLE_B, + gcvPIXEL_SWIZZLE_A = gcvTEXTURE_SWIZZLE_A, + + gcvPIXEL_SWIZZLE_INVALID, +} gcePIXEL_SWIZZLE; + +/* Primitive types. */ +typedef enum _gcePRIMITIVE +{ + gcvPRIMITIVE_POINT_LIST, + gcvPRIMITIVE_LINE_LIST, + gcvPRIMITIVE_LINE_STRIP, + gcvPRIMITIVE_LINE_LOOP, + gcvPRIMITIVE_TRIANGLE_LIST, + gcvPRIMITIVE_TRIANGLE_STRIP, + gcvPRIMITIVE_TRIANGLE_FAN, + gcvPRIMITIVE_RECTANGLE, +} +gcePRIMITIVE; + +/* Index types. */ +typedef enum _gceINDEX_TYPE +{ + gcvINDEX_8, + gcvINDEX_16, + gcvINDEX_32, +} +gceINDEX_TYPE; + +/* Multi GPU rendering modes. */ +typedef enum _gceMULTI_GPU_RENDERING_MODE +{ + gcvMULTI_GPU_RENDERING_MODE_OFF, + gcvMULTI_GPU_RENDERING_MODE_SPLIT_WIDTH, + gcvMULTI_GPU_RENDERING_MODE_SPLIT_HEIGHT, + gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_64x64, + gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_128x64, + gcvMULTI_GPU_RENDERING_MODE_INTERLEAVED_128x128 +} +gceMULTI_GPU_RENDERING_MODE; + +typedef enum _gceCORE_3D_MASK +{ + gcvCORE_3D_0_MASK = (1 << 0), + gcvCORE_3D_1_MASK = (1 << 1), + + gcvCORE_3D_ALL_MASK = (0xFFFF) +} +gceCORE_3D_MASK; + +typedef enum _gceCORE_3D_ID +{ + gcvCORE_3D_0_ID = 0, + gcvCORE_3D_1_ID = 1, - gcvMACHINECODE_NENAMARKV2_4_0 , - gcvMACHINECODE_NENAMARKV2_4_1 , + gcvCORE_3D_ID_INVALID = ~0UL +} +gceCORE_3D_ID; + +typedef enum _gceMULTI_GPU_MODE +{ + gcvMULTI_GPU_MODE_COMBINED = 0, + gcvMULTI_GPU_MODE_INDEPENDENT = 1 +} +gceMULTI_GPU_MODE; + +typedef enum _gceMACHINECODE +{ + gcvMACHINECODE_ANTUTU0 = 0x0, + + gcvMACHINECODE_GLB27_RELEASE_0, gcvMACHINECODE_GLB25_RELEASE_0, gcvMACHINECODE_GLB25_RELEASE_1, gcvMACHINECODE_GLB25_RELEASE_2, + + /* keep it as the last enum */ + gcvMACHINECODE_COUNT } gceMACHINECODE; +typedef enum _gceUNIFORMCVT +{ + gcvUNIFORMCVT_NONE = 0, + gcvUNIFORMCVT_TO_BOOL, + gcvUNIFORMCVT_TO_FLOAT, +} gceUNIFORMCVT; + +typedef enum _gceHAL_ARG_VERSION +{ + gcvHAL_ARG_VERSION_V1 = 0x0, +} +gceHAL_ARG_VERSION; + + +/* +* Bit of a requirment is 1 means requirement is a must, 0 means requirement can +* be ignored. +*/ +#define gcvALLOC_FLAG_CONTIGUOUS_BIT 0 +#define gcvALLOC_FLAG_CACHEABLE_BIT 1 +#define gcvALLOC_FLAG_SECURITY_BIT 2 +#define gcvALLOC_FLAG_NON_CONTIGUOUS_BIT 3 +#define gcvALLOC_FLAG_MEMLIMIT_BIT 4 + +/* No special needs. */ +#define gcvALLOC_FLAG_NONE (0) +/* Physical contiguous. */ +#define gcvALLOC_FLAG_CONTIGUOUS (1 << gcvALLOC_FLAG_CONTIGUOUS_BIT) +/* Can be remapped as cacheable. */ +#define gcvALLOC_FLAG_CACHEABLE (1 << gcvALLOC_FLAG_CACHEABLE_BIT) +/* Secure buffer. */ +#define gcvALLOC_FLAG_SECURITY (1 << gcvALLOC_FLAG_SECURITY_BIT) +/* Physical non contiguous. */ +#define gcvALLOC_FLAG_NON_CONTIGUOUS (1 << gcvALLOC_FLAG_NON_CONTIGUOUS_BIT) +#define gcvALLOC_FLAG_MEMLIMIT (1 << gcvALLOC_FLAG_MEMLIMIT_BIT) + +/* 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 ***************************** @@ -939,6 +1582,7 @@ gceMACHINECODE; typedef struct _gckCONTEXT * gckCONTEXT; typedef struct _gcoCMDBUF * gcoCMDBUF; + typedef struct _gcsSTATE_DELTA * gcsSTATE_DELTA_PTR; typedef struct _gcsQUEUE * gcsQUEUE_PTR; typedef struct _gcoQUEUE * gcoQUEUE; @@ -946,15 +1590,15 @@ typedef struct _gcsHAL_INTERFACE * gcsHAL_INTERFACE_PTR; typedef struct _gcs2D_PROFILE * gcs2D_PROFILE_PTR; #if gcdENABLE_VG -typedef struct _gcoVGHARDWARE * gcoVGHARDWARE; +typedef struct _gcoVGHARDWARE * gcoVGHARDWARE; typedef struct _gcoVGBUFFER * gcoVGBUFFER; typedef struct _gckVGHARDWARE * gckVGHARDWARE; -typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR; -typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR; -typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR; -typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR; -typedef struct _gckVGKERNEL * gckVGKERNEL; -typedef void * gctTHREAD; +typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR; +typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR; +typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR; +typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR; +typedef struct _gckVGKERNEL * gckVGKERNEL; +typedef void * gctTHREAD; #endif #ifdef __cplusplus 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 0608e437f54d..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,7 +22,6 @@ #ifndef __gc_hal_kernel_buffer_h_ #define __gc_hal_kernel_buffer_h_ - #ifdef __cplusplus extern "C" { #endif @@ -91,12 +90,38 @@ typedef struct _gcsSTATE_DELTA } gcsSTATE_DELTA; +/* Command buffer patch record. */ +struct _gcsPATCH +{ + /* Pointer within the buffer. */ + gctUINT32_PTR pointer; + + /* 32-bit data to write at the specified offset. */ + gctUINT32 data; +}; + +/* List of patches for the command buffer. */ +struct _gcsPATCH_LIST +{ + /* Array of patch records. */ + struct _gcsPATCH patch[1024]; + + /* Number of patches in the array. */ + gctUINT count; + + /* Next item in the list. */ + struct _gcsPATCH_LIST *next; +}; + /* Command buffer object. */ struct _gcoCMDBUF { /* The object. */ gcsOBJECT object; + /* Commit count. */ + gctUINT count; + /* Command buffer entry and exit pipes. */ gcePIPE_SELECT entryPipe; gcePIPE_SELECT exitPipe; @@ -114,20 +139,20 @@ struct _gcoCMDBUF gctUINT64 logical; /* Number of bytes in command buffer. */ - gctUINT bytes; + gctUINT32 bytes; /* Start offset into the command buffer. */ - gctUINT startOffset; + gctUINT32 startOffset; /* Current offset into the command buffer. */ - gctUINT offset; + gctUINT32 offset; /* Number of free bytes in command buffer. */ - gctUINT free; + gctUINT32 free; /* Location of the last reserved area. */ gctUINT64 lastReserve; - gctUINT lastOffset; + gctUINT32 lastOffset; #if gcdSECURE_USER /* Hint array for the current command buffer. */ @@ -142,6 +167,17 @@ struct _gcoCMDBUF gctUINT32 lastLoadStateAddress; gctUINT32 lastLoadStateCount; #endif + + /* Completion signal. */ + gctSIGNAL signal; + + /* List of patches. */ + struct _gcsPATCH_LIST *patchHead; + struct _gcsPATCH_LIST *patchTail; + + /* Link to the siblings. */ + gcoCMDBUF prev; + gcoCMDBUF next; }; typedef struct _gcsQUEUE @@ -164,20 +200,24 @@ struct _gcoQUEUE gcsQUEUE_PTR head; gcsQUEUE_PTR tail; -#ifdef __QNXNTO__ - /* Buffer for records. */ - gcsQUEUE_PTR records; - gctUINT32 freeBytes; - gctUINT32 offset; -#else + /* chunks of the records. */ + gctPOINTER chunks; + /* List of free records. */ gcsQUEUE_PTR freeList; -#endif + #define gcdIN_QUEUE_RECORD_LIMIT 16 /* Number of records currently in queue */ gctUINT32 recordCount; }; +struct _gcsTEMPCMDBUF +{ + gctUINT32 currentByteSize; + gctPOINTER buffer; + gctBOOL inUse; +}; + #ifdef __cplusplus } #endif 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 9e32878cd76d..df35019bce2a 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -20,12 +20,12 @@ /* -** Include file for the local memory management. +** Include file for the local memory management. */ #ifndef __gc_hal_mem_h_ #define __gc_hal_mem_h_ -#ifndef VIVANTE_NO_3D +#if (gcdENABLE_3D || gcdENABLE_VG) #ifdef __cplusplus extern "C" { @@ -34,100 +34,100 @@ extern "C" { /******************************************************************************* ** Usage: - The macros to declare MemPool type and functions are - gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix) - gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix) - gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) - - The data structures for MemPool are - typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL; - typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL; - typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL; - - The MemPool constructor and destructor functions are - gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT); - gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *); - gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL); - gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *); - gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT); - gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *); - - FS: for Fixed-Size data structures - VS: for Variable-size data structures - AFS: for Array of Fixed-Size data structures - - - // Example 1: For a fixed-size data structure, struct gcsNode. - // It is used locally in a file, so the functions are static without prefix. - // At top level, declear allocate and free functions. - // The first argument is the data type. - // The second armument is the short name used in the fuctions. - gcmMEM_DeclareFSMemPool(struct gcsNode, Node, ); - - // The previous macro creates two inline functions, - // _AllocateNode and _FreeNode. - - // In function or struct - gcsMEM_FS_MEM_POOL nodeMemPool; - - // In function, - struct gcsNode * node; - gceSTATUS status; - - // Before using the memory pool, initialize it. - // The second argument is the gcoOS object. - // The third argument is the number of data structures to allocate for each chunk. - status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode)); - ... - - // Allocate a node. - status = _AllocateNode(nodeMemPool, &node); - ... - // Free a node. - _FreeNode(nodeMemPool, node); - - // After using the memory pool, free it. - gcfMEM_FreeFSMemPool(&nodeMemPool); - - - // Example 2: For array of fixed-size data structures, struct gcsNode. - // It is used in several files, so the functions are extern with prefix. - // At top level, declear allocate and free functions. - // The first argument is the data type, and the second one is the short name - // used in the fuctions. - gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt); - - // The previous macro creates two inline functions, - // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray. - - // In function or struct - gcsMEM_AFS_MEM_POOL nodeArrayMemPool; - - // In function, - struct gcsNode * nodeArray; - gceSTATUS status; - - // Before using the array memory pool, initialize it. - // The second argument is the gcoOS object, the third is the number of data - // structures to allocate for each chunk. - status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode)); - ... - - // Allocate a node array of size 100. - status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100); - ... - // Free a node array. - gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray); - - // After using the array memory pool, free it. - gcfMEM_FreeAFSMemPool(&nodeArrayMemPool); + The macros to declare MemPool type and functions are + gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix) + gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix) + gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) + + The data structures for MemPool are + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL; + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL; + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL; + + The MemPool constructor and destructor functions are + gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT); + gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *); + gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL); + gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *); + gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT); + gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *); + + FS: for Fixed-Size data structures + VS: for Variable-size data structures + AFS: for Array of Fixed-Size data structures + + + // Example 1: For a fixed-size data structure, struct gcsNode. + // It is used locally in a file, so the functions are static without prefix. + // At top level, declear allocate and free functions. + // The first argument is the data type. + // The second armument is the short name used in the fuctions. + gcmMEM_DeclareFSMemPool(struct gcsNode, Node, ); + + // The previous macro creates two inline functions, + // _AllocateNode and _FreeNode. + + // In function or struct + gcsMEM_FS_MEM_POOL nodeMemPool; + + // In function, + struct gcsNode * node; + gceSTATUS status; + + // Before using the memory pool, initialize it. + // The second argument is the gcoOS object. + // The third argument is the number of data structures to allocate for each chunk. + status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode)); + ... + + // Allocate a node. + status = _AllocateNode(nodeMemPool, &node); + ... + // Free a node. + _FreeNode(nodeMemPool, node); + + // After using the memory pool, free it. + gcfMEM_FreeFSMemPool(&nodeMemPool); + + + // Example 2: For array of fixed-size data structures, struct gcsNode. + // It is used in several files, so the functions are extern with prefix. + // At top level, declear allocate and free functions. + // The first argument is the data type, and the second one is the short name + // used in the fuctions. + gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt); + + // The previous macro creates two inline functions, + // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray. + + // In function or struct + gcsMEM_AFS_MEM_POOL nodeArrayMemPool; + + // In function, + struct gcsNode * nodeArray; + gceSTATUS status; + + // Before using the array memory pool, initialize it. + // The second argument is the gcoOS object, the third is the number of data + // structures to allocate for each chunk. + status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode)); + ... + + // Allocate a node array of size 100. + status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100); + ... + // Free a node array. + gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray); + + // After using the array memory pool, free it. + gcfMEM_FreeAFSMemPool(&nodeArrayMemPool); *******************************************************************************/ /******************************************************************************* -** To switch back to use gcoOS_Allocate and gcoOS_Free, add -** #define USE_LOCAL_MEMORY_POOL 0 -** before including this file. +** To switch back to use gcoOS_Allocate and gcoOS_Free, add +** #define USE_LOCAL_MEMORY_POOL 0 +** before including this file. *******************************************************************************/ #ifndef USE_LOCAL_MEMORY_POOL /* @@ -135,161 +135,161 @@ extern "C" { This define enables the local memory management to improve performance. */ -#define USE_LOCAL_MEMORY_POOL 1 +#define USE_LOCAL_MEMORY_POOL 1 #endif /******************************************************************************* -** Memory Pool Data Structures +** Memory Pool Data Structures *******************************************************************************/ #if USE_LOCAL_MEMORY_POOL - typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL; - typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL; - typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL; + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL; + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL; + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL; #else - typedef gcoOS gcsMEM_FS_MEM_POOL; - typedef gcoOS gcsMEM_VS_MEM_POOL; - typedef gcoOS gcsMEM_AFS_MEM_POOL; + typedef gcoOS gcsMEM_FS_MEM_POOL; + typedef gcoOS gcsMEM_VS_MEM_POOL; + typedef gcoOS gcsMEM_AFS_MEM_POOL; #endif /******************************************************************************* -** Memory Pool Macros +** Memory Pool Macros *******************************************************************************/ #if USE_LOCAL_MEMORY_POOL #define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \ gceSTATUS \ Prefix##_Allocate##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type ** Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type ** Pointer \ + ) \ { \ - return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \ + return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \ } \ \ gceSTATUS \ Prefix##_CAllocate##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type ** Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type ** Pointer \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ - gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \ - gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \ + gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \ + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \ gcmFOOTER(); \ - return gcvSTATUS_OK; \ + return gcvSTATUS_OK; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type * Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type * Pointer \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName##List( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type * FirstPointer, \ - Type * LastPointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type * FirstPointer, \ + Type * LastPointer \ + ) \ { \ gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \ status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } #define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \ gceSTATUS \ Prefix##_Allocate##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Size \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Size \ + ) \ { \ gceSTATUS status;\ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } \ \ gceSTATUS \ Prefix##_CAllocate##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Size \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Size \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ - gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \ - gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \ + gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \ + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \ gcmFOOTER(); \ - return gcvSTATUS_OK; \ + return gcvSTATUS_OK; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type * Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type * Pointer \ + ) \ { \ gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \ status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } #define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \ gceSTATUS \ Prefix##_Allocate##TypeName( \ - gcsMEM_AFS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Count \ - ) \ + gcsMEM_AFS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Count \ + ) \ { \ gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } \ \ gceSTATUS \ Prefix##_CAllocate##TypeName( \ - gcsMEM_AFS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Count \ - ) \ + gcsMEM_AFS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Count \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ - gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \ - gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \ + gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \ + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \ gcmFOOTER(); \ - return gcvSTATUS_OK; \ + return gcvSTATUS_OK; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName( \ - gcsMEM_AFS_MEM_POOL MemPool, \ - Type * Pointer \ - ) \ + gcsMEM_AFS_MEM_POOL MemPool, \ + Type * Pointer \ + ) \ { \ gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } #else @@ -297,234 +297,234 @@ Prefix##_Free##TypeName( \ #define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \ gceSTATUS \ Prefix##_Allocate##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type ** Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type ** Pointer \ + ) \ { \ gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ status = gcoOS_Allocate(MemPool, \ - gcmSIZEOF(Type), \ - (gctPOINTER *) Pointer); \ + gcmSIZEOF(Type), \ + (gctPOINTER *) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } \ \ gceSTATUS \ Prefix##_CAllocate##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type ** Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type ** Pointer \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ - gcmERR_RETURN(gcoOS_Allocate(MemPool, \ - gcmSIZEOF(Type), \ - (gctPOINTER *) Pointer)); \ - gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \ + gcmERR_RETURN(gcoOS_Allocate(MemPool, \ + gcmSIZEOF(Type), \ + (gctPOINTER *) Pointer)); \ + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \ gcmFOOTER(); \ - return gcvSTATUS_OK; \ + return gcvSTATUS_OK; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName( \ - gcsMEM_FS_MEM_POOL MemPool, \ - Type * Pointer \ - ) \ + gcsMEM_FS_MEM_POOL MemPool, \ + Type * Pointer \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ status = gcmOS_SAFE_FREE(MemPool, Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } #define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \ gceSTATUS \ Prefix##_Allocate##TypeName( \ - gcsMEM_VS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Size \ - ) \ + gcsMEM_VS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Size \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ status = gcoOS_Allocate(MemPool, \ - Size, \ - (gctPOINTER *) Pointer); \ + Size, \ + (gctPOINTER *) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } \ \ gceSTATUS \ Prefix##_CAllocate##TypeName( \ - gcsMEM_VS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Size \ - ) \ + gcsMEM_VS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Size \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \ - gcmERR_RETURN(gcoOS_Allocate(MemPool, \ - Size, \ - (gctPOINTER *) Pointer)); \ - gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \ + gcmERR_RETURN(gcoOS_Allocate(MemPool, \ + Size, \ + (gctPOINTER *) Pointer)); \ + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \ gcmFOOTER(); \ - return gcvSTATUS_OK; \ + return gcvSTATUS_OK; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName( \ - gcsMEM_VS_MEM_POOL MemPool, \ - Type * Pointer \ - ) \ + gcsMEM_VS_MEM_POOL MemPool, \ + Type * Pointer \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ status = gcmOS_SAFE_FREE(MemPool, Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } #define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \ gceSTATUS \ Prefix##_Allocate##TypeName( \ - gcsMEM_AFS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Count \ - ) \ + gcsMEM_AFS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Count \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ status = gcoOS_Allocate(MemPool, \ - Count * gcmSIZEOF(Type), \ - (gctPOINTER *) Pointer); \ + Count * gcmSIZEOF(Type), \ + (gctPOINTER *) Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } \ \ gceSTATUS \ Prefix##_CAllocate##TypeName( \ - gcsMEM_AFS_MEM_POOL MemPool, \ - Type ** Pointer, \ - gctUINT Count \ - ) \ + gcsMEM_AFS_MEM_POOL MemPool, \ + Type ** Pointer, \ + gctUINT Count \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \ - gcmERR_RETURN(gcoOS_Allocate(MemPool, \ - Count * gcmSIZEOF(Type), \ - (gctPOINTER *) Pointer)); \ - gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \ + gcmERR_RETURN(gcoOS_Allocate(MemPool, \ + Count * gcmSIZEOF(Type), \ + (gctPOINTER *) Pointer)); \ + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \ gcmFOOTER(); \ - return gcvSTATUS_OK; \ + return gcvSTATUS_OK; \ } \ \ gceSTATUS \ Prefix##_Free##TypeName( \ - gcsMEM_AFS_MEM_POOL MemPool, \ - Type * Pointer \ - ) \ + gcsMEM_AFS_MEM_POOL MemPool, \ + Type * Pointer \ + ) \ { \ - gceSTATUS status; \ + gceSTATUS status; \ gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \ status = gcmOS_SAFE_FREE(MemPool, Pointer); \ gcmFOOTER(); \ - return status; \ + return status; \ } #endif /******************************************************************************* -** Memory Pool Data Functions +** Memory Pool Data Functions *******************************************************************************/ gceSTATUS gcfMEM_InitFSMemPool( - IN gcsMEM_FS_MEM_POOL * MemPool, - IN gcoOS OS, - IN gctUINT NodeCount, - IN gctUINT NodeSize - ); + IN gcsMEM_FS_MEM_POOL * MemPool, + IN gcoOS OS, + IN gctUINT NodeCount, + IN gctUINT NodeSize + ); gceSTATUS gcfMEM_FreeFSMemPool( - IN gcsMEM_FS_MEM_POOL * MemPool - ); + IN gcsMEM_FS_MEM_POOL * MemPool + ); gceSTATUS gcfMEM_FSMemPoolGetANode( - IN gcsMEM_FS_MEM_POOL MemPool, - OUT gctPOINTER * Node - ); + IN gcsMEM_FS_MEM_POOL MemPool, + OUT gctPOINTER * Node + ); gceSTATUS gcfMEM_FSMemPoolFreeANode( - IN gcsMEM_FS_MEM_POOL MemPool, - IN gctPOINTER Node - ); + IN gcsMEM_FS_MEM_POOL MemPool, + IN gctPOINTER Node + ); gceSTATUS gcfMEM_FSMemPoolFreeAList( - IN gcsMEM_FS_MEM_POOL MemPool, - IN gctPOINTER FirstNode, - IN gctPOINTER LastNode - ); + IN gcsMEM_FS_MEM_POOL MemPool, + IN gctPOINTER FirstNode, + IN gctPOINTER LastNode + ); gceSTATUS gcfMEM_InitVSMemPool( - IN gcsMEM_VS_MEM_POOL * MemPool, - IN gcoOS OS, - IN gctUINT BlockSize, - IN gctBOOL RecycleFreeNode - ); + IN gcsMEM_VS_MEM_POOL * MemPool, + IN gcoOS OS, + IN gctUINT BlockSize, + IN gctBOOL RecycleFreeNode + ); gceSTATUS gcfMEM_FreeVSMemPool( - IN gcsMEM_VS_MEM_POOL * MemPool - ); + IN gcsMEM_VS_MEM_POOL * MemPool + ); gceSTATUS gcfMEM_VSMemPoolGetANode( - IN gcsMEM_VS_MEM_POOL MemPool, - IN gctUINT Size, - IN gctUINT Alignment, - OUT gctPOINTER * Node - ); + IN gcsMEM_VS_MEM_POOL MemPool, + IN gctUINT Size, + IN gctUINT Alignment, + OUT gctPOINTER * Node + ); gceSTATUS gcfMEM_VSMemPoolFreeANode( - IN gcsMEM_VS_MEM_POOL MemPool, - IN gctPOINTER Node - ); + IN gcsMEM_VS_MEM_POOL MemPool, + IN gctPOINTER Node + ); gceSTATUS gcfMEM_InitAFSMemPool( - IN gcsMEM_AFS_MEM_POOL *MemPool, - IN gcoOS OS, - IN gctUINT NodeCount, - IN gctUINT NodeSize - ); + IN gcsMEM_AFS_MEM_POOL *MemPool, + IN gcoOS OS, + IN gctUINT NodeCount, + IN gctUINT NodeSize + ); gceSTATUS gcfMEM_FreeAFSMemPool( - IN gcsMEM_AFS_MEM_POOL *MemPool - ); + IN gcsMEM_AFS_MEM_POOL *MemPool + ); gceSTATUS gcfMEM_AFSMemPoolGetANode( - IN gcsMEM_AFS_MEM_POOL MemPool, - IN gctUINT Count, - OUT gctPOINTER * Node - ); + IN gcsMEM_AFS_MEM_POOL MemPool, + IN gctUINT Count, + OUT gctPOINTER * Node + ); gceSTATUS gcfMEM_AFSMemPoolFreeANode( - IN gcsMEM_AFS_MEM_POOL MemPool, - IN gctPOINTER Node - ); + IN gcsMEM_AFS_MEM_POOL MemPool, + IN gctPOINTER Node + ); #ifdef __cplusplus } #endif -#endif /* VIVANTE_NO_3D */ +#endif /* (gcdENABLE_3D || gcdENABLE_VG) */ #endif /* __gc_hal_mem_h_ */ 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 420437f514bc..b93015d32f92 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -18,10 +18,17 @@ * *****************************************************************************/ - #ifndef __gc_hal_options_h_ #define __gc_hal_options_h_ +/* + gcdSECURITY + +*/ +#ifndef gcdSECURITY +# define gcdSECURITY 0 +#endif + /* gcdPRINT_VERSION @@ -49,19 +56,26 @@ # define VIVANTE_PROFILER 1 #endif -#ifndef VIVANTE_PROFILER_PERDRAW -# define VIVANTE_PROFILER_PERDRAW 0 -#endif - /* VIVANTE_PROFILER_CONTEXT - This define enables the profiler according to each hw context. + This define enables the profiler according each context. */ #ifndef VIVANTE_PROFILER_CONTEXT # define VIVANTE_PROFILER_CONTEXT 1 #endif +#ifndef VIVANTE_PROFILER_PERDRAW +# define VIVANTE_PROFILER_PERDRAW 0 +#endif + +#ifndef VIVANTE_PROFILER_NEW +# define VIVANTE_PROFILER_NEW 0 +#endif + +#ifndef VIVANTE_PROFILER_PM +# define VIVANTE_PROFILER_PM 1 +#endif /* gcdUSE_VG @@ -80,13 +94,6 @@ # define USE_SW_FB 0 #endif -/* - USE_SUPER_SAMPLING - - This define enables super-sampling support. -*/ -#define USE_SUPER_SAMPLING 0 - /* PROFILE_HAL_COUNTERS @@ -167,6 +174,82 @@ # define gcdDUMP_API 0 #endif + + +/* + gcdDEBUG_OPTION + When set to 1, the debug options are enabled. We must set other MACRO to enable + sub case. +*/ +#ifndef gcdDEBUG_OPTION +# define gcdDEBUG_OPTION 0 + +#if gcdDEBUG_OPTION +/* + gcdDEBUG_OPTION_KEY + The process name of debug application. +*/ +#ifndef gcdDEBUG_OPTION_KEY +# define gcdDEBUG_OPTION_KEY "process" +# endif +/* + gcdDEBUG_OPTION_NO_GL_DRAWS + When set to 1, all glDrawArrays and glDrawElements will be skip. +*/ +#ifndef gcdDEBUG_OPTION_NO_GL_DRAWS +# define gcdDEBUG_OPTION_NO_GL_DRAWS 0 +# endif +/* + gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES + When set to 1, all DrawPrimitives will be skip. +*/ +#ifndef gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES +# define gcdDEBUG_OPTION_NO_DRAW_PRIMITIVES 0 +# endif +/* + gcdDEBUG_OPTION_SKIP_SWAP + When set to 1, just one out of gcdDEBUG_OPTION_SKIP_FRAMES(such as 1/10) eglSwapBuffers will be resolve, + others skip. +*/ +#ifndef gcdDEBUG_OPTION_SKIP_SWAP +# define gcdDEBUG_OPTION_SKIP_SWAP 0 +# define gcdDEBUG_OPTION_SKIP_FRAMES 10 +# endif +/* + gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET + When set to 1, the format of render target will force to RGB565. +*/ +#ifndef gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET +# define gcdDEBUG_OPTION_FORCE_16BIT_RENDER_TARGET 0 +# endif +/* + gcdDEBUG_OPTION_NONE_TEXTURE + When set to 1, the type of texture will be set to AQ_TEXTURE_SAMPLE_MODE_TYPE_NONE. +*/ +#ifndef gcdDEBUG_OPTION_NONE_TEXTURE +# define gcdDEBUG_OPTION_NONE_TEXTURE 0 +# endif +/* + gcdDEBUG_OPTION_NONE_DEPTH + When set to 1, the depth format of surface will be set to gcvSURF_UNKNOWN. +*/ +#ifndef gcdDEBUG_OPTION_NONE_DEPTH +# define gcdDEBUG_OPTION_NONE_DEPTH 0 +# endif + +# endif +#endif + +/* + gcdDUMP_SWAP_PER_DRAW + + When set to 1, dump swap command for every single draw to make simulation comparison happy. + Only valid for ES3 driver for now. +*/ +#ifndef gcdDUMP_SWAP_PER_DRAW +# define gcdDUMP_SWAP_PER_DRAW 0 +#endif + /* gcdDUMP_FRAMERATE When set to a value other than zero, averaqe frame rate will be dumped. @@ -175,16 +258,7 @@ in the average. Frame count starts from 1. */ #ifndef gcdDUMP_FRAMERATE -# define gcdDUMP_FRAMERATE 0 -#endif - -/* - gcdVIRTUAL_COMMAND_BUFFER - When set to 1, user command buffer and context buffer will be allocated - from gcvPOOL_VIRTUAL. -*/ -#ifndef gcdVIRTUAL_COMMAND_BUFFER -# define gcdVIRTUAL_COMMAND_BUFFER 0 +# define gcdDUMP_FRAMERATE 0 #endif /* @@ -217,6 +291,15 @@ # define gcdDUMP_COMMAND 0 #endif +/* + gcdDUMP_2D + + When set to non-zero, it will dump the 2D command and surface. +*/ +#ifndef gcdDUMP_2D +# define gcdDUMP_2D 0 +#endif + /* gcdDUMP_FRAME_TGA @@ -224,7 +307,7 @@ will be done into frame.tga. Frame count starts from 1. */ #ifndef gcdDUMP_FRAME_TGA -#define gcdDUMP_FRAME_TGA 0 +# define gcdDUMP_FRAME_TGA 0 #endif /* gcdNULL_DRIVER @@ -234,7 +317,7 @@ Set to 3 for bypassing the drivers. */ #ifndef gcdNULL_DRIVER -# define gcdNULL_DRIVER 0 +# define gcdNULL_DRIVER 0 #endif /* @@ -374,17 +457,6 @@ # define gcdREGISTER_ACCESS_FROM_USER 1 #endif -/* - gcdUSER_HEAP_ALLOCATOR - - Set to 1 to enable user mode heap allocator for fast memory allocation - and destroying. Otherwise, memory allocation/destroying in user mode - will be directly managed by system. Only for linux for now. -*/ -#ifndef gcdUSER_HEAP_ALLOCATOR -# define gcdUSER_HEAP_ALLOCATOR 1 -#endif - /* gcdHEAP_SIZE @@ -400,22 +472,17 @@ #endif /* - gcdPOWER_SUSNPEND_WHEN_IDLE + gcdPOWER_SUSPEND_WHEN_IDLE Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected, otherwise GPU will enter gcvPOWER_IDLE. */ -#ifndef gcdPOWER_SUSNPEND_WHEN_IDLE -# define gcdPOWER_SUSNPEND_WHEN_IDLE 1 +#ifndef gcdPOWER_SUSPEND_WHEN_IDLE +# define gcdPOWER_SUSPEND_WHEN_IDLE 1 #endif -/* - gcdFPGA_BUILD - - This define enables work arounds for FPGA images. -*/ #ifndef gcdFPGA_BUILD -# define gcdFPGA_BUILD 0 +# define gcdFPGA_BUILD 0 #endif /* @@ -430,8 +497,10 @@ #ifndef gcdGPU_TIMEOUT #if gcdFPGA_BUILD # define gcdGPU_TIMEOUT 0 +# define gcdGPU_2D_TIMEOUT 0 # else # define gcdGPU_TIMEOUT 20000 +# define gcdGPU_2D_TIMEOUT 4000 # endif #endif @@ -471,11 +540,21 @@ # define gcdCMD_NO_2D_CONTEXT 1 #endif +/* + gcdENABLE_BUFFER_ALIGNMENT + + When enabled, video memory is allocated with atleast 16KB aligment + between multiple sub-buffers. +*/ +#ifndef gcdENABLE_BUFFER_ALIGNMENT +# define gcdENABLE_BUFFER_ALIGNMENT 1 +#endif + /* 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. */ @@ -569,31 +648,11 @@ #endif /* - gcdENABLE_VG - enable the 2D openVG -*/ - -#ifndef gcdENABLE_VG -# define gcdENABLE_VG 0 -#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 /* @@ -608,7 +667,6 @@ This option is only for those SOC which can't enable writecombine without enabling cacheable. */ - #ifndef gcdPAGED_MEMORY_CACHEABLE # define gcdPAGED_MEMORY_CACHEABLE 0 #endif @@ -618,7 +676,6 @@ When non-zero, non paged memory will be cacheable. */ - #ifndef gcdNONPAGED_MEMORY_CACHEABLE # define gcdNONPAGED_MEMORY_CACHEABLE 0 #endif @@ -630,7 +687,6 @@ gcdNONPAGED_MEMORY_BUFFERABLE and gcdNONPAGED_MEMORY_CACHEABLE can't be set 1 at same time */ - #ifndef gcdNONPAGED_MEMORY_BUFFERABLE # define gcdNONPAGED_MEMORY_BUFFERABLE 1 #endif @@ -639,27 +695,29 @@ gcdENABLE_INFINITE_SPEED_HW enable the Infinte HW , this is for 2D openVG */ - #ifndef gcdENABLE_INFINITE_SPEED_HW # define gcdENABLE_INFINITE_SPEED_HW 0 #endif /* - gcdENABLE_TS_DOUBLE_BUFFER - enable the TS double buffer, this is for 2D openVG -*/ + gcdMULTI_GPU -#ifndef gcdENABLE_TS_DOUBLE_BUFFER -# define gcdENABLE_TS_DOUBLE_BUFFER 1 + Enable/disable multi-GPU support. + 0 : Disable multi-GPU support + 1 : Enable one of the 3D cores + [2..X] : Number of 3D GPU Cores +*/ +#ifndef gcdMULTI_GPU +# define gcdMULTI_GPU 0 #endif /* - gcd6000_SUPPORT + gcdMULTI_GPU_AFFINITY - Temporary define to enable/disable 6000 support. - */ -#ifndef gcd6000_SUPPORT -# define gcd6000_SUPPORT 0 + Enable/disable the binding of a context to one GPU +*/ +#ifndef gcdMULTI_GPU_AFFINITY +# define gcdMULTI_GPU_AFFINITY 0 #endif /* @@ -669,18 +727,10 @@ idle state, and gcdPOWEROFF_TIMEOUT is also the default timeout in milliseconds. */ - #ifndef gcdPOWEROFF_TIMEOUT # define gcdPOWEROFF_TIMEOUT 300 #endif -/* - gcdUSE_VIDMEM_PER_PID -*/ -#ifndef gcdUSE_VIDMEM_PER_PID -# define gcdUSE_VIDMEM_PER_PID 0 -#endif - /* QNX_SINGLE_THREADED_DEBUGGING */ @@ -688,15 +738,6 @@ # define QNX_SINGLE_THREADED_DEBUGGING 0 #endif -/* - gcdENABLE_RECOVERY - - This define enables the recovery code. -*/ -#ifndef gcdENABLE_RECOVERY -# define gcdENABLE_RECOVERY 1 -#endif - /* gcdRENDER_THREADS @@ -718,44 +759,11 @@ */ #ifndef gcdSMP +#ifdef __APPLE__ +# define gcdSMP 1 +#else # define gcdSMP 0 #endif - -/* - gcdSUPPORT_SWAP_RECTANGLE - - Support swap with a specific rectangle. - - Set the rectangle with eglSetSwapRectangleANDROID api. -*/ -#ifndef gcdSUPPORT_SWAP_RECTANGLE -# define gcdSUPPORT_SWAP_RECTANGLE 0 -#endif - -/* - gcdGPU_LINEAR_BUFFER_ENABLED - - Use linear buffer for GPU apps so HWC can do 2D composition. -*/ -#ifndef gcdGPU_LINEAR_BUFFER_ENABLED -# define gcdGPU_LINEAR_BUFFER_ENABLED 1 -#endif - -/* - gcdENABLE_RENDER_INTO_WINDOW - - Enable Render-Into-Window (ie, No-Resolve) feature on android. - NOTE that even if enabled, it still depends on hardware feature and - android application behavior. When hardware feature or application - behavior can not support render into window mode, it will fail back - to normal mode. - When Render-Into-Window is finally used, window back buffer of android - applications will be allocated matching render target tiling format. - Otherwise buffer tiling is decided by the above option - 'gcdGPU_LINEAR_BUFFER_ENABLED'. -*/ -#ifndef gcdENABLE_RENDER_INTO_WINDOW -# define gcdENABLE_RENDER_INTO_WINDOW 1 #endif /* @@ -764,14 +772,14 @@ Use shared resolve buffer for all app buffers. */ #ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED -# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0 +# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0 #endif /* gcdUSE_TRIANGLE_STRIP_PATCH */ #ifndef gcdUSE_TRIANGLE_STRIP_PATCH -# define gcdUSE_TRIANGLE_STRIP_PATCH 1 +# define gcdUSE_TRIANGLE_STRIP_PATCH 1 #endif /* @@ -783,23 +791,30 @@ # define gcdENABLE_OUTER_CACHE_PATCH 0 #endif -#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST -# ifdef ANDROID -# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1 -# else -# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0 -# endif -#endif +/* + gcdPROCESS_ADDRESS_SPACE -#ifndef gcdENABLE_PE_DITHER_FIX -# define gcdENABLE_PE_DITHER_FIX 1 + When non-zero, every process which attaches to galcore has its own GPU + address space, size of which is gcdPROCESS_ADDRESS_SPACE_SIZE. +*/ +#ifndef gcdPROCESS_ADDRESS_SPACE +# define gcdPROCESS_ADDRESS_SPACE 0 +# define gcdPROCESS_ADDRESS_SPACE_SIZE 0x80000000 #endif +/* + gcdSHARED_PAGETABLE + + When non-zero, multiple GPUs in one chip with same MMU use + one shared pagetable. So that when accessing same surface, + they can use same GPU virtual address. +*/ #ifndef gcdSHARED_PAGETABLE -# define gcdSHARED_PAGETABLE 1 +# define gcdSHARED_PAGETABLE !gcdPROCESS_ADDRESS_SPACE #endif + #ifndef gcdUSE_PVR -# define gcdUSE_PVR 1 +# define gcdUSE_PVR 1 #endif /* @@ -811,7 +826,7 @@ For Linux, it's the size of a page. If this requeset fallbacks to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted because they allocate a page at least. - */ +*/ #ifndef gcdSMALL_BLOCK_SIZE # define gcdSMALL_BLOCK_SIZE 4096 # define gcdRATIO_FOR_SMALL_MEMORY 32 @@ -821,19 +836,11 @@ gcdCONTIGUOUS_SIZE_LIMIT When non-zero, size of video node from gcvPOOL_CONTIGUOUS is limited by gcdCONTIGUOUS_SIZE_LIMIT. - */ +*/ #ifndef gcdCONTIGUOUS_SIZE_LIMIT # define gcdCONTIGUOUS_SIZE_LIMIT 0 #endif -#ifndef gcdDISALBE_EARLY_EARLY_Z -# define gcdDISALBE_EARLY_EARLY_Z 1 -#endif - -#ifndef gcdSHADER_SRC_BY_MACHINECODE -# define gcdSHADER_SRC_BY_MACHINECODE 1 -#endif - /* gcdLINK_QUEUE_SIZE @@ -842,71 +849,125 @@ is be used to debug. */ #ifndef gcdLINK_QUEUE_SIZE -# define gcdLINK_QUEUE_SIZE 0 +# define gcdLINK_QUEUE_SIZE 5 #endif /* gcdALPHA_KILL_IN_SHADER - * - * Enable alpha kill inside the shader. This will be set automatically by the - * HAL if certain states match a criteria. - */ + + Enable alpha kill inside the shader. This will be set automatically by the + HAL if certain states match a criteria. +*/ #ifndef gcdALPHA_KILL_IN_SHADER # define gcdALPHA_KILL_IN_SHADER 1 #endif -/* gcdHIGH_PRECISION_DELAY_ENABLE - * - * Enable high precision schedule delay with 1ms unit. otherwise schedule delay up to 10ms. - * Browser app performance will have obvious drop without this enablement + + +/* + gcdDVFS + + When non-zero, software will make use of dynamic voltage and + frequency feature. */ -#ifndef gcdHIGH_PRECISION_DELAY_ENABLE -# define gcdHIGH_PRECISION_DELAY_ENABLE 1 +#ifndef gcdDVFS +# define gcdDVFS 0 +# define gcdDVFS_ANAYLSE_WINDOW 4 +# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4) #endif -#ifndef gcdUSE_WCLIP_PATCH -# define gcdUSE_WCLIP_PATCH 1 +#ifndef gcdSYNC +# define gcdSYNC 1 #endif -#ifndef gcdHZ_L2_DISALBE -# define gcdHZ_L2_DISALBE 1 +#ifndef gcdSHADER_SRC_BY_MACHINECODE +# define gcdSHADER_SRC_BY_MACHINECODE 1 #endif -#ifndef gcdBUGFIX15_DISABLE -# define gcdBUGFIX15_DISABLE 1 +#ifndef gcdGLB27_SHADER_REPLACE_OPTIMIZATION +# define gcdGLB27_SHADER_REPLACE_OPTIMIZATION 1 #endif -#ifndef gcdDISABLE_HZ_FAST_CLEAR -# define gcdDISABLE_HZ_FAST_CLEAR 1 +/* + gcdSTREAM_OUT_BUFFER + + Enable suppport for the secondary stream out buffer. +*/ +#ifndef gcdSTREAM_OUT_BUFFER +# define gcdSTREAM_OUT_BUFFER 0 +# define gcdSTREAM_OUT_NAIVE_SYNC 0 #endif -#ifndef gcdUSE_NPOT_PATCH -#define gcdUSE_NPOT_PATCH 1 +/* + gcdUSE_HARDWARE_CONFIGURATION_TABLES + + Enable the use of hardware configuration tables, + instead of query hardware and determine the features. +*/ +#ifndef gcdUSE_HARDWARE_CONFIGURATION_TABLES +# define gcdUSE_HARDWARE_CONFIGURATION_TABLES 0 #endif -#ifndef gcdSYNC -# define gcdSYNC 1 +/* + gcdSUPPORT_SWAP_RECTANGLE + + Support swap with a specific rectangle. + + Set the rectangle with eglSetSwapRectangleVIV api. + Android only. +*/ +#ifndef gcdSUPPORT_SWAP_RECTANGLE +# define gcdSUPPORT_SWAP_RECTANGLE 1 #endif -#ifndef gcdENABLE_SPECIAL_HINT3 -# define gcdENABLE_SPECIAL_HINT3 1 +/* + gcdGPU_LINEAR_BUFFER_ENABLED + + Use linear buffer for GPU apps so HWC can do 2D composition. + Android only. +*/ +#ifndef gcdGPU_LINEAR_BUFFER_ENABLED +# define gcdGPU_LINEAR_BUFFER_ENABLED 1 #endif -#if defined(ANDROID) -#ifndef gcdPRE_ROTATION -# define gcdPRE_ROTATION 1 +/* + gcdENABLE_RENDER_INTO_WINDOW + + Enable Render-Into-Window (ie, No-Resolve) feature on android. + NOTE that even if enabled, it still depends on hardware feature and + android application behavior. When hardware feature or application + behavior can not support render into window mode, it will fail back + to normal mode. + When Render-Into-Window is finally used, window back buffer of android + applications will be allocated matching render target tiling format. + Otherwise buffer tiling is decided by the above option + 'gcdGPU_LINEAR_BUFFER_ENABLED'. + Android only for now. +*/ +#ifndef gcdENABLE_RENDER_INTO_WINDOW +# 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. + This will dynamically check if color compression is available. +*/ +#ifndef gcdENABLE_RENDER_INTO_WINDOW_WITH_FC +# define gcdENABLE_RENDER_INTO_WINDOW_WITH_FC 1 #endif /* - gcdDVFS + gcdENABLE_BLIT_BUFFER_PRESERVE - When non-zero, software will make use of dynamic voltage and - frequency feature. - */ -#ifndef gcdDVFS -# define gcdDVFS 0 -# define gcdDVFS_ANAYLSE_WINDOW 4 -# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4) + Render-Into-Window (ie, No-Resolve) does not include preserved swap + behavior. This feature can enable buffer preserve in No-Resolve mode. + When enabled, previous buffer (may be part of ) will be resolve-blitted + to current buffer. +*/ +#ifndef gcdENABLE_BLIT_BUFFER_PRESERVE +# define gcdENABLE_BLIT_BUFFER_PRESERVE 1 #endif /* @@ -927,21 +988,284 @@ 'acquireFenceFd' for framebuffer target for DC */ #ifndef gcdANDROID_NATIVE_FENCE_SYNC -# define gcdANDROID_NATIVE_FENCE_SYNC 0 +# define gcdANDROID_NATIVE_FENCE_SYNC 0 +#endif + +/* + gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC + + 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. + + 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 gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC +# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 1 +#endif + +/* + * Implicit native buffer sync is not needed when ANDROID_native_fence_sync + * is available. + */ +#if gcdANDROID_NATIVE_FENCE_SYNC +# undef gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC +# define gcdANDROID_IMPLICIT_NATIVE_BUFFER_SYNC 0 +#endif + +/* + gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST + + Enable source surface address adjust when composition on android. + Android only. +*/ +#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1 +#endif + +/* + gcdUSE_WCLIP_PATCH + + Enable wclipping patch. +*/ +#ifndef gcdUSE_WCLIP_PATCH +# define gcdUSE_WCLIP_PATCH 1 +#endif + +#ifndef gcdUSE_NPOT_PATCH +# define gcdUSE_NPOT_PATCH 1 +#endif + +/* + gcd3DBLIT + + TODO: Should be replaced by feature bit if available. +*/ +#ifndef gcd3DBLIT +# define gcd3DBLIT 0 +#endif + +/* + gcdINTERNAL_COMMENT + + Wrap internal comment, content wrapped by it and the macor itself + will be removed in release driver. +*/ +#ifndef gcdINTERNAL_COMMENT +# define gcdINTERNAL_COMMENT 1 #endif +/* + gcdRTT_DISABLE_FC + + Disable RTT FC support. For test only. +*/ +#ifndef gcdRTT_DISABLE_FC +# define gcdRTT_DISABLE_FC 0 +#endif + +/* + gcdFORCE_MIPMAP + + Force generate mipmap for texture. +*/ #ifndef gcdFORCE_MIPMAP -# define gcdFORCE_MIPMAP 0 +# define gcdFORCE_MIPMAP 0 +#endif + +/* + gcdFORCE_BILINEAR + + Force bilinear for mipfilter. +*/ +#ifndef gcdFORCE_BILINEAR +# define gcdFORCE_BILINEAR 1 #endif /* - gcdFORCE_GAL_LOAD_TWICE + gcdBINARY_TRACE + + When non-zero, binary trace will be generated. + + When gcdBINARY_TRACE_FILE_SIZE is non-zero, binary trace buffer will + be written to a file which size is limited to + gcdBINARY_TRACE_FILE_SIZE. +*/ +#ifndef gcdBINARY_TRACE +# define gcdBINARY_TRACE 0 +# define gcdBINARY_TRACE_FILE_SIZE 0 +#endif + +#ifndef gcdMOVG +# define gcdMOVG 0 +#if gcdMOVG +# define GC355_PROFILER 1 +# endif +# define gcdENABLE_TS_DOUBLE_BUFFER 1 +#else +#if gcdMOVG +# define GC355_PROFILER 1 +# define gcdENABLE_TS_DOUBLE_BUFFER 0 +#else +# define gcdENABLE_TS_DOUBLE_BUFFER 1 +#endif +#endif - When non-zero, each thread except the main one will load libGAL.so twice to avoid potential segmetantion fault when app using dlopen/dlclose. - If threads exit arbitrarily, libGAL.so may not unload until the process quit. +/* gcdINTERRUPT_STATISTIC + * + * Monitor the event send to GPU and interrupt issued by GPU. */ -#ifndef gcdFORCE_GAL_LOAD_TWICE -# define gcdFORCE_GAL_LOAD_TWICE 0 + +#ifndef gcdINTERRUPT_STATISTIC +#if defined(LINUX) +# define gcdINTERRUPT_STATISTIC 1 +#else +# define gcdINTERRUPT_STATISTIC 0 +#endif +#endif + +/* + gcdYINVERTED_RENDERING + When it's not zero, we will rendering display buffer + with top-bottom direction. All other offscreen rendering + will be bottom-top, which follow OpenGL ES spec. +*/ +#ifndef gcdYINVERTED_RENDERING +# define gcdYINVERTED_RENDERING 1 +#endif + +#if gcdYINVERTED_RENDERING +/* disable unaligned linear composition adjust in Y-inverted rendering mode. */ +# undef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0 +#endif + +/* + gcdFENCE_WAIT_LOOP_COUNT + Wait fence, loop count. +*/ +#ifndef gcdFENCE_WAIT_LOOP_COUNT +# define gcdFENCE_WAIT_LOOP_COUNT 100 +#endif + +/* + gcdHAL_3D_DRAWBLIT + When it's not zero, we will enable HAL 3D drawblit + to replace client 3dblit. +*/ +#ifndef gcdHAL_3D_DRAWBLIT +# define gcdHAL_3D_DRAWBLIT 1 +#endif + +/* + gcdPARTIAL_FAST_CLEAR + When it's not zero, partial fast clear is enabled. + Depends on gcdHAL_3D_DRAWBLIT, if gcdHAL_3D_DRAWBLIT is not enabled, + only available when scissor box is completely aligned. + Expremental, under test. +*/ +#ifndef gcdPARTIAL_FAST_CLEAR +# define gcdPARTIAL_FAST_CLEAR 1 +#endif + +/* + gcdREMOVE_SURF_ORIENTATION + When it's not zero, we will remove surface orientation function. + It wil become to a parameter of resolve function. +*/ +#ifndef gcdREMOVE_SURF_ORIENTATION +# 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 + + +/* + gcdFRAMEINFO_STATISTIC + When enable, collect frame information. +*/ +#ifndef gcdFRAMEINFO_STATISTIC + +#if (defined(DBG) && DBG) || defined(DEBUG) || defined(_DEBUG) || gcdDUMP +# define gcdFRAMEINFO_STATISTIC 1 +#else +# define gcdFRAMEINFO_STATISTIC 0 +#endif + +#endif + +/* + gcdPACKED_OUTPUT_ADDRESS + When it's not zero, ps output is already packed after linked +*/ +#ifndef gcdPACKED_OUTPUT_ADDRESS +# define gcdPACKED_OUTPUT_ADDRESS 1 +#endif + +/* + gcdENABLE_THIRD_PARTY_OPERATION + Enable third party operation like tpc or not. +*/ +#ifndef gcdENABLE_THIRD_PARTY_OPERATION +# define gcdENABLE_THIRD_PARTY_OPERATION 1 +#endif + + +/* + Core configurations. By default enable all cores. +*/ +#ifndef gcdENABLE_3D +# define gcdENABLE_3D 1 +#endif + +#ifndef gcdENABLE_2D +# define gcdENABLE_2D 1 +#endif + +#ifndef gcdENABLE_VG +# define gcdENABLE_VG 0 +#endif + +#ifndef gcdGC355_MEM_PRINT +# define gcdGC355_MEM_PRINT 0 +#else +#if (!((gcdENABLE_3D == 0) && (gcdENABLE_2D == 0) && (gcdENABLE_VG == 1))) +# undef gcdGC355_MEM_PRINT +# define gcdGC355_MEM_PRINT 0 +# endif +#endif + +#ifndef gcdENABLE_UNIFIED_CONSTANT +# define gcdENABLE_UNIFIED_CONSTANT 1 +#endif + +/* + gcdRECORD_COMMAND +*/ +#ifndef gcdRECORD_COMMAND +# define gcdRECORD_COMMAND 0 #endif #endif /* __gc_hal_options_h_ */ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h index aed73aa82c34..d2abf9a5c685 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,6 +22,10 @@ #ifndef __gc_hal_profiler_h_ #define __gc_hal_profiler_h_ +#if VIVANTE_PROFILER_NEW +#include "gc_hal_engine.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -35,6 +39,9 @@ extern "C" { #define GLTEXTURE_OBJECT 30 #define GLTEXTURE_OBJECT_BYTES 31 +#define GLBUFOBJ_OBJECT 40 +#define GLBUFOBJ_OBJECT_BYTES 41 + #if VIVANTE_PROFILER #define gcmPROFILE_GC(Enum, Value) gcoPROFILER_Count(gcvNULL, Enum, Value) #else @@ -52,12 +59,12 @@ extern "C" { #define ES11_LINECOUNT (ES11_POINTCOUNT + 1) #define ES11_TRIANGLECOUNT (ES11_LINECOUNT + 1) -#define ES20_CALLS 159 -#define ES20_DRAWCALLS (ES20_CALLS + 1) -#define ES20_STATECHANGECALLS (ES20_DRAWCALLS + 1) -#define ES20_POINTCOUNT (ES20_STATECHANGECALLS + 1) -#define ES20_LINECOUNT (ES20_POINTCOUNT + 1) -#define ES20_TRIANGLECOUNT (ES20_LINECOUNT + 1) +#define ES30_CALLS 159 +#define ES30_DRAWCALLS (ES30_CALLS + 1) +#define ES30_STATECHANGECALLS (ES30_DRAWCALLS + 1) +#define ES30_POINTCOUNT (ES30_STATECHANGECALLS + 1) +#define ES30_LINECOUNT (ES30_POINTCOUNT + 1) +#define ES30_TRIANGLECOUNT (ES30_LINECOUNT + 1) #define VG11_CALLS 88 #define VG11_DRAWCALLS (VG11_CALLS + 1) @@ -164,7 +171,7 @@ extern "C" { #define VPG_TIME 0x030000 #define VPG_MEM 0x040000 #define VPG_ES11 0x050000 -#define VPG_ES20 0x060000 +#define VPG_ES30 0x060000 #define VPG_VG11 0x070000 #define VPG_HAL 0x080000 #define VPG_HW 0x090000 @@ -182,10 +189,11 @@ extern "C" { #define VPG_PVS 0x150000 #define VPG_PPS 0x160000 #define VPG_ES11_TIME 0x170000 -#define VPG_ES20_TIME 0x180000 +#define VPG_ES30_TIME 0x180000 #define VPG_FRAME 0x190000 #define VPG_ES11_DRAW 0x200000 -#define VPG_ES20_DRAW 0x210000 +#define VPG_ES30_DRAW 0x210000 +#define VPG_VG11_TIME 0x220000 #define VPG_END 0xff0000 /* Info. */ @@ -214,13 +222,13 @@ extern "C" { #define VPC_ES11LINECOUNT (VPG_ES11 + ES11_LINECOUNT) #define VPC_ES11TRIANGLECOUNT (VPG_ES11 + ES11_TRIANGLECOUNT) -/* OpenGL ES20 Statistics Counter IDs. */ -#define VPC_ES20CALLS (VPG_ES20 + ES20_CALLS) -#define VPC_ES20DRAWCALLS (VPG_ES20 + ES20_DRAWCALLS) -#define VPC_ES20STATECHANGECALLS (VPG_ES20 + ES20_STATECHANGECALLS) -#define VPC_ES20POINTCOUNT (VPG_ES20 + ES20_POINTCOUNT) -#define VPC_ES20LINECOUNT (VPG_ES20 + ES20_LINECOUNT) -#define VPC_ES20TRIANGLECOUNT (VPG_ES20 + ES20_TRIANGLECOUNT) +/* OpenGL ES30 Statistics Counter IDs. */ +#define VPC_ES30CALLS (VPG_ES30 + ES30_CALLS) +#define VPC_ES30DRAWCALLS (VPG_ES30 + ES30_DRAWCALLS) +#define VPC_ES30STATECHANGECALLS (VPG_ES30 + ES30_STATECHANGECALLS) +#define VPC_ES30POINTCOUNT (VPG_ES30 + ES30_POINTCOUNT) +#define VPC_ES30LINECOUNT (VPG_ES30 + ES30_LINECOUNT) +#define VPC_ES30TRIANGLECOUNT (VPG_ES30 + ES30_TRIANGLECOUNT) /* OpenVG Statistics Counter IDs. */ #define VPC_VG11CALLS (VPG_VG11 + VG11_CALLS) @@ -329,11 +337,8 @@ extern "C" { #define VPC_PROGRAMHANDLE (VPG_PROG + 1) -#define VPG_ES20_DRAW_NO (VPG_ES20_DRAW + 1) -#define VPG_ES11_DRAW_NO (VPG_ES11_DRAW + 1) - -#define VPG_FRAME_USEVBO (VPG_FRAME + 1) - +#define VPC_ES30_DRAW_NO (VPG_ES30_DRAW + 1) +#define VPC_ES11_DRAW_NO (VPG_ES11_DRAW + 1) #endif @@ -416,6 +421,10 @@ typedef struct _gcsPROFILER_COUNTERS } gcsPROFILER_COUNTERS; +#if VIVANTE_PROFILER_NEW +#define NumOfDrawBuf 64 +#endif + /* HAL profile information. */ typedef struct _gcsPROFILER { @@ -424,6 +433,7 @@ typedef struct _gcsPROFILER gctBOOL enableHW; gctBOOL enableSH; gctBOOL isSyncMode; + gctBOOL disableOutputCounter; gctBOOL useSocket; gctINT sockFd; @@ -476,8 +486,10 @@ typedef struct _gcsPROFILER gctUINT32 prevPSTexInstCount; gctUINT32 prevPSPixelCount; - char* psSource; - char* vsSource; +#if VIVANTE_PROFILER_NEW + gcoBUFOBJ newCounterBuf[NumOfDrawBuf]; + gctUINT32 curBufId; +#endif } gcsPROFILER; @@ -507,7 +519,8 @@ struct _gcsSHADER_PROFILER /* Initialize the gcsProfiler. */ gceSTATUS gcoPROFILER_Initialize( - IN gcoHAL Hal + IN gcoHAL Hal, + IN gctBOOL Enable ); /* Destroy the gcProfiler. */ @@ -546,21 +559,9 @@ gcoPROFILER_EndDraw( /* Increase profile counter Enum by Value. */ gceSTATUS gcoPROFILER_Count( - IN gcoHAL Hal, - IN gctUINT32 Enum, - IN gctINT Value - ); - -gceSTATUS -gcoPROFILER_ShaderSourceFS( - IN gcoHAL Hal, - IN char* source - ); - -gceSTATUS -gcoPROFILER_ShaderSourceVS( IN gcoHAL Hal, - IN char* source + IN gctUINT32 Enum, + IN gctINT Value ); /* Profile input vertex shader. */ 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 6e4d830ee74b..035b76e09279 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -33,8 +33,8 @@ extern "C" { ****************************** Object Declarations ***************************** \******************************************************************************/ -typedef struct _gcoBRUSH * gcoBRUSH; -typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE; +typedef struct _gcoBRUSH * gcoBRUSH; +typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE; /******************************************************************************\ ******************************** gcoBRUSH Object ******************************* @@ -43,44 +43,44 @@ typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE; /* Create a new solid color gcoBRUSH object. */ gceSTATUS gcoBRUSH_ConstructSingleColor( - IN gcoHAL Hal, - IN gctUINT32 ColorConvert, - IN gctUINT32 Color, - IN gctUINT64 Mask, - gcoBRUSH * Brush - ); + IN gcoHAL Hal, + IN gctUINT32 ColorConvert, + IN gctUINT32 Color, + IN gctUINT64 Mask, + gcoBRUSH * Brush + ); /* Create a new monochrome gcoBRUSH object. */ gceSTATUS gcoBRUSH_ConstructMonochrome( - IN gcoHAL Hal, - IN gctUINT32 OriginX, - IN gctUINT32 OriginY, - IN gctUINT32 ColorConvert, - IN gctUINT32 FgColor, - IN gctUINT32 BgColor, - IN gctUINT64 Bits, - IN gctUINT64 Mask, - gcoBRUSH * Brush - ); + IN gcoHAL Hal, + IN gctUINT32 OriginX, + IN gctUINT32 OriginY, + IN gctUINT32 ColorConvert, + IN gctUINT32 FgColor, + IN gctUINT32 BgColor, + IN gctUINT64 Bits, + IN gctUINT64 Mask, + gcoBRUSH * Brush + ); /* Create a color gcoBRUSH object. */ gceSTATUS gcoBRUSH_ConstructColor( - IN gcoHAL Hal, - IN gctUINT32 OriginX, - IN gctUINT32 OriginY, - IN gctPOINTER Address, - IN gceSURF_FORMAT Format, - IN gctUINT64 Mask, - gcoBRUSH * Brush - ); + IN gcoHAL Hal, + IN gctUINT32 OriginX, + IN gctUINT32 OriginY, + IN gctPOINTER Address, + IN gceSURF_FORMAT Format, + IN gctUINT64 Mask, + gcoBRUSH * Brush + ); /* Destroy an gcoBRUSH object. */ gceSTATUS gcoBRUSH_Destroy( - IN gcoBRUSH Brush - ); + IN gcoBRUSH Brush + ); /******************************************************************************\ ******************************** gcoSURF Object ******************************* @@ -89,138 +89,151 @@ gcoBRUSH_Destroy( /* Set cipping rectangle. */ gceSTATUS gcoSURF_SetClipping( - IN gcoSURF Surface - ); + IN gcoSURF Surface + ); /* Clear one or more rectangular areas. */ gceSTATUS gcoSURF_Clear2D( - IN gcoSURF DestSurface, - IN gctUINT32 RectCount, - IN gcsRECT_PTR DestRect, - IN gctUINT32 LoColor, - IN gctUINT32 HiColor - ); + IN gcoSURF DestSurface, + IN gctUINT32 RectCount, + IN gcsRECT_PTR DestRect, + IN gctUINT32 LoColor, + IN gctUINT32 HiColor + ); /* Draw one or more Bresenham lines. */ gceSTATUS gcoSURF_Line( - IN gcoSURF Surface, - IN gctUINT32 LineCount, - IN gcsRECT_PTR Position, - IN gcoBRUSH Brush, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop - ); + IN gcoSURF Surface, + IN gctUINT32 LineCount, + IN gcsRECT_PTR Position, + IN gcoBRUSH Brush, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop + ); /* Generic rectangular blit. */ gceSTATUS gcoSURF_Blit( - IN OPTIONAL gcoSURF SrcSurface, - IN gcoSURF DestSurface, - IN gctUINT32 RectCount, - IN OPTIONAL gcsRECT_PTR SrcRect, - IN gcsRECT_PTR DestRect, - IN OPTIONAL gcoBRUSH Brush, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN OPTIONAL gceSURF_TRANSPARENCY Transparency, - IN OPTIONAL gctUINT32 TransparencyColor, - IN OPTIONAL gctPOINTER Mask, - IN OPTIONAL gceSURF_MONOPACK MaskPack - ); + IN OPTIONAL gcoSURF SrcSurface, + IN gcoSURF DestSurface, + IN gctUINT32 RectCount, + IN OPTIONAL gcsRECT_PTR SrcRect, + IN gcsRECT_PTR DestRect, + IN OPTIONAL gcoBRUSH Brush, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN OPTIONAL gceSURF_TRANSPARENCY Transparency, + IN OPTIONAL gctUINT32 TransparencyColor, + IN OPTIONAL gctPOINTER Mask, + IN OPTIONAL gceSURF_MONOPACK MaskPack + ); /* Monochrome blit. */ gceSTATUS gcoSURF_MonoBlit( - IN gcoSURF DestSurface, - IN gctPOINTER Source, - IN gceSURF_MONOPACK SourcePack, - IN gcsPOINT_PTR SourceSize, - IN gcsPOINT_PTR SourceOrigin, - IN gcsRECT_PTR DestRect, - IN OPTIONAL gcoBRUSH Brush, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gctBOOL ColorConvert, - IN gctUINT8 MonoTransparency, - IN gceSURF_TRANSPARENCY Transparency, - IN gctUINT32 FgColor, - IN gctUINT32 BgColor - ); + IN gcoSURF DestSurface, + IN gctPOINTER Source, + IN gceSURF_MONOPACK SourcePack, + IN gcsPOINT_PTR SourceSize, + IN gcsPOINT_PTR SourceOrigin, + IN gcsRECT_PTR DestRect, + IN OPTIONAL gcoBRUSH Brush, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gctBOOL ColorConvert, + IN gctUINT8 MonoTransparency, + IN gceSURF_TRANSPARENCY Transparency, + IN gctUINT32 FgColor, + IN gctUINT32 BgColor + ); /* Filter blit. */ gceSTATUS gcoSURF_FilterBlit( - IN gcoSURF SrcSurface, - IN gcoSURF DestSurface, - IN gcsRECT_PTR SrcRect, - IN gcsRECT_PTR DestRect, - IN gcsRECT_PTR DestSubRect - ); + IN gcoSURF SrcSurface, + IN gcoSURF DestSurface, + IN gcsRECT_PTR SrcRect, + IN gcsRECT_PTR DestRect, + IN gcsRECT_PTR DestSubRect + ); /* Enable alpha blending engine in the hardware and disengage the ROP engine. */ gceSTATUS gcoSURF_EnableAlphaBlend( - IN gcoSURF Surface, - IN gctUINT8 SrcGlobalAlphaValue, - IN gctUINT8 DstGlobalAlphaValue, - IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode, - IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode, - IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode, - IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode, - IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode, - IN gceSURF_BLEND_FACTOR_MODE DstFactorMode, - IN gceSURF_PIXEL_COLOR_MODE SrcColorMode, - IN gceSURF_PIXEL_COLOR_MODE DstColorMode - ); + IN gcoSURF Surface, + IN gctUINT8 SrcGlobalAlphaValue, + IN gctUINT8 DstGlobalAlphaValue, + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode, + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode, + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode, + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode, + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode, + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode, + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode, + IN gceSURF_PIXEL_COLOR_MODE DstColorMode + ); /* Disable alpha blending engine in the hardware and engage the ROP engine. */ gceSTATUS gcoSURF_DisableAlphaBlend( - IN gcoSURF Surface - ); + IN gcoSURF Surface + ); /* Copy a rectangular area with format conversion. */ gceSTATUS gcoSURF_CopyPixels( - IN gcoSURF Source, - IN gcoSURF Target, - IN gctINT SourceX, - IN gctINT SourceY, - IN gctINT TargetX, - IN gctINT TargetY, - IN gctINT Width, - IN gctINT Height - ); + IN gcoSURF Source, + IN gcoSURF Target, + IN gctINT SourceX, + IN gctINT SourceY, + IN gctINT TargetX, + IN gctINT TargetY, + IN gctINT Width, + IN gctINT Height + ); /* Read surface pixel. */ gceSTATUS gcoSURF_ReadPixel( - IN gcoSURF Surface, - IN gctPOINTER Memory, - IN gctINT X, - IN gctINT Y, - IN gceSURF_FORMAT Format, - OUT gctPOINTER PixelValue - ); + IN gcoSURF Surface, + IN gctPOINTER Memory, + IN gctINT X, + IN gctINT Y, + IN gceSURF_FORMAT Format, + OUT gctPOINTER PixelValue + ); /* Write surface pixel. */ gceSTATUS gcoSURF_WritePixel( - IN gcoSURF Surface, - IN gctPOINTER Memory, - IN gctINT X, - IN gctINT Y, - IN gceSURF_FORMAT Format, - IN gctPOINTER PixelValue - ); + IN gcoSURF Surface, + IN gctPOINTER Memory, + IN gctINT X, + IN gctINT Y, + IN gceSURF_FORMAT Format, + IN gctPOINTER PixelValue + ); gceSTATUS 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 ********************************* \******************************************************************************/ @@ -228,40 +241,40 @@ gcoSURF_SetDither( /* Construct a new gco2D object. */ gceSTATUS gco2D_Construct( - IN gcoHAL Hal, - OUT gco2D * Hardware - ); + IN gcoHAL Hal, + OUT gco2D * Hardware + ); /* Destroy an gco2D object. */ gceSTATUS gco2D_Destroy( - IN gco2D Hardware - ); + IN gco2D Hardware + ); /* Sets the maximum number of brushes in the brush cache. */ gceSTATUS gco2D_SetBrushLimit( - IN gco2D Hardware, - IN gctUINT MaxCount - ); + IN gco2D Hardware, + IN gctUINT MaxCount + ); /* Flush the brush. */ gceSTATUS gco2D_FlushBrush( - IN gco2D Engine, - IN gcoBRUSH Brush, - IN gceSURF_FORMAT Format - ); + IN gco2D Engine, + IN gcoBRUSH Brush, + IN gceSURF_FORMAT Format + ); /* Program the specified solid color brush. */ gceSTATUS gco2D_LoadSolidBrush( - IN gco2D Engine, - IN gceSURF_FORMAT Format, - IN gctUINT32 ColorConvert, - IN gctUINT32 Color, - IN gctUINT64 Mask - ); + IN gco2D Engine, + IN gceSURF_FORMAT Format, + IN gctUINT32 ColorConvert, + IN gctUINT32 Color, + IN gctUINT64 Mask + ); gceSTATUS gco2D_LoadMonochromeBrush( @@ -288,57 +301,57 @@ gco2D_LoadColorBrush( /* Configure monochrome source. */ gceSTATUS gco2D_SetMonochromeSource( - IN gco2D Engine, - IN gctBOOL ColorConvert, - IN gctUINT8 MonoTransparency, - IN gceSURF_MONOPACK DataPack, - IN gctBOOL CoordRelative, - IN gceSURF_TRANSPARENCY Transparency, - IN gctUINT32 FgColor, - IN gctUINT32 BgColor - ); + IN gco2D Engine, + IN gctBOOL ColorConvert, + IN gctUINT8 MonoTransparency, + IN gceSURF_MONOPACK DataPack, + IN gctBOOL CoordRelative, + IN gceSURF_TRANSPARENCY Transparency, + IN gctUINT32 FgColor, + IN gctUINT32 BgColor + ); /* Configure color source. */ gceSTATUS gco2D_SetColorSource( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gceSURF_ROTATION Rotation, - IN gctUINT32 SurfaceWidth, - IN gctBOOL CoordRelative, - IN gceSURF_TRANSPARENCY Transparency, - IN gctUINT32 TransparencyColor - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_FORMAT Format, + IN gceSURF_ROTATION Rotation, + IN gctUINT32 SurfaceWidth, + IN gctBOOL CoordRelative, + IN gceSURF_TRANSPARENCY Transparency, + IN gctUINT32 TransparencyColor + ); /* Configure color source extension for full rotation. */ gceSTATUS gco2D_SetColorSourceEx( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gceSURF_ROTATION Rotation, - IN gctUINT32 SurfaceWidth, - IN gctUINT32 SurfaceHeight, - IN gctBOOL CoordRelative, - IN gceSURF_TRANSPARENCY Transparency, - IN gctUINT32 TransparencyColor - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_FORMAT Format, + IN gceSURF_ROTATION Rotation, + IN gctUINT32 SurfaceWidth, + IN gctUINT32 SurfaceHeight, + IN gctBOOL CoordRelative, + IN gceSURF_TRANSPARENCY Transparency, + IN gctUINT32 TransparencyColor + ); /* Configure color source. */ gceSTATUS gco2D_SetColorSourceAdvanced( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gceSURF_ROTATION Rotation, - IN gctUINT32 SurfaceWidth, - IN gctUINT32 SurfaceHeight, - IN gctBOOL CoordRelative - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_FORMAT Format, + IN gceSURF_ROTATION Rotation, + IN gctUINT32 SurfaceWidth, + IN gctUINT32 SurfaceHeight, + IN gctBOOL CoordRelative + ); gceSTATUS gco2D_SetColorSourceN( @@ -355,62 +368,62 @@ gco2D_SetColorSourceN( /* Configure masked color source. */ gceSTATUS gco2D_SetMaskedSource( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gctBOOL CoordRelative, - IN gceSURF_MONOPACK MaskPack - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_FORMAT Format, + IN gctBOOL CoordRelative, + IN gceSURF_MONOPACK MaskPack + ); /* Configure masked color source extension for full rotation. */ gceSTATUS gco2D_SetMaskedSourceEx( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_FORMAT Format, - IN gctBOOL CoordRelative, - IN gceSURF_MONOPACK MaskPack, - IN gceSURF_ROTATION Rotation, - IN gctUINT32 SurfaceWidth, - IN gctUINT32 SurfaceHeight - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_FORMAT Format, + IN gctBOOL CoordRelative, + IN gceSURF_MONOPACK MaskPack, + IN gceSURF_ROTATION Rotation, + IN gctUINT32 SurfaceWidth, + IN gctUINT32 SurfaceHeight + ); /* Setup the source rectangle. */ gceSTATUS gco2D_SetSource( - IN gco2D Engine, - IN gcsRECT_PTR SrcRect - ); + IN gco2D Engine, + IN gcsRECT_PTR SrcRect + ); /* Set clipping rectangle. */ gceSTATUS gco2D_SetClipping( - IN gco2D Engine, - IN gcsRECT_PTR Rect - ); + IN gco2D Engine, + IN gcsRECT_PTR Rect + ); /* Configure destination. */ gceSTATUS gco2D_SetTarget( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_ROTATION Rotation, - IN gctUINT32 SurfaceWidth - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_ROTATION Rotation, + IN gctUINT32 SurfaceWidth + ); /* Configure destination extension for full rotation. */ gceSTATUS gco2D_SetTargetEx( - IN gco2D Engine, - IN gctUINT32 Address, - IN gctUINT32 Stride, - IN gceSURF_ROTATION Rotation, - IN gctUINT32 SurfaceWidth, - IN gctUINT32 SurfaceHeight - ); + IN gco2D Engine, + IN gctUINT32 Address, + IN gctUINT32 Stride, + IN gceSURF_ROTATION Rotation, + IN gctUINT32 SurfaceWidth, + IN gctUINT32 SurfaceHeight + ); /* Calculate and program the stretch factors. */ gceSTATUS @@ -423,101 +436,101 @@ gco2D_CalcStretchFactor( gceSTATUS gco2D_SetStretchFactors( - IN gco2D Engine, - IN gctUINT32 HorFactor, - IN gctUINT32 VerFactor - ); + IN gco2D Engine, + IN gctUINT32 HorFactor, + IN gctUINT32 VerFactor + ); /* Calculate and program the stretch factors based on the rectangles. */ gceSTATUS gco2D_SetStretchRectFactors( - IN gco2D Engine, - IN gcsRECT_PTR SrcRect, - IN gcsRECT_PTR DestRect - ); + IN gco2D Engine, + IN gcsRECT_PTR SrcRect, + IN gcsRECT_PTR DestRect + ); /* Create a new solid color gcoBRUSH object. */ gceSTATUS gco2D_ConstructSingleColorBrush( - IN gco2D Engine, - IN gctUINT32 ColorConvert, - IN gctUINT32 Color, - IN gctUINT64 Mask, - gcoBRUSH * Brush - ); + IN gco2D Engine, + IN gctUINT32 ColorConvert, + IN gctUINT32 Color, + IN gctUINT64 Mask, + gcoBRUSH * Brush + ); /* Create a new monochrome gcoBRUSH object. */ gceSTATUS gco2D_ConstructMonochromeBrush( - IN gco2D Engine, - IN gctUINT32 OriginX, - IN gctUINT32 OriginY, - IN gctUINT32 ColorConvert, - IN gctUINT32 FgColor, - IN gctUINT32 BgColor, - IN gctUINT64 Bits, - IN gctUINT64 Mask, - gcoBRUSH * Brush - ); + IN gco2D Engine, + IN gctUINT32 OriginX, + IN gctUINT32 OriginY, + IN gctUINT32 ColorConvert, + IN gctUINT32 FgColor, + IN gctUINT32 BgColor, + IN gctUINT64 Bits, + IN gctUINT64 Mask, + gcoBRUSH * Brush + ); /* Create a color gcoBRUSH object. */ gceSTATUS gco2D_ConstructColorBrush( - IN gco2D Engine, - IN gctUINT32 OriginX, - IN gctUINT32 OriginY, - IN gctPOINTER Address, - IN gceSURF_FORMAT Format, - IN gctUINT64 Mask, - gcoBRUSH * Brush - ); + IN gco2D Engine, + IN gctUINT32 OriginX, + IN gctUINT32 OriginY, + IN gctPOINTER Address, + IN gceSURF_FORMAT Format, + IN gctUINT64 Mask, + gcoBRUSH * Brush + ); /* Clear one or more rectangular areas. */ gceSTATUS gco2D_Clear( - IN gco2D Engine, - IN gctUINT32 RectCount, - IN gcsRECT_PTR Rect, - IN gctUINT32 Color32, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctUINT32 RectCount, + IN gcsRECT_PTR Rect, + IN gctUINT32 Color32, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gceSURF_FORMAT DestFormat + ); /* Draw one or more Bresenham lines. */ gceSTATUS gco2D_Line( - IN gco2D Engine, - IN gctUINT32 LineCount, - IN gcsRECT_PTR Position, - IN gcoBRUSH Brush, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctUINT32 LineCount, + IN gcsRECT_PTR Position, + IN gcoBRUSH Brush, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gceSURF_FORMAT DestFormat + ); /* Draw one or more Bresenham lines based on the 32-bit color. */ gceSTATUS gco2D_ColorLine( - IN gco2D Engine, - IN gctUINT32 LineCount, - IN gcsRECT_PTR Position, - IN gctUINT32 Color32, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctUINT32 LineCount, + IN gcsRECT_PTR Position, + IN gctUINT32 Color32, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gceSURF_FORMAT DestFormat + ); /* Generic blit. */ gceSTATUS gco2D_Blit( - IN gco2D Engine, - IN gctUINT32 RectCount, - IN gcsRECT_PTR Rect, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctUINT32 RectCount, + IN gcsRECT_PTR Rect, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gceSURF_FORMAT DestFormat + ); gceSTATUS gco2D_Blend( @@ -533,40 +546,40 @@ gco2D_Blend( /* Batch blit. */ gceSTATUS gco2D_BatchBlit( - IN gco2D Engine, - IN gctUINT32 RectCount, - IN gcsRECT_PTR SrcRect, - IN gcsRECT_PTR DestRect, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctUINT32 RectCount, + IN gcsRECT_PTR SrcRect, + IN gcsRECT_PTR DestRect, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gceSURF_FORMAT DestFormat + ); /* Stretch blit. */ gceSTATUS gco2D_StretchBlit( - IN gco2D Engine, - IN gctUINT32 RectCount, - IN gcsRECT_PTR Rect, - IN gctUINT8 FgRop, - IN gctUINT8 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctUINT32 RectCount, + IN gcsRECT_PTR Rect, + IN gctUINT8 FgRop, + IN gctUINT8 BgRop, + IN gceSURF_FORMAT DestFormat + ); /* Monochrome blit. */ gceSTATUS gco2D_MonoBlit( - IN gco2D Engine, - IN gctPOINTER StreamBits, - IN gcsPOINT_PTR StreamSize, - IN gcsRECT_PTR StreamRect, - IN gceSURF_MONOPACK SrcStreamPack, - IN gceSURF_MONOPACK DestStreamPack, - IN gcsRECT_PTR DestRect, - IN gctUINT32 FgRop, - IN gctUINT32 BgRop, - IN gceSURF_FORMAT DestFormat - ); + IN gco2D Engine, + IN gctPOINTER StreamBits, + IN gcsPOINT_PTR StreamSize, + IN gcsRECT_PTR StreamRect, + IN gceSURF_MONOPACK SrcStreamPack, + IN gceSURF_MONOPACK DestStreamPack, + IN gcsRECT_PTR DestRect, + IN gctUINT32 FgRop, + IN gctUINT32 BgRop, + IN gceSURF_FORMAT DestFormat + ); gceSTATUS gco2D_MonoBlitEx( @@ -588,87 +601,87 @@ gco2D_MonoBlitEx( /* Set kernel size. */ gceSTATUS gco2D_SetKernelSize( - IN gco2D Engine, - IN gctUINT8 HorKernelSize, - IN gctUINT8 VerKernelSize - ); + IN gco2D Engine, + IN gctUINT8 HorKernelSize, + IN gctUINT8 VerKernelSize + ); /* Set filter type. */ gceSTATUS gco2D_SetFilterType( - IN gco2D Engine, - IN gceFILTER_TYPE FilterType - ); + IN gco2D Engine, + IN gceFILTER_TYPE FilterType + ); /* Set the filter kernel by user. */ gceSTATUS gco2D_SetUserFilterKernel( - IN gco2D Engine, - IN gceFILTER_PASS_TYPE PassType, - IN gctUINT16_PTR KernelArray - ); + IN gco2D Engine, + IN gceFILTER_PASS_TYPE PassType, + IN gctUINT16_PTR KernelArray + ); /* Select the pass(es) to be done for user defined filter. */ gceSTATUS gco2D_EnableUserFilterPasses( - IN gco2D Engine, - IN gctBOOL HorPass, - IN gctBOOL VerPass - ); + IN gco2D Engine, + IN gctBOOL HorPass, + IN gctBOOL VerPass + ); /* Frees the temporary buffer allocated by filter blit operation. */ gceSTATUS gco2D_FreeFilterBuffer( - IN gco2D Engine - ); + IN gco2D Engine + ); /* Filter blit. */ gceSTATUS gco2D_FilterBlit( - IN gco2D Engine, - IN gctUINT32 SrcAddress, - IN gctUINT SrcStride, - IN gctUINT32 SrcUAddress, - IN gctUINT SrcUStride, - IN gctUINT32 SrcVAddress, - IN gctUINT SrcVStride, - IN gceSURF_FORMAT SrcFormat, - IN gceSURF_ROTATION SrcRotation, - IN gctUINT32 SrcSurfaceWidth, - IN gcsRECT_PTR SrcRect, - IN gctUINT32 DestAddress, - IN gctUINT DestStride, - IN gceSURF_FORMAT DestFormat, - IN gceSURF_ROTATION DestRotation, - IN gctUINT32 DestSurfaceWidth, - IN gcsRECT_PTR DestRect, - IN gcsRECT_PTR DestSubRect - ); + IN gco2D Engine, + IN gctUINT32 SrcAddress, + IN gctUINT SrcStride, + IN gctUINT32 SrcUAddress, + IN gctUINT SrcUStride, + IN gctUINT32 SrcVAddress, + IN gctUINT SrcVStride, + IN gceSURF_FORMAT SrcFormat, + IN gceSURF_ROTATION SrcRotation, + IN gctUINT32 SrcSurfaceWidth, + IN gcsRECT_PTR SrcRect, + IN gctUINT32 DestAddress, + IN gctUINT DestStride, + IN gceSURF_FORMAT DestFormat, + IN gceSURF_ROTATION DestRotation, + IN gctUINT32 DestSurfaceWidth, + IN gcsRECT_PTR DestRect, + IN gcsRECT_PTR DestSubRect + ); /* Filter blit extension for full rotation. */ gceSTATUS gco2D_FilterBlitEx( - IN gco2D Engine, - IN gctUINT32 SrcAddress, - IN gctUINT SrcStride, - IN gctUINT32 SrcUAddress, - IN gctUINT SrcUStride, - IN gctUINT32 SrcVAddress, - IN gctUINT SrcVStride, - IN gceSURF_FORMAT SrcFormat, - IN gceSURF_ROTATION SrcRotation, - IN gctUINT32 SrcSurfaceWidth, - IN gctUINT32 SrcSurfaceHeight, - IN gcsRECT_PTR SrcRect, - IN gctUINT32 DestAddress, - IN gctUINT DestStride, - IN gceSURF_FORMAT DestFormat, - IN gceSURF_ROTATION DestRotation, - IN gctUINT32 DestSurfaceWidth, - IN gctUINT32 DestSurfaceHeight, - IN gcsRECT_PTR DestRect, - IN gcsRECT_PTR DestSubRect - ); + IN gco2D Engine, + IN gctUINT32 SrcAddress, + IN gctUINT SrcStride, + IN gctUINT32 SrcUAddress, + IN gctUINT SrcUStride, + IN gctUINT32 SrcVAddress, + IN gctUINT SrcVStride, + IN gceSURF_FORMAT SrcFormat, + IN gceSURF_ROTATION SrcRotation, + IN gctUINT32 SrcSurfaceWidth, + IN gctUINT32 SrcSurfaceHeight, + IN gcsRECT_PTR SrcRect, + IN gctUINT32 DestAddress, + IN gctUINT DestStride, + IN gceSURF_FORMAT DestFormat, + IN gceSURF_ROTATION DestRotation, + IN gctUINT32 DestSurfaceWidth, + IN gctUINT32 DestSurfaceHeight, + IN gcsRECT_PTR DestRect, + IN gcsRECT_PTR DestSubRect + ); gceSTATUS gco2D_FilterBlitEx2( @@ -699,94 +712,94 @@ gco2D_FilterBlitEx2( /* Enable alpha blending engine in the hardware and disengage the ROP engine. */ gceSTATUS gco2D_EnableAlphaBlend( - IN gco2D Engine, - IN gctUINT8 SrcGlobalAlphaValue, - IN gctUINT8 DstGlobalAlphaValue, - IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode, - IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode, - IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode, - IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode, - IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode, - IN gceSURF_BLEND_FACTOR_MODE DstFactorMode, - IN gceSURF_PIXEL_COLOR_MODE SrcColorMode, - IN gceSURF_PIXEL_COLOR_MODE DstColorMode - ); + IN gco2D Engine, + IN gctUINT8 SrcGlobalAlphaValue, + IN gctUINT8 DstGlobalAlphaValue, + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode, + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode, + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode, + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode, + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode, + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode, + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode, + IN gceSURF_PIXEL_COLOR_MODE DstColorMode + ); /* Enable alpha blending engine in the hardware. */ gceSTATUS gco2D_EnableAlphaBlendAdvanced( - IN gco2D Engine, - IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode, - IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode, - IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode, - IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode, - IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode, - IN gceSURF_BLEND_FACTOR_MODE DstFactorMode - ); + IN gco2D Engine, + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode, + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode, + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode, + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode, + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode, + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode + ); /* Enable alpha blending engine with Porter Duff rule. */ gceSTATUS gco2D_SetPorterDuffBlending( - IN gco2D Engine, - IN gce2D_PORTER_DUFF_RULE Rule - ); + IN gco2D Engine, + IN gce2D_PORTER_DUFF_RULE Rule + ); /* Disable alpha blending engine in the hardware and engage the ROP engine. */ gceSTATUS gco2D_DisableAlphaBlend( - IN gco2D Engine - ); + IN gco2D Engine + ); /* Retrieve the maximum number of 32-bit data chunks for a single DE command. */ gctUINT32 gco2D_GetMaximumDataCount( - void - ); + void + ); /* Retrieve the maximum number of rectangles, that can be passed in a single DE command. */ gctUINT32 gco2D_GetMaximumRectCount( - void - ); + void + ); /* Returns the pixel alignment of the surface. */ gceSTATUS gco2D_GetPixelAlignment( - gceSURF_FORMAT Format, - gcsPOINT_PTR Alignment - ); + gceSURF_FORMAT Format, + gcsPOINT_PTR Alignment + ); /* Retrieve monochrome stream pack size. */ gceSTATUS gco2D_GetPackSize( - IN gceSURF_MONOPACK StreamPack, - OUT gctUINT32 * PackWidth, - OUT gctUINT32 * PackHeight - ); + IN gceSURF_MONOPACK StreamPack, + OUT gctUINT32 * PackWidth, + OUT gctUINT32 * PackHeight + ); /* Flush the 2D pipeline. */ gceSTATUS gco2D_Flush( - IN gco2D Engine - ); + IN gco2D Engine + ); /* Load 256-entry color table for INDEX8 source surfaces. */ gceSTATUS gco2D_LoadPalette( - IN gco2D Engine, - IN gctUINT FirstIndex, - IN gctUINT IndexCount, - IN gctPOINTER ColorTable, - IN gctBOOL ColorConvert - ); + IN gco2D Engine, + IN gctUINT FirstIndex, + IN gctUINT IndexCount, + IN gctPOINTER ColorTable, + IN gctBOOL ColorConvert + ); /* Enable/disable 2D BitBlt mirrorring. */ gceSTATUS gco2D_SetBitBlitMirror( - IN gco2D Engine, - IN gctBOOL HorizontalMirror, - IN gctBOOL VerticalMirror - ); + IN gco2D Engine, + IN gctBOOL HorizontalMirror, + IN gctBOOL VerticalMirror + ); /* * Set the transparency for source, destination and pattern. @@ -799,82 +812,82 @@ gco2D_SetTransparencyAdvancedEx( IN gce2D_TRANSPARENCY DstTransparency, IN gce2D_TRANSPARENCY PatTransparency, IN gctBOOL EnableDFBColorKeyMode - ); + ); /* Set the transparency for source, destination and pattern. */ gceSTATUS gco2D_SetTransparencyAdvanced( - IN gco2D Engine, - IN gce2D_TRANSPARENCY SrcTransparency, - IN gce2D_TRANSPARENCY DstTransparency, - IN gce2D_TRANSPARENCY PatTransparency - ); + IN gco2D Engine, + IN gce2D_TRANSPARENCY SrcTransparency, + IN gce2D_TRANSPARENCY DstTransparency, + IN gce2D_TRANSPARENCY PatTransparency + ); /* Set the source color key. */ gceSTATUS gco2D_SetSourceColorKeyAdvanced( - IN gco2D Engine, - IN gctUINT32 ColorKey - ); + IN gco2D Engine, + IN gctUINT32 ColorKey + ); /* Set the source color key range. */ gceSTATUS gco2D_SetSourceColorKeyRangeAdvanced( - IN gco2D Engine, - IN gctUINT32 ColorKeyLow, - IN gctUINT32 ColorKeyHigh - ); + IN gco2D Engine, + IN gctUINT32 ColorKeyLow, + IN gctUINT32 ColorKeyHigh + ); /* Set the target color key. */ gceSTATUS gco2D_SetTargetColorKeyAdvanced( - IN gco2D Engine, - IN gctUINT32 ColorKey - ); + IN gco2D Engine, + IN gctUINT32 ColorKey + ); /* Set the target color key range. */ gceSTATUS gco2D_SetTargetColorKeyRangeAdvanced( - IN gco2D Engine, - IN gctUINT32 ColorKeyLow, - IN gctUINT32 ColorKeyHigh - ); + IN gco2D Engine, + IN gctUINT32 ColorKeyLow, + IN gctUINT32 ColorKeyHigh + ); /* Set the YUV color space mode. */ gceSTATUS gco2D_SetYUVColorMode( - IN gco2D Engine, - IN gce2D_YUV_COLOR_MODE Mode - ); + IN gco2D Engine, + IN gce2D_YUV_COLOR_MODE Mode + ); /* Setup the source global color value in ARGB8 format. */ gceSTATUS gco2D_SetSourceGlobalColorAdvanced( - IN gco2D Engine, - IN gctUINT32 Color32 - ); + IN gco2D Engine, + IN gctUINT32 Color32 + ); /* Setup the target global color value in ARGB8 format. */ gceSTATUS gco2D_SetTargetGlobalColorAdvanced( - IN gco2D Engine, - IN gctUINT32 Color32 - ); + IN gco2D Engine, + IN gctUINT32 Color32 + ); /* Setup the source and target pixel multiply modes. */ gceSTATUS gco2D_SetPixelMultiplyModeAdvanced( - IN gco2D Engine, - IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha, - IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha, - IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode, - IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha - ); + IN gco2D Engine, + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha, + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha, + IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode, + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha + ); /* Set the GPU clock cycles after which the idle engine will keep auto-flushing. */ gceSTATUS gco2D_SetAutoFlushCycles( - IN gco2D Engine, - IN gctUINT32 Cycles - ); + IN gco2D Engine, + IN gctUINT32 Cycles + ); #if VIVANTE_PROFILER /* Read the profile registers available in the 2D engine and sets them in the profile. @@ -882,17 +895,17 @@ gco2D_SetAutoFlushCycles( */ gceSTATUS gco2D_ProfileEngine( - IN gco2D Engine, - OPTIONAL gcs2D_PROFILE_PTR Profile - ); + IN gco2D Engine, + OPTIONAL gcs2D_PROFILE_PTR Profile + ); #endif /* Enable or disable 2D dithering. */ gceSTATUS gco2D_EnableDither( - IN gco2D Engine, - IN gctBOOL Enable - ); + IN gco2D Engine, + IN gctBOOL Enable + ); gceSTATUS gco2D_SetGenericSource( @@ -1003,6 +1016,21 @@ gco2D_SetTargetRect( IN gcsRECT_PTR Rect ); +gceSTATUS +gco2D_Set2DEngine( + IN gco2D Engine + ); + +gceSTATUS +gco2D_UnSet2DEngine( + IN gco2D Engine + ); + +gceSTATUS +gco2D_Get2DEngine( + OUT gco2D * Engine + ); + #ifdef __cplusplus } #endif 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 6c10fbf78a32..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -49,8 +49,9 @@ #define gckOS_FreeContiguous gcmHAL2D(gckOS_FreeContiguous) #define gckOS_GetPageSize gcmHAL2D(gckOS_GetPageSize) #define gckOS_GetPhysicalAddress gcmHAL2D(gckOS_GetPhysicalAddress) -#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess) -#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical) +#define gckOS_UserLogicalToPhysical gcmHAL2D(gckOS_UserLogicalToPhysical) +#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess) +#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical) #define gckOS_UnmapPhysical gcmHAL2D(gckOS_UnmapPhysical) #define gckOS_ReadRegister gcmHAL2D(gckOS_ReadRegister) #define gckOS_WriteRegister gcmHAL2D(gckOS_WriteRegister) @@ -77,7 +78,6 @@ #define gckOS_QueryNeedCopy gcmHAL2D(gckOS_QueryNeedCopy) #define gckOS_CopyFromUserData gcmHAL2D(gckOS_CopyFromUserData) #define gckOS_CopyToUserData gcmHAL2D(gckOS_CopyToUserData) -#define gckOS_MapUserPhysical gcmHAL2D(gckOS_MapUserPhysical) #define gckOS_SuspendInterrupt gcmHAL2D(gckOS_SuspendInterrupt) #define gckOS_ResumeInterrupt gcmHAL2D(gckOS_ResumeInterrupt) #define gckOS_GetBaseAddress gcmHAL2D(gckOS_GetBaseAddress) @@ -151,7 +151,6 @@ #define gckHARDWARE_Execute gcmHAL2D(gckHARDWARE_Execute) #define gckHARDWARE_End gcmHAL2D(gckHARDWARE_End) #define gckHARDWARE_Nop gcmHAL2D(gckHARDWARE_Nop) -#define gckHARDWARE_Wait gcmHAL2D(gckHARDWARE_Wait) #define gckHARDWARE_PipeSelect gcmHAL2D(gckHARDWARE_PipeSelect) #define gckHARDWARE_Link gcmHAL2D(gckHARDWARE_Link) #define gckHARDWARE_Event gcmHAL2D(gckHARDWARE_Event) @@ -164,7 +163,6 @@ #define gckHARDWARE_AlignToTile gcmHAL2D(gckHARDWARE_AlignToTile) #define gckHARDWARE_UpdateQueueTail gcmHAL2D(gckHARDWARE_UpdateQueueTail) #define gckHARDWARE_ConvertLogical gcmHAL2D(gckHARDWARE_ConvertLogical) -#define gckHARDWARE_ConvertPhysical gcmHAL2D(gckHARDWARE_ConvertPhysical) #define gckHARDWARE_Interrupt gcmHAL2D(gckHARDWARE_Interrupt) #define gckHARDWARE_SetMMU gcmHAL2D(gckHARDWARE_SetMMU) #define gckHARDWARE_FlushMMU gcmHAL2D(gckHARDWARE_FlushMMU) @@ -209,9 +207,6 @@ #define gckMMU_Destroy gcmHAL2D(gckMMU_Destroy) #define gckMMU_AllocatePages gcmHAL2D(gckMMU_AllocatePages) #define gckMMU_FreePages gcmHAL2D(gckMMU_FreePages) -#define gckMMU_InsertNode gcmHAL2D(gckMMU_InsertNode) -#define gckMMU_RemoveNode gcmHAL2D(gckMMU_RemoveNode) -#define gckMMU_FreeHandleMemory gcmHAL2D(gckMMU_FreeHandleMemory) #define gckMMU_Test gcmHAL2D(gckMMU_Test) #define gckHARDWARE_QueryProfileRegisters gcmHAL2D(gckHARDWARE_QueryProfileRegisters) 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 82336e89b418..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -30,6 +30,7 @@ */ #define VIV_STAT_FRAME_BUFFER_SIZE 30 + /* Total number of frames sampled for a mode. This means @@ -64,14 +65,6 @@ typedef struct _gcsSTATISTICS_EARLYZ gcsSTATISTICS_EARLYZ; -/* Defines the statistical data keys monitored by the statistics module */ -typedef enum _gceSTATISTICS_Call -{ - gcvSTAT_ES11_GLDRAWELEMENTS = 1, -} -gceSTATISTICS_Call; - - /* HAL statistics information. */ typedef struct _gcsSTATISTICS { @@ -79,8 +72,6 @@ typedef struct _gcsSTATISTICS gctUINT64 previousFrameTime; gctUINT frame; gcsSTATISTICS_EARLYZ earlyZ; - gctUINT ES11_drawElementsCount; - gctBOOL applyRTestVAFix; } gcsSTATISTICS; @@ -104,12 +95,5 @@ gcfSTATISTICS_DisableDynamicEarlyZ ( IN gctBOOL Disabled ); -/* Checks whether or not glDrawArray function call will be discarded */ -gctBOOL -gcfSTATISTICS_DiscardCall( - gceSTATISTICS_Call Function - ); - - #endif /*__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 b44652944c92..51a686cb7257 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -25,6 +25,29 @@ #include "gc_hal_version.h" #include "gc_hal_options.h" +#if !defined(VIV_KMD) +#if defined(__KERNEL__) +#include "linux/version.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + typedef unsigned long uintptr_t; +# endif +# include "linux/types.h" +#elif defined(UNDER_CE) +#include +#elif defined(_MSC_VER) && (_MSC_VER <= 1500) +#include +#include "vadefs.h" +#elif defined(__QNXNTO__) +#define _QNX_SOURCE +#include +#include +#else +#include +#include +#include +#endif +#endif + #ifdef _WIN32 #pragma warning(disable:4127) /* Conditional expression is constant (do { } ** while(0)). */ @@ -33,6 +56,8 @@ #pragma warning(disable:4131) /* Uses old-style declarator (for Bison and ** Flex generated files). */ #pragma warning(disable:4206) /* Translation unit is empty. */ +#pragma warning(disable:4214) /* Nonstandard extension used : + ** bit field types other than int. */ #endif #ifdef __cplusplus @@ -44,26 +69,27 @@ extern "C" { */ #if defined(__GNUC__) -# define gcdHAS_ELLIPSES 1 /* GCC always has it. */ +# define gcdHAS_ELLIPSIS 1 /* GCC always has it. */ #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define gcdHAS_ELLIPSES 1 /* C99 has it. */ +# define gcdHAS_ELLIPSIS 1 /* C99 has it. */ #elif defined(_MSC_VER) && (_MSC_VER >= 1500) -# define gcdHAS_ELLIPSES 1 /* MSVC 2007+ has it. */ +# define gcdHAS_ELLIPSIS 1 /* MSVC 2007+ has it. */ #elif defined(UNDER_CE) #if UNDER_CE >= 600 -# define gcdHAS_ELLIPSES 1 +# define gcdHAS_ELLIPSIS 1 # else -# define gcdHAS_ELLIPSES 0 +# define gcdHAS_ELLIPSIS 0 # endif #else -# error "gcdHAS_ELLIPSES: Platform could not be determined" +# error "gcdHAS_ELLIPSIS: Platform could not be determined" #endif /******************************************************************************\ ************************************ Keyword *********************************** \******************************************************************************/ - -#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) +#if defined(ANDROID) && defined(__BIONIC_FORTIFY) +# define gcmINLINE __inline__ __attribute__ ((always_inline)) __attribute__ ((gnu_inline)) __attribute__ ((artificial)) +#elif ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__APPLE__)) # define gcmINLINE inline /* C99 keyword. */ #elif defined(__GNUC__) # define gcmINLINE __inline__ /* GNU keyword. */ @@ -128,7 +154,6 @@ typedef int gctBOOL; typedef gctBOOL * gctBOOL_PTR; typedef int gctINT; -typedef long gctLONG; typedef signed char gctINT8; typedef signed short gctINT16; typedef signed int gctINT32; @@ -145,7 +170,7 @@ typedef unsigned char gctUINT8; typedef unsigned short gctUINT16; typedef unsigned int gctUINT32; typedef unsigned long long gctUINT64; -typedef unsigned long gctUINTPTR_T; +typedef uintptr_t gctUINTPTR_T; typedef gctUINT * gctUINT_PTR; typedef gctUINT8 * gctUINT8_PTR; @@ -153,8 +178,9 @@ typedef gctUINT16 * gctUINT16_PTR; typedef gctUINT32 * gctUINT32_PTR; typedef gctUINT64 * gctUINT64_PTR; -typedef unsigned long gctSIZE_T; +typedef size_t gctSIZE_T; typedef gctSIZE_T * gctSIZE_T_PTR; +typedef gctUINT32 gctTRACE; #ifdef __cplusplus # define gcvNULL 0 @@ -162,6 +188,24 @@ typedef gctSIZE_T * gctSIZE_T_PTR; # define gcvNULL ((void *) 0) #endif +#define gcvMAXINT8 0x7f +#define gcvMININT8 0x80 +#define gcvMAXINT16 0x7fff +#define gcvMININT16 0x8000 +#define gcvMAXINT32 0x7fffffff +#define gcvMININT32 0x80000000 +#define gcvMAXINT64 0x7fffffffffffffff +#define gcvMININT64 0x8000000000000000 +#define gcvMAXUINT8 0xff +#define gcvMINUINT8 0x0 +#define gcvMAXUINT16 0xffff +#define gcvMINUINT16 0x8000 +#define gcvMAXUINT32 0xffffffff +#define gcvMINUINT32 0x80000000 +#define gcvMAXUINT64 0xffffffffffffffff +#define gcvMINUINT64 0x8000000000000000 +#define gcvMAXUINTPTR_T (~(gctUINTPTR_T)0) + typedef float gctFLOAT; typedef signed int gctFIXED_POINT; typedef float * gctFLOAT_PTR; @@ -173,8 +217,9 @@ typedef void * gctSIGNAL; typedef void * gctWINDOW; typedef void * gctIMAGE; typedef void * gctSYNC_POINT; +typedef void * gctSHBUF; -typedef void * gctSEMAPHORE; +typedef void * gctSEMAPHORE; typedef void * gctPOINTER; typedef const void * gctCONST_POINTER; @@ -204,6 +249,90 @@ gcuFLOAT_UINT32; #define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000) #define gcvTWO_X ((gctFIXED_POINT) 0x00020000) + + +#define gcmFIXEDCLAMP_NEG1_TO_1(_x) \ + (((_x) < gcvNEGONE_X) \ + ? gcvNEGONE_X \ + : (((_x) > gcvONE_X) \ + ? gcvONE_X \ + : (_x))) + +#define gcmFLOATCLAMP_NEG1_TO_1(_f) \ + (((_f) < -1.0f) \ + ? -1.0f \ + : (((_f) > 1.0f) \ + ? 1.0f \ + : (_f))) + + +#define gcmFIXEDCLAMP_0_TO_1(_x) \ + (((_x) < 0) \ + ? 0 \ + : (((_x) > gcvONE_X) \ + ? gcvONE_X \ + : (_x))) + +#define gcmFLOATCLAMP_0_TO_1(_f) \ + (((_f) < 0.0f) \ + ? 0.0f \ + : (((_f) > 1.0f) \ + ? 1.0f \ + : (_f))) + + +/******************************************************************************\ +******************************* Multicast Values ******************************* +\******************************************************************************/ + +/* Value types. */ +typedef enum _gceVALUE_TYPE +{ + gcvVALUE_UINT = 0x0, + gcvVALUE_FIXED, + gcvVALUE_FLOAT, + gcvVALUE_INT, + + /* + ** The value need be unsigned denormalized. clamp (0.0-1.0) should be done first. + */ + gcvVALUE_FLAG_UNSIGNED_DENORM = 0x00010000, + + /* + ** The value need be signed denormalized. clamp (-1.0-1.0) should be done first. + */ + gcvVALUE_FLAG_SIGNED_DENORM = 0x00020000, + + /* + ** The value need to gammar + */ + gcvVALUE_FLAG_GAMMAR = 0x00040000, + + /* + ** The value need to convert from float to float16 + */ + gcvVALUE_FLAG_FLOAT_TO_FLOAT16 = 0x0080000, + + /* + ** Mask for flag field. + */ + gcvVALUE_FLAG_MASK = 0xFFFF0000, +} +gceVALUE_TYPE; + +/* Value unions. */ +typedef union _gcuVALUE +{ + gctUINT uintValue; + gctFIXED_POINT fixedValue; + gctFLOAT floatValue; + gctINT intValue; +} +gcuVALUE; + + + + /* Stringizing macro. */ #define gcmSTRING(Value) #Value @@ -256,6 +385,7 @@ gcs2D_PROFILE; #define IN #define OUT +#define INOUT #define OPTIONAL /******************************************************************************\ @@ -283,11 +413,9 @@ typedef enum _gceSTATUS gcvSTATUS_INVALID_CONFIG = 15, gcvSTATUS_CHANGED = 16, gcvSTATUS_NOT_SUPPORT_DITHER = 17, - gcvSTATUS_EXECUTED = 18, + gcvSTATUS_EXECUTED = 18, gcvSTATUS_TERMINATE = 19, - gcvSTATUS_CONVERT_TO_SINGLE_STREAM = 20, - gcvSTATUS_INVALID_ARGUMENT = -1, gcvSTATUS_INVALID_OBJECT = -2, gcvSTATUS_OUT_OF_MEMORY = -3, @@ -318,20 +446,37 @@ typedef enum _gceSTATUS gcvSTATUS_NOT_MULTI_PIPE_ALIGNED = -28, /* Linker errors. */ - gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000, - gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001, - gcvSTATUS_TOO_MANY_UNIFORMS = -1002, - gcvSTATUS_TOO_MANY_VARYINGS = -1003, - gcvSTATUS_UNDECLARED_VARYING = -1004, - gcvSTATUS_VARYING_TYPE_MISMATCH = -1005, - gcvSTATUS_MISSING_MAIN = -1006, - gcvSTATUS_NAME_MISMATCH = -1007, - gcvSTATUS_INVALID_INDEX = -1008, - gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1009, + gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000, + gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001, + gcvSTATUS_TOO_MANY_UNIFORMS = -1002, + gcvSTATUS_TOO_MANY_VARYINGS = -1003, + gcvSTATUS_UNDECLARED_VARYING = -1004, + gcvSTATUS_VARYING_TYPE_MISMATCH = -1005, + gcvSTATUS_MISSING_MAIN = -1006, + gcvSTATUS_NAME_MISMATCH = -1007, + gcvSTATUS_INVALID_INDEX = -1008, + gcvSTATUS_UNIFORM_MISMATCH = -1009, + gcvSTATUS_UNSAT_LIB_SYMBOL = -1010, + gcvSTATUS_TOO_MANY_SHADERS = -1011, + gcvSTATUS_LINK_INVALID_SHADERS = -1012, + gcvSTATUS_CS_NO_WORKGROUP_SIZE = -1013, + gcvSTATUS_LINK_LIB_ERROR = -1014, + gcvSTATUS_SHADER_VERSION_MISMATCH = -1015, + gcvSTATUS_TOO_MANY_INSTRUCTION = -1016, + gcvSTATUS_SSBO_MISMATCH = -1017, + gcvSTATUS_TOO_MANY_OUTPUT = -1018, + gcvSTATUS_TOO_MANY_INPUT = -1019, + gcvSTATUS_NOT_SUPPORT_CL = -1020, + gcvSTATUS_NOT_SUPPORT_INTEGER = -1021, + gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1022, + gcvSTATUS_TOO_MANY_SAMPLER = -1023, /* Compiler errors. */ - gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000, - gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001, + gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000, + gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001, + + /* Recompilation Errors */ + gcvSTATUS_RECOMPILER_CONVERT_UNIMPLEMENTED = -3000, } gceSTATUS; @@ -567,254 +712,6 @@ gceSTATUS; ((Address & (~0U << Name ## _LSB)) == (Name ## _Address >> 2)) \ ) -/******************************************************************************* -** -** A set of macros to aid state loading. -** -** ARGUMENTS: -** -** CommandBuffer Pointer to a gcoCMDBUF object. -** StateDelta Pointer to a gcsSTATE_DELTA state delta structure. -** Memory Destination memory pointer of gctUINT32_PTR type. -** PartOfContext Whether or not the state is a part of the context. -** FixedPoint Whether or not the state is of the fixed point format. -** Count Number of consecutive states to be loaded. -** Address State address. -** Data Data to be set to the state. -*/ - -/*----------------------------------------------------------------------------*/ - -#if gcmIS_DEBUG(gcdDEBUG_CODE) - -# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \ - CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \ - CommandBuffer->lastLoadStateAddress = Address; \ - CommandBuffer->lastLoadStateCount = Count - -# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \ - gcmASSERT( \ - (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \ - == \ - (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \ - ); \ - \ - gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \ - \ - CommandBuffer->lastLoadStateCount -= 1 - -# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \ - gcmASSERT(CommandBuffer->lastLoadStateCount == 0) - -#else - -# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) -# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) -# define gcmVERIFYLOADSTATEDONE(CommandBuffer) - -#endif - -#if gcdSECURE_USER - -# define gcmDEFINESECUREUSER() \ - gctUINT __secure_user_offset__; \ - gctUINT32_PTR __secure_user_hintArray__; - -# define gcmBEGINSECUREUSER() \ - __secure_user_offset__ = reserve->lastOffset; \ - \ - __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail) - -# define gcmENDSECUREUSER() \ - reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__) - -# define gcmSKIPSECUREUSER() \ - __secure_user_offset__ += gcmSIZEOF(gctUINT32) - -# define gcmUPDATESECUREUSER() \ - *__secure_user_hintArray__ = __secure_user_offset__; \ - \ - __secure_user_offset__ += gcmSIZEOF(gctUINT32); \ - __secure_user_hintArray__ += 1 - -#else - -# define gcmDEFINESECUREUSER() -# define gcmBEGINSECUREUSER() -# define gcmENDSECUREUSER() -# define gcmSKIPSECUREUSER() -# define gcmUPDATESECUREUSER() - -#endif - -/*----------------------------------------------------------------------------*/ - -#if gcdDUMP -# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \ - if (FixedPoint) \ - { \ - gcmDUMP(gcvNULL, "@[state.x 0x%04X 0x%08X]", \ - Address, Data \ - ); \ - } \ - else \ - { \ - gcmDUMP(gcvNULL, "@[state 0x%04X 0x%08X]", \ - Address, Data \ - ); \ - } -#else -# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) -#endif - -/*----------------------------------------------------------------------------*/ - -#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \ - gcmDEFINESECUREUSER() \ - gctSIZE_T ReserveSize; \ - gcoCMDBUF CommandBuffer; \ - gctUINT32_PTR Memory; \ - gcsSTATE_DELTA_PTR StateDelta - -#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \ -{ \ - gcmONERROR(gcoBUFFER_Reserve( \ - Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \ - )); \ - \ - Memory = gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \ - \ - StateDelta = Hardware->delta; \ - \ - gcmBEGINSECUREUSER(); \ -} - -#define gcmENDSTATEBUFFER(CommandBuffer, Memory, ReserveSize) \ -{ \ - gcmENDSECUREUSER(); \ - \ - gcmASSERT( \ - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \ - == \ - (gctUINT8_PTR) Memory \ - ); \ -} - -/*----------------------------------------------------------------------------*/ - -#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \ -{ \ - gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \ - gcmASSERT((gctUINT32)Count <= 1024); \ - \ - gcmVERIFYLOADSTATEDONE(CommandBuffer); \ - \ - gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \ - \ - *Memory++ \ - = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \ - | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \ - | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \ - | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \ - \ - gcmSKIPSECUREUSER(); \ -} - -#define gcmENDSTATEBATCH(CommandBuffer, Memory) \ -{ \ - gcmVERIFYLOADSTATEDONE(CommandBuffer); \ - \ - gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \ -} - -/*----------------------------------------------------------------------------*/ - -#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \ - Address, Data) \ -{ \ - gctUINT32 __temp_data32__; \ - \ - gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ - \ - __temp_data32__ = Data; \ - \ - *Memory++ = __temp_data32__; \ - \ - gcoHARDWARE_UpdateDelta( \ - StateDelta, FixedPoint, Address, 0, __temp_data32__ \ - ); \ - \ - gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \ - \ - gcmUPDATESECUREUSER(); \ -} - -#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \ -{ \ - gctUINT32 __temp_data32__; \ - \ - gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \ - \ - __temp_data32__ = Data; \ - \ - *Memory++ = __temp_data32__; \ - \ - gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \ - \ - gcmSKIPSECUREUSER(); \ -} - -#define gcmSETFILLER(CommandBuffer, Memory) \ -{ \ - gcmVERIFYLOADSTATEDONE(CommandBuffer); \ - \ - Memory += 1; \ - \ - gcmSKIPSECUREUSER(); \ -} - -/*----------------------------------------------------------------------------*/ - -#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \ - Address, Data) \ -{ \ - gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ - gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \ - Address, Data); \ - gcmENDSTATEBATCH(CommandBuffer, Memory); \ -} - -#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \ - Address, Data) \ -{ \ - gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \ - gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \ - gcmENDSTATEBATCH(CommandBuffer, Memory); \ -} - - -/******************************************************************************* -** -** gcmSETSTARTDECOMMAND -** -** Form a START_DE command. -** -** ARGUMENTS: -** -** Memory Destination memory pointer of gctUINT32_PTR type. -** Count Number of the rectangles. -*/ - -#define gcmSETSTARTDECOMMAND(Memory, Count) \ -{ \ - *Memory++ \ - = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \ - | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \ - | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \ - \ - *Memory++ = 0xDEADDEED; \ -} - /******************************************************************************\ ******************************** Ceiling Macro ******************************** \******************************************************************************/ @@ -831,6 +728,10 @@ gceSTATUS; #define gcmABS(x) (((x) < 0) ? -(x) : (x)) #define gcmNEG(x) (((x) < 0) ? (x) : -(x)) +/******************************************************************************\ +******************************** Bit Macro ******************************** +\******************************************************************************/ +#define gcmBITSET(x, y) ((x) & (y)) /******************************************************************************* ** ** gcmPTR2INT @@ -841,17 +742,15 @@ gceSTATUS; ** ** p Pointer value. */ -#if defined(_WIN32) || (defined(__LP64__) && __LP64__) -# define gcmPTR2INT(p) \ - ( \ - (gctUINT32) (gctUINT64) (p) \ - ) -#else -# define gcmPTR2INT(p) \ - ( \ - (gctUINT32) (p) \ - ) -#endif +#define gcmPTR2INT(p) \ +( \ + (gctUINTPTR_T) (p) \ +) + +#define gcmPTR2INT32(p) \ +( \ + (gctUINT32)(gctUINTPTR_T) (p) \ +) /******************************************************************************* ** @@ -863,17 +762,11 @@ gceSTATUS; ** ** v Integer value. */ -#ifdef __LP64__ -# define gcmINT2PTR(i) \ - ( \ - (gctPOINTER) (gctINT64) (i) \ - ) -#else -# define gcmINT2PTR(i) \ - ( \ - (gctPOINTER) (i) \ - ) -#endif + +#define gcmINT2PTR(i) \ +( \ + (gctPOINTER) (gctUINTPTR_T)(i) \ +) /******************************************************************************* ** @@ -888,9 +781,15 @@ gceSTATUS; */ #define gcmOFFSETOF(s, field) \ ( \ - gcmPTR2INT(& (((struct s *) 0)->field)) \ + gcmPTR2INT32(& (((struct s *) 0)->field)) \ ) +/******************************************************************************* +** +** gcmSWAB32 +** +** Return a value with all bytes in the 32 bit argument swapped. +*/ #define gcmSWAB32(x) ((gctUINT32)( \ (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \ (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \ @@ -943,19 +842,12 @@ typedef struct _gcsHAL_FRAME_INFO OUT gctUINT readRequests[8]; OUT gctUINT writeRequests[8]; - /* FE counters. */ - OUT gctUINT drawCount; - OUT gctUINT vertexOutCount; - OUT gctUINT vertexMissCount; - /* 3D counters. */ OUT gctUINT vertexCount; OUT gctUINT primitiveCount; OUT gctUINT rejectedPrimitives; OUT gctUINT culledPrimitives; OUT gctUINT clippedPrimitives; - OUT gctUINT droppedPrimitives; - OUT gctUINT frustumClippedPrimitives; OUT gctUINT outPrimitives; OUT gctUINT inPrimitives; OUT gctUINT culledQuadCount; @@ -973,94 +865,25 @@ typedef struct _gcsHAL_FRAME_INFO OUT gctUINT shaderCycles; OUT gctUINT vsInstructionCount; OUT gctUINT vsTextureCount; - OUT gctUINT vsBranchCount; - OUT gctUINT vsVertices; OUT gctUINT psInstructionCount; OUT gctUINT psTextureCount; - OUT gctUINT psBranchCount; - OUT gctUINT psPixels; /* Texture counters. */ OUT gctUINT bilinearRequests; OUT gctUINT trilinearRequests; - OUT gctUINT txBytes8[2]; + OUT gctUINT txBytes8; OUT gctUINT txHitCount; OUT gctUINT txMissCount; } gcsHAL_FRAME_INFO; -typedef enum _gcePATCH_ID -{ - gcePATCH_UNKNOWN = 0xFFFFFFFF, - - /* Benchmark list*/ - gcePATCH_GLB11 = 0x0, - gcePATCH_GLB21, - gcePATCH_GLB25, - gcePATCH_GLB27, - - gcePATCH_BM21, - gcePATCH_MM, - gcePATCH_MM06, - gcePATCH_MM07, - gcePATCH_QUADRANT, - gcePATCH_ANTUTU, - gcePATCH_SMARTBENCH, - gcePATCH_JPCT, - gcePATCH_NENAMARK, - gcePATCH_NENAMARK2, - gcePATCH_NEOCORE, - gcePATCH_GLB, - gcePATCH_GB, - gcePATCH_RTESTVA, - gcePATCH_BMX, - gcePATCH_BMGUI, - - /* Game list */ - gcePATCH_NBA2013, - gcePATCH_BARDTALE, - gcePATCH_BUSPARKING3D, - gcePATCH_FISHBOODLE, - gcePATCH_SUBWAYSURFER, - gcePATCH_HIGHWAYDRIVER, - gcePATCH_PREMIUM, - gcePATCH_RACEILLEGAL, - gcePATCH_BLABLA, - gcePATCH_MEGARUN, - gcePATCH_GALAXYONFIRE2, - gcePATCH_GLOFTR3HM, - gcePATCH_GLOFTSXHM, - gcePATCH_GLOFTF3HM, - gcePATCH_GLOFTGANG, - gcePATCH_XRUNNER, - gcePATCH_WP, - gcePATCH_DEVIL, - gcePATCH_HOLYARCH, - gcePATCH_MUSE, - gcePATCH_SG, - gcePATCH_SIEGECRAFT, - gcePATCH_CARCHALLENGE, - gcePATCH_HEROESCALL, - gcePATCH_MONOPOLY, - gcePATCH_CTGL20, - gcePATCH_FIREFOX, - gcePATCH_CHORME, - gcePATCH_DUOKANTV, - gcePATCH_TESTAPP, - gcePATCH_GOOGLEEARTH, - - /* Count enum*/ - gcePATCH_COUNT, -} -gcePATCH_ID; - #if gcdLINK_QUEUE_SIZE typedef struct _gckLINKDATA * gckLINKDATA; struct _gckLINKDATA { gctUINT32 start; gctUINT32 end; - gctINT pid; + gctUINT32 pid; }; typedef struct _gckLINKQUEUE * gckLINKQUEUE; @@ -1073,6 +896,35 @@ struct _gckLINKQUEUE }; #endif +#define gcdENTRY_QUEUE_SIZE 256 +typedef struct _gckENTRYDATA * gckENTRYDATA; +struct _gckENTRYDATA +{ + gctUINT32 physical; + gctUINT32 bytes; +}; + +typedef struct _gckENTRYQUEUE * gckENTRYQUEUE; +struct _gckENTRYQUEUE +{ + struct _gckENTRYDATA data[gcdENTRY_QUEUE_SIZE]; + gctUINT32 rear; + gctUINT32 front; + gctUINT32 count; +}; + +typedef enum _gceTRACEMODE +{ + gcvTRACEMODE_NONE = 0, + gcvTRACEMODE_FULL = 1, + gcvTRACEMODE_LOGGER = 2, + gcvTRACEMODE_PRE = 3, + gcvTRACEMODE_POST = 4, + gcvTRACEMODE_SYSTRACE = 5, + +} gceTRACEMODE; + + #ifdef __cplusplus } #endif 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 2eab66604642..4f95350184f7 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,13 +22,15 @@ #ifndef __gc_hal_version_h_ #define __gc_hal_version_h_ -#define gcvVERSION_MAJOR 4 +#define gcvVERSION_MAJOR 5 -#define gcvVERSION_MINOR 6 +#define gcvVERSION_MINOR 0 -#define gcvVERSION_PATCH 9 +#define gcvVERSION_PATCH 11 -#define gcvVERSION_BUILD 9754 +#define gcvVERSION_BUILD 25762 + +#define gcvVERSION_STRING "5.0.11.p4.25762" #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 2a910e8ee36d..09e8b9647423 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -346,11 +346,11 @@ gckVGKERNEL_Destroy( /* Allocate linear video memory. */ gceSTATUS -gckKERNEL_AllocateLinearMemory( +gckVGKERNEL_AllocateLinearMemory( IN gckKERNEL Kernel, IN OUT gcePOOL * Pool, IN gctSIZE_T Bytes, - IN gctSIZE_T Alignment, + IN gctUINT32 Alignment, IN gceSURF_TYPE Type, OUT gcuVIDMEM_NODE_PTR * Node ); @@ -379,21 +379,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 ****************************** \******************************************************************************/ @@ -433,7 +418,7 @@ gceSTATUS gckVGHARDWARE_Execute( IN gckVGHARDWARE Hardware, IN gctUINT32 Address, - IN gctSIZE_T Count + IN gctUINT32 Count ); /* Query the available memory. */ @@ -493,6 +478,7 @@ gceSTATUS gckVGHARDWARE_ConvertLogical( IN gckVGHARDWARE Hardware, IN gctPOINTER Logical, + IN gctBOOL InUserSpace, OUT gctUINT32 * Address ); @@ -579,7 +565,7 @@ gckVGHARDWARE_QueryIdle( \******************************************************************************/ /* Vacant command buffer marker. */ -#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) (1)) +#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) ((gctSIZE_T)1)) /* Command buffer header. */ typedef struct _gcsCMDBUFFER * gcsCMDBUFFER_PTR; @@ -591,7 +577,7 @@ typedef struct _gcsCMDBUFFER /* The user sets this to the node of the container buffer whitin which this particular command buffer resides. The kernel sets this to the node of the internally allocated buffer. */ - gctUINT64 node; + gcuVIDMEM_NODE_PTR node; /* Command buffer hardware address. */ gctUINT32 address; @@ -601,7 +587,7 @@ typedef struct _gcsCMDBUFFER /* Size of the area allocated for the data portion of this particular command buffer (headers and tail reserves are excluded). */ - gctSIZE_T size; + gctUINT32 size; /* Offset into the buffer [0..size]; reflects exactly how much data has been put into the command buffer. */ @@ -609,7 +595,7 @@ typedef struct _gcsCMDBUFFER /* The number of command units in the buffer for the hardware to execute. */ - gctSIZE_T dataCount; + gctUINT32 dataCount; /* MANAGED BY : user HAL (gcoBUFFER object). USED BY : user HAL (gcoBUFFER object). @@ -664,16 +650,13 @@ typedef struct _gcsVGCONTEXT gctUINT32 currentPipe; /* State map/mod buffer. */ - gctSIZE_T mapFirst; - gctSIZE_T mapLast; -#ifdef __QNXNTO__ - gctSIZE_T mapContainerSize; -#endif - gcsVGCONTEXT_MAP_PTR mapContainer; - gcsVGCONTEXT_MAP_PTR mapPrev; - gcsVGCONTEXT_MAP_PTR mapCurr; - gcsVGCONTEXT_MAP_PTR firstPrevMap; - gcsVGCONTEXT_MAP_PTR firstCurrMap; + gctUINT32 mapFirst; + gctUINT32 mapLast; + gcsVGCONTEXT_MAP_PTR mapContainer; + gcsVGCONTEXT_MAP_PTR mapPrev; + gcsVGCONTEXT_MAP_PTR mapCurr; + gcsVGCONTEXT_MAP_PTR firstPrevMap; + gcsVGCONTEXT_MAP_PTR firstCurrMap; /* Main context buffer. */ gcsCMDBUFFER_PTR header; @@ -863,7 +846,7 @@ typedef struct _gckVGMMU * gckVGMMU; gceSTATUS gckVGMMU_Construct( IN gckVGKERNEL Kernel, - IN gctSIZE_T MmuSize, + IN gctUINT32 MmuSize, OUT gckVGMMU * Mmu ); diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h new file mode 100644 index 000000000000..fa2190f73a0a --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h @@ -0,0 +1,34 @@ +/**************************************************************************** +* +* 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. +* +*****************************************************************************/ + + +extern gceSTATUS +_DefaultAlloctorInit( + IN gckOS Os, + OUT gckALLOCATOR * Allocator + ); + +gcsALLOCATOR_DESC allocatorArray[] = +{ + /* Default allocator. */ + gcmkDEFINE_ALLOCATOR_DESC("default", _DefaultAlloctorInit), +}; + + diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h new file mode 100644 index 000000000000..acdd929a0f44 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h @@ -0,0 +1,45 @@ +/**************************************************************************** +* +* 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. +* +*****************************************************************************/ + + +extern gceSTATUS +_DefaultAlloctorInit( + IN gckOS Os, + OUT gckALLOCATOR * Allocator + ); + +#if LINUX_CMA_FSL +gceSTATUS +_CMAFSLAlloctorInit( + IN gckOS Os, + OUT gckALLOCATOR * Allocator + ); +#endif + +gcsALLOCATOR_DESC allocatorArray[] = +{ +#if LINUX_CMA_FSL + gcmkDEFINE_ALLOCATOR_DESC("cmafsl", _CMAFSLAlloctorInit), +#endif + /* Default allocator. */ + gcmkDEFINE_ALLOCATOR_DESC("default", _DefaultAlloctorInit), +}; + + diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c new file mode 100644 index 000000000000..e419558a697f --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c @@ -0,0 +1,412 @@ +/**************************************************************************** +* +* 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_allocator.h" + +#include +#include +#include +#include +#include +#include +#include + +#define _GC_OBJ_ZONE gcvZONE_OS + +typedef struct _gcsCMA_PRIV * gcsCMA_PRIV_PTR; +typedef struct _gcsCMA_PRIV { + gctUINT32 cmasize; +} +gcsCMA_PRIV; + +struct mdl_cma_priv { + gctPOINTER kvaddr; + dma_addr_t physical; +}; + +int gc_cma_usage_show(struct seq_file* m, void* data) +{ + gcsINFO_NODE *node = m->private; + gckALLOCATOR Allocator = node->device; + gcsCMA_PRIV_PTR priv = Allocator->privateData; + + seq_printf(m, "cma: %u bytes\n", priv->cmasize); + + return 0; +} + +static gcsINFO InfoList[] = +{ + {"cmausage", gc_cma_usage_show}, +}; + +static void +_DefaultAllocatorDebugfsInit( + IN gckALLOCATOR Allocator, + IN gckDEBUGFS_DIR Root + ) +{ + gcmkVERIFY_OK( + gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "cma")); + + gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles( + &Allocator->debugfsDir, + InfoList, + gcmCOUNTOF(InfoList), + Allocator + )); +} + +static void +_DefaultAllocatorDebugfsCleanup( + IN gckALLOCATOR Allocator + ) +{ + gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles( + &Allocator->debugfsDir, + InfoList, + gcmCOUNTOF(InfoList) + )); + + gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir); +} + +static gceSTATUS +_CMAFSLAlloc( + IN gckALLOCATOR Allocator, + INOUT PLINUX_MDL Mdl, + IN gctSIZE_T NumPages, + IN gctUINT32 Flags + ) +{ + gceSTATUS status; + gcsCMA_PRIV_PTR priv = (gcsCMA_PRIV_PTR)Allocator->privateData; + + struct mdl_cma_priv *mdl_priv=gcvNULL; + gckOS os = Allocator->os; + + gcmkHEADER_ARG("Mdl=%p NumPages=%d", Mdl, NumPages); + + gcmkONERROR(gckOS_Allocate(os, sizeof(struct mdl_cma_priv), (gctPOINTER *)&mdl_priv)); + mdl_priv->kvaddr = gcvNULL; + + mdl_priv->kvaddr = dma_alloc_writecombine(gcvNULL, + NumPages * PAGE_SIZE, + &mdl_priv->physical, + GFP_KERNEL | gcdNOWARN); + + if (mdl_priv->kvaddr == gcvNULL) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + + Mdl->priv = mdl_priv; + priv->cmasize += NumPages * PAGE_SIZE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if(mdl_priv) + gckOS_Free(os, mdl_priv); + gcmkFOOTER(); + return status; +} + +static void +_CMAFSLFree( + IN gckALLOCATOR Allocator, + IN OUT PLINUX_MDL Mdl + ) +{ + gckOS os = Allocator->os; + struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv; + gcsCMA_PRIV_PTR priv = (gcsCMA_PRIV_PTR)Allocator->privateData; + dma_free_writecombine(gcvNULL, + Mdl->numPages * PAGE_SIZE, + mdl_priv->kvaddr, + mdl_priv->physical); + gckOS_Free(os, mdl_priv); + priv->cmasize -= Mdl->numPages * PAGE_SIZE; +} + +gctINT +_CMAFSLMapUser( + gckALLOCATOR Allocator, + PLINUX_MDL Mdl, + PLINUX_MDL_MAP MdlMap, + gctBOOL Cacheable + ) +{ + + PLINUX_MDL mdl = Mdl; + PLINUX_MDL_MAP mdlMap = MdlMap; + struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv; + + gcmkHEADER_ARG("Allocator=%p Mdl=%p MdlMap=%p gctBOOL=%d", Allocator, Mdl, MdlMap, Cacheable); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL, + 0L, + mdl->numPages * PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED, + 0); +#else + down_write(¤t->mm->mmap_sem); + + mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL, + 0L, + mdl->numPages * PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED, + 0); + + up_write(¤t->mm->mmap_sem); +#endif + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): vmaAddr->0x%X for phys_addr->0x%X", + __FUNCTION__, __LINE__, + (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr, + (gctUINT32)(gctUINTPTR_T)mdl + ); + + if (IS_ERR(mdlMap->vmaAddr)) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): do_mmap_pgoff error", + __FUNCTION__, __LINE__ + ); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; + } + + down_write(¤t->mm->mmap_sem); + + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr); + + if (mdlMap->vma == gcvNULL) + { + up_write(¤t->mm->mmap_sem); + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): find_vma error", + __FUNCTION__, __LINE__ + ); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES); + return gcvSTATUS_OUT_OF_RESOURCES; + } + + /* Now map all the vmalloc pages to this user address. */ + if (mdl->contiguous) + { + /* map kernel memory to user space.. */ + if (dma_mmap_writecombine(gcvNULL, + mdlMap->vma, + mdl_priv->kvaddr, + mdl_priv->physical, + mdl->numPages * PAGE_SIZE) < 0) + { + up_write(¤t->mm->mmap_sem); + + gcmkTRACE_ZONE( + gcvLEVEL_WARNING, gcvZONE_OS, + "%s(%d): dma_mmap_attrs error", + __FUNCTION__, __LINE__ + ); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; + } + } + else + { + gckOS_Print("incorrect mdl:conti%d\n",mdl->contiguous); + } + + up_write(¤t->mm->mmap_sem); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +void +_CMAUnmapUser( + IN gckALLOCATOR Allocator, + IN gctPOINTER Logical, + IN gctUINT32 Size + ) +{ + if (unlikely(current->mm == gcvNULL)) + { + /* Do nothing if process is exiting. */ + return; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + if (vm_munmap((unsigned long)Logical, Size) < 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_WARNING, gcvZONE_OS, + "%s(%d): vm_munmap failed", + __FUNCTION__, __LINE__ + ); + } +#else + down_write(¤t->mm->mmap_sem); + if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_WARNING, gcvZONE_OS, + "%s(%d): do_munmap failed", + __FUNCTION__, __LINE__ + ); + } + up_write(¤t->mm->mmap_sem); +#endif +} + +gceSTATUS +_CMAMapKernel( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + OUT gctPOINTER *Logical + ) +{ + struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv; + *Logical =mdl_priv->kvaddr; + return gcvSTATUS_OK; +} + +gceSTATUS +_CMAUnmapKernel( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical + ) +{ + return gcvSTATUS_OK; +} + +extern gceSTATUS +_DefaultLogicalToPhysical( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical, + IN gctUINT32 ProcessID, + OUT gctUINT32_PTR Physical + ); + +extern gceSTATUS +_DefaultCache( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical, + IN gctUINT32 Physical, + IN gctUINT32 Bytes, + IN gceCACHEOPERATION Operation + ); + +gceSTATUS +_CMAPhysical( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctUINT32 Offset, + OUT gctUINT32_PTR Physical + ) +{ + struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv; + gcmkASSERT(!Offset); + *Physical = mdl_priv->physical; + + return gcvSTATUS_OK; +} + + +extern void +_DefaultAllocatorDestructor( + IN void* PrivateData + ); + +/* Default allocator operations. */ +gcsALLOCATOR_OPERATIONS CMAFSLAllocatorOperations = { + .Alloc = _CMAFSLAlloc, + .Free = _CMAFSLFree, + .MapUser = _CMAFSLMapUser, + .UnmapUser = _CMAUnmapUser, + .MapKernel = _CMAMapKernel, + .UnmapKernel = _CMAUnmapKernel, + .LogicalToPhysical = _DefaultLogicalToPhysical, + .Cache = _DefaultCache, + .Physical = _CMAPhysical, +}; + +/* Default allocator entry. */ +gceSTATUS +_CMAFSLAlloctorInit( + IN gckOS Os, + OUT gckALLOCATOR * Allocator + ) +{ + gceSTATUS status; + gckALLOCATOR allocator; + gcsCMA_PRIV_PTR priv = gcvNULL; + + gcmkONERROR( + gckALLOCATOR_Construct(Os, &CMAFSLAllocatorOperations, &allocator)); + + priv = kzalloc(gcmSIZEOF(gcsCMA_PRIV), GFP_KERNEL | gcdNOWARN); + + if (!priv) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + + /* Register private data. */ + allocator->privateData = priv; + allocator->privateDataDestructor = _DefaultAllocatorDestructor; + + allocator->debugfsInit = _DefaultAllocatorDebugfsInit; + allocator->debugfsCleanup = _DefaultAllocatorDebugfsCleanup; + + allocator->capability = gcvALLOC_FLAG_CONTIGUOUS; + + *Allocator = allocator; + + return gcvSTATUS_OK; + +OnError: + return status; +} + 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 new file mode 100644 index 000000000000..193b5d92c0b3 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c @@ -0,0 +1,938 @@ +/**************************************************************************** +* +* 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_allocator.h" +#include +#include +#include +#include +#include +#include + +#include "gc_hal_kernel_allocator_array.h" +#include "gc_hal_kernel_platform.h" + +#define _GC_OBJ_ZONE gcvZONE_OS + +typedef struct _gcsDEFAULT_PRIV * gcsDEFAULT_PRIV_PTR; +typedef struct _gcsDEFAULT_PRIV { + gctUINT32 low; + gctUINT32 high; +} +gcsDEFAULT_PRIV; + +/******************************************************************************\ +************************** Default Allocator Debugfs *************************** +\******************************************************************************/ + +int gc_usage_show(struct seq_file* m, void* data) +{ + gcsINFO_NODE *node = m->private; + gckALLOCATOR Allocator = node->device; + gcsDEFAULT_PRIV_PTR priv = Allocator->privateData; + + seq_printf(m, "low: %u bytes\n", priv->low); + seq_printf(m, "high: %u bytes\n", priv->high); + + return 0; +} + +static gcsINFO InfoList[] = +{ + {"lowHighUsage", gc_usage_show}, +}; + +static void +_DefaultAllocatorDebugfsInit( + IN gckALLOCATOR Allocator, + IN gckDEBUGFS_DIR Root + ) +{ + gcmkVERIFY_OK( + gckDEBUGFS_DIR_Init(&Allocator->debugfsDir, Root->root, "default")); + + gcmkVERIFY_OK(gckDEBUGFS_DIR_CreateFiles( + &Allocator->debugfsDir, + InfoList, + gcmCOUNTOF(InfoList), + Allocator + )); +} + +static void +_DefaultAllocatorDebugfsCleanup( + IN gckALLOCATOR Allocator + ) +{ + gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles( + &Allocator->debugfsDir, + InfoList, + gcmCOUNTOF(InfoList) + )); + + gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir); +} + + +static void +_NonContiguousFree( + IN struct page ** Pages, + IN gctUINT32 NumPages + ) +{ + gctINT i; + + gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages); + + gcmkASSERT(Pages != gcvNULL); + + for (i = 0; i < NumPages; i++) + { + __free_page(Pages[i]); + } + + if (is_vmalloc_addr(Pages)) + { + vfree(Pages); + } + else + { + kfree(Pages); + } + + gcmkFOOTER_NO(); +} + +static struct page ** +_NonContiguousAlloc( + IN gctUINT32 NumPages + ) +{ + struct page ** pages; + struct page *p; + gctINT i, size; + + gcmkHEADER_ARG("NumPages=%lu", NumPages); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) + if (NumPages > totalram_pages) +#else + if (NumPages > num_physpages) +#endif + { + gcmkFOOTER_NO(); + return gcvNULL; + } + + size = NumPages * sizeof(struct page *); + + pages = kmalloc(size, GFP_KERNEL | gcdNOWARN); + + if (!pages) + { + pages = vmalloc(size); + + if (!pages) + { + gcmkFOOTER_NO(); + return gcvNULL; + } + } + + for (i = 0; i < NumPages; i++) + { + p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN); + + if (!p) + { + _NonContiguousFree(pages, i); + gcmkFOOTER_NO(); + return gcvNULL; + } + + pages[i] = p; + } + + gcmkFOOTER_ARG("pages=0x%X", pages); + return pages; +} + +gctSTRING +_CreateKernelVirtualMapping( + IN PLINUX_MDL Mdl + ) +{ + gctSTRING addr = 0; + gctINT numPages = Mdl->numPages; + +#if gcdNONPAGED_MEMORY_CACHEABLE + if (Mdl->contiguous) + { + addr = page_address(Mdl->u.contiguousPages); + } + else + { + addr = vmap(Mdl->u.nonContiguousPages, + numPages, + 0, + PAGE_KERNEL); + + /* Trigger a page fault. */ + memset(addr, 0, numPages * PAGE_SIZE); + } +#else + struct page ** pages; + gctBOOL free = gcvFALSE; + gctINT i; + + if (Mdl->contiguous) + { + pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN); + + if (!pages) + { + return gcvNULL; + } + + for (i = 0; i < numPages; i++) + { + pages[i] = nth_page(Mdl->u.contiguousPages, i); + } + + free = gcvTRUE; + } + else + { + pages = Mdl->u.nonContiguousPages; + } + + /* ioremap() can't work on system memory since 2.6.38. */ + addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL)); + + if (free) + { + kfree(pages); + } + +#endif + + return addr; +} + +void +_DestoryKernelVirtualMapping( + IN gctSTRING Addr + ) +{ +#if !gcdNONPAGED_MEMORY_CACHEABLE + vunmap(Addr); +#endif +} + +void +_UnmapUserLogical( + IN gctPOINTER Logical, + IN gctUINT32 Size +) +{ + if (unlikely(current->mm == gcvNULL)) + { + /* Do nothing if process is exiting. */ + return; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + if (vm_munmap((unsigned long)Logical, Size) < 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_WARNING, gcvZONE_OS, + "%s(%d): vm_munmap failed", + __FUNCTION__, __LINE__ + ); + } +#else + down_write(¤t->mm->mmap_sem); + if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_WARNING, gcvZONE_OS, + "%s(%d): do_munmap failed", + __FUNCTION__, __LINE__ + ); + } + up_write(¤t->mm->mmap_sem); +#endif +} + +/***************************************************************************\ +************************ Default Allocator ********************************** +\***************************************************************************/ +#define C_MAX_PAGENUM (50*1024) +static gceSTATUS +_DefaultAlloc( + IN gckALLOCATOR Allocator, + INOUT PLINUX_MDL Mdl, + IN gctSIZE_T NumPages, + IN gctUINT32 Flags + ) +{ + gceSTATUS status; + gctUINT32 order; + gctSIZE_T bytes; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + gctPOINTER addr = gcvNULL; +#endif + gctUINT32 numPages; + gctUINT i = 0; + gctBOOL contiguous = Flags & gcvALLOC_FLAG_CONTIGUOUS; + struct sysinfo temsysinfo; + gcsDEFAULT_PRIV_PTR priv = (gcsDEFAULT_PRIV_PTR)Allocator->privateData; + + gcmkHEADER_ARG("Mdl=%p NumPages=%d", Mdl, NumPages); + + numPages = NumPages; + bytes = NumPages * PAGE_SIZE; + order = get_order(bytes); + + si_meminfo(&temsysinfo); + + if (Flags & gcvALLOC_FLAG_MEMLIMIT) + { + if ( (temsysinfo.freeram < NumPages) || ((temsysinfo.freeram-NumPages) < C_MAX_PAGENUM) ) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + } + + if (contiguous) + { + if (order >= MAX_ORDER) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + addr = + alloc_pages_exact(bytes, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY); + + Mdl->u.contiguousPages = addr + ? virt_to_page(addr) + : gcvNULL; + + Mdl->exact = gcvTRUE; +#else + Mdl->u.contiguousPages = + alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order); +#endif + + if (Mdl->u.contiguousPages == gcvNULL) + { + Mdl->u.contiguousPages = + alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + Mdl->exact = gcvFALSE; +#endif + } + } + else + { + Mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages); + } + + if (Mdl->u.contiguousPages == gcvNULL && Mdl->u.nonContiguousPages == gcvNULL) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + + for (i = 0; i < numPages; i++) + { + struct page *page; + + if (contiguous) + { + page = nth_page(Mdl->u.contiguousPages, i); + } + else + { + page = _NonContiguousToPage(Mdl->u.nonContiguousPages, i); + } + + SetPageReserved(page); + + if (!PageHighMem(page) && page_to_phys(page)) + { + gcmkVERIFY_OK( + gckOS_CacheFlush(Allocator->os, _GetProcessID(), gcvNULL, + page_to_phys(page), + page_address(page), + PAGE_SIZE)); + + priv->low += PAGE_SIZE; + } + else + { + flush_dcache_page(page); + +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE) && gcdENABLE_OUTER_CACHE_PATCH + if (page_to_phys(page)) + { + _HandleOuterCache( + Allocator->os, + page_to_phys(page), + gcvNULL, + PAGE_SIZE, + gcvCACHE_FLUSH + ); + } +#endif + + priv->high += PAGE_SIZE; + } + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +static void +_DefaultFree( + IN gckALLOCATOR Allocator, + IN OUT PLINUX_MDL Mdl + ) +{ + gctINT i; + struct page * page; + gcsDEFAULT_PRIV_PTR priv = (gcsDEFAULT_PRIV_PTR)Allocator->privateData; + + for (i = 0; i < Mdl->numPages; i++) + { + if (Mdl->contiguous) + { + page = nth_page(Mdl->u.contiguousPages, i); + } + else + { + page = _NonContiguousToPage(Mdl->u.nonContiguousPages, i); + } + + ClearPageReserved(page); + + if (PageHighMem(page)) + { + priv->high -= PAGE_SIZE; + } + else + { + priv->low -= PAGE_SIZE; + } + } + + if (Mdl->contiguous) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + if (Mdl->exact == gcvTRUE) + { + free_pages_exact(page_address(Mdl->u.contiguousPages), Mdl->numPages * PAGE_SIZE); + } + else +#endif + { + __free_pages(Mdl->u.contiguousPages, get_order(Mdl->numPages * PAGE_SIZE)); + } + } + else + { + _NonContiguousFree(Mdl->u.nonContiguousPages, Mdl->numPages); + } +} + +gctINT +_DefaultMapUser( + gckALLOCATOR Allocator, + PLINUX_MDL Mdl, + PLINUX_MDL_MAP MdlMap, + gctBOOL Cacheable + ) +{ + + gctSTRING addr; + 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; + + gcmkHEADER_ARG("Allocator=%p Mdl=%p MdlMap=%p gctBOOL=%d", Allocator, Mdl, MdlMap, Cacheable); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) + mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL, + 0L, + mdl->numPages * PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED, + 0); +#else + down_write(¤t->mm->mmap_sem); + + mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL, + 0L, + mdl->numPages * PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_SHARED, + 0); + + up_write(¤t->mm->mmap_sem); +#endif + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): vmaAddr->0x%X for phys_addr->0x%X", + __FUNCTION__, __LINE__, + (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr, + (gctUINT32)(gctUINTPTR_T)mdl + ); + + if (IS_ERR(mdlMap->vmaAddr)) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): do_mmap_pgoff error", + __FUNCTION__, __LINE__ + ); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; + } + + down_write(¤t->mm->mmap_sem); + + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr); + + if (mdlMap->vma == gcvNULL) + { + up_write(¤t->mm->mmap_sem); + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): find_vma error", + __FUNCTION__, __LINE__ + ); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES); + return gcvSTATUS_OUT_OF_RESOURCES; + } + + mdlMap->vma->vm_flags |= gcdVM_FLAGS; + + if (Cacheable == gcvFALSE) + { + /* Make this mapping non-cached. */ + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot); + } + + if (platform && platform->ops->adjustProt) + { + platform->ops->adjustProt(mdlMap->vma); + } + + addr = mdl->addr; + + /* Now map all the vmalloc pages to this user address. */ + if (mdl->contiguous) + { + /* map kernel memory to user space.. */ + if (remap_pfn_range(mdlMap->vma, + mdlMap->vma->vm_start, + page_to_pfn(mdl->u.contiguousPages), + mdlMap->vma->vm_end - mdlMap->vma->vm_start, + mdlMap->vma->vm_page_prot) < 0) + { + up_write(¤t->mm->mmap_sem); + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): unable to mmap ret", + __FUNCTION__, __LINE__ + ); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; + } + } + else + { + start = mdlMap->vma->vm_start; + + for (i = 0; i < mdl->numPages; i++) + { + pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i); + + if (remap_pfn_range(mdlMap->vma, + start, + pfn, + PAGE_SIZE, + mdlMap->vma->vm_page_prot) < 0) + { + up_write(¤t->mm->mmap_sem); + + mdlMap->vmaAddr = gcvNULL; + + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; + } + + start += PAGE_SIZE; + addr += PAGE_SIZE; + } + } + + up_write(¤t->mm->mmap_sem); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +void +_DefaultUnmapUser( + IN gckALLOCATOR Allocator, + IN gctPOINTER Logical, + IN gctUINT32 Size + ) +{ + _UnmapUserLogical(Logical, Size); +} + +gceSTATUS +_DefaultMapKernel( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + OUT gctPOINTER *Logical + ) +{ + *Logical = _CreateKernelVirtualMapping(Mdl); + return gcvSTATUS_OK; +} + +gceSTATUS +_DefaultUnmapKernel( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical + ) +{ + _DestoryKernelVirtualMapping(Logical); + return gcvSTATUS_OK; +} + +gceSTATUS +_DefaultLogicalToPhysical( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical, + IN gctUINT32 ProcessID, + OUT gctUINT32_PTR Physical + ) +{ + return _ConvertLogical2Physical( + Allocator->os, Logical, ProcessID, Mdl, Physical); +} + +gceSTATUS +_DefaultCache( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical, + IN gctUINT32 Physical, + IN gctUINT32 Bytes, + IN gceCACHEOPERATION Operation + ) +{ + return gcvSTATUS_OK; +} + +gceSTATUS +_DefaultPhysical( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctUINT32 Offset, + OUT gctUINT32_PTR Physical + ) +{ + gcmkASSERT(Mdl->pagedMem && !Mdl->contiguous); + *Physical = _NonContiguousToPhys(Mdl->u.nonContiguousPages, Offset); + + return gcvSTATUS_OK; +} + +void +_DefaultAllocatorDestructor( + IN void* PrivateData + ) +{ + kfree(PrivateData); +} + +/* Default allocator operations. */ +gcsALLOCATOR_OPERATIONS DefaultAllocatorOperations = { + .Alloc = _DefaultAlloc, + .Free = _DefaultFree, + .MapUser = _DefaultMapUser, + .UnmapUser = _DefaultUnmapUser, + .MapKernel = _DefaultMapKernel, + .UnmapKernel = _DefaultUnmapKernel, + .LogicalToPhysical = _DefaultLogicalToPhysical, + .Cache = _DefaultCache, + .Physical = _DefaultPhysical, +}; + +/* Default allocator entry. */ +gceSTATUS +_DefaultAlloctorInit( + IN gckOS Os, + OUT gckALLOCATOR * Allocator + ) +{ + gceSTATUS status; + gckALLOCATOR allocator; + gcsDEFAULT_PRIV_PTR priv = gcvNULL; + + gcmkONERROR( + gckALLOCATOR_Construct(Os, &DefaultAllocatorOperations, &allocator)); + + priv = kzalloc(gcmSIZEOF(gcsDEFAULT_PRIV), GFP_KERNEL | gcdNOWARN); + + if (!priv) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + + /* Register private data. */ + allocator->privateData = priv; + allocator->privateDataDestructor = _DefaultAllocatorDestructor; + + allocator->debugfsInit = _DefaultAllocatorDebugfsInit; + allocator->debugfsCleanup = _DefaultAllocatorDebugfsCleanup; + + *Allocator = allocator; + + return gcvSTATUS_OK; + +OnError: + return status; +} + +/***************************************************************************\ +************************ Allocator helper *********************************** +\***************************************************************************/ + +gceSTATUS +gckALLOCATOR_Construct( + IN gckOS Os, + IN gcsALLOCATOR_OPERATIONS * Operations, + OUT gckALLOCATOR * Allocator + ) +{ + gceSTATUS status; + gckALLOCATOR allocator; + + gcmkHEADER_ARG("Os=%p, Operations=%p, Allocator=%p", + Os, Operations, Allocator); + + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Allocator != gcvNULL); + gcmkVERIFY_ARGUMENT + ( Operations + && Operations->Alloc + && Operations->Free + && Operations->MapUser + && Operations->UnmapUser + && Operations->MapKernel + && Operations->UnmapKernel + && Operations->LogicalToPhysical + && Operations->Cache + && Operations->Physical + ); + + gcmkONERROR( + gckOS_Allocate(Os, gcmSIZEOF(gcsALLOCATOR), (gctPOINTER *)&allocator)); + + gckOS_ZeroMemory(allocator, gcmSIZEOF(gcsALLOCATOR)); + + /* Record os. */ + allocator->os = Os; + + /* Set operations. */ + allocator->ops = Operations; + + allocator->capability = gcvALLOC_FLAG_CONTIGUOUS + | gcvALLOC_FLAG_NON_CONTIGUOUS + | gcvALLOC_FLAG_CACHEABLE + | gcvALLOC_FLAG_MEMLIMIT; + ; + + *Allocator = allocator; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +/******************************************************************************\ +******************************** Debugfs Support ******************************* +\******************************************************************************/ + +static gceSTATUS +_AllocatorDebugfsInit( + IN gckOS Os + ) +{ + gceSTATUS status; + gckGALDEVICE device = Os->device; + + gckDEBUGFS_DIR dir = &Os->allocatorDebugfsDir; + + gcmkONERROR(gckDEBUGFS_DIR_Init(dir, device->debugfsDir.root, "allocators")); + + return gcvSTATUS_OK; + +OnError: + return status; +} + +static void +_AllocatorDebugfsCleanup( + IN gckOS Os + ) +{ + gckDEBUGFS_DIR dir = &Os->allocatorDebugfsDir; + + gckDEBUGFS_DIR_Deinit(dir); +} + +/***************************************************************************\ +************************ Allocator management ******************************* +\***************************************************************************/ + +gceSTATUS +gckOS_ImportAllocators( + gckOS Os + ) +{ + gceSTATUS status; + gctUINT i; + gckALLOCATOR allocator; + + _AllocatorDebugfsInit(Os); + + INIT_LIST_HEAD(&Os->allocatorList); + + for (i = 0; i < gcmCOUNTOF(allocatorArray); i++) + { + if (allocatorArray[i].construct) + { + /* Construct allocator. */ + status = allocatorArray[i].construct(Os, &allocator); + + if (gcmIS_ERROR(status)) + { + gcmkPRINT("["DEVICE_NAME"]: Can't construct allocator(%s)", + allocatorArray[i].name); + + continue; + } + + allocator->name = allocatorArray[i].name; + + if (allocator->debugfsInit) + { + /* Init allocator's debugfs. */ + allocator->debugfsInit(allocator, &Os->allocatorDebugfsDir); + } + + list_add_tail(&allocator->head, &Os->allocatorList); + } + } + +#if gcdDEBUG + list_for_each_entry(allocator, &Os->allocatorList, head) + { + gcmkTRACE_ZONE( + gcvLEVEL_WARNING, gcvZONE_OS, + "%s(%d) Allocator: %s", + __FUNCTION__, __LINE__, + allocator->name + ); + } +#endif + + return gcvSTATUS_OK; +} + +gceSTATUS +gckOS_FreeAllocators( + gckOS Os + ) +{ + gckALLOCATOR allocator; + gckALLOCATOR temp; + + list_for_each_entry_safe(allocator, temp, &Os->allocatorList, head) + { + list_del(&allocator->head); + + if (allocator->debugfsCleanup) + { + /* Clean up allocator's debugfs. */ + allocator->debugfsCleanup(allocator); + } + + /* Free private data. */ + if (allocator->privateDataDestructor && allocator->privateData) + { + allocator->privateDataDestructor(allocator->privateData); + } + + gckOS_Free(Os, allocator); + } + + _AllocatorDebugfsCleanup(Os); + + 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 new file mode 100644 index 000000000000..f36e1b0de869 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h @@ -0,0 +1,400 @@ +/**************************************************************************** +* +* 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_allocator_h_ +#define __gc_hal_kernel_allocator_h_ + +#include "gc_hal_kernel_linux.h" + +typedef struct _gcsALLOCATOR * gckALLOCATOR; + +typedef struct _gcsALLOCATOR_OPERATIONS +{ + /************************************************************************** + ** + ** Alloc + ** + ** Allocte memory, request size is page aligned. + ** + ** INPUT: + ** + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_Mdl + ** Pointer to Mdl whichs stores information + ** about allocated memory. + ** + ** gctSIZE_T NumPages + ** Number of pages need to allocate. + ** + ** gctUINT32 Flag + ** Allocation option. + ** + ** OUTPUT: + ** + ** Nothing. + ** + */ + gceSTATUS + (*Alloc)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctSIZE_T NumPages, + IN gctUINT32 Flag + ); + + /************************************************************************** + ** + ** Free + ** + ** Free memory. + ** + ** INPUT: + ** + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Mdl which stores information. + ** + ** OUTPUT: + ** + ** Nothing. + ** + */ + void + (*Free)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl + ); + + /************************************************************************** + ** + ** MapUser + ** + ** Map memory to user space. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Pointer to a Mdl. + ** + ** PLINUX_MDL_MAP MdlMap + ** Pointer to a MdlMap, mapped address is stored + ** in MdlMap->vmaAddr + ** + ** gctBOOL Cacheable + ** Whether this mapping is cacheable. + ** + ** OUTPUT: + ** + ** Nothing. + ** + */ + gctINT + (*MapUser)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN PLINUX_MDL_MAP MdlMap, + IN gctBOOL Cacheable + ); + + /************************************************************************** + ** + ** UnmapUser + ** + ** Unmap address from user address space. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** gctPOINTER Logical + ** Address to be unmap + ** + ** gctUINT32 Size + ** Size of address space + ** + ** OUTPUT: + ** + ** Nothing. + ** + */ + void + (*UnmapUser)( + IN gckALLOCATOR Allocator, + IN gctPOINTER Logical, + IN gctUINT32 Size + ); + + /************************************************************************** + ** + ** MapKernel + ** + ** Map memory to kernel space. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Pointer to a Mdl object. + ** + ** OUTPUT: + ** gctPOINTER * Logical + ** Mapped kernel address. + */ + gceSTATUS + (*MapKernel)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + OUT gctPOINTER *Logical + ); + + /************************************************************************** + ** + ** UnmapKernel + ** + ** Unmap memory from kernel space. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Pointer to a Mdl object. + ** + ** gctPOINTER Logical + ** Mapped kernel address. + ** + ** OUTPUT: + ** + ** Nothing. + ** + */ + gceSTATUS + (*UnmapKernel)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical + ); + + /************************************************************************** + ** + ** LogicalToPhysical + ** + ** Get physical address from logical address, logical + ** address could be user virtual address or kernel + ** virtual address. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Pointer to a Mdl object. + ** + ** gctPOINTER Logical + ** Mapped kernel address. + ** + ** gctUINT32 ProcessID + ** pid of current process. + ** OUTPUT: + ** + ** gctUINT32_PTR Physical + ** Physical address. + ** + */ + gceSTATUS + (*LogicalToPhysical)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical, + IN gctUINT32 ProcessID, + OUT gctUINT32_PTR Physical + ); + + /************************************************************************** + ** + ** Cache + ** + ** Maintain cache coherency. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Pointer to a Mdl object. + ** + ** gctPOINTER Logical + ** Logical address, could be user address or kernel address + ** + ** gctUINT32_PTR Physical + ** Physical address. + ** + ** gctUINT32 Bytes + ** Size of memory region. + ** + ** gceCACHEOPERATION Opertaion + ** Cache operation. + ** + ** OUTPUT: + ** + ** Nothing. + ** + */ + gceSTATUS (*Cache)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctPOINTER Logical, + IN gctUINT32 Physical, + IN gctUINT32 Bytes, + IN gceCACHEOPERATION Operation + ); + + /************************************************************************** + ** + ** Physical + ** + ** Get physical address from a offset in memory region. + ** + ** INPUT: + ** gckALLOCATOR Allocator + ** Pointer to an gckALLOCATOER object. + ** + ** PLINUX_MDL Mdl + ** Pointer to a Mdl object. + ** + ** gctUINT32 Offset + ** Offset in this memory region. + ** + ** OUTPUT: + ** gctUINT32_PTR Physical + ** Physical address. + ** + */ + gceSTATUS (*Physical)( + IN gckALLOCATOR Allocator, + IN PLINUX_MDL Mdl, + IN gctUINT32 Offset, + OUT gctUINT32_PTR Physical + ); +} +gcsALLOCATOR_OPERATIONS; + +typedef struct _gcsALLOCATOR +{ + /* Pointer to gckOS Object. */ + gckOS os; + + /* Name. */ + gctSTRING name; + + /* Operations. */ + gcsALLOCATOR_OPERATIONS* ops; + + /* Capability of this allocator. */ + gctUINT32 capability; + + struct list_head head; + + /* Debugfs entry of this allocator. */ + gcsDEBUGFS_DIR debugfsDir; + + /* Init allocator debugfs. */ + void (*debugfsInit)(gckALLOCATOR, gckDEBUGFS_DIR); + + /* Cleanup allocator debugfs. */ + void (*debugfsCleanup)(gckALLOCATOR); + + /* Private data used by customer allocator. */ + void * privateData; + + /* Private data destructor. */ + void (*privateDataDestructor)(void *); +} +gcsALLOCATOR; + +typedef struct _gcsALLOCATOR_DESC +{ + /* Name of a allocator. */ + char * name; + + /* Entry function to construct a allocator. */ + gceSTATUS (*construct)(gckOS, gckALLOCATOR *); +} +gcsALLOCATOR_DESC; + +/* +* Helpers +*/ + +/* Fill a gcsALLOCATOR_DESC structure. */ +#define gcmkDEFINE_ALLOCATOR_DESC(Name, Construct) \ + { \ + .name = Name, \ + .construct = Construct, \ + } + +/* Construct a allocator. */ +gceSTATUS +gckALLOCATOR_Construct( + IN gckOS Os, + IN gcsALLOCATOR_OPERATIONS * Operations, + OUT gckALLOCATOR * Allocator + ); + +/* + How to implement customer allocator + + Build in customer alloctor + + It is recommanded that customer allocator is implmented in independent + source file(s) which is specified by CUSOMTER_ALLOCATOR_OBJS in Kbuld. + + Register gcsALLOCATOR + + For each customer specified allocator, a desciption entry must be added + to allocatorArray defined in gc_hal_kernel_allocator_array.h. + + An entry in allocatorArray is a gcsALLOCATOR_DESC structure which describes + name and constructor of a gckALLOCATOR object. + + + Implement gcsALLOCATOR_DESC.init() + + In gcsALLOCATOR_DESC.init(), gckALLOCATOR_Construct should be called + to create a gckALLOCATOR object, customer specified private data can + be put in gcsALLOCATOR.privateData. + + + Implement gcsALLOCATOR_OPERATIONS + + When call gckALLOCATOR_Construct to create a gckALLOCATOR object, a + gcsALLOCATOR_OPERATIONS structure must be provided whose all members + implemented. + +*/ +#endif 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 339dff462780..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -43,14 +43,18 @@ typedef va_list gctARGUMENTS; #define gcmkARGUMENTS_END(Arguments) \ va_end(Arguments) +#define gcmkARGUMENTS_ARG(Arguments, Type) \ + va_arg(Arguments, Type) + #define gcmkDECLARE_LOCK(__spinLock__) \ - static DEFINE_SPINLOCK(__spinLock__); + static DEFINE_SPINLOCK(__spinLock__); \ + unsigned long __spinLock__##flags = 0; #define gcmkLOCKSECTION(__spinLock__) \ - spin_lock(&__spinLock__) + spin_lock_irqsave(&__spinLock__, __spinLock__##flags) #define gcmkUNLOCKSECTION(__spinLock__) \ - spin_unlock(&__spinLock__) + spin_unlock_irqrestore(&__spinLock__, __spinLock__##flags) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) # define gcmkGETPROCESSID() \ @@ -69,10 +73,11 @@ typedef va_list gctARGUMENTS; #endif #define gcmkOUTPUT_STRING(String) \ - if(gckDebugFileSystemIsEnabled()) \ - gckDebugFileSystemPrint(String);\ - else\ - printk(String); \ + if(gckDEBUGFS_IsEnabled()) {\ + while(-ERESTARTSYS == gckDEBUGFS_Print(String));\ + }else{\ + printk(String); \ + }\ touch_softlockup_watchdog() @@ -86,11 +91,17 @@ typedef va_list gctARGUMENTS; snprintf(Destination, Size, Message, Value1, Value2, Value3) #define gcmkVSPRINTF(Destination, Size, Message, Arguments) \ - vsnprintf(Destination, Size, Message, *(va_list *) &Arguments) + vsnprintf(Destination, Size, Message, *((va_list*)Arguments)) #define gcmkSTRCAT(Destination, Size, String) \ strncat(Destination, String, Size) +#define gcmkMEMCPY(Destination, Source, Size) \ + memcpy(Destination, Source, Size) + +#define gcmkSTRLEN(String) \ + strlen(String) + /* If not zero, forces data alignment in the variable argument list by its individual size. */ #define gcdALIGNBYSIZE 1 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 6bdc5a625609..35b125f28e92 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -41,7 +41,9 @@ #include #include #include +#include #include "gc_hal_kernel_linux.h" +#include "gc_hal_kernel.h" /* Prequsite: @@ -59,13 +61,19 @@ 2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug" 3) To read what is being printed in the debugfs file system: - Ex : cat /sys/kernel/debug/gpu/galcore_trace + Ex : cat /sys/kernel/debug/gc/galcore_trace 4)To write into the debug file system from user side : - Ex: echo "hello" > cat /sys/kernel/debug/gpu/galcore_trace + Ex: echo "hello" > cat /sys/kernel/debug/gc/galcore_trace - 5)To write into debugfs from kernel side, Use the function called gckDebugFileSystemPrint + 5)To write into debugfs from kernel side, Use the function called gckDEBUGFS_Print + How to Get Video Memory Usage: + 1) Select a process whose video memory usage can be dump, no need to reset it until is needed to be change. + echo > /sys/kernel/debug/gc/vidmem + + 2) Get video memory usage. + cat /sys/kernel/debug/gc/vidmem USECASE Kernel Dump: @@ -87,18 +95,18 @@ /**/ typedef va_list gctDBGARGS ; #define gcmkARGS_START(argument, pointer) va_start(argument, pointer) -#define gcmkARGS_END(argument) va_end(argument) +#define gcmkARGS_END(argument) va_end(argument) -#define gcmkDBGFSPRINT(ArgumentSize, Message) \ +#define gcmkDEBUGFS_PRINT(ArgumentSize, Message) \ { \ - gctDBGARGS __arguments__; \ - gcmkARGS_START(__arguments__, Message); \ - _DebugFSPrint(ArgumentSize, Message, __arguments__);\ - gcmkARGS_END(__arguments__); \ + gctDBGARGS __arguments__; \ + gcmkARGS_START(__arguments__, Message); \ + _debugfs_res = _DebugFSPrint(ArgumentSize, Message, &__arguments__);\ + gcmkARGS_END(__arguments__); \ } -/*Debug File System Node Struct*/ -struct _gcsDebugFileSystemNode +/* Debug File System Node Struct. */ +struct _gcsDEBUGFS_Node { /*wait queues for read and write operations*/ #if defined(DECLARE_WAIT_QUEUE_HEAD) @@ -108,6 +116,7 @@ struct _gcsDebugFileSystemNode #endif struct dentry *parent ; /*parent directory*/ struct dentry *filen ; /*filename*/ + struct dentry *vidmem; struct semaphore sem ; /* mutual exclusion semaphore */ char *data ; /* The circular buffer data */ int size ; /* Size of the buffer pointed to by 'data' */ @@ -115,8 +124,8 @@ struct _gcsDebugFileSystemNode int read_point ; /* Offset in circ. buffer of oldest data */ int write_point ; /* Offset in circ. buffer of newest data */ int offset ; /* Byte number of read_point in the stream */ - struct _gcsDebugFileSystemNode *next ; -} ; + struct _gcsDEBUGFS_Node *next ; +}; /* amount of data in the queue */ #define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \ @@ -135,22 +144,131 @@ struct _gcsDebugFileSystemNode #define gcmkMIN(x, y) ((x) < (y) ? (x) : y) /*Debug File System Struct*/ -typedef struct _gcsDebugFileSystem +typedef struct _gcsDEBUGFS_ { - gcsDebugFileSystemNode* linkedlist ; - gcsDebugFileSystemNode* currentNode ; + gcsDEBUGFS_Node* linkedlist ; + gcsDEBUGFS_Node* currentNode ; int isInited ; -} gcsDebugFileSystem ; - +} gcsDEBUGFS_ ; /*debug file system*/ -static gcsDebugFileSystem gc_dbgfs ; +static gcsDEBUGFS_ gc_dbgfs ; + +static int gc_debugfs_open(struct inode *inode, struct file *file) +{ + gcsINFO_NODE *node = inode->i_private; + + return single_open(file, node->info->show, node); +} + +static const struct file_operations gc_debugfs_operations = { + .owner = THIS_MODULE, + .open = gc_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +gceSTATUS +gckDEBUGFS_DIR_Init( + IN gckDEBUGFS_DIR Dir, + IN struct dentry *root, + IN gctCONST_STRING Name + ) +{ + Dir->root = debugfs_create_dir(Name, root); + + if (!Dir->root) + { + return gcvSTATUS_NOT_SUPPORTED; + } + + INIT_LIST_HEAD(&Dir->nodeList); + + return gcvSTATUS_OK; +} + +gceSTATUS +gckDEBUGFS_DIR_CreateFiles( + IN gckDEBUGFS_DIR Dir, + IN gcsINFO * List, + IN int count, + IN gctPOINTER Data + ) +{ + int i; + gcsINFO_NODE * node; + gceSTATUS status; + + for (i = 0; i < count; i++) + { + /* Create a node. */ + node = (gcsINFO_NODE *)kzalloc(sizeof(gcsINFO_NODE), GFP_KERNEL); + + node->info = &List[i]; + node->device = Data; + /* Bind to a file. TODO: clean up when fail. */ + node->entry = debugfs_create_file( + List[i].name, S_IRUGO|S_IWUSR, Dir->root, node, &gc_debugfs_operations); + if (!node->entry) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + + list_add(&(node->head), &(Dir->nodeList)); + } + + return gcvSTATUS_OK; + +OnError: + gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(Dir, List, count)); + return status; +} + +gceSTATUS +gckDEBUGFS_DIR_RemoveFiles( + IN gckDEBUGFS_DIR Dir, + IN gcsINFO * List, + IN int count + ) +{ + int i; + gcsINFO_NODE * node; + gcsINFO_NODE * temp; + + for (i = 0; i < count; i++) + { + list_for_each_entry_safe(node, temp, &Dir->nodeList, head) + { + if (node->info == &List[i]) + { + debugfs_remove(node->entry); + list_del(&node->head); + kfree(node); + } + } + } + + return gcvSTATUS_OK; +} + +void +gckDEBUGFS_DIR_Deinit( + IN gckDEBUGFS_DIR Dir + ) +{ + if (Dir->root != NULL) + { + debugfs_remove(Dir->root); + Dir->root = NULL; + } +} /******************************************************************************* ** - ** READ & WRITE FUNCTIONS (START) + ** READ & WRITE FUNCTIONS (START) ** *******************************************************************************/ @@ -158,15 +276,15 @@ static gcsDebugFileSystem gc_dbgfs ; ** ** _ReadFromNode ** - ** 1) reading bytes out of a circular buffer with wraparound. - ** 2)returns caddr_t, pointer to data read, which the caller must free. - ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to - ** be the number of bytes actually returned + ** 1) reading bytes out of a circular buffer with wraparound. + ** 2)returns caddr_t, pointer to data read, which the caller must free. + ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to + ** be the number of bytes actually returned ** *******************************************************************************/ static caddr_t _ReadFromNode ( - gcsDebugFileSystemNode* Node , + gcsDEBUGFS_Node* Node , size_t *Length , loff_t *Offset ) @@ -228,7 +346,7 @@ _ReadFromNode ( *********************************************************************************/ static void _WriteToNode ( - gcsDebugFileSystemNode* Node , + gcsDEBUGFS_Node* Node , caddr_t Buf , int Length ) @@ -243,7 +361,7 @@ _WriteToNode ( /* in case of overflow, figure out where the new buffer will * begin. we start by figuring out where the current buffer ENDS: - * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset + * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset * by the Length of the current write, and work backwards to * figure out what the oldest unoverwritten data will be (i.e., * size of the buffer). */ @@ -271,10 +389,9 @@ _WriteToNode ( } } - /******************************************************************************* ** - ** PRINTING UTILITY (START) + ** PRINTING UTILITY (START) ** *******************************************************************************/ @@ -309,7 +426,7 @@ _GetArgumentSize ( *******************************************************************************/ static ssize_t _AppendString ( - IN gcsDebugFileSystemNode* Node , + IN gcsDEBUGFS_Node* Node , IN gctCONST_STRING String , IN int Length ) @@ -341,18 +458,28 @@ _AppendString ( ** ** *******************************************************************************/ -static void +static ssize_t _DebugFSPrint ( IN unsigned int ArgumentSize , IN const char* Message , - IN gctDBGARGS Arguments + IN gctDBGARGS * Arguments ) { char buffer[MAX_LINE_SIZE] ; int len ; - down ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ; - len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) & Arguments ) ; + ssize_t res=0; + + if(in_interrupt()) + { + return - ERESTARTSYS ; + } + + if(down_interruptible( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ) + { + return - ERESTARTSYS ; + } + len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) Arguments ) ; buffer[len] = '\0' ; /* Add end-of-line if missing. */ @@ -361,9 +488,10 @@ _DebugFSPrint ( buffer[len ++] = '\n' ; buffer[len] = '\0' ; } - _AppendString ( gc_dbgfs.currentNode , buffer , len ) ; + res = _AppendString ( gc_dbgfs.currentNode , buffer , len ) ; up ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ; wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/ + return res; } /******************************************************************************* @@ -375,15 +503,15 @@ _DebugFSPrint ( /******************************************************************************* ** ** find the vivlog structure associated with an inode. - ** returns a pointer to the structure if found, NULL if not found + ** returns a pointer to the structure if found, NULL if not found ** *******************************************************************************/ -static gcsDebugFileSystemNode* +static gcsDEBUGFS_Node* _GetNodeInfo ( IN struct inode *Inode ) { - gcsDebugFileSystemNode* node ; + gcsDEBUGFS_Node* node ; if ( Inode == NULL ) return NULL ; @@ -410,7 +538,7 @@ _DebugFSRead ( { int retval ; caddr_t data_to_return ; - gcsDebugFileSystemNode* node ; + gcsDEBUGFS_Node* node ; /* get the metadata about this emlog */ if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL ) { @@ -477,7 +605,7 @@ _DebugFSWrite ( { caddr_t message = NULL ; int n ; - gcsDebugFileSystemNode*node ; + gcsDEBUGFS_Node*node ; /* get the metadata about this log */ if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL ) @@ -502,6 +630,7 @@ _DebugFSWrite ( return - ENOMEM ; } + /* copy into our temp buffer */ if ( copy_from_user ( message , buffer , n ) > 0 ) { @@ -524,6 +653,230 @@ _DebugFSWrite ( return n ; } +int dumpProcess = 0; + +void +_PrintCounter( + struct seq_file *file, + gcsDATABASE_COUNTERS * counter, + gctCONST_STRING Name + ) +{ + seq_printf(file,"Counter: %s\n", Name); + + seq_printf(file,"%-9s%10s","", "All"); + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Current"); + + seq_printf(file,"%10lld", counter->bytes); + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Maximum"); + + seq_printf(file,"%10lld", counter->maxBytes); + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Total"); + + seq_printf(file,"%10lld", counter->totalBytes); + + seq_printf(file, "\n"); +} + +void +_ShowCounters( + struct seq_file *file, + gcsDATABASE_PTR database + ) +{ + gctUINT i = 0; + gcsDATABASE_COUNTERS * counter; + gcsDATABASE_COUNTERS * nonPaged; + + static gctCONST_STRING surfaceTypes[] = { + "UNKNOWN", + "Index", + "Vertex", + "Texture", + "RT", + "Depth", + "Bitmap", + "TS", + "Image", + "Mask", + "Scissor", + "HZDepth", + }; + + /* Get pointer to counters. */ + counter = &database->vidMem; + + nonPaged = &database->nonPaged; + + seq_printf(file,"Counter: vidMem (for each surface type)\n"); + + seq_printf(file,"%-9s%10s","", "All"); + + for (i = 1; i < gcvSURF_NUM_TYPES; i++) + { + counter = &database->vidMemType[i]; + + seq_printf(file, "%10s",surfaceTypes[i]); + } + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Current"); + + seq_printf(file,"%10lld", database->vidMem.bytes); + + for (i = 1; i < gcvSURF_NUM_TYPES; i++) + { + counter = &database->vidMemType[i]; + + seq_printf(file,"%10lld", counter->bytes); + } + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Maximum"); + + seq_printf(file,"%10lld", database->vidMem.maxBytes); + + for (i = 1; i < gcvSURF_NUM_TYPES; i++) + { + counter = &database->vidMemType[i]; + + seq_printf(file,"%10lld", counter->maxBytes); + } + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Total"); + + seq_printf(file,"%10lld", database->vidMem.totalBytes); + + for (i = 1; i < gcvSURF_NUM_TYPES; i++) + { + counter = &database->vidMemType[i]; + + seq_printf(file,"%10lld", counter->totalBytes); + } + + seq_printf(file, "\n"); + + seq_printf(file,"Counter: vidMem (for each pool)\n"); + + seq_printf(file,"%-9s%10s","", "All"); + + for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++) + { + seq_printf(file, "%10d", i); + } + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Current"); + + seq_printf(file,"%10lld", database->vidMem.bytes); + + for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++) + { + counter = &database->vidMemPool[i]; + + seq_printf(file,"%10lld", counter->bytes); + } + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Maximum"); + + seq_printf(file,"%10lld", database->vidMem.maxBytes); + + for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++) + { + counter = &database->vidMemPool[i]; + + seq_printf(file,"%10lld", counter->maxBytes); + } + + seq_printf(file, "\n"); + + seq_printf(file,"%-9s","Total"); + + seq_printf(file,"%10lld", database->vidMem.totalBytes); + + for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++) + { + counter = &database->vidMemPool[i]; + + seq_printf(file,"%10lld", counter->totalBytes); + } + + seq_printf(file, "\n"); + + /* Print nonPaged. */ + _PrintCounter(file, &database->nonPaged, "nonPaged"); + _PrintCounter(file, &database->contiguous, "contiguous"); + _PrintCounter(file, &database->mapUserMemory, "mapUserMemory"); + _PrintCounter(file, &database->mapMemory, "mapMemory"); +} + +gckKERNEL +_GetValidKernel( + gckGALDEVICE Device +); +static int vidmem_show(struct seq_file *file, void *unused) +{ + gceSTATUS status; + gcsDATABASE_PTR database; + gckGALDEVICE device = file->private; + + gckKERNEL kernel = _GetValidKernel(device); + if(kernel == gcvNULL) + { + return 0; + } + + /* Find the database. */ + gcmkONERROR( + gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database)); + + seq_printf(file, "VidMem Usage (Process %d):\n", dumpProcess); + + _ShowCounters(file, database); + + return 0; + +OnError: + return 0; +} + +static int +vidmem_open( + struct inode *inode, + struct file *file + ) +{ + return single_open(file, vidmem_show, inode->i_private); +} + +static ssize_t +vidmem_write( + struct file *file, + const char __user *buf, + size_t count, + loff_t *pos + ) +{ + dumpProcess = simple_strtol(buf, NULL, 0); + return count; +} + /******************************************************************************* ** ** File Operations Table @@ -535,6 +888,14 @@ static const struct file_operations debugfs_operations = { .write = _DebugFSWrite , } ; +static const struct file_operations vidmem_operations = { + .owner = THIS_MODULE , + .open = vidmem_open, + .read = seq_read, + .write = vidmem_write, + .llseek = seq_lseek, +} ; + /******************************************************************************* ** ** INTERFACE FUNCTIONS (START) @@ -543,7 +904,7 @@ static const struct file_operations debugfs_operations = { /******************************************************************************* ** - ** gckDebugFileSystemIsEnabled + ** gckDEBUGFS_IsEnabled ** ** ** INPUT: @@ -554,13 +915,13 @@ static const struct file_operations debugfs_operations = { gctINT -gckDebugFileSystemIsEnabled ( void ) +gckDEBUGFS_IsEnabled ( void ) { return gc_dbgfs.isInited ; } /******************************************************************************* ** - ** gckDebugFileSystemInitialize + ** gckDEBUGFS_Initialize ** ** ** INPUT: @@ -570,7 +931,7 @@ gckDebugFileSystemIsEnabled ( void ) *******************************************************************************/ gctINT -gckDebugFileSystemInitialize ( void ) +gckDEBUGFS_Initialize ( void ) { if ( ! gc_dbgfs.isInited ) { @@ -582,7 +943,7 @@ gckDebugFileSystemInitialize ( void ) } /******************************************************************************* ** - ** gckDebugFileSystemTerminate + ** gckDEBUGFS_Terminate ** ** ** INPUT: @@ -592,17 +953,17 @@ gckDebugFileSystemInitialize ( void ) *******************************************************************************/ gctINT -gckDebugFileSystemTerminate ( void ) +gckDEBUGFS_Terminate ( void ) { - gcsDebugFileSystemNode * next = gcvNULL ; - gcsDebugFileSystemNode * temp = gcvNULL ; + gcsDEBUGFS_Node * next = gcvNULL ; + gcsDEBUGFS_Node * temp = gcvNULL ; if ( gc_dbgfs.isInited ) { temp = gc_dbgfs.linkedlist ; while ( temp != gcvNULL ) { next = temp->next ; - gckDebugFileSystemFreeNode ( temp ) ; + gckDEBUGFS_FreeNode ( temp ) ; kfree ( temp ) ; temp = next ; } @@ -614,33 +975,34 @@ gckDebugFileSystemTerminate ( void ) /******************************************************************************* ** - ** gckDebugFileSystemCreateNode + ** gckDEBUGFS_CreateNode ** ** ** INPUT: ** ** OUTPUT: ** - ** gckDebugFileSystemFreeNode * Device - ** Pointer to a variable receiving the gcsDebugFileSystemNode object pointer on - ** success. + ** gckDEBUGFS_FreeNode * Device + ** Pointer to a variable receiving the gcsDEBUGFS_Node object pointer on + ** success. *********************************************************************************/ gctINT -gckDebugFileSystemCreateNode ( - IN gctINT SizeInKB , - IN gctCONST_STRING ParentName , - IN gctCONST_STRING NodeName , - OUT gcsDebugFileSystemNode **Node - ) +gckDEBUGFS_CreateNode ( + IN gctPOINTER Device, + IN gctINT SizeInKB , + IN struct dentry * Root , + IN gctCONST_STRING NodeName , + OUT gcsDEBUGFS_Node **Node + ) { - gcsDebugFileSystemNode*node ; + gcsDEBUGFS_Node*node ; /* allocate space for our metadata and initialize it */ - if ( ( node = kmalloc ( sizeof (gcsDebugFileSystemNode ) , GFP_KERNEL ) ) == NULL ) + if ( ( node = kmalloc ( sizeof (gcsDEBUGFS_Node ) , GFP_KERNEL ) ) == NULL ) goto struct_malloc_failed ; /*Zero it out*/ - memset ( node , 0 , sizeof (gcsDebugFileSystemNode ) ) ; + memset ( node , 0 , sizeof (gcsDEBUGFS_Node ) ) ; /*Init the sync primitives*/ #if defined(DECLARE_WAIT_QUEUE_HEAD) @@ -657,28 +1019,34 @@ gckDebugFileSystemCreateNode ( sema_init ( gcmkNODE_SEM ( node ) , 1 ) ; /*End the sync primitives*/ - - /* figure out how much of a buffer this should be and allocate the buffer */ - node->size = 1024 * SizeInKB ; - if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL ) - goto data_malloc_failed ; - /*creating the debug file system*/ - node->parent = debugfs_create_dir ( ParentName , NULL ) ; + node->parent = Root; - /*creating the file*/ - node->filen = debugfs_create_file ( NodeName , S_IRUGO | S_IWUSR , node->parent , NULL , - &debugfs_operations ) ; + if (SizeInKB) + { + /* figure out how much of a buffer this should be and allocate the buffer */ + node->size = 1024 * SizeInKB ; + if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL ) + goto data_malloc_failed ; + + /*creating the file*/ + node->filen = debugfs_create_file(NodeName, S_IRUGO|S_IWUSR, node->parent, NULL, + &debugfs_operations); + } + + node->vidmem + = debugfs_create_file("vidmem", S_IRUGO|S_IWUSR, node->parent, Device, &vidmem_operations); /* add it to our linked list */ node->next = gc_dbgfs.linkedlist ; gc_dbgfs.linkedlist = node ; + /* pass the struct back */ *Node = node ; return 0 ; - vfree ( node->data ) ; + data_malloc_failed: kfree ( node ) ; struct_malloc_failed: @@ -687,7 +1055,7 @@ struct_malloc_failed: /******************************************************************************* ** - ** gckDebugFileSystemFreeNode + ** gckDEBUGFS_FreeNode ** ** ** INPUT: @@ -696,12 +1064,12 @@ struct_malloc_failed: ** *******************************************************************************/ void -gckDebugFileSystemFreeNode ( - IN gcsDebugFileSystemNode * Node +gckDEBUGFS_FreeNode ( + IN gcsDEBUGFS_Node * Node ) { - gcsDebugFileSystemNode **ptr ; + gcsDEBUGFS_Node **ptr ; if ( Node == NULL ) { @@ -714,13 +1082,14 @@ gckDebugFileSystemFreeNode ( vfree ( Node->data ) ; /*Close Debug fs*/ - if ( Node->filen ) + if (Node->vidmem) { - debugfs_remove ( Node->filen ) ; + debugfs_remove(Node->vidmem); } - if ( Node->parent ) + + if ( Node->filen ) { - debugfs_remove ( Node->parent ) ; + debugfs_remove ( Node->filen ) ; } /* now delete the node from the linked list */ @@ -741,7 +1110,7 @@ gckDebugFileSystemFreeNode ( /******************************************************************************* ** - ** gckDebugFileSystemSetCurrentNode + ** gckDEBUGFS_SetCurrentNode ** ** ** INPUT: @@ -750,8 +1119,8 @@ gckDebugFileSystemFreeNode ( ** *******************************************************************************/ void -gckDebugFileSystemSetCurrentNode ( - IN gcsDebugFileSystemNode * Node +gckDEBUGFS_SetCurrentNode ( + IN gcsDEBUGFS_Node * Node ) { gc_dbgfs.currentNode = Node ; @@ -759,7 +1128,7 @@ gckDebugFileSystemSetCurrentNode ( /******************************************************************************* ** - ** gckDebugFileSystemGetCurrentNode + ** gckDEBUGFS_GetCurrentNode ** ** ** INPUT: @@ -768,8 +1137,8 @@ gckDebugFileSystemSetCurrentNode ( ** *******************************************************************************/ void -gckDebugFileSystemGetCurrentNode ( - OUT gcsDebugFileSystemNode ** Node +gckDEBUGFS_GetCurrentNode ( + OUT gcsDEBUGFS_Node ** Node ) { *Node = gc_dbgfs.currentNode ; @@ -777,7 +1146,7 @@ gckDebugFileSystemGetCurrentNode ( /******************************************************************************* ** - ** gckDebugFileSystemPrint + ** gckDEBUGFS_Print ** ** ** INPUT: @@ -785,11 +1154,13 @@ gckDebugFileSystemGetCurrentNode ( ** OUTPUT: ** *******************************************************************************/ -void -gckDebugFileSystemPrint ( +ssize_t +gckDEBUGFS_Print ( IN gctCONST_STRING Message , ... ) { - gcmkDBGFSPRINT ( _GetArgumentSize ( Message ) , Message ) ; + ssize_t _debugfs_res; + gcmkDEBUGFS_PRINT ( _GetArgumentSize ( Message ) , Message ) ; + return _debugfs_res; } 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 78d819918988..9d17e879410d 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -24,11 +24,61 @@ #ifndef __gc_hal_kernel_debugfs_h_ #define __gc_hal_kernel_debugfs_h_ - #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */ - - - typedef struct _gcsDebugFileSystemNode gcsDebugFileSystemNode ; - + #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */ + + + typedef struct _gcsDEBUGFS_Node gcsDEBUGFS_Node; + +typedef struct _gcsDEBUGFS_DIR *gckDEBUGFS_DIR; +typedef struct _gcsDEBUGFS_DIR +{ + struct dentry * root; + struct list_head nodeList; +} +gcsDEBUGFS_DIR; + +typedef struct _gcsINFO +{ + const char * name; + int (*show)(struct seq_file*, void*); +} +gcsINFO; + +typedef struct _gcsINFO_NODE +{ + gcsINFO * info; + gctPOINTER device; + struct dentry * entry; + struct list_head head; +} +gcsINFO_NODE; + +gceSTATUS +gckDEBUGFS_DIR_Init( + IN gckDEBUGFS_DIR Dir, + IN struct dentry *root, + IN gctCONST_STRING Name + ); + +gceSTATUS +gckDEBUGFS_DIR_CreateFiles( + IN gckDEBUGFS_DIR Dir, + IN gcsINFO * List, + IN int count, + IN gctPOINTER Data + ); + +gceSTATUS +gckDEBUGFS_DIR_RemoveFiles( + IN gckDEBUGFS_DIR Dir, + IN gcsINFO * List, + IN int count + ); + +void +gckDEBUGFS_DIR_Deinit( + IN gckDEBUGFS_DIR Dir + ); /******************************************************************************* ** @@ -36,11 +86,11 @@ ** *******************************************************************************/ -gctINT gckDebugFileSystemIsEnabled(void); +gctINT gckDEBUGFS_IsEnabled(void); -gctINT gckDebugFileSystemInitialize(void); +gctINT gckDEBUGFS_Initialize(void); -gctINT gckDebugFileSystemTerminate(void); +gctINT gckDEBUGFS_Terminate(void); /******************************************************************************* @@ -49,35 +99,36 @@ gctINT gckDebugFileSystemTerminate(void); ** *******************************************************************************/ -gctINT gckDebugFileSystemCreateNode( - IN gctINT SizeInKB, - IN gctCONST_STRING ParentName , - IN gctCONST_STRING NodeName, - OUT gcsDebugFileSystemNode **Node - ); - +gctINT +gckDEBUGFS_CreateNode( + IN gctPOINTER Device, + IN gctINT SizeInKB, + IN struct dentry * Root, + IN gctCONST_STRING NodeName, + OUT gcsDEBUGFS_Node **Node + ); -void gckDebugFileSystemFreeNode( - IN gcsDebugFileSystemNode * Node - ); +void gckDEBUGFS_FreeNode( + IN gcsDEBUGFS_Node * Node + ); -void gckDebugFileSystemSetCurrentNode( - IN gcsDebugFileSystemNode * Node - ); +void gckDEBUGFS_SetCurrentNode( + IN gcsDEBUGFS_Node * Node + ); -void gckDebugFileSystemGetCurrentNode( - OUT gcsDebugFileSystemNode ** Node - ); +void gckDEBUGFS_GetCurrentNode( + OUT gcsDEBUGFS_Node ** Node + ); -void gckDebugFileSystemPrint( - IN gctCONST_STRING Message, - ... - ); +ssize_t gckDEBUGFS_Print( + IN gctCONST_STRING Message, + ... + ); #endif 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 bff85a0e9bf4..ccec82f282bc 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,25 +22,407 @@ #include "gc_hal_kernel_linux.h" #include #include -#include #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) -#include -#endif -#include #define _GC_OBJ_ZONE gcvZONE_DEVICE -#define DEBUG_FILE "galcore_trace" -#define PARENT_FILE "gpu" +#define DEBUG_FILE "galcore_trace" +#define PARENT_FILE "gpu" #ifdef FLAREON static struct dove_gpio_irq_handler gc500_handle; #endif -#define gcmIS_CORE_PRESENT(Device, Core) (Device->irqLines[Core] > 0) +gckKERNEL +_GetValidKernel( + gckGALDEVICE Device + ) +{ + if (Device->kernels[gcvCORE_MAJOR]) + { + return Device->kernels[gcvCORE_MAJOR]; + } + else + if (Device->kernels[gcvCORE_2D]) + { + return Device->kernels[gcvCORE_2D]; + } + else + if (Device->kernels[gcvCORE_VG]) + { + return Device->kernels[gcvCORE_VG]; + } + else + { + return gcvNULL; + } +} + +/******************************************************************************\ +******************************** Debugfs Support ******************************* +\******************************************************************************/ + +/******************************************************************************\ +***************************** DEBUG SHOW FUNCTIONS ***************************** +\******************************************************************************/ + +int gc_info_show(struct seq_file* m, void* data) +{ + gcsINFO_NODE *node = m->private; + gckGALDEVICE device = node->device; + int i = 0; + gceCHIPMODEL chipModel; + gctUINT32 chipRevision; + + for (i = 0; i < gcdMAX_GPU_COUNT; i++) + { + if (device->irqLines[i] != -1) + { +#if gcdENABLE_VG + if (i == gcvCORE_VG) + { + chipModel = device->kernels[i]->vg->hardware->chipModel; + chipRevision = device->kernels[i]->vg->hardware->chipRevision; + } + else +#endif + { + chipModel = device->kernels[i]->hardware->identity.chipModel; + chipRevision = device->kernels[i]->hardware->identity.chipRevision; + } + + seq_printf(m, "gpu : %d\n", i); + seq_printf(m, "model : %4x\n", chipModel); + seq_printf(m, "revision : %4x\n", chipRevision); + seq_printf(m, "\n"); + } + } + + return 0; +} + +int gc_clients_show(struct seq_file* m, void* data) +{ + gcsINFO_NODE *node = m->private; + gckGALDEVICE device = node->device; + + gckKERNEL kernel = _GetValidKernel(device); + + gcsDATABASE_PTR database; + gctINT i, pid; + gctUINT8 name[24]; + + seq_printf(m, "%-8s%s\n", "PID", "NAME"); + seq_printf(m, "------------------------\n"); + + /* Acquire the database mutex. */ + gcmkVERIFY_OK( + gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE)); + + /* Walk the databases. */ + for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i) + { + for (database = kernel->db->db[i]; + database != gcvNULL; + database = database->next) + { + pid = database->processID; + + gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name))); + + gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name)); + + seq_printf(m, "%-8d%s\n", pid, name); + } + } + + /* Release the database mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex)); + + /* Success. */ + return 0; +} + +static void +_CounterAdd( + gcsDATABASE_COUNTERS * Dest, + gcsDATABASE_COUNTERS * Src + ) +{ + Dest->bytes += Src->bytes; + Dest->maxBytes += Src->maxBytes; + Dest->totalBytes += Src->totalBytes; +} + +static void +_CounterPrint( + gcsDATABASE_COUNTERS * Counter, + gctCONST_STRING Name, + struct seq_file* m + ) +{ + seq_printf(m, " %s:\n", Name); + seq_printf(m, " Used : %10llu B\n", Counter->bytes); +} + +int gc_meminfo_show(struct seq_file* m, void* data) +{ + gcsINFO_NODE *node = m->private; + gckGALDEVICE device = node->device; + gckKERNEL kernel = _GetValidKernel(device); + gckVIDMEM memory; + gceSTATUS status; + gcsDATABASE_PTR database; + gctUINT32 i; + + gctUINT32 free = 0, used = 0, total = 0; + + gcsDATABASE_COUNTERS contiguousCounter = {0, 0, 0}; + gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0}; + gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0}; + + status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory); + + if (gcmIS_SUCCESS(status)) + { + gcmkVERIFY_OK( + gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE)); + + free = memory->freeBytes; + used = memory->bytes - memory->freeBytes; + total = memory->bytes; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex)); + } + + seq_printf(m, "VIDEO MEMORY:\n"); + seq_printf(m, " gcvPOOL_SYSTEM:\n"); + seq_printf(m, " Free : %10u B\n", free); + seq_printf(m, " Used : %10u B\n", used); + seq_printf(m, " Total : %10u B\n", total); + + /* Acquire the database mutex. */ + gcmkVERIFY_OK( + gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE)); + + /* Walk the databases. */ + for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i) + { + for (database = kernel->db->db[i]; + database != gcvNULL; + database = database->next) + { + gcsDATABASE_COUNTERS * counter = &database->vidMemPool[gcvPOOL_CONTIGUOUS]; + _CounterAdd(&contiguousCounter, counter); + + counter = &database->vidMemPool[gcvPOOL_VIRTUAL]; + _CounterAdd(&virtualCounter, counter); + + + counter = &database->nonPaged; + _CounterAdd(&nonPagedCounter, counter); + } + } + + /* Release the database mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex)); + + _CounterPrint(&contiguousCounter, "gcvPOOL_CONTIGUOUS", m); + _CounterPrint(&virtualCounter, "gcvPOOL_VIRTUAL", m); + + seq_printf(m, "\n"); + + seq_printf(m, "NON PAGED MEMORY:\n"); + seq_printf(m, " Used : %10llu B\n", nonPagedCounter.bytes); + + return 0; +} + +static int +_ShowRecord( + IN struct seq_file *file, + IN gcsDATABASE_RECORD_PTR record + ) +{ + seq_printf(file, "%4d%8d%16p%16p%16zu\n", + record->type, + record->kernel->core, + record->data, + record->physical, + record->bytes + ); + + return 0; +} + +static int +_ShowRecords( + IN struct seq_file *File, + IN gcsDATABASE_PTR Database + ) +{ + gctUINT i; + + seq_printf(File, "Records:\n"); + + seq_printf(File, "%s%8s%16s%16s%16s\n", + "Type", "GPU", "Data", "Physical", "Bytes"); + + for (i = 0; i < gcmCOUNTOF(Database->list); i++) + { + gcsDATABASE_RECORD_PTR record = Database->list[i]; + + while (record != NULL) + { + _ShowRecord(File, record); + record = record->next; + } + } + + return 0; +} + +void +_ShowCounters( + struct seq_file *File, + gcsDATABASE_PTR Database + ); + +static void +_ShowProcess( + IN struct seq_file *File, + IN gcsDATABASE_PTR Database + ) +{ + gctINT pid; + gctUINT8 name[24]; + + /* Process ID and name */ + pid = Database->processID; + gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name))); + gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name)); + + seq_printf(File, "--------------------------------------------------------------------------------\n"); + seq_printf(File, "Process: %-8d %s\n", pid, name); + + /* Detailed records */ + _ShowRecords(File, Database); + + seq_printf(File, "Counters:\n"); + + _ShowCounters(File, Database); +} + +static void +_ShowProcesses( + IN struct seq_file * file, + IN gckKERNEL Kernel + ) +{ + gcsDATABASE_PTR database; + gctINT i; + + /* Acquire the database mutex. */ + gcmkVERIFY_OK( + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE)); + + /* Idle time since last call */ + seq_printf(file, "GPU Idle: %llu ns\n", Kernel->db->idleTime); + Kernel->db->idleTime = 0; + + /* Walk the databases. */ + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i) + { + for (database = Kernel->db->db[i]; + database != gcvNULL; + database = database->next) + { + _ShowProcess(file, database); + } + } + + /* Release the database mutex. */ + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex)); +} + +static int +gc_db_show(struct seq_file *m, void *data) +{ + gcsINFO_NODE *node = m->private; + gckGALDEVICE device = node->device; + gckKERNEL kernel = _GetValidKernel(device); + _ShowProcesses(m, kernel); + return 0 ; +} + +static int +gc_version_show(struct seq_file *m, void *data) +{ + seq_printf(m, "%s\n", gcvVERSION_STRING); + + return 0 ; +} + +int gc_idle_show(struct seq_file* m, void* data) +{ + gcsINFO_NODE *node = m->private; + gckGALDEVICE device = node->device; + gckKERNEL kernel = _GetValidKernel(device); + gcuDATABASE_INFO info; + + gckKERNEL_QueryProcessDB(kernel, 0, gcvFALSE, gcvDB_IDLE, &info); + + seq_printf(m, "GPU idle time since last query: %llu ns\n", info.time); + + return 0; +} + +static gcsINFO InfoList[] = +{ + {"info", gc_info_show}, + {"clients", gc_clients_show}, + {"meminfo", gc_meminfo_show}, + {"idle", gc_idle_show}, + {"database", gc_db_show}, + {"version", gc_version_show}, +}; + +static gceSTATUS +_DebugfsInit( + IN gckGALDEVICE Device + ) +{ + gceSTATUS status; + + gckDEBUGFS_DIR dir = &Device->debugfsDir; + + gcmkONERROR(gckDEBUGFS_DIR_Init(dir, gcvNULL, "gc")); + + gcmkONERROR(gckDEBUGFS_DIR_CreateFiles(dir, InfoList, gcmCOUNTOF(InfoList), Device)); + + return gcvSTATUS_OK; + +OnError: + return status; +} + +static void +_DebugfsCleanup( + IN gckGALDEVICE Device + ) +{ + gckDEBUGFS_DIR dir = &Device->debugfsDir; + + if (Device->debugfsDir.root) + { + gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(dir, InfoList, gcmCOUNTOF(InfoList))); + + gckDEBUGFS_DIR_Deinit(dir); + } +} + /******************************************************************************\ *************************** Memory Allocation Wrappers ************************* @@ -68,7 +450,7 @@ _AllocateMemory( Device->os, gcvFALSE, &Bytes, Physical, Logical )); - *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle - Device->baseAddress; + *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle; /* Success. */ gcmkFOOTER_ARG( @@ -78,38 +460,261 @@ _AllocateMemory( return gcvSTATUS_OK; -OnError: - gcmkFOOTER(); - return status; +OnError: + gcmkFOOTER(); + return status; +} + +static gceSTATUS +_FreeMemory( + IN gckGALDEVICE Device, + IN gctPOINTER Logical, + IN gctPHYS_ADDR Physical) +{ + gceSTATUS status; + + gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x", + Device, Logical, Physical); + + gcmkVERIFY_ARGUMENT(Device != NULL); + + status = gckOS_FreeContiguous( + Device->os, Physical, Logical, + ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE + ); + + gcmkFOOTER(); + return status; +} + + + +/******************************************************************************\ +******************************* Interrupt Handler ****************************** +\******************************************************************************/ +#if gcdMULTI_GPU +static irqreturn_t isrRoutine3D0(int irq, void *ctxt) +{ + gceSTATUS status; + gckGALDEVICE device; + + device = (gckGALDEVICE) ctxt; + + /* Call kernel interrupt notification. */ + status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], + gcvCORE_3D_0_ID, + gcvNOTIFY_INTERRUPT, + gcvTRUE); + + if (gcmIS_SUCCESS(status)) + { + /* Wake up the threadRoutine to process events. */ + device->dataReady3D[gcvCORE_3D_0_ID] = gcvTRUE; + wake_up_interruptible(&device->intrWaitQueue3D[gcvCORE_3D_0_ID]); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int threadRoutine3D0(void *ctxt) +{ + gckGALDEVICE device = (gckGALDEVICE) ctxt; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, + "Starting isr Thread with extension=%p", + device); + + for (;;) + { + /* Sleep until being awaken by the interrupt handler. */ + wait_event_interruptible(device->intrWaitQueue3D[gcvCORE_3D_0_ID], + device->dataReady3D[gcvCORE_3D_0_ID] == gcvTRUE); + device->dataReady3D[gcvCORE_3D_0_ID] = gcvFALSE; + + if (device->killThread == gcvTRUE) + { + /* The daemon exits. */ + while (!kthread_should_stop()) + { + gckOS_Delay(device->os, 1); + } + + return 0; + } + + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], + gcvCORE_3D_0_ID, + gcvNOTIFY_INTERRUPT, + gcvFALSE); + } +} + +#if gcdMULTI_GPU > 1 +static irqreturn_t isrRoutine3D1(int irq, void *ctxt) +{ + gceSTATUS status; + gckGALDEVICE device; + + device = (gckGALDEVICE) ctxt; + + /* Call kernel interrupt notification. */ + status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], + gcvCORE_3D_1_ID, + gcvNOTIFY_INTERRUPT, + gcvTRUE); + + if (gcmIS_SUCCESS(status)) + { + /* Wake up the worker thread to process events. */ + device->dataReady3D[gcvCORE_3D_1_ID] = gcvTRUE; + wake_up_interruptible(&device->intrWaitQueue3D[gcvCORE_3D_1_ID]); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int threadRoutine3D1(void *ctxt) +{ + gckGALDEVICE device = (gckGALDEVICE) ctxt; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, + "Starting isr Thread with extension=%p", + device); + + for (;;) + { + /* Sleep until being awaken by the interrupt handler. */ + wait_event_interruptible(device->intrWaitQueue3D[gcvCORE_3D_1_ID], + device->dataReady3D[gcvCORE_3D_1_ID] == gcvTRUE); + device->dataReady3D[gcvCORE_3D_1_ID] = gcvFALSE; + + if (device->killThread == gcvTRUE) + { + /* The daemon exits. */ + while (!kthread_should_stop()) + { + gckOS_Delay(device->os, 1); + } + + return 0; + } + + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], + gcvCORE_3D_1_ID, + gcvNOTIFY_INTERRUPT, + gcvFALSE); + } +} +#endif +#elif gcdMULTI_GPU_AFFINITY +static irqreturn_t isrRoutine3D0(int irq, void *ctxt) +{ + gceSTATUS status; + gckGALDEVICE device; + + device = (gckGALDEVICE) ctxt; + + /* Call kernel interrupt notification. */ + status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvTRUE); + + if (gcmIS_SUCCESS(status)) + { + up(&device->semas[gcvCORE_MAJOR]); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int threadRoutine3D0(void *ctxt) +{ + gckGALDEVICE device = (gckGALDEVICE) ctxt; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, + "Starting isr Thread with extension=%p", + device); + + for (;;) + { + static int down; + + down = down_interruptible(&device->semas[gcvCORE_MAJOR]); + if (down); /*To make gcc 4.6 happye*/ + + if (device->killThread == gcvTRUE) + { + /* The daemon exits. */ + while (!kthread_should_stop()) + { + gckOS_Delay(device->os, 1); + } + + return 0; + } + + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], + gcvNOTIFY_INTERRUPT, + gcvFALSE); + } +} + +static irqreturn_t isrRoutine3D1(int irq, void *ctxt) +{ + gceSTATUS status; + gckGALDEVICE device; + + device = (gckGALDEVICE) ctxt; + + /* Call kernel interrupt notification. */ + status = gckKERNEL_Notify(device->kernels[gcvCORE_OCL], gcvNOTIFY_INTERRUPT, gcvTRUE); + + if (gcmIS_SUCCESS(status)) + { + up(&device->semas[gcvCORE_OCL]); + + return IRQ_HANDLED; + } + + return IRQ_NONE; } -static gceSTATUS -_FreeMemory( - IN gckGALDEVICE Device, - IN gctPOINTER Logical, - IN gctPHYS_ADDR Physical) +static int threadRoutine3D1(void *ctxt) { - gceSTATUS status; - - gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x", - Device, Logical, Physical); + gckGALDEVICE device = (gckGALDEVICE) ctxt; - gcmkVERIFY_ARGUMENT(Device != NULL); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, + "Starting isr Thread with extension=%p", + device); - status = gckOS_FreeContiguous( - Device->os, Physical, Logical, - ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE - ); + for (;;) + { + static int down; - gcmkFOOTER(); - return status; -} + down = down_interruptible(&device->semas[gcvCORE_OCL]); + if (down); /*To make gcc 4.6 happye*/ + if (device->killThread == gcvTRUE) + { + /* The daemon exits. */ + while (!kthread_should_stop()) + { + gckOS_Delay(device->os, 1); + } + return 0; + } -/******************************************************************************\ -******************************* Interrupt Handler ****************************** -\******************************************************************************/ + gckKERNEL_Notify(device->kernels[gcvCORE_OCL], + gcvNOTIFY_INTERRUPT, + gcvFALSE); + } +} +#else static irqreturn_t isrRoutine(int irq, void *ctxt) { gceSTATUS status; @@ -122,8 +727,6 @@ static irqreturn_t isrRoutine(int irq, void *ctxt) if (gcmIS_SUCCESS(status)) { - device->dataReadys[gcvCORE_MAJOR] = gcvTRUE; - up(&device->semas[gcvCORE_MAJOR]); return IRQ_HANDLED; @@ -146,7 +749,6 @@ static int threadRoutine(void *ctxt) down = down_interruptible(&device->semas[gcvCORE_MAJOR]); if (down); /*To make gcc 4.6 happye*/ - device->dataReadys[gcvCORE_MAJOR] = gcvFALSE; if (device->killThread == gcvTRUE) { @@ -159,9 +761,12 @@ static int threadRoutine(void *ctxt) return 0; } - gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvFALSE); + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], + gcvNOTIFY_INTERRUPT, + gcvFALSE); } } +#endif static irqreturn_t isrRoutine2D(int irq, void *ctxt) { @@ -171,12 +776,14 @@ static irqreturn_t isrRoutine2D(int irq, void *ctxt) device = (gckGALDEVICE) ctxt; /* Call kernel interrupt notification. */ - status = gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvTRUE); - + status = gckKERNEL_Notify(device->kernels[gcvCORE_2D], +#if gcdMULTI_GPU + 0, +#endif + gcvNOTIFY_INTERRUPT, + gcvTRUE); if (gcmIS_SUCCESS(status)) { - device->dataReadys[gcvCORE_2D] = gcvTRUE; - up(&device->semas[gcvCORE_2D]); return IRQ_HANDLED; @@ -199,7 +806,6 @@ static int threadRoutine2D(void *ctxt) down = down_interruptible(&device->semas[gcvCORE_2D]); if (down); /*To make gcc 4.6 happye*/ - device->dataReadys[gcvCORE_2D] = gcvFALSE; if (device->killThread == gcvTRUE) { @@ -211,8 +817,12 @@ static int threadRoutine2D(void *ctxt) return 0; } - - gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvFALSE); + gckKERNEL_Notify(device->kernels[gcvCORE_2D], +#if gcdMULTI_GPU + 0, +#endif + gcvNOTIFY_INTERRUPT, + gcvFALSE); } } @@ -224,13 +834,13 @@ static irqreturn_t isrRoutineVG(int irq, void *ctxt) device = (gckGALDEVICE) ctxt; - /* Serve the interrupt. */ - status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt); + /* Serve the interrupt. */ + status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt); - /* Determine the return value. */ - return (status == gcvSTATUS_NOT_OUR_INTERRUPT) - ? IRQ_RETVAL(0) - : IRQ_RETVAL(1); + /* Determine the return value. */ + return (status == gcvSTATUS_NOT_OUR_INTERRUPT) + ? IRQ_RETVAL(0) + : IRQ_RETVAL(1); #else return IRQ_NONE; #endif @@ -250,7 +860,6 @@ static int threadRoutineVG(void *ctxt) down = down_interruptible(&device->semas[gcvCORE_VG]); if (down); /*To make gcc 4.6 happye*/ - device->dataReadys[gcvCORE_VG] = gcvFALSE; if (device->killThread == gcvTRUE) { @@ -262,8 +871,12 @@ static int threadRoutineVG(void *ctxt) return 0; } - - gckKERNEL_Notify(device->kernels[gcvCORE_VG], gcvNOTIFY_INTERRUPT, gcvFALSE); + gckKERNEL_Notify(device->kernels[gcvCORE_VG], +#if gcdMULTI_GPU + 0, +#endif + gcvNOTIFY_INTERRUPT, + gcvFALSE); } } @@ -287,9 +900,18 @@ static int threadRoutineVG(void *ctxt) */ gceSTATUS gckGALDEVICE_Construct( +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + IN gctINT IrqLine3D0, + IN gctUINT32 RegisterMemBase3D0, + IN gctSIZE_T RegisterMemSize3D0, + IN gctINT IrqLine3D1, + IN gctUINT32 RegisterMemBase3D1, + IN gctSIZE_T RegisterMemSize3D1, +#else IN gctINT IrqLine, IN gctUINT32 RegisterMemBase, IN gctSIZE_T RegisterMemSize, +#endif IN gctINT IrqLine2D, IN gctUINT32 RegisterMemBase2D, IN gctSIZE_T RegisterMemSize2D, @@ -305,9 +927,9 @@ 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, OUT gckGALDEVICE *Device ) { @@ -320,10 +942,25 @@ gckGALDEVICE_Construct( gckGALDEVICE device; gceSTATUS status; gctINT32 i; +#if gcdMULTI_GPU + gctINT32 j; +#endif gceHARDWARE_TYPE type; gckDB sharedDB = gcvNULL; gckKERNEL kernel = gcvNULL; +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + gcmkHEADER_ARG("IrqLine3D0=%d RegisterMemBase3D0=0x%08x RegisterMemSize3D0=%u " + "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u " + "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u " + "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu " + "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d", + IrqLine3D0, RegisterMemBase3D0, RegisterMemSize3D0, + IrqLine2D, RegisterMemBase2D, RegisterMemSize2D, + IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG, + ContiguousBase, ContiguousSize, BankSize, FastClear, Compression, + PhysBaseAddr, PhysSize, Signal); +#else gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u " "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u " "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u " @@ -334,9 +971,15 @@ gckGALDEVICE_Construct( IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG, ContiguousBase, ContiguousSize, BankSize, FastClear, Compression, PhysBaseAddr, PhysSize, Signal); +#endif + +#if gcdDISABLE_CORES_2D3D + IrqLine = -1; + IrqLine2D = -1; +#endif /* Allocate device structure. */ - device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL); + device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN); if (!device) { @@ -345,179 +988,182 @@ gckGALDEVICE_Construct( memset(device, 0, sizeof(struct _gckGALDEVICE)); - device->dbgnode = gcvNULL; - if(LogFileSize != 0) - { - if(gckDebugFileSystemCreateNode(LogFileSize,PARENT_FILE,DEBUG_FILE,&(device->dbgnode)) != 0) - { - gcmkTRACE_ZONE( - gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): Failed to create the debug file system %s/%s \n", - __FUNCTION__, __LINE__, - PARENT_FILE, DEBUG_FILE - ); - } - else - { - /*Everything is OK*/ - gckDebugFileSystemSetCurrentNode(device->dbgnode); - } - } -#ifdef CONFIG_PM - /*Init runtime pm for gpu*/ - pm_runtime_enable(pdev); - device->pmdev = pdev; -#endif + device->dbgNode = gcvNULL; -#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); + device->platform = Args->platform; + + gcmkONERROR(_DebugfsInit(device)); + + if (gckDEBUGFS_CreateNode( + device, LogFileSize, device->debugfsDir.root ,DEBUG_FILE, &(device->dbgNode))) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Failed to create the debug file system %s/%s \n", + __FUNCTION__, __LINE__, + PARENT_FILE, DEBUG_FILE + ); } -#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"); - } - } - } + else if (LogFileSize) + { + gckDEBUGFS_SetCurrentNode(device->dbgNode); + } + +#if gcdMULTI_GPU + if (IrqLine3D0 != -1) + { + device->requestedRegisterMemBase3D[gcvCORE_3D_0_ID] = RegisterMemBase3D0; + device->requestedRegisterMemSize3D[gcvCORE_3D_0_ID] = RegisterMemSize3D0; + } + + if (IrqLine3D1 != -1) + { + device->requestedRegisterMemBase3D[gcvCORE_3D_1_ID] = RegisterMemBase3D1; + device->requestedRegisterMemSize3D[gcvCORE_3D_1_ID] = RegisterMemSize3D1; + } +#elif gcdMULTI_GPU_AFFINITY + if (IrqLine3D0 != -1) + { + device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase3D0; + device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize3D0; } + if (IrqLine3D1 != -1) + { + device->requestedRegisterMemBases[gcvCORE_OCL] = RegisterMemBase3D1; + device->requestedRegisterMemSizes[gcvCORE_OCL] = RegisterMemSize3D1; + } +#else if (IrqLine != -1) { - device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase; - device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize; + device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase; + device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize; } +#endif if (IrqLine2D != -1) { - device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D; - device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D; + device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D; + device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D; } if (IrqLineVG != -1) { - device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG; - device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG; + device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG; + device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG; } device->requestedContiguousBase = 0; device->requestedContiguousSize = 0; - for (i = 0; i < gcdMAX_GPU_COUNT; i++) { - physical = device->requestedRegisterMemBases[i]; +#if gcdMULTI_GPU + if (i == gcvCORE_MAJOR) + { + for (j = 0; j < gcdMULTI_GPU; j++) + { + physical = device->requestedRegisterMemBase3D[j]; + + /* Set up register memory region. */ + if (physical != 0) + { + mem_region = request_mem_region(physical, + device->requestedRegisterMemSize3D[j], + "galcore register region"); + + if (mem_region == gcvNULL) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Failed to claim %lu bytes @ 0x%08X\n", + __FUNCTION__, __LINE__, + physical, device->requestedRegisterMemSize3D[j] + ); + + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } + + device->registerBase3D[j] = (gctPOINTER) ioremap_nocache( + physical, device->requestedRegisterMemSize3D[j]); + + if (device->registerBase3D[j] == gcvNULL) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Unable to map %ld bytes @ 0x%08X\n", + __FUNCTION__, __LINE__, + physical, device->requestedRegisterMemSize3D[j] + ); + + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } - /* Set up register memory region. */ - if (physical != 0) + physical += device->requestedRegisterMemSize3D[j]; + } + else + { + device->registerBase3D[j] = gcvNULL; + } + } + } + else +#endif { - mem_region = request_mem_region( - physical, device->requestedRegisterMemSizes[i], "galcore register region" - ); + physical = device->requestedRegisterMemBases[i]; - if (mem_region == gcvNULL) + /* Set up register memory region. */ + if (physical != 0) { - gcmkTRACE_ZONE( - gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): Failed to claim %lu bytes @ 0x%08X\n", - __FUNCTION__, __LINE__, - physical, device->requestedRegisterMemSizes[i] + mem_region = request_mem_region(physical, + device->requestedRegisterMemSizes[i], + "galcore register region"); + + if (mem_region == gcvNULL) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Failed to claim %lu bytes @ 0x%08X\n", + __FUNCTION__, __LINE__, + physical, device->requestedRegisterMemSizes[i] ); - gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); - } + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } - device->registerBases[i] = (gctPOINTER) ioremap_nocache( - physical, device->requestedRegisterMemSizes[i]); + device->registerBases[i] = (gctPOINTER) ioremap_nocache( + physical, device->requestedRegisterMemSizes[i]); - if (device->registerBases[i] == gcvNULL) - { - gcmkTRACE_ZONE( - gcvLEVEL_ERROR, gcvZONE_DRIVER, - "%s(%d): Unable to map %ld bytes @ 0x%08X\n", - __FUNCTION__, __LINE__, - physical, device->requestedRegisterMemSizes[i] + if (device->registerBases[i] == gcvNULL) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Unable to map %ld bytes @ 0x%08X\n", + __FUNCTION__, __LINE__, + physical, device->requestedRegisterMemSizes[i] ); - gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); - } + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } - physical += device->requestedRegisterMemSizes[i]; - } - else - { - device->registerBases[i] = gcvNULL; + physical += device->requestedRegisterMemSizes[i]; + } } } /* Set the base address */ - device->baseAddress = PhysBaseAddr; + device->baseAddress = device->physBase = PhysBaseAddr; + device->physSize = PhysSize; + device->mmu = Args->mmu; /* Construct the gckOS object. */ gcmkONERROR(gckOS_Construct(device, &device->os)); +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + if (IrqLine3D0 != -1) +#else if (IrqLine != -1) +#endif { /* Construct the gckKERNEL object. */ gcmkONERROR(gckKERNEL_Construct( @@ -544,14 +1190,42 @@ gckGALDEVICE_Construct( device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression )); - gcmkONERROR(gckHARDWARE_SetPowerManagement( - device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement + if(PowerManagement != -1) + { + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_MAJOR]->hardware, gcvFALSE + )); + gcmkONERROR(gckHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement + )); + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_MAJOR]->hardware, gcvTRUE + )); + } + else + { + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_MAJOR]->hardware, gcvFALSE + )); + gcmkONERROR(gckHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_MAJOR]->hardware, gcvTRUE + )); + } + +#if gcdENABLE_FSCALE_VAL_ADJUST + gcmkONERROR(gckHARDWARE_SetMinFscaleValue( + device->kernels[gcvCORE_MAJOR]->hardware, Args->gpu3DMinClock )); +#endif gcmkONERROR(gckHARDWARE_SetGpuProfiler( device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler )); + gcmkVERIFY_OK(gckKERNEL_SetRecovery( + device->kernels[gcvCORE_MAJOR], Args->recovery, Args->stuckDump + )); + #if COMMAND_PROCESSOR_VERSION == 1 /* Start the command queue. */ gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command)); @@ -562,6 +1236,79 @@ gckGALDEVICE_Construct( device->kernels[gcvCORE_MAJOR] = gcvNULL; } +#if gcdMULTI_GPU_AFFINITY + if (IrqLine3D1 != -1) + { + /* Construct the gckKERNEL object. */ + gcmkONERROR(gckKERNEL_Construct( + device->os, gcvCORE_OCL, device, + gcvNULL, &device->kernels[gcvCORE_OCL])); + + if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_OCL]->db; + + /* Initialize core mapping */ + if (device->kernels[gcvCORE_MAJOR] == gcvNULL) + { + for (i = 0; i < 8; i++) + { + device->coreMapping[i] = gcvCORE_OCL; + } + } + else + { + device->coreMapping[gcvHARDWARE_OCL] = gcvCORE_OCL; + } + + /* Setup the ISR manager. */ + gcmkONERROR(gckHARDWARE_SetIsrManager( + device->kernels[gcvCORE_OCL]->hardware, + (gctISRMANAGERFUNC) gckGALDEVICE_Setup_ISR, + (gctISRMANAGERFUNC) gckGALDEVICE_Release_ISR, + device + )); + + gcmkONERROR(gckHARDWARE_SetFastClear( + device->kernels[gcvCORE_OCL]->hardware, FastClear, Compression + )); + +#if gcdENABLE_FSCALE_VAL_ADJUST + gcmkONERROR(gckHARDWARE_SetMinFscaleValue( + device->kernels[gcvCORE_OCL]->hardware, Args->gpu3DMinClock + )); +#endif + if(PowerManagement != -1) + { + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_OCL]->hardware, gcvFALSE + )); + gcmkONERROR(gckHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_OCL]->hardware, PowerManagement + )); + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_OCL]->hardware, gcvTRUE + )); + } + else + { + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_OCL]->hardware, gcvFALSE + )); + gcmkONERROR(gckHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_OCL]->hardware, gcvTRUE + )); + } + +#if COMMAND_PROCESSOR_VERSION == 1 + /* Start the command queue. */ + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_OCL]->command)); +#endif + } + else + { + device->kernels[gcvCORE_OCL] = gcvNULL; + } +#endif + if (IrqLine2D != -1) { gcmkONERROR(gckKERNEL_Construct( @@ -586,7 +1333,11 @@ gckGALDEVICE_Construct( } /* Initialize core mapping */ - if (device->kernels[gcvCORE_MAJOR] == gcvNULL) + if (device->kernels[gcvCORE_MAJOR] == gcvNULL +#if gcdMULTI_GPU_AFFINITY + && device->kernels[gcvCORE_OCL] == gcvNULL +#endif + ) { for (i = 0; i < 8; i++) { @@ -606,10 +1357,37 @@ gckGALDEVICE_Construct( device )); - gcmkONERROR(gckHARDWARE_SetPowerManagement( - device->kernels[gcvCORE_2D]->hardware, PowerManagement + if(PowerManagement != -1) + { + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_2D]->hardware, gcvFALSE + )); + gcmkONERROR(gckHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_2D]->hardware, PowerManagement + )); + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_2D]->hardware, gcvTRUE + )); + } + else + { + gcmkONERROR(gckHARDWARE_SetPowerManagementLock( + device->kernels[gcvCORE_2D]->hardware, gcvFALSE + )); + gcmkONERROR(gckHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_2D]->hardware, gcvTRUE + )); + } + +#if gcdENABLE_FSCALE_VAL_ADJUST + gcmkONERROR(gckHARDWARE_SetMinFscaleValue( + device->kernels[gcvCORE_2D]->hardware, 1 )); +#endif + gcmkVERIFY_OK(gckKERNEL_SetRecovery( + device->kernels[gcvCORE_2D], Args->recovery, Args->stuckDump + )); #if COMMAND_PROCESSOR_VERSION == 1 /* Start the command queue. */ @@ -630,6 +1408,9 @@ gckGALDEVICE_Construct( /* Initialize core mapping */ if (device->kernels[gcvCORE_MAJOR] == gcvNULL && device->kernels[gcvCORE_2D] == gcvNULL +#if gcdMULTI_GPU_AFFINITY + && device->kernels[gcvCORE_OCL] == gcvNULL +#endif ) { for (i = 0; i < 8; i++) @@ -642,11 +1423,21 @@ gckGALDEVICE_Construct( device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG; } + if(PowerManagement != -1) + { + gcmkONERROR(gckVGHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_VG]->vg->hardware, + PowerManagement + )); + } + else + { + gcmkONERROR(gckVGHARDWARE_SetPowerManagement( + device->kernels[gcvCORE_VG]->vg->hardware, + gcvTRUE + )); + } - gcmkONERROR(gckVGHARDWARE_SetPowerManagement( - device->kernels[gcvCORE_VG]->vg->hardware, - PowerManagement - )); #endif } @@ -656,14 +1447,36 @@ gckGALDEVICE_Construct( } /* Initialize the ISR. */ +#if gcdMULTI_GPU + device->irqLine3D[gcvCORE_3D_0_ID] = IrqLine3D0; +#if gcdMULTI_GPU > 1 + device->irqLine3D[gcvCORE_3D_1_ID] = IrqLine3D1; +#endif +#elif gcdMULTI_GPU_AFFINITY + device->irqLines[gcvCORE_MAJOR] = IrqLine3D0; + device->irqLines[gcvCORE_OCL] = IrqLine3D1; +#else device->irqLines[gcvCORE_MAJOR] = IrqLine; - device->irqLines[gcvCORE_2D] = IrqLine2D; - device->irqLines[gcvCORE_VG] = IrqLineVG; +#endif + device->irqLines[gcvCORE_2D] = IrqLine2D; + device->irqLines[gcvCORE_VG] = IrqLineVG; /* Initialize the kernel thread semaphores. */ for (i = 0; i < gcdMAX_GPU_COUNT; i++) { - if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0); +#if gcdMULTI_GPU + if (i == gcvCORE_MAJOR) + { + for (j = 0; j < gcdMULTI_GPU; j++) + { + if (device->irqLine3D[j] != -1) init_waitqueue_head(&device->intrWaitQueue3D[j]); + } + } + else +#endif + { + if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0); + } } device->signal = Signal; @@ -674,9 +1487,9 @@ gckGALDEVICE_Construct( } if (i == gcdMAX_GPU_COUNT) - { - gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); - } + { + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } #if gcdENABLE_VG if (i == gcvCORE_VG) @@ -718,10 +1531,26 @@ gckGALDEVICE_Construct( /* Grab the first availiable kernel */ for (i = 0; i < gcdMAX_GPU_COUNT; i++) { - if (device->irqLines[i] != -1) +#if gcdMULTI_GPU + if (i == gcvCORE_MAJOR) + { + for (j = 0; j < gcdMULTI_GPU; j++) + { + if (device->irqLine3D[j] != -1) + { + kernel = device->kernels[i]; + break; + } + } + } + else +#endif { - kernel = device->kernels[i]; - break; + if (device->irqLines[i] != -1) + { + kernel = device->kernels[i]; + break; + } } } @@ -862,45 +1691,28 @@ 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->contiguousRequested = Args->contiguousRequested; device->contiguousPhysical = gcvNULL; device->contiguousPhysicalName = 0; @@ -911,7 +1723,7 @@ gckGALDEVICE_Construct( } /* Return pointer to the device. */ - * Device = device; + *Device = device; gcmkFOOTER_ARG("*Device=0x%x", * Device); return gcvSTATUS_OK; @@ -947,7 +1759,9 @@ gckGALDEVICE_Destroy( gckGALDEVICE Device) { gctINT i; - gceSTATUS status = gcvSTATUS_OK; +#if gcdMULTI_GPU + gctINT j; +#endif gckKERNEL kernel = gcvNULL; gcmkHEADER_ARG("Device=0x%x", Device); @@ -957,12 +1771,29 @@ gckGALDEVICE_Destroy( /* Grab the first availiable kernel */ for (i = 0; i < gcdMAX_GPU_COUNT; i++) { - if (Device->irqLines[i] != -1) +#if gcdMULTI_GPU + if (i == gcvCORE_MAJOR) { - kernel = Device->kernels[i]; - break; + for (j = 0; j < gcdMULTI_GPU; j++) + { + if (Device->irqLine3D[j] != -1) + { + kernel = Device->kernels[i]; + break; + } + } + } + else +#endif + { + if (Device->irqLines[i] != -1) + { + kernel = Device->kernels[i]; + break; + } } } + if (Device->internalPhysicalName != 0) { gcmRELEASE_NAME(Device->internalPhysicalName); @@ -990,144 +1821,118 @@ gckGALDEVICE_Destroy( } } + if (Device->internalLogical != gcvNULL) { - if (Device->internalLogical != gcvNULL) - { - /* Unmap the internal memory. */ - iounmap(Device->internalLogical); - Device->internalLogical = gcvNULL; - } + /* Unmap the internal memory. */ + iounmap(Device->internalLogical); + Device->internalLogical = gcvNULL; + } - if (Device->internalVidMem != gcvNULL) - { - /* Destroy the internal heap. */ - gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem)); - Device->internalVidMem = gcvNULL; - } + if (Device->internalVidMem != gcvNULL) + { + /* Destroy the internal heap. */ + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem)); + Device->internalVidMem = gcvNULL; } + if (Device->externalLogical != gcvNULL) { - if (Device->externalLogical != gcvNULL) - { - /* Unmap the external memory. */ - iounmap(Device->externalLogical); - Device->externalLogical = gcvNULL; - } + /* Unmap the external memory. */ + iounmap(Device->externalLogical); + Device->externalLogical = gcvNULL; + } - if (Device->externalVidMem != gcvNULL) + if (Device->externalVidMem != gcvNULL) + { + /* destroy the external heap */ + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem)); + Device->externalVidMem = gcvNULL; + } + + if (Device->contiguousBase != gcvNULL) + { + if (Device->contiguousMapped == gcvFALSE) { - /* destroy the external heap */ - gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem)); - Device->externalVidMem = gcvNULL; + gcmkVERIFY_OK(_FreeMemory( + Device, + Device->contiguousBase, + Device->contiguousPhysical + )); } + + Device->contiguousBase = gcvNULL; + Device->contiguousPhysical = gcvNULL; } + if (Device->requestedContiguousBase != 0 + && Device->contiguousRequested == gcvFALSE + ) { - 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 - { - gcmkONERROR(_FreeMemory( - Device, - Device->contiguousBase, - Device->contiguousPhysical - )); - } + release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize); + Device->requestedContiguousBase = 0; + Device->requestedContiguousSize = 0; + } - Device->contiguousBase = gcvNULL; - Device->contiguousPhysical = gcvNULL; - } + if (Device->contiguousVidMem != gcvNULL) + { + /* Destroy the contiguous heap. */ + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem)); + Device->contiguousVidMem = gcvNULL; + } - if (Device->requestedContiguousBase != 0) - { - release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize); - Device->requestedContiguousBase = 0; - Device->requestedContiguousSize = 0; - } + if (Device->dbgNode) + { + gckDEBUGFS_FreeNode(Device->dbgNode); - if (Device->contiguousVidMem != gcvNULL) + if(Device->dbgNode != gcvNULL) { - /* Destroy the contiguous heap. */ - gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem)); - Device->contiguousVidMem = gcvNULL; + kfree(Device->dbgNode); + Device->dbgNode = gcvNULL; } } - { - if(gckDebugFileSystemIsEnabled()) - { - gckDebugFileSystemFreeNode(Device->dbgnode); - kfree(Device->dbgnode); - Device->dbgnode = gcvNULL; - } - } - for (i = 0; i < gcdMAX_GPU_COUNT; i++) { - if (Device->registerBases[i] != gcvNULL) +#if gcdMULTI_GPU + if (i == gcvCORE_MAJOR) { - /* Unmap register memory. */ - iounmap(Device->registerBases[i]); - if (Device->requestedRegisterMemBases[i] != 0) - { - release_mem_region(Device->requestedRegisterMemBases[i], Device->requestedRegisterMemSizes[i]); - } - - Device->registerBases[i] = gcvNULL; - Device->requestedRegisterMemBases[i] = 0; - Device->requestedRegisterMemSizes[i] = 0; + for (j = 0; j < gcdMULTI_GPU; j++) + { + if (Device->registerBase3D[j] != gcvNULL) + { + /* Unmap register memory. */ + iounmap(Device->registerBase3D[j]); + if (Device->requestedRegisterMemBase3D[j] != 0) + { + release_mem_region(Device->requestedRegisterMemBase3D[j], + Device->requestedRegisterMemSize3D[j]); + } + + Device->registerBase3D[j] = gcvNULL; + Device->requestedRegisterMemBase3D[j] = 0; + Device->requestedRegisterMemSize3D[j] = 0; + } + } } - } - - /*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); + else #endif + { + if (Device->registerBases[i] != gcvNULL) + { + /* Unmap register memory. */ + iounmap(Device->registerBases[i]); + if (Device->requestedRegisterMemBases[i] != 0) + { + release_mem_region(Device->requestedRegisterMemBases[i], + Device->requestedRegisterMemSizes[i]); + } -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) - if (Device->gpu_regulator) { - regulator_put(Device->gpu_regulator); - Device->gpu_regulator = NULL; + Device->registerBases[i] = gcvNULL; + Device->requestedRegisterMemBases[i] = 0; + Device->requestedRegisterMemSizes[i] = 0; + } + } } -#endif /* Destroy the gckOS object. */ if (Device->os != gcvNULL) @@ -1136,16 +1941,14 @@ gckGALDEVICE_Destroy( Device->os = gcvNULL; } + _DebugfsCleanup(Device); + /* Free the device. */ kfree(Device); } gcmkFOOTER_NO(); return gcvSTATUS_OK; - -OnError: - gcmkFOOTER(); - return status; } /******************************************************************************* @@ -1176,7 +1979,7 @@ gckGALDEVICE_Setup_ISR( ) { gceSTATUS status; - gctINT ret; + gctINT ret = 0; gcmkHEADER_ARG("Device=0x%x", Device); @@ -1198,12 +2001,94 @@ gckGALDEVICE_Setup_ISR( ret = dove_gpio_request( DOVE_GPIO0_7, &gc500_handle ); +#else +#if gcdMULTI_GPU + ret = request_irq( + Device->irqLine3D[gcvCORE_3D_0_ID], isrRoutine3D0, IRQF_DISABLED, + "galcore_3d_0", Device + ); + + if (ret != 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not register irq line %d (error=%d)\n", + __FUNCTION__, __LINE__, + Device->irqLine3D[gcvCORE_3D_0_ID], ret + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + /* Mark ISR as initialized. */ + Device->isrInitialized3D[gcvCORE_3D_0_ID] = gcvTRUE; + +#if gcdMULTI_GPU > 1 + ret = request_irq( + Device->irqLine3D[gcvCORE_3D_1_ID], isrRoutine3D1, IRQF_DISABLED, + "galcore_3d_1", Device + ); + + if (ret != 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not register irq line %d (error=%d)\n", + __FUNCTION__, __LINE__, + Device->irqLine3D[gcvCORE_3D_1_ID], ret + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + /* Mark ISR as initialized. */ + Device->isrInitialized3D[gcvCORE_3D_1_ID] = gcvTRUE; +#endif +#elif gcdMULTI_GPU_AFFINITY + ret = request_irq( + Device->irqLines[gcvCORE_MAJOR], isrRoutine3D0, IRQF_DISABLED, + "galcore_3d_0", Device + ); + + if (ret != 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not register irq line %d (error=%d)\n", + __FUNCTION__, __LINE__, + Device->irqLines[gcvCORE_MAJOR], ret + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + /* Mark ISR as initialized. */ + Device->isrInitializeds[gcvCORE_MAJOR] = gcvTRUE; + + ret = request_irq( + Device->irqLines[gcvCORE_OCL], isrRoutine3D1, IRQF_DISABLED, + "galcore_3d_1", Device + ); + + if (ret != 0) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not register irq line %d (error=%d)\n", + __FUNCTION__, __LINE__, + Device->irqLines[gcvCORE_OCL], ret + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + /* Mark ISR as initialized. */ + Device->isrInitializeds[gcvCORE_OCL] = gcvTRUE; #else ret = request_irq( Device->irqLines[gcvCORE_MAJOR], isrRoutine, IRQF_DISABLED, "galcore interrupt service", Device ); -#endif if (ret != 0) { @@ -1219,6 +2104,8 @@ gckGALDEVICE_Setup_ISR( /* Mark ISR as initialized. */ Device->isrInitializeds[gcvCORE_MAJOR] = gcvTRUE; +#endif +#endif gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -1372,6 +2259,22 @@ gckGALDEVICE_Release_ISR( gcmkVERIFY_ARGUMENT(Device != NULL); +#if gcdMULTI_GPU + /* release the irq */ + if (Device->isrInitialized3D[gcvCORE_3D_0_ID]) + { + free_irq(Device->irqLine3D[gcvCORE_3D_0_ID], Device); + Device->isrInitialized3D[gcvCORE_3D_0_ID] = gcvFALSE; + } +#if gcdMULTI_GPU > 1 + /* release the irq */ + if (Device->isrInitialized3D[gcvCORE_3D_1_ID]) + { + free_irq(Device->irqLine3D[gcvCORE_3D_1_ID], Device); + Device->isrInitialized3D[gcvCORE_3D_1_ID] = gcvFALSE; + } +#endif +#else /* release the irq */ if (Device->isrInitializeds[gcvCORE_MAJOR]) { @@ -1380,9 +2283,9 @@ gckGALDEVICE_Release_ISR( #else free_irq(Device->irqLines[gcvCORE_MAJOR], Device); #endif - - Device->isrInitializeds[gcvCORE_MAJOR] = gcvFALSE; + Device->isrInitializeds[gcvCORE_MAJOR] = gcvFALSE; } +#endif gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -1406,7 +2309,7 @@ gckGALDEVICE_Release_ISR_2D( free_irq(Device->irqLines[gcvCORE_2D], Device); #endif - Device->isrInitializeds[gcvCORE_2D] = gcvFALSE; + Device->isrInitializeds[gcvCORE_2D] = gcvFALSE; } gcmkFOOTER_NO(); @@ -1431,7 +2334,7 @@ gckGALDEVICE_Release_ISR_VG( free_irq(Device->irqLines[gcvCORE_VG], Device); #endif - Device->isrInitializeds[gcvCORE_VG] = gcvFALSE; + Device->isrInitializeds[gcvCORE_VG] = gcvFALSE; } gcmkFOOTER_NO(); @@ -1472,6 +2375,86 @@ gckGALDEVICE_Start_Threads( gcmkVERIFY_ARGUMENT(Device != NULL); +#if gcdMULTI_GPU + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL) + { + /* Start the kernel thread. */ + task = kthread_run(threadRoutine3D0, Device, "galcore_3d_0"); + + if (IS_ERR(task)) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not start the kernel thread.\n", + __FUNCTION__, __LINE__ + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + Device->threadCtxt3D[gcvCORE_3D_0_ID] = task; + Device->threadInitialized3D[gcvCORE_3D_0_ID] = gcvTRUE; + +#if gcdMULTI_GPU > 1 + /* Start the kernel thread. */ + task = kthread_run(threadRoutine3D1, Device, "galcore_3d_1"); + + if (IS_ERR(task)) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not start the kernel thread.\n", + __FUNCTION__, __LINE__ + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + Device->threadCtxt3D[gcvCORE_3D_1_ID] = task; + Device->threadInitialized3D[gcvCORE_3D_1_ID] = gcvTRUE; +#endif + } +#elif gcdMULTI_GPU_AFFINITY + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL) + { + /* Start the kernel thread. */ + task = kthread_run(threadRoutine3D0, Device, "galcore_3d_0"); + + if (IS_ERR(task)) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not start the kernel thread.\n", + __FUNCTION__, __LINE__ + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + Device->threadCtxts[gcvCORE_MAJOR] = task; + Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE; + } + + if (Device->kernels[gcvCORE_OCL] != gcvNULL) + { + /* Start the kernel thread. */ + task = kthread_run(threadRoutine3D1, Device, "galcore_3d_1"); + + if (IS_ERR(task)) + { + gcmkTRACE_ZONE( + gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Could not start the kernel thread.\n", + __FUNCTION__, __LINE__ + ); + + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + Device->threadCtxts[gcvCORE_OCL] = task; + Device->threadInitializeds[gcvCORE_OCL] = gcvTRUE; + } +#else if (Device->kernels[gcvCORE_MAJOR] != gcvNULL) { /* Start the kernel thread. */ @@ -1491,6 +2474,7 @@ gckGALDEVICE_Start_Threads( Device->threadCtxts[gcvCORE_MAJOR] = task; Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE; } +#endif if (Device->kernels[gcvCORE_2D] != gcvNULL) { @@ -1574,6 +2558,9 @@ gckGALDEVICE_Stop_Threads( ) { gctINT i; +#if gcdMULTI_GPU + gctINT j; +#endif gcmkHEADER_ARG("Device=0x%x", Device); @@ -1581,15 +2568,37 @@ gckGALDEVICE_Stop_Threads( for (i = 0; i < gcdMAX_GPU_COUNT; i++) { - /* Stop the kernel threads. */ - if (Device->threadInitializeds[i]) +#if gcdMULTI_GPU + if (i == gcvCORE_MAJOR) + { + for (j = 0; j < gcdMULTI_GPU; j++) + { + /* Stop the kernel threads. */ + if (Device->threadInitialized3D[j]) + { + Device->killThread = gcvTRUE; + Device->dataReady3D[j] = gcvTRUE; + wake_up_interruptible(&Device->intrWaitQueue3D[j]); + + kthread_stop(Device->threadCtxt3D[j]); + Device->threadCtxt3D[j] = gcvNULL; + Device->threadInitialized3D[j] = gcvFALSE; + } + } + } + else +#endif { - Device->killThread = gcvTRUE; - up(&Device->semas[i]); + /* Stop the kernel threads. */ + if (Device->threadInitializeds[i]) + { + Device->killThread = gcvTRUE; + up(&Device->semas[i]); - kthread_stop(Device->threadCtxts[i]); - Device->threadCtxts[i] = gcvNULL; - Device->threadInitializeds[i] = gcvFALSE; + kthread_stop(Device->threadCtxts[i]); + Device->threadCtxts[i] = gcvNULL; + Device->threadInitializeds[i] = gcvFALSE; + } } } @@ -1657,10 +2666,12 @@ gckGALDEVICE_Start( /* Setup the ISR routine. */ gcmkONERROR(gckGALDEVICE_Setup_ISR_VG(Device)); +#if gcdENABLE_VG /* Switch to SUSPEND power state. */ gcmkONERROR(gckVGHARDWARE_SetPowerManagementState( Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST )); +#endif } gcmkFOOTER_NO(); 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 c51432f47c17..089001584977 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -22,25 +22,20 @@ #ifndef __gc_hal_kernel_device_h_ #define __gc_hal_kernel_device_h_ +#include "gc_hal_kernel_debugfs.h" + /******************************************************************************\ ******************************* 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; @@ -59,22 +54,43 @@ typedef struct _gckGALDEVICE gctSIZE_T contiguousSize; gctBOOL contiguousMapped; gctPOINTER contiguousMappedUser; + gctBOOL contiguousRequested; gctSIZE_T systemMemorySize; gctUINT32 systemMemoryBaseAddress; +#if gcdMULTI_GPU + gctPOINTER registerBase3D[gcdMULTI_GPU]; + gctSIZE_T registerSize3D[gcdMULTI_GPU]; +#endif gctPOINTER registerBases[gcdMAX_GPU_COUNT]; gctSIZE_T registerSizes[gcdMAX_GPU_COUNT]; gctUINT32 baseAddress; + gctUINT32 physBase; + gctUINT32 physSize; + gctBOOL mmu; +#if gcdMULTI_GPU + gctUINT32 requestedRegisterMemBase3D[gcdMULTI_GPU]; + gctSIZE_T requestedRegisterMemSize3D[gcdMULTI_GPU]; +#endif gctUINT32 requestedRegisterMemBases[gcdMAX_GPU_COUNT]; gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT]; gctUINT32 requestedContiguousBase; gctSIZE_T requestedContiguousSize; /* IRQ management. */ +#if gcdMULTI_GPU + gctINT irqLine3D[gcdMULTI_GPU]; + gctBOOL isrInitialized3D[gcdMULTI_GPU]; + gctBOOL dataReady3D[gcdMULTI_GPU]; +#endif gctINT irqLines[gcdMAX_GPU_COUNT]; gctBOOL isrInitializeds[gcdMAX_GPU_COUNT]; - gctBOOL dataReadys[gcdMAX_GPU_COUNT]; /* Thread management. */ +#if gcdMULTI_GPU + struct task_struct *threadCtxt3D[gcdMULTI_GPU]; + wait_queue_head_t intrWaitQueue3D[gcdMULTI_GPU]; + gctBOOL threadInitialized3D[gcdMULTI_GPU]; +#endif struct task_struct *threadCtxts[gcdMAX_GPU_COUNT]; struct semaphore semas[gcdMAX_GPU_COUNT]; gctBOOL threadInitializeds[gcdMAX_GPU_COUNT]; @@ -89,27 +105,10 @@ typedef struct _gckGALDEVICE /* States before suspend. */ gceCHIPPOWERSTATE statesStored[gcdMAX_GPU_COUNT]; - /*Device Debug File System Entry in Kernel*/ - struct _gcsDebugFileSystemNode * dbgnode; + /* 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 + gcsDEBUGFS_DIR debugfsDir; } * gckGALDEVICE; @@ -123,6 +122,18 @@ typedef struct _gcsHAL_PRIVATE_DATA } gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR; +typedef struct _gcsDEVICE_CONSTRUCT_ARGS +{ + gctBOOL recovery; + gctUINT stuckDump; + gctUINT gpu3DMinClock; + + gctBOOL contiguousRequested; + gcsPLATFORM* platform; + gctBOOL mmu; +} +gcsDEVICE_CONSTRUCT_ARGS; + gceSTATUS gckGALDEVICE_Setup_ISR( IN gckGALDEVICE Device ); @@ -164,9 +175,18 @@ gceSTATUS gckGALDEVICE_Stop( ); gceSTATUS gckGALDEVICE_Construct( +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + IN gctINT IrqLine3D0, + IN gctUINT32 RegisterMemBase3D0, + IN gctSIZE_T RegisterMemSize3D0, + IN gctINT IrqLine3D1, + IN gctUINT32 RegisterMemBase3D1, + IN gctSIZE_T RegisterMemSize3D1, +#else IN gctINT IrqLine, IN gctUINT32 RegisterMemBase, IN gctSIZE_T RegisterMemSize, +#endif IN gctINT IrqLine2D, IN gctUINT32 RegisterMemBase2D, IN gctSIZE_T RegisterMemSize2D, @@ -182,9 +202,9 @@ 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, OUT gckGALDEVICE *Device ); diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c new file mode 100644 index 000000000000..43202f6ff1d2 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c @@ -0,0 +1,216 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2014 by Vivante Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the license, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****************************************************************************/ + + +#include "gc_hal_kernel_linux.h" +#include "gc_hal_kernel_device.h" + +#include +#include + +#define _GC_OBJ_ZONE gcvZONE_OS + +typedef struct _gcsIOMMU +{ + struct iommu_domain * domain; + struct device * device; +} +gcsIOMMU; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +static int +_IOMMU_Fault_Handler( + struct iommu_domain * Domain, + struct device * Dev, + unsigned long DomainAddress, + int flags, + void * args + ) +#else +static int +_IOMMU_Fault_Handler( + struct iommu_domain * Domain, + struct device * Dev, + unsigned long DomainAddress, + int flags + ) +#endif +{ + return 0; +} + +static int +_FlatMapping( + IN gckIOMMU Iommu + ) +{ + gceSTATUS status; + gctUINT32 physical; + + for (physical = 0; physical < 0x80000000; physical += PAGE_SIZE) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "Map %x => %x bytes = %d", + physical, physical, PAGE_SIZE + ); + + gcmkONERROR(gckIOMMU_Map(Iommu, physical, physical, PAGE_SIZE)); + } + + return gcvSTATUS_OK; + +OnError: + return status; +} + +void +gckIOMMU_Destory( + IN gckOS Os, + IN gckIOMMU Iommu + ) +{ + gcmkHEADER(); + + if (Iommu->domain && Iommu->device) + { + iommu_attach_device(Iommu->domain, Iommu->device); + } + + if (Iommu->domain) + { + iommu_domain_free(Iommu->domain); + } + + if (Iommu) + { + gcmkOS_SAFE_FREE(Os, Iommu); + } + + gcmkFOOTER_NO(); +} + +gceSTATUS +gckIOMMU_Construct( + IN gckOS Os, + OUT gckIOMMU * Iommu + ) +{ + gceSTATUS status; + gckIOMMU iommu = gcvNULL; + struct device *dev; + int ret; + + gcmkHEADER(); + + dev = &Os->device->platform->device->dev; + + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsIOMMU), (gctPOINTER *)&iommu)); + + gckOS_ZeroMemory(iommu, gcmSIZEOF(gcsIOMMU)); + + iommu->domain = iommu_domain_alloc(&platform_bus_type); + + if (!iommu->domain) + { + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_domain_alloc() fail"); + + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) + iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler, dev); +#else + iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler); +#endif + + ret = iommu_attach_device(iommu->domain, dev); + + if (ret) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail %d", ret); + + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + + iommu->device = dev; + + _FlatMapping(iommu); + + *Iommu = iommu; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + + gckIOMMU_Destory(Os, iommu); + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckIOMMU_Map( + IN gckIOMMU Iommu, + IN gctUINT32 DomainAddress, + IN gctUINT32 Physical, + IN gctUINT32 Bytes + ) +{ + gceSTATUS status; + int ret; + + gcmkHEADER_ARG("DomainAddress=%#X, Physical=%#X, Bytes=%d", + DomainAddress, Physical, Bytes); + + ret = iommu_map(Iommu->domain, DomainAddress, Physical, Bytes, 0); + + if (ret) + { + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + + gcmkFOOTER(); + return status; + +} + +gceSTATUS +gckIOMMU_Unmap( + IN gckIOMMU Iommu, + IN gctUINT32 DomainAddress, + IN gctUINT32 Bytes + ) +{ + gcmkHEADER(); + + iommu_unmap(Iommu->domain, DomainAddress, Bytes); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c index de82c12f8617..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -256,13 +256,15 @@ gckKERNEL_MapVideoMemoryEx( OUT gctPOINTER * Logical ) { - gckGALDEVICE device; - PLINUX_MDL mdl; - PLINUX_MDL_MAP mdlMap; - gcePOOL pool; - gctUINT32 offset, base; + gckGALDEVICE device = gcvNULL; + PLINUX_MDL mdl = gcvNULL; + PLINUX_MDL_MAP mdlMap = gcvNULL; + gcePOOL pool = gcvPOOL_UNKNOWN; + gctUINT32 offset = 0; + gctUINT32 base = 0; gceSTATUS status; - gctPOINTER logical; + gctPOINTER logical = gcvNULL; + gctUINT32 baseAddress; gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x", Kernel, InUserSpace, Address); @@ -332,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)); } @@ -421,6 +430,9 @@ gckKERNEL_MapVideoMemory( gceSTATUS gckKERNEL_Notify( IN gckKERNEL Kernel, +#if gcdMULTI_GPU + IN gctUINT CoreId, +#endif IN gceNOTIFY Notification, IN gctBOOL Data ) @@ -441,7 +453,11 @@ gckKERNEL_Notify( #if COMMAND_PROCESSOR_VERSION > 1 status = gckINTERRUPT_Notify(Kernel->interrupt, Data); #else - status = gckHARDWARE_Interrupt(Kernel->hardware, Data); + status = gckHARDWARE_Interrupt(Kernel->hardware, +#if gcdMULTI_GPU + CoreId, +#endif + Data); #endif break; 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 3c148f6e3323..02847e90fad6 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -37,6 +37,8 @@ #include #include +#include + #ifdef MODVERSIONS # include #endif @@ -45,17 +47,18 @@ #if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) #include -#include #endif #define NTSTRSAFE_NO_CCH_FUNCTIONS #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) @@ -64,14 +67,20 @@ #define FIND_TASK_BY_PID(x) find_task_by_pid(x) #endif -#define _WIDE(string) L##string -#define WIDE(string) _WIDE(string) +#define _WIDE(string) L##string +#define WIDE(string) _WIDE(string) -#define countof(a) (sizeof(a) / sizeof(a[0])) +#define countof(a) (sizeof(a) / sizeof(a[0])) -#define DRV_NAME "galcore" +#ifndef DEVICE_NAME +#ifdef CONFIG_DOVE_GPU +# define DEVICE_NAME "dove_gpu" +#else +# define DEVICE_NAME "galcore" +#endif +#endif -#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) +#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) #if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0) #define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP) @@ -79,16 +88,312 @@ #define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED) #endif +/* Protection bit when mapping memroy to user sapce */ +#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x) + +#if gcdNONPAGED_MEMORY_BUFFERABLE +#define gcmkIOREMAP ioremap_wc +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x) +#elif !gcdNONPAGED_MEMORY_CACHEABLE +#define gcmkIOREMAP ioremap_nocache +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x) +#endif + +#define gcdSUPPRESS_OOM_MESSAGE 1 + +#if gcdSUPPRESS_OOM_MESSAGE +#define gcdNOWARN __GFP_NOWARN +#else +#define gcdNOWARN 0 +#endif + +/******************************************************************************\ +********************************** Structures ********************************** +\******************************************************************************/ +typedef struct _gcsIOMMU * gckIOMMU; + +typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR; +typedef struct _gcsUSER_MAPPING +{ + /* Pointer to next mapping structure. */ + gcsUSER_MAPPING_PTR next; + + /* Physical address of this mapping. */ + gctUINT32 physical; + + /* Logical address of this mapping. */ + gctPOINTER logical; + + /* Number of bytes of this mapping. */ + gctSIZE_T bytes; + + /* Starting address of this mapping. */ + gctINT8_PTR start; + + /* Ending address of this mapping. */ + gctINT8_PTR end; +} +gcsUSER_MAPPING; + +typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR; +typedef struct _gcsINTEGER_DB +{ + struct idr idr; + spinlock_t lock; + gctINT curr; +} +gcsINTEGER_DB; + +struct _gckOS +{ + /* Object. */ + gcsOBJECT object; + + /* Pointer to device */ + gckGALDEVICE device; + + /* Memory management */ + gctPOINTER memoryLock; + gctPOINTER memoryMapLock; + + struct _LINUX_MDL *mdlHead; + struct _LINUX_MDL *mdlTail; + + /* Kernel process ID. */ + gctUINT32 kernelProcessID; + + /* Signal management. */ + + /* Lock. */ + gctPOINTER signalMutex; + + /* signal id database. */ + gcsINTEGER_DB signalDB; + +#if gcdANDROID_NATIVE_FENCE_SYNC + /* Lock. */ + gctPOINTER syncPointMutex; + + /* sync point id database. */ + gcsINTEGER_DB syncPointDB; +#endif + + gcsUSER_MAPPING_PTR userMap; + gctPOINTER debugLock; + + /* workqueue for os timer. */ + struct workqueue_struct * workqueue; + + /* Allocate extra page to avoid cache overflow */ + struct page* paddingPage; + + /* Detect unfreed allocation. */ + atomic_t allocateCount; + + struct list_head allocatorList; + + gcsDEBUGFS_DIR allocatorDebugfsDir; + + /* 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]; + + /* IOMMU. */ + gckIOMMU iommu; +}; + +typedef struct _gcsSIGNAL * gcsSIGNAL_PTR; +typedef struct _gcsSIGNAL +{ + /* Kernel sync primitive. */ + struct completion obj; + + /* Manual reset flag. */ + gctBOOL manualReset; + + /* The reference counter. */ + atomic_t ref; + + /* The owner of the signal. */ + gctHANDLE process; + + gckHARDWARE hardware; + + /* ID. */ + gctUINT32 id; +} +gcsSIGNAL; + +#if gcdANDROID_NATIVE_FENCE_SYNC +typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR; +typedef struct _gcsSYNC_POINT +{ + /* The reference counter. */ + atomic_t ref; + + /* State. */ + atomic_t state; + + /* timeline. */ + struct sync_timeline * timeline; + + /* ID. */ + gctUINT32 id; +} +gcsSYNC_POINT; +#endif + +typedef struct _gcsPageInfo * gcsPageInfo_PTR; +typedef struct _gcsPageInfo +{ + struct page **pages; + gctUINT32_PTR pageTable; + gctUINT32 extraPage; + gctUINT32 address; +#if gcdPROCESS_ADDRESS_SPACE + gckMMU mmu; +#endif +} +gcsPageInfo; + +typedef struct _gcsOSTIMER * gcsOSTIMER_PTR; +typedef struct _gcsOSTIMER +{ + struct delayed_work work; + gctTIMERFUNCTION function; + gctPOINTER data; +} gcsOSTIMER; + +gceSTATUS +gckOS_ImportAllocators( + gckOS Os + ); + +gceSTATUS +gckOS_FreeAllocators( + gckOS Os + ); + +gceSTATUS +_HandleOuterCache( + IN gckOS Os, + IN gctUINT32 Physical, + IN gctPOINTER Logical, + IN gctSIZE_T Bytes, + IN gceCACHEOPERATION Type + ); + +gceSTATUS +_ConvertLogical2Physical( + IN gckOS Os, + IN gctPOINTER Logical, + IN gctUINT32 ProcessID, + IN PLINUX_MDL Mdl, + OUT gctUINT32_PTR Physical + ); + +gctSTRING +_CreateKernelVirtualMapping( + IN PLINUX_MDL Mdl + ); + +void +_DestoryKernelVirtualMapping( + IN gctSTRING Addr + ); + +void +_UnmapUserLogical( + IN gctPOINTER Logical, + IN gctUINT32 Size + ); + static inline gctINT -GetOrder( - IN gctINT numPages - ) +_GetProcessID( + void + ) { - gctINT order = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) + return task_tgid_vnr(current); +#else + return current->tgid; +#endif +} - while ((1 << order) < numPages) order++; +static inline struct page * +_NonContiguousToPage( + IN struct page ** Pages, + IN gctUINT32 Index + ) +{ + gcmkASSERT(Pages != gcvNULL); + return Pages[Index]; +} - return order; +static inline unsigned long +_NonContiguousToPfn( + IN struct page ** Pages, + IN gctUINT32 Index + ) +{ + gcmkASSERT(Pages != gcvNULL); + return page_to_pfn(_NonContiguousToPage(Pages, Index)); } +static inline unsigned long +_NonContiguousToPhys( + IN struct page ** Pages, + IN gctUINT32 Index + ) +{ + gcmkASSERT(Pages != gcvNULL); + return page_to_phys(_NonContiguousToPage(Pages, Index)); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +static inline int +is_vmalloc_addr( + void *Addr + ) +{ + unsigned long addr = (unsigned long)Addr; + + return addr >= VMALLOC_START && addr < VMALLOC_END; +} +#endif + +#ifdef CONFIG_IOMMU_SUPPORT +void +gckIOMMU_Destory( + IN gckOS Os, + IN gckIOMMU Iommu + ); + +gceSTATUS +gckIOMMU_Construct( + IN gckOS Os, + OUT gckIOMMU * Iommu + ); + +gceSTATUS +gckIOMMU_Map( + IN gckIOMMU Iommu, + IN gctUINT32 DomainAddress, + IN gctUINT32 Physical, + IN gctUINT32 Bytes + ); + +gceSTATUS +gckIOMMU_Unmap( + IN gckIOMMU Iommu, + IN gctUINT32 DomainAddress, + IN gctUINT32 Bytes + ); +#endif + #endif /* __gc_hal_kernel_linux_h_ */ diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c index 992aeff43b8c..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 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 9a55c90015cf..2dbd73d0abe4 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -23,50 +23,29 @@ #include #include -#include #include -#include #include #include #include -#include -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) -#include -#endif #include -#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 LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +#include +#endif #if gcdANDROID_NATIVE_FENCE_SYNC #include #include "gc_hal_kernel_sync.h" #endif - #define _GC_OBJ_ZONE gcvZONE_OS -/******************************************************************************* -***** Version Signature *******************************************************/ - -#ifdef ANDROID -const char * _PLATFORM = "\n\0$PLATFORM$Android$\n"; -#else -const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n"; -#endif - -#define USER_SIGNAL_TABLE_LEN_INIT 64 -#define gcdSUPPRESS_OOM_MESSAGE 1 +#include "gc_hal_kernel_allocator.h" #define MEMORY_LOCK(os) \ gcmkVERIFY_OK(gckOS_AcquireMutex( \ @@ -86,206 +65,10 @@ const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n"; #define MEMORY_MAP_UNLOCK(os) \ gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock)) -/* Protection bit when mapping memroy to user sapce */ -#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x) - -#if gcdNONPAGED_MEMORY_BUFFERABLE -#define gcmkIOREMAP ioremap_wc -#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x) -#elif !gcdNONPAGED_MEMORY_CACHEABLE -#define gcmkIOREMAP ioremap_nocache -#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x) -#endif - -#if gcdSUPPRESS_OOM_MESSAGE -#define gcdNOWARN __GFP_NOWARN -#else -#define gcdNOWARN 0 -#endif - -#define gcdINFINITE_TIMEOUT (60 * 1000) -#define gcdDETECT_TIMEOUT 0 -#define gcdDETECT_DMA_ADDRESS 1 -#define gcdDETECT_DMA_STATE 1 - -#define gcdUSE_NON_PAGED_MEMORY_CACHE 10 - -/******************************************************************************\ -********************************** Structures ********************************** -\******************************************************************************/ -#if gcdUSE_NON_PAGED_MEMORY_CACHE -typedef struct _gcsNonPagedMemoryCache -{ -#ifndef NO_DMA_COHERENT - gctINT size; - gctSTRING addr; - dma_addr_t dmaHandle; -#else - long order; - struct page * page; -#endif - - struct _gcsNonPagedMemoryCache * prev; - struct _gcsNonPagedMemoryCache * next; -} -gcsNonPagedMemoryCache; -#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */ - -typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR; -typedef struct _gcsUSER_MAPPING -{ - /* Pointer to next mapping structure. */ - gcsUSER_MAPPING_PTR next; - - /* Physical address of this mapping. */ - gctUINT32 physical; - - /* Logical address of this mapping. */ - gctPOINTER logical; - - /* Number of bytes of this mapping. */ - gctSIZE_T bytes; - - /* Starting address of this mapping. */ - gctINT8_PTR start; - - /* Ending address of this mapping. */ - gctINT8_PTR end; -} -gcsUSER_MAPPING; - -typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR; -typedef struct _gcsINTEGER_DB -{ - struct idr idr; - spinlock_t lock; - gctINT curr; -} -gcsINTEGER_DB; - -struct _gckOS -{ - /* Object. */ - gcsOBJECT object; - - /* Heap. */ - gckHEAP heap; - - /* Pointer to device */ - gckGALDEVICE device; - - /* Memory management */ - gctPOINTER memoryLock; - gctPOINTER memoryMapLock; - - struct _LINUX_MDL *mdlHead; - struct _LINUX_MDL *mdlTail; - - /* Kernel process ID. */ - gctUINT32 kernelProcessID; - - /* Signal management. */ - - /* Lock. */ - gctPOINTER signalMutex; - - /* signal id database. */ - gcsINTEGER_DB signalDB; - -#if gcdANDROID_NATIVE_FENCE_SYNC - /* Lock. */ - gctPOINTER syncPointMutex; - - /* sync point id database. */ - gcsINTEGER_DB syncPointDB; -#endif - - gcsUSER_MAPPING_PTR userMap; - gctPOINTER debugLock; - -#if gcdUSE_NON_PAGED_MEMORY_CACHE - gctUINT cacheSize; - gcsNonPagedMemoryCache * cacheHead; - gcsNonPagedMemoryCache * cacheTail; -#endif - - /* workqueue for os timer. */ - struct workqueue_struct * workqueue; -}; - -typedef struct _gcsSIGNAL * gcsSIGNAL_PTR; -typedef struct _gcsSIGNAL -{ - /* Kernel sync primitive. */ - struct completion obj; - - /* Manual reset flag. */ - gctBOOL manualReset; - - /* The reference counter. */ - atomic_t ref; - - /* The owner of the signal. */ - gctHANDLE process; - - gckHARDWARE hardware; - - /* ID. */ - gctUINT32 id; -} -gcsSIGNAL; - -#if gcdANDROID_NATIVE_FENCE_SYNC -typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR; -typedef struct _gcsSYNC_POINT -{ - /* The reference counter. */ - atomic_t ref; - - /* State. */ - atomic_t state; - - /* timeline. */ - struct sync_timeline * timeline; - - /* ID. */ - gctUINT32 id; -} -gcsSYNC_POINT; -#endif - -typedef struct _gcsPageInfo * gcsPageInfo_PTR; -typedef struct _gcsPageInfo -{ - struct page **pages; - gctUINT32_PTR pageTable; -} -gcsPageInfo; - -typedef struct _gcsOSTIMER * gcsOSTIMER_PTR; -typedef struct _gcsOSTIMER -{ - struct delayed_work work; - gctTIMERFUNCTION function; - gctPOINTER data; -} gcsOSTIMER; /******************************************************************************\ ******************************* Private Functions ****************************** \******************************************************************************/ - -static gctINT -_GetProcessID( - void - ) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) - return task_tgid_vnr(current); -#else - return current->tgid; -#endif -} - static gctINT _GetThreadID( void @@ -300,24 +83,14 @@ _GetThreadID( static PLINUX_MDL _CreateMdl( - IN gctINT ProcessID + void ) { PLINUX_MDL mdl; - gcmkHEADER_ARG("ProcessID=%d", ProcessID); + gcmkHEADER(); mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN); - if (mdl == gcvNULL) - { - gcmkFOOTER_NO(); - return gcvNULL; - } - - mdl->pid = ProcessID; - mdl->maps = gcvNULL; - mdl->prev = gcvNULL; - mdl->next = gcvNULL; gcmkFOOTER_ARG("0x%X", mdl); return mdl; @@ -456,346 +229,6 @@ FindMdlMap( return gcvNULL; } -void -OnProcessExit( - IN gckOS Os, - IN gckKERNEL Kernel - ) -{ -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -static inline int -is_vmalloc_addr( - void *Addr - ) -{ - unsigned long addr = (unsigned long)Addr; - - return addr >= VMALLOC_START && addr < VMALLOC_END; -} -#endif - -static void -_NonContiguousFree( - IN struct page ** Pages, - IN gctUINT32 NumPages - ) -{ - gctINT i; - - gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages); - - gcmkASSERT(Pages != gcvNULL); - - for (i = 0; i < NumPages; i++) - { - __free_page(Pages[i]); - } - - if (is_vmalloc_addr(Pages)) - { - vfree(Pages); - } - else - { - kfree(Pages); - } - - gcmkFOOTER_NO(); -} - -static struct page ** -_NonContiguousAlloc( - IN gctUINT32 NumPages - ) -{ - struct page ** pages; - struct page *p; - gctINT i, size; - - gcmkHEADER_ARG("NumPages=%lu", NumPages); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) - if (NumPages > totalram_pages) -#else - if (NumPages > num_physpages) -#endif - { - gcmkFOOTER_NO(); - return gcvNULL; - } - - size = NumPages * sizeof(struct page *); - - pages = kmalloc(size, GFP_KERNEL | gcdNOWARN); - - if (!pages) - { - pages = vmalloc(size); - - if (!pages) - { - gcmkFOOTER_NO(); - return gcvNULL; - } - } - - for (i = 0; i < NumPages; i++) - { - p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN); - - if (!p) - { - _NonContiguousFree(pages, i); - gcmkFOOTER_NO(); - return gcvNULL; - } - - pages[i] = p; - } - - gcmkFOOTER_ARG("pages=0x%X", pages); - return pages; -} - -static inline struct page * -_NonContiguousToPage( - IN struct page ** Pages, - IN gctUINT32 Index - ) -{ - gcmkASSERT(Pages != gcvNULL); - return Pages[Index]; -} - -static inline unsigned long -_NonContiguousToPfn( - IN struct page ** Pages, - IN gctUINT32 Index - ) -{ - gcmkASSERT(Pages != gcvNULL); - return page_to_pfn(_NonContiguousToPage(Pages, Index)); -} - -static inline unsigned long -_NonContiguousToPhys( - IN struct page ** Pages, - IN gctUINT32 Index - ) -{ - gcmkASSERT(Pages != gcvNULL); - return page_to_phys(_NonContiguousToPage(Pages, Index)); -} - - -#if gcdUSE_NON_PAGED_MEMORY_CACHE - -static gctBOOL -_AddNonPagedMemoryCache( - gckOS Os, -#ifndef NO_DMA_COHERENT - gctINT Size, - gctSTRING Addr, - dma_addr_t DmaHandle -#else - long Order, - struct page * Page -#endif - ) -{ - gcsNonPagedMemoryCache *cache; - - if (Os->cacheSize >= gcdUSE_NON_PAGED_MEMORY_CACHE) - { - return gcvFALSE; - } - - /* Allocate the cache record */ - cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC); - - if (cache == gcvNULL) return gcvFALSE; - -#ifndef NO_DMA_COHERENT - cache->size = Size; - cache->addr = Addr; - cache->dmaHandle = DmaHandle; -#else - cache->order = Order; - cache->page = Page; -#endif - - /* Add to list */ - if (Os->cacheHead == gcvNULL) - { - cache->prev = gcvNULL; - cache->next = gcvNULL; - Os->cacheHead = - Os->cacheTail = cache; - } - else - { - /* Add to the tail. */ - cache->prev = Os->cacheTail; - cache->next = gcvNULL; - Os->cacheTail->next = cache; - Os->cacheTail = cache; - } - - Os->cacheSize++; - - return gcvTRUE; -} - -#ifndef NO_DMA_COHERENT -static gctSTRING -_GetNonPagedMemoryCache( - gckOS Os, - gctINT Size, - dma_addr_t * DmaHandle - ) -#else -static struct page * -_GetNonPagedMemoryCache( - gckOS Os, - long Order - ) -#endif -{ - gcsNonPagedMemoryCache *cache; -#ifndef NO_DMA_COHERENT - gctSTRING addr; -#else - struct page * page; -#endif - - if (Os->cacheHead == gcvNULL) return gcvNULL; - - /* Find the right cache */ - cache = Os->cacheHead; - - while (cache != gcvNULL) - { -#ifndef NO_DMA_COHERENT - if (cache->size == Size) break; -#else - if (cache->order == Order) break; -#endif - - cache = cache->next; - } - - if (cache == gcvNULL) return gcvNULL; - - /* Remove the cache from list */ - if (cache == Os->cacheHead) - { - Os->cacheHead = cache->next; - - if (Os->cacheHead == gcvNULL) - { - Os->cacheTail = gcvNULL; - } - } - else - { - cache->prev->next = cache->next; - - if (cache == Os->cacheTail) - { - Os->cacheTail = cache->prev; - } - else - { - cache->next->prev = cache->prev; - } - } - - /* Destroy cache */ -#ifndef NO_DMA_COHERENT - addr = cache->addr; - *DmaHandle = cache->dmaHandle; -#else - page = cache->page; -#endif - - kfree(cache); - - Os->cacheSize--; - -#ifndef NO_DMA_COHERENT - return addr; -#else - return page; -#endif -} - -static void -_FreeAllNonPagedMemoryCache( - gckOS Os - ) -{ - gcsNonPagedMemoryCache *cache, *nextCache; - - MEMORY_LOCK(Os); - - cache = Os->cacheHead; - - while (cache != gcvNULL) - { - if (cache != Os->cacheTail) - { - nextCache = cache->next; - } - else - { - nextCache = gcvNULL; - } - - /* Remove the cache from list */ - if (cache == Os->cacheHead) - { - Os->cacheHead = cache->next; - - if (Os->cacheHead == gcvNULL) - { - Os->cacheTail = gcvNULL; - } - } - else - { - cache->prev->next = cache->next; - - if (cache == Os->cacheTail) - { - Os->cacheTail = cache->prev; - } - else - { - cache->next->prev = cache->prev; - } - } - -#ifndef NO_DMA_COHERENT - dma_free_coherent(gcvNULL, - cache->size, - cache->addr, - cache->dmaHandle); -#else - free_pages((unsigned long)page_address(cache->page), cache->order); -#endif - - kfree(cache); - - cache = nextCache; - } - - MEMORY_UNLOCK(Os); -} - -#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */ - /******************************************************************************* ** Integer Id Management. */ @@ -815,11 +248,15 @@ _AllocateIntegerId( spin_lock(&Database->lock); next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1; + result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC); - if (!result) + /* ID allocated should not be 0. */ + gcmkASSERT(result != 0); + + if (result > 0) { - Database->curr = *Id; + Database->curr = *Id = result; } spin_unlock(&Database->lock); @@ -830,8 +267,6 @@ _AllocateIntegerId( { return gcvSTATUS_OUT_OF_RESOURCES; } - - *Id = result; #else again: if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0) @@ -843,7 +278,7 @@ again: next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1; - /* Try to get a id greater than current id. */ + /* Try to get a id greater than 0. */ result = idr_get_new_above(&Database->idr, KernelPointer, next, Id); if (!result) @@ -913,93 +348,232 @@ _DestroyIntegerId( return gcvSTATUS_OK; } -static void -_UnmapUserLogical( - IN gctINT Pid, +gceSTATUS +_QueryProcessPageTable( IN gctPOINTER Logical, - IN gctUINT32 Size -) + OUT gctUINT32 * Address + ) { - if (unlikely(current->mm == gcvNULL)) + spinlock_t *lock; + gctUINTPTR_T logical = (gctUINTPTR_T)Logical; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + if (!current->mm) { - /* Do nothing if process is exiting. */ - return; + return gcvSTATUS_NOT_FOUND; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) - if (vm_munmap((unsigned long)Logical, Size) < 0) + pgd = pgd_offset(current->mm, logical); + if (pgd_none(*pgd) || pgd_bad(*pgd)) { - gcmkTRACE_ZONE( - gcvLEVEL_WARNING, gcvZONE_OS, - "%s(%d): vm_munmap failed", - __FUNCTION__, __LINE__ - ); + return gcvSTATUS_NOT_FOUND; } -#else - down_write(¤t->mm->mmap_sem); - if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0) + + pud = pud_offset(pgd, logical); + if (pud_none(*pud) || pud_bad(*pud)) { - gcmkTRACE_ZONE( - gcvLEVEL_WARNING, gcvZONE_OS, - "%s(%d): do_munmap failed", - __FUNCTION__, __LINE__ - ); + return gcvSTATUS_NOT_FOUND; } - up_write(¤t->mm->mmap_sem); -#endif + + pmd = pmd_offset(pud, logical); + if (pmd_none(*pmd) || pmd_bad(*pmd)) + { + return gcvSTATUS_NOT_FOUND; + } + + pte = pte_offset_map_lock(current->mm, pmd, logical, &lock); + if (!pte) + { + return gcvSTATUS_NOT_FOUND; + } + + if (!pte_present(*pte)) + { + pte_unmap_unlock(pte, lock); + return gcvSTATUS_NOT_FOUND; + } + + *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK); + pte_unmap_unlock(pte, lock); + + return gcvSTATUS_OK; +} + +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE) +static inline gceSTATUS +outer_func( + gceCACHEOPERATION Type, + unsigned long Start, + unsigned long End + ) +{ + switch (Type) + { + case gcvCACHE_CLEAN: + outer_clean_range(Start, End); + break; + case gcvCACHE_INVALIDATE: + outer_inv_range(Start, End); + break; + case gcvCACHE_FLUSH: + outer_flush_range(Start, End); + break; + default: + return gcvSTATUS_INVALID_ARGUMENT; + break; + } + return gcvSTATUS_OK; +} + +#if gcdENABLE_OUTER_CACHE_PATCH +/******************************************************************************* +** _HandleOuterCache +** +** Handle the outer cache for the specified addresses. +** +** ARGUMENTS: +** +** gckOS Os +** Pointer to gckOS object. +** +** gctPOINTER Physical +** Physical address to flush. +** +** gctPOINTER Logical +** Logical address to flush. +** +** gctSIZE_T Bytes +** Size of the address range in bytes to flush. +** +** gceOUTERCACHE_OPERATION Type +** Operation need to be execute. +*/ +gceSTATUS +_HandleOuterCache( + IN gckOS Os, + IN gctUINT32 Physical, + IN gctPOINTER Logical, + IN gctSIZE_T Bytes, + IN gceCACHEOPERATION Type + ) +{ + gceSTATUS status; + unsigned long paddr; + gctPOINTER vaddr; + gctUINT32 offset, bytes, left; + + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", + Os, Logical, Bytes); + + if (Physical != gcvINVALID_ADDRESS) + { + /* Non paged memory or gcvPOOL_USER surface */ + paddr = (unsigned long) Physical; + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes)); + } + else + { + /* Non contiguous virtual memory */ + vaddr = Logical; + left = Bytes; + + while (left) + { + /* Handle (part of) current page. */ + offset = (gctUINTPTR_T)vaddr & ~PAGE_MASK; + + bytes = gcmMIN(left, PAGE_SIZE - offset); + + gcmkONERROR(_QueryProcessPageTable(vaddr, (gctUINT32*)&paddr)); + gcmkONERROR(outer_func(Type, paddr, paddr + bytes)); + + vaddr = (gctUINT8_PTR)vaddr + bytes; + left -= bytes; + } + } + + mb(); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; } +#endif +#endif -gceSTATUS -_QueryProcessPageTable( - IN gctPOINTER Logical, - OUT gctUINT32 * Address +gctBOOL +_AllowAccess( + IN gckOS Os, + IN gceCORE Core, + IN gctUINT32 Address ) { - spinlock_t *lock; - gctUINTPTR_T logical = (gctUINTPTR_T)Logical; - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; + gctUINT32 data; - if (!current->mm) + /* Check external clock state. */ + if (Os->clockStates[Core] == gcvFALSE) { - return gcvSTATUS_NOT_FOUND; + gcmkPRINT("[galcore]: %s(%d) External clock off", __FUNCTION__, __LINE__); + return gcvFALSE; } - pgd = pgd_offset(current->mm, logical); - if (pgd_none(*pgd) || pgd_bad(*pgd)) + /* Check internal clock state. */ + if (Address == 0) { - return gcvSTATUS_NOT_FOUND; + return gcvTRUE; } - pud = pud_offset(pgd, logical); - if (pud_none(*pud) || pud_bad(*pud)) +#if gcdMULTI_GPU + if (Core == gcvCORE_MAJOR) { - return gcvSTATUS_NOT_FOUND; + data = readl((gctUINT8 *)Os->device->registerBases[gcvCORE_3D_0_ID] + 0x0); } - - pmd = pmd_offset(pud, logical); - if (pmd_none(*pmd) || pmd_bad(*pmd)) + else +#endif { - return gcvSTATUS_NOT_FOUND; + data = readl((gctUINT8 *)Os->device->registerBases[Core] + 0x0); } - pte = pte_offset_map_lock(current->mm, pmd, logical, &lock); - if (!pte) + if ((data & 0x3) == 0x3) { - return gcvSTATUS_NOT_FOUND; + gcmkPRINT("[galcore]: %s(%d) Internal clock off", __FUNCTION__, __LINE__); + return gcvFALSE; } - if (!pte_present(*pte)) + 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) { - pte_unmap_unlock(pte, lock); - return gcvSTATUS_NOT_FOUND; + platform->ops->shrinkMemory(platform); + } + else + { + gcmkFOOTER_NO(); + return gcvSTATUS_NOT_SUPPORTED; } - *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK); - pte_unmap_unlock(pte, lock); - + gcmkFOOTER_NO(); return gcvSTATUS_OK; } @@ -1027,6 +601,7 @@ gckOS_Construct( { gckOS os; gceSTATUS status; + gctINT i; gcmkHEADER_ARG("Context=0x%X", Context); @@ -1052,8 +627,8 @@ gckOS_Construct( /* Set device device. */ os->device = Context; - /* IMPORTANT! No heap yet. */ - os->heap = gcvNULL; + /* Set allocateCount to 0, gckOS_Allocate has not been used yet. */ + atomic_set(&os->allocateCount, 0); /* Initialize the memory lock. */ gcmkONERROR(gckOS_CreateMutex(os, &os->memoryLock)); @@ -1062,7 +637,6 @@ gckOS_Construct( /* Create debug lock mutex. */ gcmkONERROR(gckOS_CreateMutex(os, &os->debugLock)); - os->mdlHead = os->mdlTail = gcvNULL; /* Get the kernel process ID. */ @@ -1096,12 +670,6 @@ gckOS_Construct( idr_init(&os->syncPointDB.idr); #endif -#if gcdUSE_NON_PAGED_MEMORY_CACHE - os->cacheSize = 0; - os->cacheHead = gcvNULL; - os->cacheTail = gcvNULL; -#endif - /* Create a workqueue for os timer. */ os->workqueue = create_singlethread_workqueue("galcore workqueue"); @@ -1111,6 +679,41 @@ gckOS_Construct( gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } + os->paddingPage = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN); + if (os->paddingPage == gcvNULL) + { + /* Out of memory. */ + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + else + { + SetPageReserved(os->paddingPage); + } + + for (i = 0; i < gcdMAX_GPU_COUNT; i++) + { + mutex_init(&os->registerAccessLocks[i]); + } + + gckOS_ImportAllocators(os); + +#ifdef CONFIG_IOMMU_SUPPORT + if (((gckGALDEVICE)(os->device))->mmu == gcvFALSE) + { + /* Only use IOMMU when internal MMU is not enabled. */ + status = gckIOMMU_Construct(os, &os->iommu); + + if (gcmIS_ERROR(status)) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): Fail to setup IOMMU", + __FUNCTION__, __LINE__ + ); + } + } +#endif + /* Return pointer to the gckOS object. */ *Os = os; @@ -1134,12 +737,6 @@ OnError: gckOS_DeleteMutex(os, os->signalMutex)); } - if (os->heap != gcvNULL) - { - gcmkVERIFY_OK( - gckHEAP_Destroy(os->heap)); - } - if (os->memoryMapLock != gcvNULL) { gcmkVERIFY_OK( @@ -1190,16 +787,17 @@ gckOS_Destroy( IN gckOS Os ) { - gckHEAP heap; - gcmkHEADER_ARG("Os=0x%X", Os); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); -#if gcdUSE_NON_PAGED_MEMORY_CACHE - _FreeAllNonPagedMemoryCache(Os); -#endif + if (Os->paddingPage != gcvNULL) + { + ClearPageReserved(Os->paddingPage); + __free_page(Os->paddingPage); + Os->paddingPage = gcvNULL; + } #if gcdANDROID_NATIVE_FENCE_SYNC /* @@ -1217,16 +815,6 @@ gckOS_Destroy( /* Destroy the mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->signalMutex)); - if (Os->heap != gcvNULL) - { - /* Mark gckHEAP as gone. */ - heap = Os->heap; - Os->heap = gcvNULL; - - /* Destroy the gckHEAP object. */ - gcmkVERIFY_OK(gckHEAP_Destroy(heap)); - } - /* Destroy the memory lock. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryMapLock)); gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryLock)); @@ -1240,12 +828,22 @@ gckOS_Destroy( /* Destory work queue. */ destroy_workqueue(Os->workqueue); + gckOS_FreeAllocators(Os); + +#ifdef CONFIG_IOMMU_SUPPORT + if (Os->iommu) + { + gckIOMMU_Destory(Os, Os->iommu); + } +#endif + /* Flush the debug cache. */ gcmkDEBUGFLUSH(~0U); /* Mark the gckOS object as unknown. */ Os->object.type = gcvOBJ_UNKNOWN; + /* Free the gckOS object. */ kfree(Os); @@ -1254,101 +852,73 @@ gckOS_Destroy( return gcvSTATUS_OK; } -static gctSTRING -_CreateKernelVirtualMapping( - IN PLINUX_MDL Mdl +gceSTATUS +gckOS_CreateKernelVirtualMapping( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T Bytes, + OUT gctPOINTER * Logical, + OUT gctSIZE_T * PageCount ) { - gctSTRING addr = 0; - gctINT numPages = Mdl->numPages; - -#if gcdNONPAGED_MEMORY_CACHEABLE - if (Mdl->contiguous) - { - addr = page_address(Mdl->u.contiguousPages); - } - else - { - addr = vmap(Mdl->u.nonContiguousPages, - numPages, - 0, - PAGE_KERNEL); - - /* Trigger a page fault. */ - memset(addr, 0, numPages * PAGE_SIZE); - } -#else - struct page ** pages; - gctBOOL free = gcvFALSE; - gctINT i; - - if (Mdl->contiguous) - { - pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN); - - if (!pages) - { - return gcvNULL; - } - - for (i = 0; i < numPages; i++) - { - pages[i] = nth_page(Mdl->u.contiguousPages, i); - } - - free = gcvTRUE; - } - else - { - pages = Mdl->u.nonContiguousPages; - } + gceSTATUS status; + PLINUX_MDL mdl = (PLINUX_MDL)Physical; + gckALLOCATOR allocator = mdl->allocator; - /* ioremap() can't work on system memory since 2.6.38. */ - addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL)); + gcmkHEADER(); - /* Trigger a page fault. */ - memset(addr, 0, numPages * PAGE_SIZE); + *PageCount = mdl->numPages; - if (free) - { - kfree(pages); - } + gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical)); -#endif + gcmkFOOTER_NO(); + return gcvSTATUS_OK; - return addr; +OnError: + gcmkFOOTER(); + return status; } -static void -_DestoryKernelVirtualMapping( - IN gctSTRING Addr +gceSTATUS +gckOS_DestroyKernelVirtualMapping( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T Bytes, + IN gctPOINTER Logical ) { -#if !gcdNONPAGED_MEMORY_CACHEABLE - vunmap(Addr); -#endif + PLINUX_MDL mdl = (PLINUX_MDL)Physical; + gckALLOCATOR allocator = mdl->allocator; + + gcmkHEADER(); + + allocator->ops->UnmapKernel(allocator, mdl, Logical); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; } gceSTATUS -gckOS_CreateKernelVirtualMapping( +gckOS_CreateUserVirtualMapping( + IN gckOS Os, IN gctPHYS_ADDR Physical, - OUT gctSIZE_T * PageCount, - OUT gctPOINTER * Logical + IN gctSIZE_T Bytes, + OUT gctPOINTER * Logical, + OUT gctSIZE_T * PageCount ) { - *PageCount = ((PLINUX_MDL)Physical)->numPages; - *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical); - - return gcvSTATUS_OK; + return gckOS_LockPages(Os, Physical, Bytes, gcvFALSE, Logical, PageCount); } gceSTATUS -gckOS_DestroyKernelVirtualMapping( +gckOS_DestroyUserVirtualMapping( + IN gckOS Os, + IN gctPHYS_ADDR Physical, + IN gctSIZE_T Bytes, IN gctPOINTER Logical ) { - _DestoryKernelVirtualMapping((gctSTRING)Logical); - return gcvSTATUS_OK; + return gckOS_UnlockPages(Os, Physical, Bytes, Logical); } /******************************************************************************* @@ -1386,16 +956,7 @@ gckOS_Allocate( gcmkVERIFY_ARGUMENT(Bytes > 0); gcmkVERIFY_ARGUMENT(Memory != gcvNULL); - /* Do we have a heap? */ - if (Os->heap != gcvNULL) - { - /* Allocate from the heap. */ - gcmkONERROR(gckHEAP_Allocate(Os->heap, Bytes, Memory)); - } - else - { - gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory)); - } + gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory)); /* Success. */ gcmkFOOTER_ARG("*Memory=0x%X", *Memory); @@ -1439,16 +1000,7 @@ gckOS_Free( gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); gcmkVERIFY_ARGUMENT(Memory != gcvNULL); - /* Do we have a heap? */ - if (Os->heap != gcvNULL) - { - /* Free from the heap. */ - gcmkONERROR(gckHEAP_Free(Os->heap, Memory)); - } - else - { - gcmkONERROR(gckOS_FreeMemory(Os, Memory)); - } + gcmkONERROR(gckOS_FreeMemory(Os, Memory)); /* Success. */ gcmkFOOTER_NO(); @@ -1507,6 +1059,9 @@ gckOS_AllocateMemory( gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } + /* Increase count. */ + atomic_inc(&Os->allocateCount); + /* Return pointer to the memory allocation. */ *Memory = memory; @@ -1556,6 +1111,9 @@ gckOS_FreeMemory( kfree(Memory); } + /* Decrease count. */ + atomic_dec(&Os->allocateCount); + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -1689,7 +1247,7 @@ gckOS_MapMemory( } #ifndef NO_DMA_COHERENT - if (dma_mmap_coherent(gcvNULL, + if (dma_mmap_writecombine(gcvNULL, mdlMap->vma, mdl->addr, mdl->dmaHandle, @@ -1863,7 +1421,7 @@ gckOS_UnmapMemoryEx( return gcvSTATUS_INVALID_ARGUMENT; } - _UnmapUserLogical(PID, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE); + _UnmapUserLogical(mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE); gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap)); } @@ -1968,6 +1526,7 @@ gckOS_AllocateNonPagedMemory( PLINUX_MDL mdl = gcvNULL; PLINUX_MDL_MAP mdlMap = gcvNULL; gctSTRING addr; + gckKERNEL kernel; #ifdef NO_DMA_COHERENT struct page * page; long size, order; @@ -1993,7 +1552,7 @@ gckOS_AllocateNonPagedMemory( numPages = GetPageCount(bytes, 0); /* Allocate mdl+vector structure */ - mdl = _CreateMdl(_GetProcessID()); + mdl = _CreateMdl(); if (mdl == gcvNULL) { gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); @@ -2006,45 +1565,19 @@ gckOS_AllocateNonPagedMemory( locked = gcvTRUE; #ifndef NO_DMA_COHERENT -#if gcdUSE_NON_PAGED_MEMORY_CACHE - addr = _GetNonPagedMemoryCache(Os, - mdl->numPages * PAGE_SIZE, - &mdl->dmaHandle); - - if (addr == gcvNULL) -#endif - { - addr = dma_alloc_coherent(gcvNULL, - mdl->numPages * PAGE_SIZE, - &mdl->dmaHandle, - GFP_KERNEL | gcdNOWARN); - } -#if gcdUSE_NON_PAGED_MEMORY_CACHE - if(addr == gcvNULL) - { - MEMORY_UNLOCK(Os); - locked = gcvFALSE; - /*Free all cache and try again*/ - _FreeAllNonPagedMemoryCache(Os); - MEMORY_LOCK(Os); - locked = gcvTRUE; - addr = dma_alloc_coherent(gcvNULL, - mdl->numPages * PAGE_SIZE, - &mdl->dmaHandle, - GFP_KERNEL | gcdNOWARN); - } +#ifdef CONFIG_ARM64 + addr = dma_alloc_coherent(gcvNULL, +#else + addr = dma_alloc_writecombine(gcvNULL, #endif + mdl->numPages * PAGE_SIZE, + &mdl->dmaHandle, + GFP_KERNEL | gcdNOWARN); #else size = mdl->numPages * PAGE_SIZE; order = get_order(size); -#if gcdUSE_NON_PAGED_MEMORY_CACHE - page = _GetNonPagedMemoryCache(Os, order); - if (page == gcvNULL) -#endif - { - page = alloc_pages(GFP_KERNEL | gcdNOWARN, order); - } + page = alloc_pages(GFP_KERNEL | gcdNOWARN, order); if (page == gcvNULL) { @@ -2057,7 +1590,9 @@ gckOS_AllocateNonPagedMemory( addr = _CreateKernelVirtualMapping(mdl); mdl->dmaHandle = virt_to_phys(vaddr); mdl->kaddr = vaddr; - mdl->u.contiguousPages = page; + + /* Trigger a page fault. */ + memset(addr, 0, numPages * PAGE_SIZE); #if !defined(CONFIG_PPC) /* Cache invalidate. */ @@ -2082,6 +1617,15 @@ gckOS_AllocateNonPagedMemory( gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } + kernel = Os->device->kernels[gcvCORE_MAJOR] != gcvNULL ? + Os->device->kernels[gcvCORE_MAJOR] : Os->device->kernels[gcvCORE_2D]; + if (((Os->device->baseAddress & 0x80000000) != (mdl->dmaHandle & 0x80000000)) && + kernel->hardware->mmuVersion == 0) + { + mdl->dmaHandle = (mdl->dmaHandle & ~0x80000000) + | (Os->device->baseAddress & 0x80000000); + } + mdl->addr = addr; /* Return allocated memory. */ @@ -2168,7 +1712,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; @@ -2196,7 +1742,11 @@ gckOS_AllocateNonPagedMemory( } else { +#if gcdSECURITY + *Logical = (gctPOINTER)mdl->kaddr; +#else *Logical = (gctPOINTER)mdl->addr; +#endif } /* @@ -2237,6 +1787,8 @@ OnError: /* Free LINUX_MDL. */ gcmkVERIFY_OK(_DestroyMdl(mdl)); } + *Physical = gcvNULL; + *Bytes = 0; if (locked) { @@ -2302,18 +1854,14 @@ gceSTATUS gckOS_FreeNonPagedMemory( MEMORY_LOCK(Os); #ifndef NO_DMA_COHERENT -#if gcdUSE_NON_PAGED_MEMORY_CACHE - if (!_AddNonPagedMemoryCache(Os, - mdl->numPages * PAGE_SIZE, - mdl->addr, - mdl->dmaHandle)) +#ifdef CONFIG_ARM64 + dma_free_coherent(gcvNULL, +#else + dma_free_writecombine(gcvNULL, #endif - { - dma_free_coherent(gcvNULL, - mdl->numPages * PAGE_SIZE, - mdl->addr, - mdl->dmaHandle); - } + mdl->numPages * PAGE_SIZE, + mdl->addr, + mdl->dmaHandle); #else size = mdl->numPages * PAGE_SIZE; vaddr = mdl->kaddr; @@ -2326,14 +1874,7 @@ gceSTATUS gckOS_FreeNonPagedMemory( size -= PAGE_SIZE; } -#if gcdUSE_NON_PAGED_MEMORY_CACHE - if (!_AddNonPagedMemoryCache(Os, - get_order(mdl->numPages * PAGE_SIZE), - virt_to_page(mdl->kaddr))) -#endif - { - free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE)); - } + free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE)); _DestoryKernelVirtualMapping(mdl->addr); #endif /* NO_DMA_COHERENT */ @@ -2342,11 +1883,8 @@ gceSTATUS gckOS_FreeNonPagedMemory( while (mdlMap != gcvNULL) { - if (mdlMap->vmaAddr != gcvNULL) - { - /* No mapped memory exists when free nonpaged memory */ - gcmkASSERT(0); - } + /* No mapped memory exists when free nonpaged memory */ + gcmkASSERT(mdlMap->vmaAddr == gcvNULL); mdlMap = mdlMap->next; } @@ -2422,15 +1960,63 @@ gckOS_ReadRegisterEx( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); +#if !gcdMULTI_GPU gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]); +#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) + { + *Data = readl((gctUINT8 *)Os->device->registerBase3D[gcvCORE_3D_0_ID] + Address); + } + else +#endif + { + *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; +} + +#if gcdMULTI_GPU +gceSTATUS +gckOS_ReadRegisterByCoreId( + IN gckOS Os, + IN gceCORE Core, + IN gctUINT32 CoreId, + IN gctUINT32 Address, + OUT gctUINT32 * Data + ) +{ + gcmkHEADER_ARG("Os=0x%X Core=%d CoreId=%d Address=0x%X", + Os, Core, CoreId, Address); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); gcmkVERIFY_ARGUMENT(Data != gcvNULL); - *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address); + *Data = readl((gctUINT8 *)Os->device->registerBase3D[CoreId] + Address); /* Success. */ gcmkFOOTER_ARG("*Data=0x%08x", *Data); return gcvSTATUS_OK; } +#endif /******************************************************************************* ** @@ -2473,14 +2059,61 @@ gckOS_WriteRegisterEx( { gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X Data=0x%08x", Os, Core, Address, Data); +#if !gcdMULTI_GPU 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) + { + writel(Data, (gctUINT8 *)Os->device->registerBase3D[gcvCORE_3D_0_ID] + Address); +#if gcdMULTI_GPU > 1 + writel(Data, (gctUINT8 *)Os->device->registerBase3D[gcvCORE_3D_1_ID] + Address); +#endif + } + else +#endif + { + writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address); + } + + if (!in_interrupt()) + { + mutex_unlock(&Os->registerAccessLocks[Core]); + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +#if gcdMULTI_GPU +gceSTATUS +gckOS_WriteRegisterByCoreId( + IN gckOS Os, + IN gceCORE Core, + IN gctUINT32 CoreId, + IN gctUINT32 Address, + IN gctUINT32 Data + ) +{ + gcmkHEADER_ARG("Os=0x%X Core=%d CoreId=%d Address=0x%X Data=0x%08x", + Os, Core, CoreId, Address, Data); - writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address); + writel(Data, (gctUINT8 *)Os->device->registerBase3D[CoreId] + Address); /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; } +#endif /******************************************************************************* ** @@ -2565,6 +2198,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; @@ -2575,6 +2210,34 @@ OnError: return status; } +/******************************************************************************* +** +** gckOS_UserLogicalToPhysical +** +** Get the physical system address of a corresponding user virtual address. +** +** INPUT: +** +** gckOS Os +** Pointer to an gckOS object. +** +** gctPOINTER Logical +** Logical address. +** +** OUTPUT: +** +** gctUINT32 * Address +** Pointer to a variable that receives the 32-bit physical address. +*/ +gceSTATUS gckOS_UserLogicalToPhysical( + IN gckOS Os, + IN gctPOINTER Logical, + OUT gctUINT32 * Address + ) +{ + return gckOS_GetPhysicalAddress(Os, Logical, Address); +} + #if gcdSECURE_USER static gceSTATUS gckOS_AddMapping( @@ -2660,7 +2323,7 @@ OnError: } #endif -static gceSTATUS +gceSTATUS _ConvertLogical2Physical( IN gckOS Os, IN gctPOINTER Logical, @@ -2674,7 +2337,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) @@ -2696,7 +2363,7 @@ _ConvertLogical2Physical( } else { - *Physical = gcmPTR2INT(virt_to_phys(base)) + offset; + *Physical = gcmPTR2INT32(virt_to_phys(base)) + offset; } return gcvSTATUS_OK; @@ -2784,6 +2451,7 @@ gckOS_GetPhysicalAddressProcess( { PLINUX_MDL mdl; gctINT8_PTR base; + gckALLOCATOR allocator = gcvNULL; gceSTATUS status = gcvSTATUS_INVALID_ADDRESS; gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID); @@ -2826,11 +2494,27 @@ gckOS_GetPhysicalAddressProcess( for (mdl = Os->mdlHead; mdl != gcvNULL; mdl = mdl->next) { /* Try this MDL. */ - status = _ConvertLogical2Physical(Os, - Logical, - ProcessID, - mdl, - Address); + allocator = mdl->allocator; + + if (allocator) + { + status = allocator->ops->LogicalToPhysical( + allocator, + mdl, + Logical, + ProcessID, + Address + ); + } + else + { + status = _ConvertLogical2Physical(Os, + Logical, + ProcessID, + mdl, + Address); + } + if (gcmIS_SUCCESS(status)) { break; @@ -2915,41 +2599,77 @@ gckOS_MapPhysical( 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); + } - if (logical == gcvNULL) + logical = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL)); + + kfree(pages); + + 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); @@ -3014,7 +2734,7 @@ gckOS_UnmapPhysical( if (mdl == gcvNULL) { /* Unmap the memory. */ - iounmap(Logical); + vunmap((void *)((unsigned long)Logical & PAGE_MASK)); } MEMORY_UNLOCK(Os); @@ -3103,7 +2823,7 @@ gckOS_DeleteMutex( gcmkVERIFY_ARGUMENT(Mutex != gcvNULL); /* Destroy the mutex. */ - mutex_destroy(Mutex); + mutex_destroy((struct mutex *)Mutex); /* Free the mutex structure. */ gcmkONERROR(gckOS_Free(Os, Mutex)); @@ -3147,84 +2867,12 @@ gckOS_AcquireMutex( IN gctUINT32 Timeout ) { -#if gcdDETECT_TIMEOUT - gctUINT32 timeout; -#endif - gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout); /* Validate the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); gcmkVERIFY_ARGUMENT(Mutex != gcvNULL); -#if gcdDETECT_TIMEOUT - timeout = 0; - - for (;;) - { - /* Try to acquire the mutex. */ - if (mutex_trylock(Mutex)) - { - /* Success. */ - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - } - - /* Advance the timeout. */ - timeout += 1; - - if (Timeout == gcvINFINITE) - { - if (timeout == gcdINFINITE_TIMEOUT) - { - gctUINT32 dmaAddress1, dmaAddress2; - gctUINT32 dmaState1, dmaState2; - - dmaState1 = dmaState2 = - dmaAddress1 = dmaAddress2 = 0; - - /* Verify whether DMA is running. */ - gcmkVERIFY_OK(_VerifyDMA( - Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2 - )); - -#if gcdDETECT_DMA_ADDRESS - /* Dump only if DMA appears stuck. */ - if ( - (dmaAddress1 == dmaAddress2) -#if gcdDETECT_DMA_STATE - && (dmaState1 == dmaState2) -# endif - ) -# endif - { - gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR)); - - gcmkPRINT( - "%s(%d): mutex 0x%X; forced message flush.", - __FUNCTION__, __LINE__, Mutex - ); - - /* Flush the debug cache. */ - gcmkDEBUGFLUSH(dmaAddress2); - } - - timeout = 0; - } - } - else - { - /* Timedout? */ - if (timeout >= Timeout) - { - break; - } - } - - /* Wait for 1 millisecond. */ - gcmkVERIFY_OK(gckOS_Delay(Os, 1)); - } -#else if (Timeout == gcvINFINITE) { /* Lock the mutex. */ @@ -3253,7 +2901,6 @@ gckOS_AcquireMutex( /* Wait for 1 millisecond. */ gcmkVERIFY_OK(gckOS_Delay(Os, 1)); } -#endif /* Timeout. */ gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT); @@ -3334,6 +2981,7 @@ gckOS_AtomicExchange( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(OldValue != gcvNULL); /* Exchange the pair of 32-bit values. */ *OldValue = (gctUINT32) atomic_xchg((atomic_t *) Target, (int) NewValue); @@ -3379,6 +3027,7 @@ gckOS_AtomicExchangePtr( /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(OldValue != gcvNULL); /* Exchange the pair of pointers. */ *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue); @@ -3388,7 +3037,6 @@ gckOS_AtomicExchangePtr( return gcvSTATUS_OK; } -#if gcdSMP /******************************************************************************* ** ** gckOS_AtomicSetMask @@ -3464,7 +3112,6 @@ gckOS_AtomClearMask( gcmkFOOTER_NO(); return gcvSTATUS_OK; } -#endif /******************************************************************************* ** @@ -3748,13 +3395,12 @@ gckOS_Delay( if (Delay > 0) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) - ktime_t delay = ktime_set(Delay/1000, (Delay%1000) * NSEC_PER_MSEC); + ktime_t delay = ktime_set((Delay / MSEC_PER_SEC), (Delay % MSEC_PER_SEC) * NSEC_PER_MSEC); __set_current_state(TASK_UNINTERRUPTIBLE); schedule_hrtimeout(&delay, HRTIMER_MODE_REL); #else msleep(Delay); #endif - } /* Success. */ @@ -3842,9 +3488,12 @@ gckOS_GetTime( OUT gctUINT64_PTR Time ) { + struct timeval tv; gcmkHEADER(); - *Time = 0; + /* Return the time of day in microseconds. */ + do_gettimeofday(&tv); + *Time = (tv.tv_sec * 1000000ULL) + tv.tv_usec; gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -3933,7 +3582,7 @@ gckOS_AllocatePagedMemory( gcmkVERIFY_ARGUMENT(Physical != gcvNULL); /* Allocate the memory. */ - gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvFALSE, Bytes, Physical)); + gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvALLOC_FLAG_NONE, Bytes, gcvNULL, Physical)); /* Success. */ gcmkFOOTER_ARG("*Physical=0x%X", *Physical); @@ -3956,14 +3605,17 @@ OnError: ** gckOS Os ** Pointer to an gckOS object. ** -** gctBOOL Contiguous -** Need contiguous memory or not. +** gctUINT32 Flag +** Allocation attribute. ** ** gctSIZE_T Bytes ** Number of bytes to allocate. ** ** OUTPUT: ** +** gctUINT32 * Gid +** Save the global ID for the piece of allocated memory. +** ** gctPHYS_ADDR * Physical ** Pointer to a variable that receives the physical address of the ** memory allocation. @@ -3971,22 +3623,19 @@ OnError: gceSTATUS gckOS_AllocatePagedMemoryEx( IN gckOS Os, - IN gctBOOL Contiguous, + IN gctUINT32 Flag, IN gctSIZE_T Bytes, + OUT gctUINT32 * Gid, OUT gctPHYS_ADDR * Physical ) { gctINT numPages; - gctINT i; PLINUX_MDL mdl = gcvNULL; gctSIZE_T bytes; - gctBOOL locked = gcvFALSE; - gceSTATUS status; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - gctPOINTER addr = gcvNULL; -#endif + gceSTATUS status = gcvSTATUS_OUT_OF_MEMORY; + gckALLOCATOR allocator; - gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes); + gcmkHEADER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); @@ -3997,90 +3646,51 @@ gckOS_AllocatePagedMemoryEx( numPages = GetPageCount(bytes, 0); - MEMORY_LOCK(Os); - locked = gcvTRUE; - - mdl = _CreateMdl(_GetProcessID()); + mdl = _CreateMdl(); if (mdl == gcvNULL) { gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } - if (Contiguous) + /* Walk all allocators. */ + list_for_each_entry(allocator, &Os->allocatorList, head) { - gctUINT32 order = get_order(bytes); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d) flag = %x allocator->capability = %x", + __FUNCTION__, __LINE__, Flag, allocator->capability); - if (order >= MAX_ORDER) + if ((Flag & allocator->capability) != Flag) { - gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + continue; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - addr = - alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY); + status = allocator->ops->Alloc(allocator, mdl, numPages, Flag); - mdl->u.contiguousPages = addr - ? virt_to_page(addr) - : gcvNULL; - - mdl->exact = gcvTRUE; -#else - mdl->u.contiguousPages = - alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order); -#endif - if (mdl->u.contiguousPages == gcvNULL) + if (gcmIS_SUCCESS(status)) { - mdl->u.contiguousPages = - alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - mdl->exact = gcvFALSE; -#endif + mdl->allocator = allocator; + break; } } - else - { - mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages); - } - if (mdl->u.contiguousPages == gcvNULL && mdl->u.nonContiguousPages == gcvNULL) - { - gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); - } + /* Check status. */ + gcmkONERROR(status); mdl->dmaHandle = 0; mdl->addr = 0; mdl->numPages = numPages; mdl->pagedMem = 1; - mdl->contiguous = Contiguous; - - for (i = 0; i < mdl->numPages; i++) - { - struct page *page; - - if (mdl->contiguous) - { - page = nth_page(mdl->u.contiguousPages, i); - } - else - { - page = _NonContiguousToPage(mdl->u.nonContiguousPages, i); - } + mdl->contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS; - SetPageReserved(page); + /* Return physical address. */ + *Physical = (gctPHYS_ADDR) mdl; - if (!PageHighMem(page) && page_to_phys(page)) - { - gcmkVERIFY_OK( - gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL, - (gctPOINTER)(gctUINTPTR_T)page_to_phys(page), - page_address(page), - PAGE_SIZE)); - } + if (Gid != gcvNULL) + { + *Gid = mdl->gid; } - /* Return physical address. */ - *Physical = (gctPHYS_ADDR) mdl; + MEMORY_LOCK(Os); /* * Add this to a global list. @@ -4112,15 +3722,10 @@ OnError: /* Free the memory. */ _DestroyMdl(mdl); } - - if (locked) - { - /* Unlock the memory. */ - MEMORY_UNLOCK(Os); - } + *Physical = gcvNULL; /* Return the status. */ - gcmkFOOTER(); + gcmkFOOTER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes); return status; } @@ -4153,7 +3758,7 @@ gckOS_FreePagedMemory( ) { PLINUX_MDL mdl = (PLINUX_MDL) Physical; - gctINT i; + gckALLOCATOR allocator = (gckALLOCATOR)mdl->allocator; gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes); @@ -4162,40 +3767,8 @@ gckOS_FreePagedMemory( gcmkVERIFY_ARGUMENT(Physical != gcvNULL); gcmkVERIFY_ARGUMENT(Bytes > 0); - /*addr = mdl->addr;*/ - MEMORY_LOCK(Os); - for (i = 0; i < mdl->numPages; i++) - { - if (mdl->contiguous) - { - ClearPageReserved(nth_page(mdl->u.contiguousPages, i)); - } - else - { - ClearPageReserved(_NonContiguousToPage(mdl->u.nonContiguousPages, i)); - } - } - - if (mdl->contiguous) - { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) - if (mdl->exact == gcvTRUE) - { - free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE); - } - else -#endif - { - __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages)); - } - } - else - { - _NonContiguousFree(mdl->u.nonContiguousPages, mdl->numPages); - } - /* Remove the node from global list. */ if (mdl == Os->mdlHead) { @@ -4220,6 +3793,8 @@ gckOS_FreePagedMemory( MEMORY_UNLOCK(Os); + allocator->ops->Free(allocator, mdl); + /* Free the structure... */ gcmkVERIFY_OK(_DestroyMdl(mdl)); @@ -4268,184 +3843,50 @@ gckOS_LockPages( OUT gctSIZE_T * PageCount ) { - PLINUX_MDL mdl; - PLINUX_MDL_MAP mdlMap; - gctSTRING addr; - unsigned long start; - unsigned long pfn; - gctINT i; - - gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical); - - /* Verify the arguments. */ - gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); - gcmkVERIFY_ARGUMENT(Physical != gcvNULL); - gcmkVERIFY_ARGUMENT(Logical != gcvNULL); - gcmkVERIFY_ARGUMENT(PageCount != gcvNULL); - - mdl = (PLINUX_MDL) Physical; - - MEMORY_LOCK(Os); - - mdlMap = FindMdlMap(mdl, _GetProcessID()); - - if (mdlMap == gcvNULL) - { - mdlMap = _CreateMdlMap(mdl, _GetProcessID()); - - if (mdlMap == gcvNULL) - { - MEMORY_UNLOCK(Os); - - gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); - return gcvSTATUS_OUT_OF_MEMORY; - } - } - - if (mdlMap->vmaAddr == gcvNULL) - { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) - mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL, - 0L, - mdl->numPages * PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_SHARED, - 0); -#else - down_write(¤t->mm->mmap_sem); - - mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL, - 0L, - mdl->numPages * PAGE_SIZE, - PROT_READ | PROT_WRITE, - MAP_SHARED, - 0); - - up_write(¤t->mm->mmap_sem); -#endif - - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): vmaAddr->0x%X for phys_addr->0x%X", - __FUNCTION__, __LINE__, - (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr, - (gctUINT32)(gctUINTPTR_T)mdl - ); + gceSTATUS status; + PLINUX_MDL mdl; + PLINUX_MDL_MAP mdlMap; + gckALLOCATOR allocator; - if (IS_ERR(mdlMap->vmaAddr)) - { - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): do_mmap_pgoff error", - __FUNCTION__, __LINE__ - ); + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical); - mdlMap->vmaAddr = gcvNULL; + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Physical != gcvNULL); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + gcmkVERIFY_ARGUMENT(PageCount != gcvNULL); - MEMORY_UNLOCK(Os); + mdl = (PLINUX_MDL) Physical; + allocator = mdl->allocator; - gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); - return gcvSTATUS_OUT_OF_MEMORY; - } + MEMORY_LOCK(Os); - down_write(¤t->mm->mmap_sem); + mdlMap = FindMdlMap(mdl, _GetProcessID()); - mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr); + if (mdlMap == gcvNULL) + { + mdlMap = _CreateMdlMap(mdl, _GetProcessID()); - if (mdlMap->vma == gcvNULL) + if (mdlMap == gcvNULL) { - up_write(¤t->mm->mmap_sem); - - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): find_vma error", - __FUNCTION__, __LINE__ - ); - - mdlMap->vmaAddr = gcvNULL; - MEMORY_UNLOCK(Os); - gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES); - return gcvSTATUS_OUT_OF_RESOURCES; - } - - mdlMap->vma->vm_flags |= gcdVM_FLAGS; - - if (Cacheable == gcvFALSE) - { - /* Make this mapping non-cached. */ - mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot); + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); + return gcvSTATUS_OUT_OF_MEMORY; } + } - addr = mdl->addr; - - /* Now map all the vmalloc pages to this user address. */ - if (mdl->contiguous) - { - /* map kernel memory to user space.. */ - if (remap_pfn_range(mdlMap->vma, - mdlMap->vma->vm_start, - page_to_pfn(mdl->u.contiguousPages), - mdlMap->vma->vm_end - mdlMap->vma->vm_start, - mdlMap->vma->vm_page_prot) < 0) - { - up_write(¤t->mm->mmap_sem); - - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): unable to mmap ret", - __FUNCTION__, __LINE__ - ); - - mdlMap->vmaAddr = gcvNULL; - - MEMORY_UNLOCK(Os); + if (mdlMap->vmaAddr == gcvNULL) + { + status = allocator->ops->MapUser(allocator, mdl, mdlMap, Cacheable); - gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); - return gcvSTATUS_OUT_OF_MEMORY; - } - } - else + if (gcmIS_ERROR(status)) { - start = mdlMap->vma->vm_start; - - for (i = 0; i < mdl->numPages; i++) - { - pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i); - - if (remap_pfn_range(mdlMap->vma, - start, - pfn, - PAGE_SIZE, - mdlMap->vma->vm_page_prot) < 0) - { - up_write(¤t->mm->mmap_sem); - - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X", - __FUNCTION__, __LINE__, - (gctUINT32)(gctUINTPTR_T)Physical, - (gctUINT32)(gctUINTPTR_T)*Logical, - (gctUINT32)(gctUINTPTR_T)addr, - (gctUINT32)(gctUINTPTR_T)start - ); - - mdlMap->vmaAddr = gcvNULL; - - MEMORY_UNLOCK(Os); - - gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY); - return gcvSTATUS_OUT_OF_MEMORY; - } + MEMORY_UNLOCK(Os); - start += PAGE_SIZE; - addr += PAGE_SIZE; - } + gcmkFOOTER_ARG("*status=%d", status); + return status; } - - up_write(¤t->mm->mmap_sem); } mdlMap->count++; @@ -4465,7 +3906,7 @@ gckOS_LockPages( Os, _GetProcessID(), Physical, - gcvNULL, + gcvINVALID_ADDRESS, (gctPOINTER)mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE )); @@ -4511,6 +3952,7 @@ gckOS_MapPages( gcvCORE_MAJOR, Physical, PageCount, + 0, PageTable); } @@ -4520,6 +3962,7 @@ gckOS_MapPagesEx( IN gceCORE Core, IN gctPHYS_ADDR Physical, IN gctSIZE_T PageCount, + IN gctUINT32 Address, IN gctPOINTER PageTable ) { @@ -4534,6 +3977,12 @@ gckOS_MapPagesEx( gctPHYS_ADDR pageTablePhysical; #endif +#if gcdPROCESS_ADDRESS_SPACE + gckKERNEL kernel = Os->device->kernels[Core]; + gckMMU mmu; +#endif + gckALLOCATOR allocator; + gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X", Os, Core, Physical, PageCount, PageTable); @@ -4546,6 +3995,8 @@ gckOS_MapPagesEx( /* Convert pointer to MDL. */ mdl = (PLINUX_MDL)Physical; + allocator = mdl->allocator; + gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d", @@ -4555,7 +4006,9 @@ gckOS_MapPagesEx( mdl->pagedMem ); - MEMORY_LOCK(Os); +#if gcdPROCESS_ADDRESS_SPACE + gcmkONERROR(gckKERNEL_GetProcessMMU(kernel, &mmu)); +#endif table = (gctUINT32 *)PageTable; #if gcdNONPAGED_MEMORY_CACHEABLE @@ -4567,82 +4020,86 @@ gckOS_MapPagesEx( /* Get all the physical addresses and store them in the page table. */ offset = 0; + PageCount = PageCount / (PAGE_SIZE / 4096); - if (mdl->pagedMem) + /* Try to get the user pages so DMA can happen. */ + while (PageCount-- > 0) { - /* Try to get the user pages so DMA can happen. */ - while (PageCount-- > 0) + gctUINT i; + gctUINT32 phys = ~0; + + if (mdl->pagedMem && !mdl->contiguous) + { + allocator->ops->Physical(allocator, mdl, offset, &phys); + } + 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)); + } + + gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys)); + +#ifdef CONFIG_IOMMU_SUPPORT + if (Os->iommu) + { + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): Setup mapping in IOMMU %x => %x", + __FUNCTION__, __LINE__, + Address + (offset * PAGE_SIZE), phys + ); + + /* When use IOMMU, GPU use system PAGE_SIZE. */ + gcmkONERROR(gckIOMMU_Map( + Os->iommu, Address + (offset * PAGE_SIZE), phys, PAGE_SIZE)); + } + else +#endif { + #if gcdENABLE_VG if (Core == gcvCORE_VG) { - if (mdl->contiguous) + for (i = 0; i < (PAGE_SIZE / 4096); i++) { gcmkONERROR( gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu, - page_to_phys(nth_page(mdl->u.contiguousPages, offset)), - table)); - } - else - { - gcmkONERROR( - gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu, - _NonContiguousToPhys(mdl->u.nonContiguousPages, offset), - table)); + phys + (i * 4096), + table++)); } } else #endif { - if (mdl->contiguous) + for (i = 0; i < (PAGE_SIZE / 4096); i++) { +#if gcdPROCESS_ADDRESS_SPACE + gctUINT32_PTR pageTableEntry; + gckMMU_GetPageEntry(mmu, Address + (offset * 4096), &pageTableEntry); gcmkONERROR( - gckMMU_SetPage(Os->device->kernels[Core]->mmu, - page_to_phys(nth_page(mdl->u.contiguousPages, offset)), - table)); - } - else - { + gckMMU_SetPage(mmu, + phys + (i * 4096), + pageTableEntry)); +#else gcmkONERROR( gckMMU_SetPage(Os->device->kernels[Core]->mmu, - _NonContiguousToPhys(mdl->u.nonContiguousPages, offset), - table)); + phys + (i * 4096), + table++)); +#endif } } - - table++; - offset += 1; } - } - else - { - gcmkTRACE_ZONE( - gcvLEVEL_INFO, gcvZONE_OS, - "%s(%d): we should not get this call for Non Paged Memory!", - __FUNCTION__, __LINE__ - ); - while (PageCount-- > 0) - { -#if gcdENABLE_VG - if (Core == gcvCORE_VG) - { - gcmkONERROR( - gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu, - page_to_phys(nth_page(mdl->u.contiguousPages, offset)), - table)); - } - else -#endif - { - gcmkONERROR( - gckMMU_SetPage(Os->device->kernels[Core]->mmu, - page_to_phys(nth_page(mdl->u.contiguousPages, offset)), - table)); - } - table++; - offset += 1; - } + offset += 1; } #if gcdNONPAGED_MEMORY_CACHEABLE @@ -4663,13 +4120,29 @@ gckOS_MapPagesEx( OnError: - MEMORY_UNLOCK(Os); - /* Return the status. */ gcmkFOOTER(); return status; } +gceSTATUS +gckOS_UnmapPages( + IN gckOS Os, + IN gctSIZE_T PageCount, + IN gctUINT32 Address + ) +{ +#ifdef CONFIG_IOMMU_SUPPORT + if (Os->iommu) + { + gcmkVERIFY_OK(gckIOMMU_Unmap( + Os->iommu, Address, PageCount * PAGE_SIZE)); + } +#endif + + return gcvSTATUS_OK; +} + /******************************************************************************* ** ** gckOS_UnlockPages @@ -4704,6 +4177,7 @@ gckOS_UnlockPages( { PLINUX_MDL_MAP mdlMap; PLINUX_MDL mdl = (PLINUX_MDL)Physical; + gckALLOCATOR allocator = mdl->allocator; gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X", Os, Physical, Bytes, Logical); @@ -4713,10 +4187,6 @@ gckOS_UnlockPages( gcmkVERIFY_ARGUMENT(Physical != gcvNULL); gcmkVERIFY_ARGUMENT(Logical != gcvNULL); - /* Make sure there is already a mapping...*/ - gcmkVERIFY_ARGUMENT(mdl->u.nonContiguousPages != gcvNULL - || mdl->u.contiguousPages != gcvNULL); - MEMORY_LOCK(Os); mdlMap = mdl->maps; @@ -4727,7 +4197,11 @@ gckOS_UnlockPages( { if (--mdlMap->count == 0) { - _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE); + allocator->ops->UnmapUser( + allocator, + mdlMap->vmaAddr, + mdl->numPages * PAGE_SIZE); + mdlMap->vmaAddr = gcvNULL; } } @@ -5399,6 +4873,9 @@ OnError: gctUINTPTR_T start, end, memory; gctUINT32 offset; gctINT result = 0; +#if gcdPROCESS_ADDRESS_SPACE + gckMMU mmu; +#endif gcsPageInfo_PTR info = gcvNULL; struct page **pages = gcvNULL; @@ -5412,6 +4889,8 @@ OnError: do { + gctSIZE_T extraPage; + memory = (gctUINTPTR_T) Memory; /* Get the number of required pages. */ @@ -5419,6 +4898,9 @@ OnError: start = memory >> PAGE_SHIFT; pageCount = end - start; + /* Allocate extra 64 bytes to avoid cache overflow */ + extraPage = (((memory + gcmALIGN(Size + 64, 64) + PAGE_SIZE - 1) >> PAGE_SHIFT) > end) ? 1 : 0; + gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): pageCount: %d.", @@ -5444,8 +4926,10 @@ OnError: break; } + info->extraPage = 0; + /* Allocate the array of page addresses. */ - pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | gcdNOWARN); + pages = (struct page **)kmalloc((pageCount + extraPage) * sizeof(struct page *), GFP_KERNEL | gcdNOWARN); if (pages == gcvNULL) { @@ -5458,7 +4942,11 @@ OnError: for (i = 0; i < pageCount; i++) { pages[i] = pfn_to_page((Physical >> PAGE_SHIFT) + i); - get_page(pages[i]); + + if (pfn_valid(page_to_pfn(pages[i]))) + { + get_page(pages[i]); + } } } else @@ -5568,6 +5056,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); @@ -5579,7 +5070,10 @@ OnError: /* Reference pages. */ for (i = 0; i < pageCount; i++) { - get_page(pages[i]); + if (pfn_valid(page_to_pfn(pages[i]))) + { + get_page(pages[i]); + } } } } @@ -5593,11 +5087,66 @@ OnError: /* Flush(clean) the data cache. */ gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL, - (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]), + page_to_phys(pages[i]), (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE, PAGE_SIZE)); } +#if gcdPROCESS_ADDRESS_SPACE + gcmkONERROR(gckKERNEL_GetProcessMMU(Os->device->kernels[Core], &mmu)); +#endif + + if (extraPage) + { + pages[pageCount++] = Os->paddingPage; + 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) { @@ -5610,11 +5159,19 @@ OnError: else #endif { +#if gcdPROCESS_ADDRESS_SPACE + /* Allocate pages inside the page table. */ + gcmkERR_BREAK(gckMMU_AllocatePages(mmu, + pageCount * (PAGE_SIZE/4096), + (gctPOINTER *) &pageTable, + &address)); +#else /* Allocate pages inside the page table. */ gcmkERR_BREAK(gckMMU_AllocatePages(Os->device->kernels[Core]->mmu, pageCount * (PAGE_SIZE/4096), (gctPOINTER *) &pageTable, &address)); +#endif } /* Fill the page table. */ @@ -5623,37 +5180,63 @@ OnError: gctUINT32 phys; gctUINT32_PTR tab = pageTable + i * (PAGE_SIZE/4096); +#if gcdPROCESS_ADDRESS_SPACE + gckMMU_GetPageEntry(mmu, address + i * 4096, &tab); +#endif phys = page_to_phys(pages[i]); -#if gcdENABLE_VG - if (Core == gcvCORE_VG) +#ifdef CONFIG_IOMMU_SUPPORT + if (Os->iommu) { - /* Get the physical address from page struct. */ - gcmkONERROR( - gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu, - phys, - tab)); + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_OS, + "%s(%d): Setup mapping in IOMMU %x => %x", + __FUNCTION__, __LINE__, + Address + (i * PAGE_SIZE), phys + ); + + gcmkONERROR(gckIOMMU_Map( + Os->iommu, address + i * PAGE_SIZE, phys, PAGE_SIZE)); } else #endif { - /* Get the physical address from page struct. */ - gcmkONERROR( - gckMMU_SetPage(Os->device->kernels[Core]->mmu, - phys, - tab)); - } - for (j = 1; j < (PAGE_SIZE/4096); j++) - { - pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j; +#if gcdENABLE_VG + if (Core == gcvCORE_VG) + { + gcmkVERIFY_OK( + gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys)); + + /* Get the physical address from page struct. */ + gcmkONERROR( + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu, + phys, + tab)); + } + else +#endif + { + /* Get the physical address from page struct. */ + gcmkONERROR( + gckMMU_SetPage(Os->device->kernels[Core]->mmu, + phys, + tab)); + } + + for (j = 1; j < (PAGE_SIZE/4096); j++) + { + pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j; + } } +#if !gcdPROCESS_ADDRESS_SPACE gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_OS, "%s(%d): pageTable[%d]: 0x%X 0x%X.", __FUNCTION__, __LINE__, i, phys, pageTable[i]); +#endif } #if gcdENABLE_VG @@ -5664,8 +5247,15 @@ OnError: else #endif { - gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu)); +#if gcdPROCESS_ADDRESS_SPACE + info->mmu = mmu; + gcmkONERROR(gckMMU_Flush(mmu)); +#else + gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu, gcvSURF_TYPE_UNKNOWN)); +#endif } +#endif + info->address = address; /* Save pointer to page table. */ info->pageTable = pageTable; @@ -5881,8 +5471,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) { @@ -5895,11 +5506,32 @@ OnError: else #endif { - /* Free the pages from the MMU. */ - gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu, - info->pageTable, - pageCount * (PAGE_SIZE/4096) - )); + /* Free the pages from the MMU. */ +#if gcdPROCESS_ADDRESS_SPACE + gcmkERR_BREAK(gckMMU_FreePagesEx(info->mmu, + info->address, + pageCount * (PAGE_SIZE/4096) + )); + +#else + gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu, + info->pageTable, + pageCount * (PAGE_SIZE/4096) + )); +#endif + + gcmkERR_BREAK(gckOS_UnmapPages( + Os, + pageCount * (PAGE_SIZE/4096), + info->address + )); + } +#endif + + if (info->extraPage) + { + pageCount -= 1; + info->extraPage = 0; } /* Release the page cache. */ @@ -5919,7 +5551,10 @@ OnError: SetPageDirty(pages[i]); } - page_cache_release(pages[i]); + if (pfn_valid(page_to_pfn(pages[i]))) + { + page_cache_release(pages[i]); + } } } @@ -5992,6 +5627,32 @@ gckOS_SuspendInterrupt( return gckOS_SuspendInterruptEx(Os, gcvCORE_MAJOR); } +#if gcdMULTI_GPU +gceSTATUS +gckOS_SuspendInterruptEx( + IN gckOS Os, + IN gceCORE Core + ) +{ + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + + if (Core == gcvCORE_MAJOR) + { + disable_irq(Os->device->irqLine3D[gcvCORE_3D_0_ID]); + disable_irq(Os->device->irqLine3D[gcvCORE_3D_1_ID]); + } + else + { + disable_irq(Os->device->irqLines[Core]); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} +#else gceSTATUS gckOS_SuspendInterruptEx( IN gckOS Os, @@ -6008,6 +5669,7 @@ gckOS_SuspendInterruptEx( gcmkFOOTER_NO(); return gcvSTATUS_OK; } +#endif gceSTATUS gckOS_ResumeInterrupt( @@ -6017,6 +5679,32 @@ gckOS_ResumeInterrupt( return gckOS_ResumeInterruptEx(Os, gcvCORE_MAJOR); } +#if gcdMULTI_GPU +gceSTATUS +gckOS_ResumeInterruptEx( + IN gckOS Os, + IN gceCORE Core + ) +{ + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + + if (Core == gcvCORE_MAJOR) + { + enable_irq(Os->device->irqLine3D[gcvCORE_3D_0_ID]); + enable_irq(Os->device->irqLine3D[gcvCORE_3D_1_ID]); + } + else + { + enable_irq(Os->device->irqLines[Core]); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} +#else gceSTATUS gckOS_ResumeInterruptEx( IN gckOS Os, @@ -6033,6 +5721,7 @@ gckOS_ResumeInterruptEx( gcmkFOOTER_NO(); return gcvSTATUS_OK; } +#endif gceSTATUS gckOS_MemCopy( @@ -6075,128 +5764,6 @@ gckOS_ZeroMemory( ********************************* Cache Control ******************************** *******************************************************************************/ -#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE) -static inline gceSTATUS -outer_func( - gceCACHEOPERATION Type, - unsigned long Start, - unsigned long End - ) -{ - switch (Type) - { - case gcvCACHE_CLEAN: - outer_clean_range(Start, End); - break; - case gcvCACHE_INVALIDATE: - outer_inv_range(Start, End); - break; - case gcvCACHE_FLUSH: - outer_flush_range(Start, End); - break; - default: - return gcvSTATUS_INVALID_ARGUMENT; - break; - } - return gcvSTATUS_OK; -} - -#if gcdENABLE_OUTER_CACHE_PATCH -/******************************************************************************* -** _HandleOuterCache -** -** Handle the outer cache for the specified addresses. -** -** ARGUMENTS: -** -** gckOS Os -** Pointer to gckOS object. -** -** gctUINT32 ProcessID -** Process ID Logical belongs. -** -** gctPHYS_ADDR Handle -** Physical address handle. If gcvNULL it is video memory. -** -** gctPOINTER Physical -** Physical address to flush. -** -** gctPOINTER Logical -** Logical address to flush. -** -** gctSIZE_T Bytes -** Size of the address range in bytes to flush. -** -** gceOUTERCACHE_OPERATION Type -** Operation need to be execute. -*/ -static gceSTATUS -_HandleOuterCache( - IN gckOS Os, - IN gctUINT32 ProcessID, - IN gctPHYS_ADDR Handle, - IN gctPOINTER Physical, - IN gctPOINTER Logical, - IN gctSIZE_T Bytes, - IN gceCACHEOPERATION Type - ) -{ - gceSTATUS status; - gctUINT32 i, pageNum; - unsigned long paddr; - gctPOINTER vaddr; - - gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu", - Os, ProcessID, Handle, Logical, Bytes); - - if (Physical != gcvNULL) - { - /* Non paged memory or gcvPOOL_USER surface */ - paddr = (unsigned long) Physical; - gcmkONERROR(outer_func(Type, paddr, paddr + Bytes)); - } - else if ((Handle == gcvNULL) - || (Handle != gcvNULL && ((PLINUX_MDL)Handle)->contiguous) - ) - { - /* Video Memory or contiguous virtual memory */ - gcmkONERROR(gckOS_GetPhysicalAddress(Os, Logical, (gctUINT32*)&paddr)); - gcmkONERROR(outer_func(Type, paddr, paddr + Bytes)); - } - else - { - /* Non contiguous virtual memory */ - vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE); - pageNum = GetPageCount(Bytes, 0); - - for (i = 0; i < pageNum; i += 1) - { - gcmkONERROR(_ConvertLogical2Physical( - Os, - vaddr + PAGE_SIZE * i, - ProcessID, - (PLINUX_MDL)Handle, - (gctUINT32*)&paddr - )); - - gcmkONERROR(outer_func(Type, paddr, paddr + PAGE_SIZE)); - } - } - - mb(); - - /* Success. */ - gcmkFOOTER_NO(); - return gcvSTATUS_OK; - -OnError: - /* Return the status. */ - gcmkFOOTER(); - return status; -} -#endif -#endif - /******************************************************************************* ** gckOS_CacheClean ** @@ -6229,11 +5796,13 @@ gckOS_CacheClean( IN gckOS Os, IN gctUINT32 ProcessID, IN gctPHYS_ADDR Handle, - IN gctPOINTER Physical, + IN gctUINT32 Physical, IN gctPOINTER Logical, IN gctSIZE_T Bytes ) { + gcsPLATFORM * platform; + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu", Os, ProcessID, Handle, Logical, Bytes); @@ -6242,6 +5811,25 @@ gckOS_CacheClean( gcmkVERIFY_ARGUMENT(Logical != gcvNULL); gcmkVERIFY_ARGUMENT(Bytes > 0); + platform = Os->device->platform; + + if (platform && platform->ops->cache) + { + platform->ops->cache( + platform, + ProcessID, + Handle, + Physical, + Logical, + Bytes, + gcvCACHE_CLEAN + ); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + #if !gcdCACHE_FUNCTION_UNIMPLEMENTED #ifdef CONFIG_ARM @@ -6255,7 +5843,7 @@ gckOS_CacheClean( #if defined(CONFIG_OUTER_CACHE) /* Outer cache. */ #if gcdENABLE_OUTER_CACHE_PATCH - _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_CLEAN); + _HandleOuterCache(Os, Physical, Logical, Bytes, gcvCACHE_CLEAN); #else outer_clean_range((unsigned long) Handle, (unsigned long) Handle + Bytes); #endif @@ -6312,11 +5900,13 @@ gckOS_CacheInvalidate( IN gckOS Os, IN gctUINT32 ProcessID, IN gctPHYS_ADDR Handle, - IN gctPOINTER Physical, + IN gctUINT32 Physical, IN gctPOINTER Logical, IN gctSIZE_T Bytes ) { + gcsPLATFORM * platform; + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu", Os, ProcessID, Handle, Logical, Bytes); @@ -6325,6 +5915,25 @@ gckOS_CacheInvalidate( gcmkVERIFY_ARGUMENT(Logical != gcvNULL); gcmkVERIFY_ARGUMENT(Bytes > 0); + platform = Os->device->platform; + + if (platform && platform->ops->cache) + { + platform->ops->cache( + platform, + ProcessID, + Handle, + Physical, + Logical, + Bytes, + gcvCACHE_INVALIDATE + ); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + #if !gcdCACHE_FUNCTION_UNIMPLEMENTED #ifdef CONFIG_ARM @@ -6338,7 +5947,7 @@ gckOS_CacheInvalidate( #if defined(CONFIG_OUTER_CACHE) /* Outer cache. */ #if gcdENABLE_OUTER_CACHE_PATCH - _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_INVALIDATE); + _HandleOuterCache(Os, Physical, Logical, Bytes, gcvCACHE_INVALIDATE); #else outer_inv_range((unsigned long) Handle, (unsigned long) Handle + Bytes); #endif @@ -6391,11 +6000,13 @@ gckOS_CacheFlush( IN gckOS Os, IN gctUINT32 ProcessID, IN gctPHYS_ADDR Handle, - IN gctPOINTER Physical, + IN gctUINT32 Physical, IN gctPOINTER Logical, IN gctSIZE_T Bytes ) { + gcsPLATFORM * platform; + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu", Os, ProcessID, Handle, Logical, Bytes); @@ -6404,6 +6015,25 @@ gckOS_CacheFlush( gcmkVERIFY_ARGUMENT(Logical != gcvNULL); gcmkVERIFY_ARGUMENT(Bytes > 0); + platform = Os->device->platform; + + if (platform && platform->ops->cache) + { + platform->ops->cache( + platform, + ProcessID, + Handle, + Physical, + Logical, + Bytes, + gcvCACHE_FLUSH + ); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + #if !gcdCACHE_FUNCTION_UNIMPLEMENTED #ifdef CONFIG_ARM /* Inner cache. */ @@ -6412,7 +6042,7 @@ gckOS_CacheFlush( #if defined(CONFIG_OUTER_CACHE) /* Outer cache. */ #if gcdENABLE_OUTER_CACHE_PATCH - _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_FLUSH); + _HandleOuterCache(Os, Physical, Logical, Bytes, gcvCACHE_FLUSH); #else outer_flush_range((unsigned long) Handle, (unsigned long) Handle + Bytes); #endif @@ -6515,7 +6145,7 @@ gckOS_Broadcast( /* Put GPU IDLE. */ gcmkONERROR( gckHARDWARE_SetPowerManagementState(Hardware, -#if gcdPOWER_SUSNPEND_WHEN_IDLE +#if gcdPOWER_SUSPEND_WHEN_IDLE gcvPOWER_SUSPEND_BROADCAST)); #else gcvPOWER_IDLE_BROADCAST)); @@ -6544,9 +6174,6 @@ gckOS_Broadcast( case gcvBROADCAST_GPU_STUCK: gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n"); -#if !gcdENABLE_RECOVERY - gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware)); -#endif gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel)); break; @@ -6555,6 +6182,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. */ @@ -6944,7 +6589,7 @@ gckOS_GetThreadID( ** gckOS Os ** Pointer to a gckOS object. ** -** gckCORE Core +** gceCORE Core ** GPU whose power is set. ** ** gctBOOL Clock @@ -6965,172 +6610,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,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - int ret; -#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; - } - else - { -#endif - oldClockState = Os->device->kernels[Core]->hardware->clockState; - oldPowerState = Os->device->kernels[Core]->hardware->powerState; -#if gcdENABLE_VG - } -#endif - } - if((Power == gcvTRUE) && (oldPowerState == gcvFALSE)) - { -#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); + gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power)); } -#else - imx_gpc_power_up_pu(true); -#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; - } - } + Os->powerStates[Core] = Power; } -#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 (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]); } -#endif - if((Power == gcvFALSE) && (oldPowerState == gcvTRUE)) - { -#ifdef CONFIG_PM - pm_runtime_put_sync(Os->device->pmdev); -#endif -#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 + if (powerChange && (Power == gcvFALSE)) + { + if (platform && platform->ops->setPower) + { + gcmkVERIFY_OK(platform->ops->setPower(platform, Core, Power)); + } + + Os->powerStates[Core] = Power; + } - } - /* TODO: Put your code here. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; } @@ -7159,41 +6686,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; } /******************************************************************************* @@ -7656,7 +7163,11 @@ gckOS_Signal( else { /* Set the event to an unsignaled state. */ - reinit_completion(&signal->obj); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0) + reinit_completion(&signal->obj); +#else + INIT_COMPLETION(signal->obj); +#endif } gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex)); @@ -7851,17 +7362,9 @@ gckOS_WaitSignal( else { /* Convert wait to milliseconds. */ -#if gcdDETECT_TIMEOUT - gctINT timeout = (Wait == gcvINFINITE) - ? gcdINFINITE_TIMEOUT * HZ / 1000 - : Wait * HZ / 1000; - - gctUINT complained = 0; -#else - gctINT timeout = (Wait == gcvINFINITE) + long timeout = (Wait == gcvINFINITE) ? MAX_SCHEDULE_TIMEOUT : Wait * HZ / 1000; -#endif DECLARE_WAITQUEUE(wait, current); wait.flags |= WQ_FLAG_EXCLUSIVE; @@ -7892,49 +7395,6 @@ gckOS_WaitSignal( break; } -#if gcdDETECT_TIMEOUT - if ((Wait == gcvINFINITE) && (timeout == 0)) - { - gctUINT32 dmaAddress1, dmaAddress2; - gctUINT32 dmaState1, dmaState2; - - dmaState1 = dmaState2 = - dmaAddress1 = dmaAddress2 = 0; - - /* Verify whether DMA is running. */ - gcmkVERIFY_OK(_VerifyDMA( - Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2 - )); - -#if gcdDETECT_DMA_ADDRESS - /* Dump only if DMA appears stuck. */ - if ( - (dmaAddress1 == dmaAddress2) -#if gcdDETECT_DMA_STATE - && (dmaState1 == dmaState2) -#endif - ) -#endif - { - /* Increment complain count. */ - complained += 1; - - gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR)); - - gcmkPRINT( - "%s(%d): signal 0x%X; forced message flush (%d).", - __FUNCTION__, __LINE__, Signal, complained - ); - - /* Flush the debug cache. */ - gcmkDEBUGFLUSH(dmaAddress2); - } - - /* Reset timeout. */ - timeout = gcdINFINITE_TIMEOUT * HZ / 1000; - } -#endif - if (timeout == 0) { @@ -7944,16 +7404,6 @@ gckOS_WaitSignal( } __remove_wait_queue(&signal->obj.wait, &wait); - -#if gcdDETECT_TIMEOUT - if (complained) - { - gcmkPRINT( - "%s(%d): signal=0x%X; waiting done; status=%d", - __FUNCTION__, __LINE__, Signal, status - ); - } -#endif } spin_unlock_irq(&signal->obj.wait.lock); @@ -8022,17 +7472,17 @@ OnError: /******************************************************************************* ** -** gckOS_UnmapSignal +** gckOS_UnmapSignal ** -** Unmap a signal . +** Unmap a signal . ** -** INPUT: +** INPUT: ** -** gckOS Os -** Pointer to an gckOS object. +** gckOS Os +** Pointer to an gckOS object. ** -** gctSIGNAL Signal -** Pointer to that gctSIGNAL mapped. +** gctSIGNAL Signal +** Pointer to that gctSIGNAL mapped. */ gceSTATUS gckOS_UnmapSignal( @@ -8076,9 +7526,10 @@ gckOS_CreateUserSignal( gctSIZE_T signal; /* Create a new signal. */ - status = gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal); + gcmkONERROR(gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal)); *SignalID = (gctINT) signal; +OnError: return status; } @@ -8191,11 +7642,11 @@ gckOS_CreateSemaphoreVG( do { /* Allocate the semaphore structure. */ - newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN); - if (newSemaphore == gcvNULL) - { - gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY); - } + newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN); + if (newSemaphore == gcvNULL) + { + gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY); + } /* Initialize the semaphore. */ sema_init(newSemaphore, 0); @@ -8592,22 +8043,21 @@ gckOS_StartTimer( timer = (gcsOSTIMER_PTR)Timer; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) + mod_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay)); +#else if (unlikely(delayed_work_pending(&timer->work))) { - if (unlikely(!cancel_delayed_work(&timer->work))) - { - cancel_work_sync(&timer->work.work); - - if (unlikely(delayed_work_pending(&timer->work))) - { - gckOS_Print("gckOS_StartTimer error, the pending worker cannot complete!!!! \n"); - - return gcvSTATUS_INVALID_REQUEST; - } - } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) + cancel_delayed_work_sync(&timer->work); +#else + cancel_delayed_work(&timer->work); + flush_workqueue(Os->workqueue); +#endif } queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay)); +#endif gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -8651,23 +8101,6 @@ gckOS_StopTimer( return gcvSTATUS_OK; } - -gceSTATUS -gckOS_DumpCallStack( - IN gckOS Os - ) -{ - gcmkHEADER_ARG("Os=0x%X", Os); - - gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); - - dump_stack(); - - gcmkFOOTER_NO(); - return gcvSTATUS_OK; -} - - gceSTATUS gckOS_GetProcessNameByPid( IN gctINT Pid, @@ -8696,6 +8129,56 @@ gckOS_GetProcessNameByPid( return gcvSTATUS_OK; } +gceSTATUS +gckOS_DumpCallStack( + IN gckOS Os + ) +{ + gcmkHEADER_ARG("Os=0x%X", Os); + + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + + dump_stack(); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckOS_DetectProcessByName +** +** task->comm maybe part of process name, so this function +** can only be used for debugging. +** +** INPUT: +** +** gctCONST_POINTER Name +** Pointer to a string to hold name to be check. If the length +** of name is longer than TASK_COMM_LEN (16), use part of name +** to detect. +** +** OUTPUT: +** +** gcvSTATUS_TRUE if name of current process matches Name. +** +*/ +gceSTATUS +gckOS_DetectProcessByName( + IN gctCONST_POINTER Name + ) +{ + char comm[sizeof(current->comm)]; + + memset(comm, 0, sizeof(comm)); + + gcmkVERIFY_OK( + gckOS_GetProcessNameByPid(_GetProcessID(), sizeof(current->comm), comm)); + + return strstr(comm, Name) ? gcvSTATUS_TRUE + : gcvSTATUS_FALSE; +} + #if gcdANDROID_NATIVE_FENCE_SYNC gceSTATUS @@ -8834,6 +8317,7 @@ gckOS_SignalSyncPoint( { gceSTATUS status; gcsSYNC_POINT_PTR syncPoint; + struct sync_timeline * timeline; gctBOOL acquired = gcvFALSE; gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint); @@ -8852,18 +8336,21 @@ gckOS_SignalSyncPoint( gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint); - /* Get state. */ - atomic_set(&syncPoint->state, gcvTRUE); + /* Set signaled state. */ + atomic_set(&syncPoint->state, 1); - /* Signal timeline. */ - if (syncPoint->timeline) - { - sync_timeline_signal(syncPoint->timeline); - } + /* Get parent timeline. */ + timeline = syncPoint->timeline; gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex)); acquired = gcvFALSE; + /* Signal timeline. */ + if (timeline) + { + sync_timeline_signal(timeline); + } + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -9031,3 +8518,223 @@ OnError: return status; } #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; + gckALLOCATOR allocator; + + 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; + + allocator = mdl->allocator; + + /* 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) + { + if (allocator) + { + gctUINT32 phys_addr; + allocator->ops->Physical(allocator, mdl, offset, &phys_addr); + phys = (unsigned long)phys_addr; + } + } + 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; +} + +gceSTATUS +gckOS_PhysicalToPhysicalAddress( + IN gckOS Os, + IN gctPOINTER Physical, + OUT gctUINT32 * PhysicalAddress + ) +{ + PLINUX_MDL mdl = (PLINUX_MDL)Physical; + gckALLOCATOR allocator = mdl->allocator; + + if (allocator) + { + return allocator->ops->Physical(allocator, mdl, 0, PhysicalAddress); + } + + return gcvSTATUS_NOT_SUPPORTED; +} + +gceSTATUS +gckOS_QueryOption( + IN gckOS Os, + IN gctCONST_STRING Option, + OUT gctUINT32 * Value + ) +{ + gckGALDEVICE device = Os->device; + + if (!strcmp(Option, "physBase")) + { + *Value = device->physBase; + return gcvSTATUS_OK; + } + else if (!strcmp(Option, "physSize")) + { + *Value = device->physSize; + return gcvSTATUS_OK; + } + else if (!strcmp(Option, "mmu")) + { +#if gcdSECURITY + *Value = 0; +#else + *Value = device->mmu; +#endif + return gcvSTATUS_OK; + } + + return gcvSTATUS_NOT_SUPPORTED; +} + +static int +fd_release( + struct inode *inode, + struct file *file + ) +{ + gcsFDPRIVATE_PTR private = (gcsFDPRIVATE_PTR)file->private_data; + + if (private && private->release) + { + return private->release(private); + } + + return 0; +} + +static const struct file_operations fd_fops = { + .release = fd_release, +}; + +gceSTATUS +gckOS_GetFd( + IN gctSTRING Name, + IN gcsFDPRIVATE_PTR Private, + OUT gctINT *Fd + ) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + *Fd = anon_inode_getfd(Name, &fd_fops, Private, O_RDWR); + + if (*Fd < 0) + { + return gcvSTATUS_OUT_OF_RESOURCES; + } + + return gcvSTATUS_OK; +#else + return gcvSTATUS_NOT_SUPPORTED; +#endif +} + 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 b22081740fdb..9d3126d1d772 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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -36,7 +36,6 @@ typedef struct _LINUX_MDL_MAP * PLINUX_MDL_MAP; typedef struct _LINUX_MDL { - gctINT pid; char * addr; union _pages @@ -62,6 +61,14 @@ typedef struct _LINUX_MDL PLINUX_MDL_MAP maps; struct _LINUX_MDL * prev; struct _LINUX_MDL * next; + + /* Pointer to allocator which allocates memory for this mdl. */ + void * allocator; + + /* Private data used by allocator. */ + void * priv; + + uint gid; } LINUX_MDL, *PLINUX_MDL; 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..23b7178d83ba --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h @@ -0,0 +1,279 @@ +/**************************************************************************** +* +* 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; + gctUINT gpu3DMinClock; +} +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 + ); + + /******************************************************************************* + ** + ** setClock + ** + ** 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 + ** + ** Override Prot flag when mapping paged memory to userspace. + */ + gceSTATUS + (*adjustProt)( + IN struct vm_area_struct * vma + ); + + /******************************************************************************* + ** + ** shrinkMemory + ** + ** Do something to collect memory, eg, act as oom killer. + */ + gceSTATUS + (*shrinkMemory)( + IN gckPLATFORM Platform + ); + + /******************************************************************************* + ** + ** cache + ** + ** Cache operation. + */ + gceSTATUS + (*cache)( + IN gckPLATFORM Platform, + IN gctUINT32 ProcessID, + IN gctPHYS_ADDR Handle, + IN gctUINT32 Physical, + IN gctPOINTER Logical, + IN gctSIZE_T Bytes, + IN gceCACHEOPERATION Operation + ); +} +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 62% 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 3822f37a44e2..054e32e8f6a5 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 @@ -1,7 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. -* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. +* 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 @@ -19,9 +18,10 @@ * *****************************************************************************/ + #include #include -#include + #include "gc_hal_kernel_linux.h" #include "gc_hal_driver.h" @@ -35,71 +35,40 @@ #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 -#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; module_param(major, uint, 0644); +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY +static int irqLine3D0 = -1; +module_param(irqLine3D0, int, 0644); + +static ulong registerMemBase3D0 = 0; +module_param(registerMemBase3D0, ulong, 0644); + +static ulong registerMemSize3D0 = 2 << 10; +module_param(registerMemSize3D0, ulong, 0644); + +static int irqLine3D1 = -1; +module_param(irqLine3D1, int, 0644); + +static ulong registerMemBase3D1 = 0; +module_param(registerMemBase3D1, ulong, 0644); + +static ulong registerMemSize3D1 = 2 << 10; +module_param(registerMemSize3D1, ulong, 0644); +#else static int irqLine = -1; module_param(irqLine, int, 0644); @@ -108,6 +77,7 @@ module_param(registerMemBase, ulong, 0644); static ulong registerMemSize = 2 << 10; module_param(registerMemSize, ulong, 0644); +#endif static int irqLine2D = -1; module_param(irqLine2D, int, 0644); @@ -127,11 +97,10 @@ 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; +#ifndef gcdDEFAULT_CONTIGUOUS_SIZE +#define gcdDEFAULT_CONTIGUOUS_SIZE (4 << 20) #endif +static ulong contiguousSize = gcdDEFAULT_CONTIGUOUS_SIZE; module_param(contiguousSize, ulong, 0644); static ulong contiguousBase = 0; @@ -146,7 +115,7 @@ module_param(fastClear, int, 0644); static int compression = -1; module_param(compression, int, 0644); -static int powerManagement = 1; +static int powerManagement = -1; module_param(powerManagement, int, 0644); static int gpuProfiler = 0; @@ -161,19 +130,27 @@ module_param(baseAddress, ulong, 0644); static ulong physSize = 0; module_param(physSize, ulong, 0644); -static uint logFileSize=0; +static uint logFileSize = 0; module_param(logFileSize,uint, 0644); +static uint recovery = 1; +module_param(recovery, uint, 0644); +MODULE_PARM_DESC(recovery, "Recover GPU from stuck (1: Enable, 0: Disable)"); + +/* Middle needs about 40KB buffer, Maximal may need more than 200KB buffer. */ +static uint stuckDump = 1; +module_param(stuckDump, uint, 0644); +MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle, 3: Maximal)"); + static int showArgs = 0; module_param(showArgs, int, 0644); -int gpu3DMinClock = 0; -module_param(gpu3DMinClock, int, 0644); +static int mmu = 1; +module_param(mmu, int, 0644); -#if ENABLE_GPU_CLOCK_BY_DRIVER - unsigned long coreClock = 156000000; - module_param(coreClock, ulong, 0644); -#endif +static int gpu3DMinClock = 1; + +static int contiguousRequested = 0; static int drv_open( struct inode* inode, @@ -208,29 +185,92 @@ static struct file_operations driver_fops = .mmap = drv_mmap, }; -#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, -}; +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; + gpu3DMinClock = Param->gpu3DMinClock; +} -size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m) +void +gckOS_DumpParam( + void + ) { - gcuDATABASE_INFO info; - unsigned int processid = p->pid; - gckKERNEL gpukernel = m->data; + printk("Galcore options:\n"); +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + printk(" irqLine3D0 = %d\n", irqLine3D0); + printk(" registerMemBase3D0 = 0x%08lX\n", registerMemBase3D0); + printk(" registerMemSize3D0 = 0x%08lX\n", registerMemSize3D0); - /* ignore error happens in this api. */ - if (gckKERNEL_QueryProcessDB(gpukernel, processid, false, gcvDB_VIDEO_MEMORY, &info) != gcvSTATUS_OK) - return 0; + if (irqLine3D1 != -1) + { + printk(" irqLine3D1 = %d\n", irqLine3D1); + printk(" registerMemBase3D1 = 0x%08lX\n", registerMemBase3D1); + printk(" registerMemSize3D1 = 0x%08lX\n", registerMemSize3D1); + } +#else + printk(" irqLine = %d\n", irqLine); + printk(" registerMemBase = 0x%08lX\n", registerMemBase); + printk(" registerMemSize = 0x%08lX\n", registerMemSize); +#endif - /* we return pages. */ - if (info.counters.bytes > 0) - return info.counters.bytes / PAGE_SIZE; - return 0; + if (irqLine2D != -1) + { + printk(" irqLine2D = %d\n", irqLine2D); + printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D); + printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D); + } + + if (irqLineVG != -1) + { + printk(" irqLineVG = %d\n", irqLineVG); + printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG); + printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG); + } + + printk(" contiguousSize = %ld\n", contiguousSize); + printk(" contiguousBase = 0x%08lX\n", contiguousBase); + printk(" bankSize = 0x%08lX\n", bankSize); + printk(" fastClear = %d\n", fastClear); + printk(" compression = %d\n", compression); + printk(" signal = %d\n", signal); + printk(" powerManagement = %d\n", powerManagement); + printk(" baseAddress = 0x%08lX\n", baseAddress); + printk(" physSize = 0x%08lX\n", physSize); + printk(" logFileSize = %d KB \n", logFileSize); + printk(" recovery = %d\n", recovery); + printk(" stuckDump = %d\n", stuckDump); + printk(" gpuProfiler = %d\n", gpuProfiler); } -#endif int drv_open( struct inode* inode, @@ -255,7 +295,7 @@ int drv_open( gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } - data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL); + data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL | __GFP_NOWARN); if (data == gcvNULL) { @@ -285,12 +325,15 @@ int drv_open( if (!galDevice->contiguousMapped) { - gcmkONERROR(gckOS_MapMemory( - galDevice->os, - galDevice->contiguousPhysical, - galDevice->contiguousSize, - &data->contiguousLogical - )); + if (galDevice->contiguousPhysical != gcvNULL) + { + gcmkONERROR(gckOS_MapMemory( + galDevice->os, + galDevice->contiguousPhysical, + galDevice->contiguousSize, + &data->contiguousLogical + )); + } } filp->private_data = data; @@ -429,6 +472,7 @@ long drv_ioctl( gckGALDEVICE device; gcsHAL_PRIVATE_DATA_PTR data; gctINT32 i, count; + gckVIDMEM_NODE nodeObject; gcmkHEADER_ARG( "filp=0x%08X ioctlCode=0x%08X arg=0x%08X", @@ -558,7 +602,7 @@ long drv_ioctl( } else { - if (iface.hardwareType < 0 || iface.hardwareType > 7) + if (iface.hardwareType > 7) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, @@ -595,7 +639,17 @@ long drv_ioctl( if (gcmIS_SUCCESS(status) && (iface.command == gcvHAL_LOCK_VIDEO_MEMORY)) { - gcuVIDMEM_NODE_PTR node = gcmUINT64_TO_PTR(iface.u.LockVideoMemory.node); + gcuVIDMEM_NODE_PTR node; + gctUINT32 processID; + + gckOS_GetProcessID(&processID); + + gcmkONERROR(gckVIDMEM_HANDLE_Lookup(device->kernels[device->coreMapping[iface.hardwareType]], + processID, + (gctUINT32)iface.u.LockVideoMemory.node, + &nodeObject)); + node = nodeObject->node; + /* Special case for mapped memory. */ if ((data->mappedMemory != gcvNULL) && (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) @@ -736,7 +790,6 @@ static int drv_mmap( return 0; } - OnError: gcmkFOOTER(); return -ENOTTY; @@ -746,7 +799,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; @@ -755,104 +808,49 @@ static int drv_init(struct device *pdev) gckGALDEVICE device = gcvNULL; struct class* device_class = gcvNULL; - 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); + gcsDEVICE_CONSTRUCT_ARGS args = { + .recovery = recovery, + .stuckDump = stuckDump, + .gpu3DMinClock = gpu3DMinClock, + .contiguousRequested = contiguousRequested, + .platform = &platform, + .mmu = mmu, + }; -#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) - gc_pwr(1); -# endif -# endif - } -#endif + gcmkHEADER(); printk(KERN_INFO "Galcore version %d.%d.%d.%d\n", gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD); + +#if !VIVANTE_PROFILER_PM /* when enable gpu profiler, we need to turn off gpu powerMangement */ - if(gpuProfiler) + if (gpuProfiler) + { powerManagement = 0; + } +#endif + if (showArgs) { - printk("galcore options:\n"); - printk(" irqLine = %d\n", irqLine); - printk(" registerMemBase = 0x%08lX\n", registerMemBase); - printk(" registerMemSize = 0x%08lX\n", registerMemSize); - - if (irqLine2D != -1) - { - printk(" irqLine2D = %d\n", irqLine2D); - printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D); - printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D); - } - - if (irqLineVG != -1) - { - printk(" irqLineVG = %d\n", irqLineVG); - printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG); - printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG); - } - - printk(" contiguousSize = %ld\n", contiguousSize); - printk(" contiguousBase = 0x%08lX\n", contiguousBase); - printk(" bankSize = 0x%08lX\n", bankSize); - printk(" fastClear = %d\n", fastClear); - printk(" compression = %d\n", compression); - printk(" signal = %d\n", signal); - printk(" baseAddress = 0x%08lX\n", baseAddress); - printk(" physSize = 0x%08lX\n", physSize); - printk(" logFileSize = %d KB \n", logFileSize); - printk(" powerManagement = %d\n", powerManagement); - printk(" gpuProfiler = %d\n", gpuProfiler); -#if ENABLE_GPU_CLOCK_BY_DRIVER - printk(" coreClock = %lu\n", coreClock); -#endif + gckOS_DumpParam(); } - if(logFileSize != 0) + if (logFileSize != 0) { - gckDebugFileSystemInitialize(); + gckDEBUGFS_Initialize(); } /* Create the GAL device. */ - gcmkONERROR(gckGALDEVICE_Construct( + status = gckGALDEVICE_Construct( +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + irqLine3D0, + registerMemBase3D0, registerMemSize3D0, + irqLine3D1, + registerMemBase3D1, registerMemSize3D1, +#else irqLine, registerMemBase, registerMemSize, +#endif irqLine2D, registerMemBase2D, registerMemSize2D, irqLineVG, @@ -860,15 +858,20 @@ static int drv_init(struct device *pdev) contiguousBase, contiguousSize, bankSize, fastClear, compression, baseAddress, physSize, signal, logFileSize, - pdev, powerManagement, gpuProfiler, + &args, &device - )); + ); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - device->pool = dev_get_drvdata(pdev); -#endif + if (gcmIS_ERROR(status)) + { + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER, + "%s(%d): Failed to create the GAL device: status=%d\n", + __FUNCTION__, __LINE__, status); + + goto OnError; + } /* Start the GAL device. */ gcmkONERROR(gckGALDEVICE_Start(device)); @@ -877,31 +880,12 @@ 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); - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, - "Enable new MMU: status=%d\n", status); - - if ((device->kernels[gcvCORE_2D] != gcvNULL) - && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0)) - { - status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize); - gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, - "Enable new MMU for 2D: status=%d\n", status); - } - /* 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, DRV_NAME, &driver_fops); + ret = register_chrdev(major, DEVICE_NAME, &driver_fops); if (ret < 0) { @@ -934,20 +918,29 @@ static int drv_init(struct device *pdev) } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) - device_create(device_class, NULL, MKDEV(major, 0), NULL, "galcore"); + device_create(device_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); #else - device_create(device_class, NULL, MKDEV(major, 0), "galcore"); + device_create(device_class, NULL, MKDEV(major, 0), DEVICE_NAME); #endif galDevice = device; gpuClass = device_class; +#if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_DRIVER, + "%s(%d): irqLine3D0=%d, contiguousSize=%lu, memBase3D0=0x%lX\n", + __FUNCTION__, __LINE__, + irqLine3D0, contiguousSize, registerMemBase3D0 + ); +#else gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_DRIVER, "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n", __FUNCTION__, __LINE__, irqLine, contiguousSize, registerMemBase ); +#endif /* Success. */ gcmkFOOTER_NO(); @@ -979,38 +972,19 @@ 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, DRV_NAME); + unregister_chrdev(major, DEVICE_NAME); gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice)); gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice)); - if(gckDebugFileSystemIsEnabled()) - { - gckDebugFileSystemTerminate(); - } - -#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + if(gckDEBUGFS_IsEnabled()) { -# 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 + gckDEBUGFS_Terminate(); } -#endif gcmkFOOTER_NO(); } @@ -1020,40 +994,6 @@ static void drv_exit(void) module_exit(drv_exit); #else -#ifdef CONFIG_DOVE_GPU -# define DEVICE_NAME "dove_gpu" -#else -# define DEVICE_NAME "galcore" -#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 = 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 @@ -1061,114 +1001,68 @@ 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 - gcmkHEADER(); + .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, + .gpu3DMinClock = gpu3DMinClock, + }; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr"); - if (res) - baseAddress = res->start; + gcmkHEADER(); - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d"); - if (res) - irqLine = res->start; + platform.device = pdev; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d"); - if (res) + if (platform.ops->getPower) { - registerMemBase = res->start; - registerMemSize = res->end - res->start + 1; + if (gcmIS_ERROR(platform.ops->getPower(&platform))) + { + gcmkFOOTER_NO(); + return ret; + } } - 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) + if (platform.ops->adjustParam) { - registerMemBase2D = res->start; - registerMemSize2D = res->end - res->start + 1; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg"); - if (res) - irqLineVG = res->start; + /* Override default module param. */ + platform.ops->adjustParam(&platform, &moduleParam); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg"); - if (res) - { - registerMemBaseVG = res->start; - registerMemSizeVG = res->end - res->start + 1; + /* Update module param because drv_init() uses them directly. */ + _UpdateModuleParam(&moduleParam); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL); - if (!pool) - return -ENOMEM; - 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); + ret = drv_init(); if (!ret) { -#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; - - rstc = devm_reset_control_get(&pdev->dev, "gpu2d"); - galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc; - - rstc = devm_reset_control_get(&pdev->dev, "gpuvg"); - galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc; -#endif platform_set_drvdata(pdev, galDevice); -#if gcdENABLE_FSCALE_VAL_ADJUST - if (galDevice->kernels[gcvCORE_MAJOR]) - REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier); -#endif gcmkFOOTER_NO(); 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; } @@ -1179,20 +1073,15 @@ 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 + drv_exit(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - 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; } @@ -1205,6 +1094,11 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state) device = platform_get_drvdata(dev); + if (!device) + { + return -1; + } + for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->kernels[i] != gcvNULL) @@ -1236,6 +1130,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; @@ -1256,6 +1151,11 @@ static int gpu_resume(struct platform_device *dev) device = platform_get_drvdata(dev); + if (!device) + { + return -1; + } + for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->kernels[i] != gcvNULL) @@ -1294,14 +1194,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 { @@ -1318,47 +1218,24 @@ 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,10,0) - release_bus_freq(BUS_FREQ_HIGH); -#endif - return 0; -} - -static int gpu_runtime_resume(struct device *dev) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) - request_bus_freq(BUS_FREQ_HIGH); -#endif - return 0; -} - +#if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) +#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, @@ -1373,72 +1250,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 +#if defined(CONFIG_PM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) + .pm = &gpu_pm_ops, #endif } }; -#if 0 /*CONFIG_DOVE_GPU*/ -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; - - gpu_resources[1].start = registerMemBase; - gpu_resources[1].end = registerMemBase + registerMemSize - 1; + memset(&platform, 0, sizeof(gcsPLATFORM)); - gpu_resources[2].start = contiguousBase; - gpu_resources[2].end = contiguousBase + contiguousSize - 1; + gckPLATFORM_QueryOperations(&platform.ops); - /* 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) @@ -1446,11 +1316,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; @@ -1459,9 +1327,18 @@ out: static void __exit gpu_exit(void) { platform_driver_unregister(&gpu_driver); -#if 0 /*ndef CONFIG_DOVE_GPU*/ - platform_device_unregister(gpu_device); -#endif + + if (platform.ops->needAddDevice + && platform.ops->needAddDevice(&platform)) + { + platform_device_unregister(platform.device); + } + + if (platform.priv) + { + /* Free platform private data. */ + platform.ops->freePriv(&platform); + } } 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 new file mode 100644 index 000000000000..e745a6f7c199 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c @@ -0,0 +1,385 @@ +/**************************************************************************** +* +* 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 + +#include "tee_client_api.h" + +#define _GC_OBJ_ZONE gcvZONE_OS + +#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; + +typedef struct _gcsSecurityChannel { + gckOS os; + TEEC_Session session; + int * virtual; + TEEC_SharedMemory inputBuffer; + gctUINT32 bytes; + gctPOINTER mutex; +} gcsSecurityChannel; + +TEEC_SharedMemory * +gpu3d_allocate_secure_mem( + gckOS Os, + unsigned int size + ) +{ + TEEC_Result result; + TEEC_Context *context = &teecContext; + TEEC_SharedMemory *shm = NULL; + void *handle = NULL; + unsigned int phyAddr = 0xFFFFFFFF; + gceSTATUS status; + gctSIZE_T bytes = size; + + shm = kmalloc(sizeof(TEEC_SharedMemory), GFP_KERNEL); + + if (NULL == shm) + { + return NULL; + } + + memset(shm, 0, sizeof(TEEC_SharedMemory)); + + status = gckOS_AllocatePagedMemoryEx( + Os, + gcvALLOC_FLAG_SECURITY, + bytes, + gcvNULL, + (gctPHYS_ADDR *)&handle); + + if (gcmIS_ERROR(status)) + { + kfree(shm); + return NULL; + } + + status = gckOS_PhysicalToPhysicalAddress( + Os, + handle, + &phyAddr); + + if (gcmIS_ERROR(status)) + { + kfree(shm); + return NULL; + } + + /* record the handle into shm->user_data */ + shm->userdata = handle; + + /* [b] Bulk input buffer. */ + shm->size = size; + shm->flags = TEEC_MEM_INPUT; + + /* Use TEE Client API to register the underlying memory buffer. */ + shm->phyAddr = (void *)phyAddr; + + result = TEEC_RegisterSharedMemory( + context, + shm); + + if (result != TEEC_SUCCESS) + { + gckOS_FreePagedMemory(Os, (gctPHYS_ADDR)handle, shm->size); + kfree(shm); + return NULL; + } + + return shm; +} + +void gpu3d_release_secure_mem( + gckOS Os, + void *shm_handle + ) +{ + TEEC_SharedMemory *shm = shm_handle; + void * handle; + + if (!shm) + { + return; + } + + handle = shm->userdata; + + TEEC_ReleaseSharedMemory(shm); + gckOS_FreePagedMemory(Os, (gctPHYS_ADDR)handle, shm->size); + + kfree(shm); + + return; +} + +static TEEC_Result gpu3d_session_callback( + TEEC_Session* session, + uint32_t commandID, + TEEC_Operation* operation, + void* userdata + ) +{ + gcsSecurityChannel *channel = userdata; + + if (channel == gcvNULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + switch(commandID) + { + case gcvTA_CALLBACK_ALLOC_SECURE_MEM: + { + uint32_t size = operation->params[0].value.a; + TEEC_SharedMemory *shm = NULL; + + shm = gpu3d_allocate_secure_mem(channel->os, size); + + /* use the value to save the pointer in client side */ + operation->params[0].value.a = (uint32_t)shm; + operation->params[0].value.b = (uint32_t)shm->phyAddr; + + break; + } + case gcvTA_CALLBACK_FREE_SECURE_MEM: + { + TEEC_SharedMemory *shm = (TEEC_SharedMemory *)operation->params[0].value.a; + + gpu3d_release_secure_mem(channel->os, shm); + break; + } + default: + break; + } + + return TEEC_SUCCESS; +} + +gceSTATUS +gckOS_OpenSecurityChannel( + IN gckOS Os, + IN gceCORE GPU, + OUT gctUINT32 *Channel + ) +{ + gceSTATUS status; + TEEC_Result result; + static bool initialized = gcvFALSE; + gcsSecurityChannel *channel = gcvNULL; + + TEEC_Operation operation = {0}; + + /* Connect to TEE. */ + if (initialized == gcvFALSE) + { + result = TEEC_InitializeContext(NULL, &teecContext); + + if (result != TEEC_SUCCESS) { + gcmkONERROR(gcvSTATUS_CHIP_NOT_READY); + } + + initialized = gcvTRUE; + } + + /* Construct channel. */ + gcmkONERROR( + gckOS_Allocate(Os, gcmSIZEOF(*channel), (gctPOINTER *)&channel)); + + gckOS_ZeroMemory(channel, gcmSIZEOF(gcsSecurityChannel)); + + channel->os = Os; + + gcmkONERROR(gckOS_CreateMutex(Os, &channel->mutex)); + + /* Allocate shared memory for passing gcTA_INTERFACE. */ + channel->bytes = gcmSIZEOF(gcsTA_INTERFACE); + channel->virtual = kmalloc(channel->bytes, GFP_KERNEL | __GFP_NOWARN); + + if (!channel->virtual) + { + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); + } + + channel->inputBuffer.size = channel->bytes; + channel->inputBuffer.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; + channel->inputBuffer.phyAddr = (void *)virt_to_phys(channel->virtual); + + result = TEEC_RegisterSharedMemory(&teecContext, &channel->inputBuffer); + + if (result != TEEC_SUCCESS) + { + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); + } + + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_NONE, + TEEC_NONE); + + operation.params[0].value.a = GPU; + + /* Open session with TEE application. */ + result = TEEC_OpenSession( + &teecContext, + &channel->session, + &gpu3d_uuid, + TEEC_LOGIN_USER, + NULL, + &operation, + NULL); + + /* Prepare callback. */ + TEEC_RegisterCallback(&channel->session, gpu3d_session_callback, channel); + + *Channel = (gctUINT32)channel; + + return gcvSTATUS_OK; + +OnError: + if (channel) + { + if (channel->virtual) + { + } + + if (channel->mutex) + { + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, channel->mutex)); + } + + gcmkVERIFY_OK(gckOS_Free(Os, channel)); + } + + return status; +} + +gceSTATUS +gckOS_CloseSecurityChannel( + IN gctUINT32 Channel + ) +{ + /* TODO . */ + return gcvSTATUS_OK; +} + +gceSTATUS +gckOS_CallSecurityService( + IN gctUINT32 Channel, + IN gcsTA_INTERFACE *Interface + ) +{ + gceSTATUS status; + TEEC_Result result; + gcsSecurityChannel *channel = (gcsSecurityChannel *)Channel; + TEEC_Operation operation = {0}; + + gcmkHEADER(); + gcmkVERIFY_ARGUMENT(Channel != 0); + + gckOS_AcquireMutex(channel->os, channel->mutex, gcvINFINITE); + + gckOS_MemCopy(channel->virtual, Interface, channel->bytes); + + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_MEMREF_PARTIAL_INPUT, + TEEC_NONE, + TEEC_NONE, + TEEC_NONE); + + /* Note: we use the updated size in the MemRef output by the encryption. */ + operation.params[0].memref.parent = &channel->inputBuffer; + operation.params[0].memref.offset = 0; + operation.params[0].memref.size = sizeof(gcsTA_INTERFACE); + operation.started = true; + + /* Start the commit command within the TEE application. */ + result = TEEC_InvokeCommand( + &channel->session, + gcvTA_COMMAND_DISPATCH, + &operation, + NULL); + + gckOS_MemCopy(Interface, channel->virtual, channel->bytes); + + gckOS_ReleaseMutex(channel->os, channel->mutex); + + if (result != TEEC_SUCCESS) + { + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckOS_InitSecurityChannel( + IN gctUINT32 Channel + ) +{ + gceSTATUS status; + TEEC_Result result; + gcsSecurityChannel *channel = (gcsSecurityChannel *)Channel; + TEEC_Operation operation = {0}; + + gcmkHEADER(); + gcmkVERIFY_ARGUMENT(Channel != 0); + + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_MEMREF_PARTIAL_INPUT, + TEEC_NONE, + TEEC_NONE, + TEEC_NONE); + + /* Note: we use the updated size in the MemRef output by the encryption. */ + operation.params[0].memref.parent = &channel->inputBuffer; + operation.params[0].memref.offset = 0; + operation.params[0].memref.size = gcmSIZEOF(gcsTA_INTERFACE); + operation.started = true; + + /* Start the commit command within the TEE application. */ + result = TEEC_InvokeCommand( + &channel->session, + gcvTA_COMMAND_INIT, + &operation, + NULL); + + if (result != TEEC_SUCCESS) + { + gcmkONERROR(gcvSTATUS_GENERIC_IO); + } + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} 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 7efae1c74bbe..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -19,6 +19,11 @@ *****************************************************************************/ +#include +#include + +#if gcdANDROID_NATIVE_FENCE_SYNC + #include #include #include @@ -29,8 +34,6 @@ #include "gc_hal_kernel_sync.h" -#if gcdANDROID_NATIVE_FENCE_SYNC - static struct sync_pt * viv_sync_pt_dup( struct sync_pt * sync_pt 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 6fc12e5d0832..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 @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2013 by Vivante Corp. +* 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 @@ -24,7 +24,8 @@ #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..b31d06e6af43 --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c @@ -0,0 +1,877 @@ +/**************************************************************************** +* +* 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 +#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 + +static int initgpu3DMinClock = 1; +module_param(initgpu3DMinClock, int, 0644); + +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; + + rcu_read_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); + rcu_read_unlock(); + + 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; + } + + rcu_read_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; + } + rcu_read_unlock(); + 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) + { + force_contiguous_lowmem_shrink(kernel); + } + 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, + }; + +static ssize_t show_gpu3DMinClock(struct device_driver *dev, char *buf) +{ + gctUINT currentf,minf,maxf; + gckGALDEVICE galDevice; + + galDevice = platform_get_drvdata(pdevice); + if(galDevice->kernels[gcvCORE_MAJOR]) + { + gckHARDWARE_GetFscaleValue(galDevice->kernels[gcvCORE_MAJOR]->hardware, + ¤tf, &minf, &maxf); + } + snprintf(buf, PAGE_SIZE, "%d\n", minf); + return strlen(buf); +} + +static ssize_t update_gpu3DMinClock(struct device_driver *dev, const char *buf, size_t count) +{ + + gctINT fields; + gctUINT MinFscaleValue; + gckGALDEVICE galDevice; + + galDevice = platform_get_drvdata(pdevice); + if(galDevice->kernels[gcvCORE_MAJOR]) + { + fields = sscanf(buf, "%d", &MinFscaleValue); + if (fields < 1) + return -EINVAL; + + gckHARDWARE_SetMinFscaleValue(galDevice->kernels[gcvCORE_MAJOR]->hardware,MinFscaleValue); + } + + return count; +} + +static DRIVER_ATTR(gpu3DMinClock, S_IRUGO | S_IWUSR, show_gpu3DMinClock, update_gpu3DMinClock); +#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,14,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + /*Power management.*/ + struct regulator *gpu_regulator; +#endif +#endif + /*Run time pm*/ + struct device *pmdev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + 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) +#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) + Args->contiguousBase = 0; +#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 "); + + Args->gpu3DMinClock = initgpu3DMinClock; + + 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 + ) +{ +#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); + { + int ret = 0; + ret = driver_create_file(pdevice->dev.driver, &driver_attr_gpu3DMinClock); + if(ret) + dev_err(&pdevice->dev, "create gpu3DMinClock attr failed (%d)\n", ret); + } +#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); + + driver_remove_file(pdevice->dev.driver, &driver_attr_gpu3DMinClock); +#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) +{ + return 0; +} + +static int gpu_runtime_resume(struct device *dev) +{ + 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; +} + diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config new file mode 100644 index 000000000000..6575148b596e --- /dev/null +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.config @@ -0,0 +1,15 @@ +EXTRA_CFLAGS += -DgcdDEFAULT_CONTIGUOUS_SIZE=134217728 + +ifneq ($(CONFIG_ANDROID),) +# build for android +EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=3 + +ifeq ($(CONFIG_SYNC),) +$(warn CONFIG_SYNC is not set in kernel config) +$(warn Android native fence sync needs CONFIG_SYNC) +endif +endif + +EXTRA_CFLAGS += -DLINUX_CMA_FSL=1 +ALLOCATOR_ARRAY_H_LOCATION := $(OS_KERNEL_DIR)/allocator/freescale +CUSTOMER_ALLOCATOR_OBJS := $(ALLOCATOR_ARRAY_H_LOCATION)/gc_hal_kernel_allocator_cma.o