diff options
123 files changed, 3897 insertions, 1874 deletions
diff --git a/drivers/gpu/mali/Kconfig b/drivers/gpu/mali/Kconfig index 0781bcbd854..bc2cc660bc3 100644 --- a/drivers/gpu/mali/Kconfig +++ b/drivers/gpu/mali/Kconfig @@ -13,3 +13,10 @@ config GPU_MALI_DEBUG ---help--- This enables debug prints in the mali device driver. Debug mode must be enabled in order to use the intrumentation feature of the mali libraries. + +config MALI_DRM + boolean "DRM driver for Mali" + default n + depends on GPU_MALI + ---help--- + This enables the DRM driver for Mali GPU. diff --git a/drivers/gpu/mali/Makefile b/drivers/gpu/mali/Makefile index 93c95aca19a..698dcb0e590 100644 --- a/drivers/gpu/mali/Makefile +++ b/drivers/gpu/mali/Makefile @@ -3,7 +3,7 @@ MALIDRM_SUBFOLDER := mali400ko/x11/mali_drm/mali MALI_FOLDER := $(srctree)/$(src)/$(MALI_SUBFOLDER) ifeq ($(shell [ -d $(MALI_FOLDER) ] && echo "OK"), OK) obj-$(CONFIG_GPU_MALI) += $(MALI_SUBFOLDER)/ -obj-y += $(MALIDRM_SUBFOLDER)/ +obj-$(CONFIG_MALI_DRM) += $(MALIDRM_SUBFOLDER)/ else $(warning WARNING: mali: Could not find $(MALI_FOLDER) - mali device driver will not be built) obj-n += ./ diff --git a/drivers/gpu/mali/mali400ko/.gitignore b/drivers/gpu/mali/mali400ko/.gitignore deleted file mode 100644 index e2d66d55882..00000000000 --- a/drivers/gpu/mali/mali400ko/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -#symlinks created during build -driver/src/devicedrv/mali/arch -driver/bin -driver/devdrv -driver/lib - -#build output -driver/build -.tmp_versions -*.cmd -*.o -*.d -driver/src/devicedrv/linux/__mali_build_info.* -driver/src/devicedrv/linux/modules.order -driver/src/devicedrv/linux/Module.symvers -driver/src/devicedrv/mali/Module.symvers -driver/src/devicedrv/mali/__malidrv_build_info.c -driver/src/devicedrv/mali/mali.ko -driver/src/devicedrv/mali/mali.mod.c -driver/src/devicedrv/mali/modules.order -driver/out* -driver/src/shared/essl_compiler/src/shadergen_maligp2/shader_pieces.* - -out -kernel - -#temp files from editors and Eclipse project files -*~ -.cproject -.project -.settings - diff --git a/drivers/gpu/mali/mali400ko/Makefile b/drivers/gpu/mali/mali400ko/Makefile index 9176f9f3795..f61981f68fc 100644 --- a/drivers/gpu/mali/mali400ko/Makefile +++ b/drivers/gpu/mali/mali400ko/Makefile @@ -1,6 +1,5 @@ #This Makefile can be called to do an out-of-kernel build of tha mali kernel module. #It is not used when mali is built from the kernel build system. - CROSS_COMPILE ?= arm-eabi- ifeq ($(TARGET_PRODUCT),ste_u5500) @@ -8,6 +7,7 @@ CONFIG_UX500_SOC_DB5500=y export CONFIG_UX500_SOC_DB5500 endif + PWD:=$(shell pwd) #if KERNEL_BUILD_DIR parameter is not set, assume there is a symlink to the kernel diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild new file mode 100644 index 00000000000..e90137714d2 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild @@ -0,0 +1,272 @@ +# +# Copyright (C) 2010-2012 ARM Limited. All rights reserved. +# +# This program is free software and is provided to you under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. +# +# A copy of the licence is included with the program, and can also be obtained from Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +# This file is called by the Linux build system. + +OSKOS=linux +FILES_PREFIX= + +# Get path to driver source from Linux build system +DRIVER_DIR=$(srctree)/$(src) + +include $(DRIVER_DIR)/Makefile.platform + +# set up defaults if not defined by the user +USING_UMP ?= 0 +USING_HWMEM ?= 0 +USING_OS_MEMORY ?= 0 +USING_MALI_PMU ?= 0 +USING_PMM ?= 1 +USING_GPU_UTILIZATION ?= 0 +USING_MALI_RUN_TIME_PM ?= 1 +USING_MALI_PMM_TESTSUITE ?= 0 +OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6 +USING_PROFILING ?= 1 +USING_INTERNAL_PROFILING ?= 0 +DISABLE_PP0 ?= 0 +DISABLE_PP1 ?= 0 +DISABLE_PP2 ?= 0 +DISABLE_PP3 ?= 0 +TIMESTAMP ?= default +BUILD ?= debug +TARGET_PLATFORM ?= default +KERNEL_RUNTIME_PM_ENABLED ?= 0 +CONFIG ?= pb-virtex5-m200 + +MALI_RELEASE_NAME=$(shell cat $(DRIVER_DIR)/.version 2> /dev/null) +include $(DRIVER_DIR)/Makefile.common + +# Validate selected config +ifneq ($(shell [ -d $(DRIVER_DIR)/arch-$(CONFIG) ] && [ -f $(DRIVER_DIR)/arch-$(CONFIG)/config.h ] && echo "OK"), OK) +$(warning Current directory is $(shell pwd)) +$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists) +else +# Link arch to the selected arch-config directory +$(shell [ -L $(DRIVER_DIR)/arch ] && rm $(DRIVER_DIR)/arch) +$(shell ln -sf arch-$(CONFIG) $(DRIVER_DIR)/arch) +$(shell touch $(DRIVER_DIR)/arch/config.h) +endif + +# Set up our defines, which will be passed to gcc +DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY) +DEFINES += -DUSING_MMU=1 +DEFINES += -DUSING_UMP=$(USING_UMP) +DEFINES += -DUSING_HWMEM=$(USING_HWMEM) +DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP +DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) +DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING) +DEFINES += -DDISABLE_PP0=$(DISABLE_PP0) +DEFINES += -DDISABLE_PP1=$(DISABLE_PP1) +DEFINES += -DDISABLE_PP2=$(DISABLE_PP2) +DEFINES += -DDISABLE_PP3=$(DISABLE_PP3) +DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) +ifeq ($(shell test $(SUBLEVEL) -gt 32 -a $(PATCHLEVEL) = 6 -a $(VERSION) = 2 -o $(VERSION) -gt 2 && echo "OK"),OK) +# MALI_STATE_TRACKING is only supported on Linux kernels from version 2.6.32. +DEFINES += -DMALI_STATE_TRACKING=1 +else +DEFINES += -DMALI_STATE_TRACKING=0 +endif +DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) + +MALI_PLATFORM_FILE = platform/$(TARGET_PLATFORM)/mali_platform.c + +DEFINES += -DUSING_MALI_PMM=$(USING_PMM) +DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), PMU),0) + USING_MALI_PMU = 1 +endif + +ifeq ($(USING_MALI_RUN_TIME_PM),1) +ifdef CONFIG_PM +ifdef CONFIG_PM_RUNTIME + KERNEL_RUNTIME_PM_ENABLED = 1 +endif +endif +endif + +DEFINES += -DUSING_MALI_PMU=$(USING_MALI_PMU) +DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED) + +ifeq ($(BUILD), debug) +DEFINES += -DDEBUG +endif +DEFINES += -DSVN_REV=$(SVN_REV) +DEFINES += -DSVN_REV_STRING=\"$(SVN_REV)\" + +# Linux has its own mmap cleanup handlers (see mali_kernel_mem_mmu.c) +DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP + +ifeq ($(USING_UMP),1) + DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 + ccflags-y += -I$(DRIVER_DIR)/../../ump/include/ump +else + DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 +endif + +# Use our defines when compiling +ccflags-y += $(DEFINES) -I$(DRIVER_DIR) -I$(DRIVER_DIR)/common -I$(DRIVER_DIR)/linux -I$(DRIVER_DIR)/platform + +# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases: +# The ARM proprietary product will only include the license/proprietary directory +# The GPL product will only include the license/gpl directory + +ifeq ($(wildcard $(DRIVER_DIR)/linux/license/gpl/*),) +ccflags-y += -I$(DRIVER_DIR)/linux/license/proprietary +else +ccflags-y += -I$(DRIVER_DIR)/linux/license/gpl +endif +ccflags-y += -I$(DRIVER_DIR)/common/pmm + +# Source files which always are included in a build +SRC = \ + common/mali_kernel_core.c \ + linux/mali_kernel_linux.c \ + $(OSKOS)/mali_osk_indir_mmap.c \ + common/mali_kernel_rendercore.c \ + common/mali_kernel_descriptor_mapping.c \ + common/mali_kernel_vsync.c \ + linux/mali_ukk_vsync.c \ + linux/mali_kernel_sysfs.c \ + common/mali_kernel_mem_mmu.c \ + common/mali_kernel_memory_engine.c \ + common/mali_block_allocator.c \ + common/mali_kernel_mem_os.c \ + $(MALI_PLATFORM_FILE) \ + $(OSKFILES) \ + $(UKKFILES) \ + __malidrv_build_info.c + +# Selecting files to compile by parsing the config file + +# Use Gator profiling by default +ifeq ($(USING_PROFILING),1) +PROFILING_BACKEND_SOURCES = \ + linux/mali_osk_profiling_gator.c +endif + +# If internal profiling is selected, overwrite the PROFILING_BACKEND_SOURCES +# to use it instead. +ifeq ($(USING_INTERNAL_PROFILING),1) +PROFILING_BACKEND_SOURCES = \ + linux/mali_osk_profiling_internal.c \ + timestamp-$(TIMESTAMP)/mali_timestamp.c +ccflags-y += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP) +endif + +# Add the profiling sources +SRC += $(PROFILING_BACKEND_SOURCES) + +ifeq ($(USING_PMM),1) +ifeq ($(USING_MALI_PMU),1) +SRC += \ + common/pmm/mali_pmm_pmu.c +endif +SRC += \ + common/pmm/mali_pmm.c \ + common/pmm/mali_pmm_policy.c \ + common/pmm/mali_pmm_policy_alwayson.c \ + common/pmm/mali_pmm_policy_jobcontrol.c \ + common/pmm/mali_pmm_state.c \ + linux/mali_kernel_pm.c \ + linux/mali_osk_pm.c \ + linux/mali_device_pause_resume.c +endif + +ifeq ($(USING_MALI_PMM_TESTSUITE),1) +ccflags-y += -I$(DRIVER_DIR)/platform/mali_pmu_testing +ifeq ($(USING_MALI_PMU),0) +SRC += \ + platform/mali_pmu_testing/mali_platform_pmu_internal_testing.c +endif +endif + +ifeq ($(USING_GPU_UTILIZATION),1) +SRC += \ + common/mali_kernel_utilization.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400PP),0) + # Mali-400 PP in use + ccflags-y += -DUSING_MALI400 + SRC += common/mali_kernel_MALI200.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400GP),0) + # Mali-400 GP in use + SRC += common/mali_kernel_GP2.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300PP),0) + # Mali-400 PP in use + ccflags-y += -DUSING_MALI400 + SRC += common/mali_kernel_MALI200.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300GP),0) + # Mali-400 GP in use + SRC += common/mali_kernel_GP2.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI200),0) + # Mali200 in use + ccflags-y += -DUSING_MALI200 + SRC += common/mali_kernel_MALI200.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALIGP2),0) + # MaliGP2 in use + SRC += common/mali_kernel_GP2.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400L2),0) + # Mali Level2 cache in use + ccflags-y += -DUSING_MALI400_L2_CACHE + SRC += common/mali_kernel_l2_cache.c +endif + +ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300L2),0) + # Mali Level2 cache in use + ccflags-y += -DUSING_MALI400_L2_CACHE + SRC += common/mali_kernel_l2_cache.c +endif + +ifeq ($(USING_HWMEM),1) + # HWMEM used as backend for UMP api + EXTRA_CFLAGS += -I$(DRIVER_DIR)/../ump/common + SRC += platform/ux500/ump_kernel_api_hwmem.c +endif + +# Tell the Linux build system from which .o file to create the kernel module +obj-$(CONFIG_GPU_MALI) := mali.o +# Tell the Linux build system to enable building of our .c files +mali-y := $(SRC:.c=.o) + +# Extend common version-string +VERSION_STRINGS += BUILD=$(shell echo $(BUILD) | tr a-z A-Z) +VERSION_STRINGS += CPU=$(CPU) +VERSION_STRINGS += USING_UMP=$(USING_UMP) +VERSION_STRINGS += USING_HWMEM=$(USING_HWMEM) +VERSION_STRINGS += USING_PMM=$(USING_PMM) +VERSION_STRINGS += USING_MALI200=$(call submodule_enabled, $(DRIVER_DIR), MALI200) +VERSION_STRINGS += USING_MALI400=$(call submodule_enabled, $(DRIVER_DIR), MALI400) +VERSION_STRINGS += USING_MALI400_L2_CACHE=$(call submodule_enabled, $(DRIVER_DIR), MALI400L2) +VERSION_STRINGS += USING_GP2=$(call submodule_enabled, $(DRIVER_DIR), MALIGP2) +VERSION_STRINGS += KDIR=$(KDIR) +VERSION_STRINGS += MALI_PLATFORM_FILE=$(MALI_PLATFORM_FILE) +VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) +VERSION_STRINGS += USING_PROFILING=$(USING_PROFILING) +VERSION_STRINGS += USING_INTERNAL_PROFILING=$(USING_INTERNAL_PROFILING) +VERSION_STRINGS += USING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) +VERSION_STRINGS += USING_MALI_RUN_TIME_PM=$(USING_MALI_RUN_TIME_PM) + +# Create file with Mali driver configuration +$(DRIVER_DIR)/__malidrv_build_info.c: + @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(DRIVER_DIR)/__malidrv_build_info.c diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile index 20b57359167..db7d1642e0d 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile @@ -8,215 +8,27 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # -OSKOS=linux -FILES_PREFIX= - -ifneq ($(KBUILD_EXTMOD),) -DRIVER_DIR=$(KBUILD_EXTMOD) -else -src?=. -srctree?=. -DRIVER_DIR?=$(srctree)/$(src) -M?=$(DRIVER_DIR) -endif -MALI_RELEASE_NAME=$(shell cat $(DRIVER_DIR)/.version 2> /dev/null) -include $(DRIVER_DIR)/Makefile.platform -include $(DRIVER_DIR)/Makefile.common +# The Makefile sets up "arch" based on the CONFIG, creates the version info +# string and the __malidrv_build_info.c file, and then call the Linux build +# system to actually build the driver. After that point the Kbuild file takes +# over. # set up defaults if not defined by the user ARCH ?= arm -USING_MMU ?= 1 -USING_UMP ?= 0 -USING_HWMEM ?= 0 -USING_OS_MEMORY ?= 0 -USING_PMM ?= 0 -USING_GPU_UTILIZATION ?= 0 -USING_MALI_RUN_TIME_PM ?= 0 -USING_MALI_PMM_TESTSUITE ?= 0 -OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6 -USING_PROFILING ?= 0 -TIMESTAMP ?= default -BUILD ?= debug -TARGET_PLATFORM ?= default - -ifeq ($(USING_UMP),1) -ifneq ($(USING_HWMEM),1) - UMP_SYMVERS_FILE = ../ump/Module.symvers - KBUILD_EXTRA_SYMBOLS = $(KBUILD_EXTMOD)/$(UMP_SYMVERS_FILE) -endif -endif - -# Check if a Mali Core sub module should be enabled, true or false returned -submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2)) -# linux build system integration -ifneq ($(KERNELRELEASE),) -# Inside the kernel build system +OSKOS=linux +FILES_PREFIX= # This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak -include ../../../arm_internal.mak -# Set up our defines, which will be passed to gcc -DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY) -DEFINES += -DUSING_MMU=$(USING_MMU) -DEFINES += -DUSING_UMP=$(USING_UMP) -DEFINES += -DUSING_HWMEM=$(USING_HWMEM) -DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP -DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) -DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) -DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(USING_MALI_RUN_TIME_PM) -DEFINES += -DMALI_STATE_TRACKING=1 -DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB) - -ifneq ($(call submodule_enabled, $M, PMU),0) - MALI_PLATFORM_FILE = platform/mali400-pmu/mali_platform.c -else - MALI_PLATFORM_FILE = platform/$(TARGET_PLATFORM)/mali_platform.c -endif - -DEFINES += -DUSING_MALI_PMM=$(USING_PMM) -DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) - -ifeq ($(BUILD), debug) -DEFINES += -DDEBUG -endif -DEFINES += -DSVN_REV=$(SVN_REV) -DEFINES += -DSVN_REV_STRING=\"$(SVN_REV)\" - -# Linux has its own mmap cleanup handlers (see mali_kernel_mem_mmu.c) -DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP - +ifneq ($(USING_HWMEM),1) ifeq ($(USING_UMP),1) - DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 - EXTRA_CFLAGS += -I$(DRIVER_DIR)/../../../include/ump -else - DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 -endif - -# Use our defines when compiling -EXTRA_CFLAGS += $(DEFINES) -I$(DRIVER_DIR) -I$(DRIVER_DIR)/common -I$(DRIVER_DIR)/linux -I$(DRIVER_DIR)/platform - -# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases: -# The ARM proprietary product will only include the license/proprietary directory -# The GPL product will only include the license/gpl directory - -ifeq ($(wildcard $(DRIVER_DIR)/linux/license/gpl/*),) -EXTRA_CFLAGS += -I$(DRIVER_DIR)/linux/license/proprietary -else -EXTRA_CFLAGS += -I$(DRIVER_DIR)/linux/license/gpl -endif -EXTRA_CFLAGS += -I$(DRIVER_DIR)/common/pmm - -# Source files which always are included in a build -SRC = \ - common/mali_kernel_core.c \ - linux/mali_kernel_linux.c \ - $(OSKOS)/mali_osk_indir_mmap.c \ - common/mali_kernel_rendercore.c \ - common/mali_kernel_descriptor_mapping.c \ - common/mali_kernel_vsync.c \ - linux/mali_ukk_vsync.c \ - $(MALI_PLATFORM_FILE) \ - $(OSKFILES) \ - $(UKKFILES) - #__malidrv_build_info.c - -ifeq ($(USING_PROFILING),1) -SRC += \ - common/mali_kernel_profiling.c \ - timestamp-$(TIMESTAMP)/mali_timestamp.c -EXTRA_CFLAGS += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP) -endif - -# Selecting files to compile by parsing the config file - -ifeq ($(USING_PMM),1) -SRC += \ - common/pmm/mali_pmm.c \ - common/pmm/mali_pmm_policy.c \ - common/pmm/mali_pmm_policy_alwayson.c \ - common/pmm/mali_pmm_policy_jobcontrol.c \ - common/pmm/mali_pmm_state.c \ - linux/mali_kernel_pm.c \ - linux/mali_osk_pm.c \ - linux/mali_device_pause_resume.c -endif - -ifeq ($(USING_GPU_UTILIZATION),1) -SRC += \ - common/mali_kernel_utilization.c -endif - -ifneq ($(call submodule_enabled, $M, MALI400PP),0) - # Mali-400 PP in use - EXTRA_CFLAGS += -DUSING_MALI400 - SRC += common/mali_kernel_MALI200.c -endif - -ifneq ($(call submodule_enabled, $M, MALI400GP),0) - # Mali-400 GP in use - SRC += common/mali_kernel_GP2.c -endif - -ifneq ($(call submodule_enabled, $M, MALI300PP),0) - # Mali-400 PP in use - EXTRA_CFLAGS += -DUSING_MALI400 - SRC += common/mali_kernel_MALI200.c -endif - -ifneq ($(call submodule_enabled, $M, MALI300GP),0) - # Mali-400 GP in use - SRC += common/mali_kernel_GP2.c -endif - -ifneq ($(call submodule_enabled, $M, MALI200),0) - # Mali200 in use - EXTRA_CFLAGS += -DUSING_MALI200 - SRC += common/mali_kernel_MALI200.c -endif - -ifneq ($(call submodule_enabled, $M, MALIGP2),0) - # MaliGP2 in use - SRC += common/mali_kernel_GP2.c -endif - -ifneq ($(call submodule_enabled, $M, MMU),0) - # Mali MMU in use - SRC += common/mali_kernel_mem_mmu.c common/mali_kernel_memory_engine.c common/mali_block_allocator.c common/mali_kernel_mem_os.c -else - # No Mali MMU in use - SRC += common/mali_kernel_mem_buddy.c -endif - -ifneq ($(call submodule_enabled, $M, MALI400L2)$(),0) - # Mali Level2 cache in use - EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE - SRC += common/mali_kernel_l2_cache.c -endif - -ifneq ($(call submodule_enabled, $M, MALI300L2)$(),0) - # Mali Level2 cache in use - EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE - SRC += common/mali_kernel_l2_cache.c + UMP_SYMVERS_FILE = ../ump/Module.symvers + KBUILD_EXTRA_SYMBOLS = $(CURDIR)/$(UMP_SYMVERS_FILE) endif - -ifeq ($(USING_HWMEM),1) - # HWMEM used as backend for UMP api - EXTRA_CFLAGS += -I$(DRIVER_DIR)/../ump/common - SRC += platform/ux500/ump_kernel_api_hwmem.c endif -# Target build file -MODULE:=mali.ko - -# Tell the Linux build system from which .o file to create the kernel module -obj-$(CONFIG_GPU_MALI) := $(MODULE:.ko=.o) -# Tell the Linux build system to enable building of our .c files -$(MODULE:.ko=-y) := $(SRC:.c=.o) - -else -# Outside the kernel build system - # Get any user defined KDIR-<names> or maybe even a hardcoded KDIR -include KDIR_CONFIGURATION @@ -248,99 +60,17 @@ endif ifdef ARM_INTERNAL_BUILD $(warning Config $(CONFIG)) $(warning Host CPU $(CPU)) -$(warning MMU $(USING_MMU)) $(warning OS_MEMORY $(USING_OS_MEMORY)) endif -# Validate selected config -ifneq ($(shell [ -d $(DRIVER_DIR)/arch-$(CONFIG) ] && [ -f $(DRIVER_DIR)/arch-$(CONFIG)/config.h ] && echo "OK"), OK) -$(warning Current directory is $(shell pwd)) -$(error No configuration found for config $(CONFIG). Check that $(DRIVER_DIR)/arch-$(CONFIG)/config.h exists) -else -# Link arch to the selected arch-config directory -$(shell [ -L $(DRIVER_DIR)/arch ] && rm $(DRIVER_DIR)/arch) -$(shell ln -sf $(DRIVER_DIR)/arch-$(CONFIG) $(DRIVER_DIR)/arch) -$(shell touch $(DRIVER_DIR)/arch/config.h) - -# Register number of Mali400 cores for routing test jobs to the right Mali-400 -ifeq ($CONFIG, pb-virtex5-m400-1) -VERSION_STRINGS += USING_MALI400_PP_CORES=1 -endif -ifeq ($CONFIG, pb-virtex5-m400-2) -VERSION_STRINGS += USING_MALI400_PP_CORES=2 -endif -ifeq ($CONFIG, pb-virtex5-m400-3) -VERSION_STRINGS += USING_MALI400_PP_CORES=3 -endif -ifeq ($CONFIG, pb-virtex5-m400-4) -VERSION_STRINGS += USING_MALI400_PP_CORES=4 -endif - -endif - -# Filename to use when patching. Original will be saved as this -PATCH_BACKUP_FILE:=config_makefile_patch_backup.h - -ifdef ARM_INTERNAL_BUILD -$(warning Looking for previous backup) -endif -# Look for previous backup -shell_output:=$(shell [ -f arch/$(PATCH_BACKUP_FILE) ] && mv -vf arch/$(PATCH_BACKUP_FILE) arch/config.h && echo "Patch backup restored") -ifneq ($(shell_output),) -ifdef ARM_INTERNAL_BUILD -$(warning $(shell_output)) -endif -endif - -ifdef PATCH -ifdef ARM_INTERNAL_BUILD -$(warning Patching using: $(PATCH) ) -endif -ifneq ($(shell [ -f arch/$(PATCH).diff ] && echo "OK"), OK) -# The patch file does not exist -shell_output:=$(shell echo "Possible PATCH arguments are:" ; find arch/ -name "*.diff" |sed -r 's/.*\/(.*)\.diff/\1/') -ifdef ARM_INTERNAL_BUILD -$(warning $(shell_output)) -endif -$(error Could not find file arch-$(CONFIG)/$(PATCH).diff ) -else -# Patch file found, do patching -shell_output:=$(shell cp -f arch/config.h arch/$(PATCH_BACKUP_FILE) && patch --no-backup-if-mismatch -st -p0 arch/config.h -i arch/$(PATCH).diff && echo "OK") -ifneq ($(shell_output), OK) -$(warning Output from failed patch: $(shell_output)) -$(shell mv -f arch/$(PATCH_BACKUP_FILE) arch/config.h) -$(error Could not patch file arch-$(CONFIG)/config.h with arch-$(CONFIG)/$(PATCH).diff.) -endif -endif -endif - -# Extend common version-string -VERSION_STRINGS += BUILD=$(shell echo $(BUILD) | tr a-z A-Z) -VERSION_STRINGS += CPU=$(CPU) -VERSION_STRINGS += USING_MMU=$(USING_MMU) -VERSION_STRINGS += USING_UMP=$(USING_UMP) -VERSION_STRINGS += USING_HWMEM=$(USING_HWMEM) -VERSION_STRINGS += USING_PMM=$(USING_PMM) -VERSION_STRINGS += USING_MALI200=$(call submodule_enabled, ., MALI200) -VERSION_STRINGS += USING_MALI400=$(call submodule_enabled, ., MALI400) -VERSION_STRINGS += USING_MALI400_L2_CACHE=$(call submodule_enabled, ., MALI400L2) -VERSION_STRINGS += USING_GP2=$(call submodule_enabled, ., MALIGP2) -VERSION_STRINGS += KDIR=$(KDIR) - -all: make-build-info-file $(UMP_SYMVERS_FILE) +all: $(UMP_SYMVERS_FILE) $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) CONFIG_GPU_MALI=m modules - @([ "$(PATCH)" != "" ] && [ -f arch/$(PATCH_BACKUP_FILE) ] && mv -f arch/$(PATCH_BACKUP_FILE) arch/config.h && echo "Patch backup restored") || echo No Unpatching needed - @rm -f $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o + @rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o clean: $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean - @([ "$(PATCH)" != "" ] && [ -f arch/$(PATCH_BACKUP_FILE) ] && mv -f arch/$(PATCH_BACKUP_FILE) arch/config.h && echo "Patch backup restored") || echo No Unpatching needed - -make-build-info-file: - @echo 'char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(FILES_PREFIX)__malidrv_build_info.c kernelrelease: $(MAKE) -C $(KDIR) kernelrelease -# end of outside kernel build system block -endif +export CONFIG KBUILD_EXTRA_SYMBOLS diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common index ebe3b9e3399..116afb6c75a 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common @@ -8,6 +8,9 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # +# Check if a Mali Core sub module should be enabled, true or false returned +submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2)) + OSKFILES=\ $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.c \ $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.c \ @@ -45,7 +48,7 @@ SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV) endif # Common version-string, will be extended by OS-specifc sections -VERSION_STRINGS = +VERSION_STRINGS := VERSION_STRINGS += CONFIG=$(CONFIG) VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY) VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)common\/mali_uk_types.h | cut -d' ' -f 3 ) diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.platform b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.platform index 1f8068e25de..ed84506163c 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.platform +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.platform @@ -1,8 +1,6 @@ #these are the build options for the ST-Ericsson Ux500 platforms. ifeq ($(CONFIG_UX500_SOC_DB5500),y) -TARGET_PLATFORM = default -USING_GPU_UTILIZATION = 0 DEFINES += -DSOC_DB5500=1 endif @@ -25,21 +23,6 @@ endif KDIR-$(CPU)=$(srctree) -#these are paths relative to the mali400ko/driver/src/devicedrv/mali folder -#not to be confused with the drivers/gpu/mali symlink in the kernel tree EXTRA_CFLAGS += -I$(realpath $(DRIVER_DIR)/../../../include/ump) EXTRA_CFLAGS += -I$(realpath $(DRIVER_DIR)/../ump/common) -#The following is duplicated from the main Makefile to ensure that the 'arch' -#link is created even during an in-kernel build. - -# Validate selected config -ifneq ($(shell [ -d $(DRIVER_DIR)/arch-$(CONFIG) ] && [ -f $(DRIVER_DIR)/arch-$(CONFIG)/config.h ] && echo "OK"), OK) -$(warning Current directory is $(shell pwd)) -$(error No configuration found for config $(CONFIG). Check that $(DRIVER_DIR)/arch-$(CONFIG)/config.h exists) -else -# Link arch to the selected arch-config directory -$(shell [ -L $(DRIVER_DIR)/arch ] && rm $(DRIVER_DIR)/arch) -$(shell ln -sf $(DRIVER_DIR)/arch-$(CONFIG) $(DRIVER_DIR)/arch) -$(shell touch $(DRIVER_DIR)/arch/config.h) -endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h index 5011c97a28c..5d5ef16e304 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h @@ -37,7 +37,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-300 PP", .mmu_id = 2 }, -#if USING_MMU { .type = MMU, .base = 0xC0003000, @@ -52,7 +51,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-300 MMU for PP", .mmu_id = 2 }, -#endif { .type = MEMORY, .description = "Mali SDRAM remapped to baseboard", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h index ee53f49bfe0..58fc5f2207d 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h @@ -37,7 +37,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 PP", .mmu_id = 2 }, -#if USING_MMU { .type = MMU, .base = 0xC0003000, @@ -52,7 +51,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 MMU for PP", .mmu_id = 2 }, -#endif { .type = OS_MEMORY, .description = "OS Memory", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h index 5c7c7f3ef13..d85c0907aa3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h @@ -37,7 +37,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 PP", .mmu_id = 2 }, -#if USING_MMU { .type = MMU, .base = 0xC0003000, @@ -52,7 +51,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 MMU for PP", .mmu_id = 2 }, -#endif { .type = MEMORY, .description = "Mali SDRAM remapped to baseboard", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h index 9f675fd1d23..50393a29e81 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h @@ -29,7 +29,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 PP", .mmu_id = 2 }, -#if USING_MMU { .type = MMU, .base = 0xC0003000, @@ -44,7 +43,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 MMU for PP", .mmu_id = 2 }, -#endif { .type = MEMORY, .description = "Mali SDRAM remapped to baseboard", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h index cc1f05cb5f4..ec4570686d8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h @@ -35,8 +35,7 @@ static _mali_osk_resource_t arch_configuration [] = .irq = -1, .description = "Mali-400 PP 1", .mmu_id = 3 -}, -#if USING_MMU + }, { .type = MMU, .base = 0xC0003000, @@ -58,7 +57,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 MMU for PP 1", .mmu_id = 3 }, -#endif { .type = MEMORY, .description = "Mali SDRAM remapped to baseboard", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h index a672e7d22ef..03d8fae5f51 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h @@ -43,7 +43,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 PP 2", .mmu_id = 4 }, -#if USING_MMU { .type = MMU, .base = 0xC0003000, @@ -72,7 +71,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 MMU for PP 2", .mmu_id = 4 }, -#endif { .type = MEMORY, .description = "Mali SDRAM remapped to baseboard", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h index ae9100c1ae4..71da7974e6d 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h @@ -50,7 +50,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 PP 3", .mmu_id = 5 }, -#if USING_MMU { .type = MMU, .base = 0xC0003000, @@ -86,7 +85,6 @@ static _mali_osk_resource_t arch_configuration [] = .description = "Mali-400 MMU for PP 3", .mmu_id = 5 }, -#endif { .type = MEMORY, .description = "Mali SDRAM remapped to baseboard", diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-ux500/config.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-ux500/config.h index dc324cf0d39..1ee8b184209 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-ux500/config.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/arch-ux500/config.h @@ -1,109 +1,109 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * - * Architecture configuration for ST-Ericsson Ux500 platforms - * - * Author: Magnus Wendt <magnus.wendt@stericsson.com> for - * ST-Ericsson. - * License terms: GNU General Public License (GPL) version 2. - */ - -#ifndef __ARCH_UX500_CONFIG_H__ -#define __ARCH_UX500_CONFIG_H__ - -/* #include <mach/hardware.h> */ - -#define U5500_SGA_BASE 0x801D0000 -#define U8500_SGA_BASE 0xA0300000 - -#if defined(SOC_DB5500) && (1 == SOC_DB5500) -#define UX500_SGA_BASE U5500_SGA_BASE -#else -#define UX500_SGA_BASE U8500_SGA_BASE -#endif - -#define MEGABYTE (1024*1024) -#define MALI_MEM_BASE (128 * MEGABYTE) -#define MALI_MEM_SIZE ( 32 * MEGABYTE) -#define OS_MEM_SIZE (128 * MEGABYTE) - -/* Hardware revision u8500 v1: GX570-BU-00000-r0p1 - * Hardware revision u8500 v2: GX570-BU-00000-r1p0 - * Hardware revision u5500: GX570-BU-00000-r1p0 - * configuration registers: 0xA0300000-0xA031FFFFF (stw8500v1_usermanual p269) - * - * Shared Peripheral Interrupt assignments: (stw8500v1_usermanual p265-266) - * Nb | Interrupt Source - * 116 | Mali400 combined - * 115 | Mali400 geometry processor - * 114 | Mali400 geometry processor MMU - * 113 | Mali400 pixel processor - * 112 | Mali400 pixel processor MMU - * - * irq offset: 32 - */ - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = UX500_SGA_BASE + 0x0000, - .irq = 115+32, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = UX500_SGA_BASE + 0x8000, - .irq = 113+32, - .description = "Mali-400 PP", - .mmu_id = 2 - }, -#if USING_MMU - { - .type = MMU, - .base = UX500_SGA_BASE + 0x3000, - .irq = 114+32, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = UX500_SGA_BASE + 0x4000, - .irq = 112+32, - .description = "Mali-400 MMU for PP", - .mmu_id = 2 - }, -#endif - { - .type = MEMORY, - .description = "Mali SDRAM", - .alloc_order = 0, /* Highest preference for this memory */ - .base = MALI_MEM_BASE, - .size = MALI_MEM_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, -#if USING_OS_MEMORY - { - .type = OS_MEMORY, - .description = "Linux kernel memory", - .alloc_order = 5, /* Medium preference for this memory */ - .size = OS_MEM_SIZE, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE - }, -#endif - { - .type = MEM_VALIDATION, - .description = "Framebuffer", - .base = 0x00000000, /* Validate all memory for now */ - .size = 2047 * MEGABYTE, /* "2GB ought to be enough for anyone" */ - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE - }, - { - .type = MALI400L2, - .base = UX500_SGA_BASE + 0x1000, - .description = "Mali-400 L2 cache" - }, -}; - -#endif /* __ARCH_UX500_CONFIG_H__ */ +/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Architecture configuration for ST-Ericsson Ux500 platforms
+ *
+ * Author: Magnus Wendt <magnus.wendt@stericsson.com> for
+ * ST-Ericsson.
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+
+#ifndef __ARCH_UX500_CONFIG_H__
+#define __ARCH_UX500_CONFIG_H__
+
+/* #include <mach/hardware.h> */
+
+#define U5500_SGA_BASE 0x801D0000
+#define U8500_SGA_BASE 0xA0300000
+
+#if defined(SOC_DB5500) && (1 == SOC_DB5500)
+#define UX500_SGA_BASE U5500_SGA_BASE
+#else
+#define UX500_SGA_BASE U8500_SGA_BASE
+#endif
+
+#define MEGABYTE (1024*1024)
+#define MALI_MEM_BASE (128 * MEGABYTE)
+#define MALI_MEM_SIZE ( 32 * MEGABYTE)
+#define OS_MEM_SIZE (128 * MEGABYTE)
+
+/* Hardware revision u8500 v1: GX570-BU-00000-r0p1
+ * Hardware revision u8500 v2: GX570-BU-00000-r1p0
+ * Hardware revision u5500: GX570-BU-00000-r1p0
+ * configuration registers: 0xA0300000-0xA031FFFFF (stw8500v1_usermanual p269)
+ *
+ * Shared Peripheral Interrupt assignments: (stw8500v1_usermanual p265-266)
+ * Nb | Interrupt Source
+ * 116 | Mali400 combined
+ * 115 | Mali400 geometry processor
+ * 114 | Mali400 geometry processor MMU
+ * 113 | Mali400 pixel processor
+ * 112 | Mali400 pixel processor MMU
+ *
+ * irq offset: 32
+ */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = UX500_SGA_BASE + 0x0000,
+ .irq = 115+32,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = UX500_SGA_BASE + 0x8000,
+ .irq = 113+32,
+ .description = "Mali-400 PP",
+ .mmu_id = 2
+ },
+#if USING_MMU
+ {
+ .type = MMU,
+ .base = UX500_SGA_BASE + 0x3000,
+ .irq = 114+32,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = UX500_SGA_BASE + 0x4000,
+ .irq = 112+32,
+ .description = "Mali-400 MMU for PP",
+ .mmu_id = 2
+ },
+#endif
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM",
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = MALI_MEM_BASE,
+ .size = MALI_MEM_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+#if USING_OS_MEMORY
+ {
+ .type = OS_MEMORY,
+ .description = "Linux kernel memory",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .size = 2047 * MEGABYTE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
+ },
+#endif
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0x00000000, /* Validate all memory for now */
+ .size = 2047 * MEGABYTE, /* "2GB ought to be enough for anyone" */
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = UX500_SGA_BASE + 0x1000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_UX500_CONFIG_H__ */
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c index fc80a20c813..5416ca9ea4d 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c @@ -49,6 +49,7 @@ static void block_allocator_release(void * ctx, void * handle); static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block); static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block ); static void block_allocator_destroy(mali_physical_memory_allocator * allocator); +static u32 block_allocator_stat(mali_physical_memory_allocator * allocator); mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name) { @@ -97,6 +98,7 @@ mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u allocator->allocate = block_allocator_allocate; allocator->allocate_page_table_block = block_allocator_allocate_page_table_block; allocator->destroy = block_allocator_destroy; + allocator->stat = block_allocator_stat; allocator->ctx = info; allocator->name = name; @@ -275,7 +277,8 @@ static void block_allocator_release(void * ctx, void * handle) _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - _mali_osk_free( allocation );} + _mali_osk_free( allocation ); +} static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) @@ -368,3 +371,21 @@ static void block_allocator_release_page_table_block( mali_page_table_block *pag _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); } +static u32 block_allocator_stat(mali_physical_memory_allocator * allocator) +{ + block_allocator * info; + block_info *block; + u32 free_blocks = 0; + + MALI_DEBUG_ASSERT_POINTER(allocator); + + info = (block_allocator*)allocator->ctx; + block = info->first_free; + + while(block) + { + free_blocks++; + block = block->next; + } + return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE; +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h index c3b5761e23a..d3f0f9be60a 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h new file mode 100644 index 00000000000..dee50a359a1 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h @@ -0,0 +1,117 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _CINSTR_PROFILING_EVENTS_M200_H_ +#define _CINSTR_PROFILING_EVENTS_M200_H_ + +/* + * The event ID is a 32 bit value consisting of different fields + * reserved, 4 bits, for future use + * event type, 4 bits, cinstr_profiling_event_type_t + * event channel, 8 bits, the source of the event. + * event data, 16 bit field, data depending on event type + */ + +/** + * Specifies what kind of event this is + */ +typedef enum +{ + MALI_PROFILING_EVENT_TYPE_SINGLE = 0 << 24, + MALI_PROFILING_EVENT_TYPE_START = 1 << 24, + MALI_PROFILING_EVENT_TYPE_STOP = 2 << 24, + MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24, + MALI_PROFILING_EVENT_TYPE_RESUME = 4 << 24, +} cinstr_profiling_event_type_t; + + +/** + * Secifies the channel/source of the event + */ +typedef enum +{ + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE = 0 << 16, + MALI_PROFILING_EVENT_CHANNEL_GP0 = 1 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP0 = 5 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP1 = 6 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP2 = 7 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP3 = 8 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP4 = 9 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP5 = 10 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP6 = 11 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP7 = 12 << 16, + MALI_PROFILING_EVENT_CHANNEL_GPU = 21 << 16, +} cinstr_profiling_event_channel_t; + + +#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16) +#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16) + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME = 1, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH = 2, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS = 3, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4 +} cinstr_profiling_event_reason_single_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1, +} cinstr_profiling_event_reason_start_stop_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT= 27, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC= 28, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33, +} cinstr_profiling_event_reason_suspend_resume_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx) + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT = 1, + MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH = 2, +} cinstr_profiling_event_reason_single_hw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1, +} cinstr_profiling_event_reason_single_gpu_t; + +#endif /*_CINSTR_PROFILING_EVENTS_M200_H_*/ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c index e91abe120cb..dd357dec3b9 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -15,8 +15,8 @@ #include "mali_kernel_rendercore.h" #include "mali_osk.h" #include "mali_osk_list.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" #endif #if defined(USING_MALI400_L2_CACHE) #include "mali_kernel_l2_cache.h" @@ -80,7 +80,7 @@ typedef struct maligp_job u32 perf_counter_l2_val1; #endif -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_TIMELINE_PROFILING_ENABLED u32 pid; u32 tid; #endif @@ -102,7 +102,7 @@ static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resou static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data); #endif #if MALI_STATE_TRACKING -void maligp_subsystem_dump_state(void); +u32 maligp_subsystem_dump_state(char *buf, u32 size); #endif /* Internal support functions */ @@ -583,8 +583,9 @@ static void maligp_initialize_registers_mgmt(mali_core_renderunit *core ) MALI_DEBUG_PRINT(6, ("Mali GP: maligp_initialize_registers_mgmt: %s\n", core->description)) ; for(i=0 ; i< (sizeof(default_mgmt_regs)/sizeof(*default_mgmt_regs)) ; ++i) { - mali_core_renderunit_register_write(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value); + mali_core_renderunit_register_write_relaxed(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value); } + _mali_osk_write_mem_barrier(); } @@ -627,17 +628,43 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_ &(jobgp->user_input.frame_registers[0]), sizeof(jobgp->user_input.frame_registers)/sizeof(jobgp->user_input.frame_registers[0])); +#if MALI_TIMELINE_PROFILING_ENABLED + /* + * If the hardware counters are not turned on, ask the external profiler + * if they should be. + */ + if (jobgp->user_input.perf_counter_flag == 0) + { + mali_bool src0_enabled = _mali_osk_profiling_query_hw_counter(COUNTER_VP_C0, + &(jobgp->user_input.perf_counter_src0)); + mali_bool src1_enabled = _mali_osk_profiling_query_hw_counter(COUNTER_VP_C1, + &(jobgp->user_input.perf_counter_src1)); + + if (src0_enabled == MALI_TRUE) + { + jobgp->user_input.perf_counter_flag |= + _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE; + } + + if (src1_enabled == MALI_TRUE) + { + jobgp->user_input.perf_counter_flag |= + _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE; + } + } +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ + /* This selects which performance counters we are reading */ if ( 0 != jobgp->user_input.perf_counter_flag ) { if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) { - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, jobgp->user_input.perf_counter_src0); - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); @@ -645,12 +672,12 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_ if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) { - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, jobgp->user_input.perf_counter_src1); - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); @@ -689,13 +716,13 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_ jobgp->have_extended_progress_checking = 1; - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED ); - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); @@ -704,14 +731,20 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_ subsystem_flush_mapped_mem_cache(); MALI_DEBUG_PRINT(4, ("Mali GP: STARTING GP WITH CMD: 0x%x\n", startcmd)); +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_started); +#endif /* This is the command that starts the Core */ mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd); + _mali_osk_write_mem_barrier(); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0); +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, + jobgp->user_input.frame_builder_id, jobgp->user_input.flush_id, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0); #endif MALI_SUCCESS; @@ -729,12 +762,16 @@ static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core) irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT); - MALI_DEBUG_PRINT(5, ("Mali GP: IRQ: %04x\n", irq_readout)) ; if ( MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout ) { /* Mask out all IRQs from this core until IRQ is handled */ - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK , MALIGP2_REG_VAL_IRQ_MASK_NONE); + mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); +#endif + /* We do need to handle this in a bottom half, return 1 */ return 1; } @@ -792,15 +829,17 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) if ( 0 != jobgp->is_stalled_waiting_for_more_memory ) { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ -#endif - /* Readback the performance counters */ if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) ) { jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); + +#if MALI_TIMELINE_PROFILING_ENABLED + /* Report the hardware counter values to the external profiler */ + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, jobgp->perf_counter0); + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, jobgp->perf_counter1); +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ } #if defined(USING_MALI400_L2_CACHE) @@ -832,16 +871,19 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) } #endif +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ +#endif + MALI_DEBUG_PRINT(2, ("Mali GP: Job aborted - userspace would not provide more heap memory.\n")); +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/ } /* finished ? */ else if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE)) { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ -#endif - #ifdef DEBUG MALI_DEBUG_PRINT(4, ("Mali GP: Registers On job end:\n")); maligp_print_regs(4, core); @@ -859,6 +901,12 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) { jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); + +#if MALI_TIMELINE_PROFILING_ENABLED + /* Report the hardware counter values to the external profiler */ + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, jobgp->perf_counter0); + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, jobgp->perf_counter1); +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ } #if defined(USING_MALI400_L2_CACHE) @@ -891,8 +939,25 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) #endif } +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), + jobgp->perf_counter0, jobgp->perf_counter1, + jobgp->user_input.perf_counter_src0 | (jobgp->user_input.perf_counter_src1 << 8) +#if defined(USING_MALI400_L2_CACHE) + | (jobgp->user_input.perf_counter_l2_src0 << 16) | (jobgp->user_input.perf_counter_l2_src1 << 24), + jobgp->perf_counter_l2_val0, + jobgp->perf_counter_l2_val1 +#else + ,0, 0 +#endif + ); +#endif + mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif return JOB_STATUS_END_SUCCESS; /* core idle */ } /* sw watchdog timeout handling or time to do hang checking ? */ @@ -910,8 +975,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) { /* no progress detected, killed by the watchdog */ -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ #endif MALI_DEBUG_PRINT(1, ("Mali GP: SW-Timeout. Regs:\n")); @@ -922,6 +987,11 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) #ifdef DEBUG maligp_print_regs(2, core); #endif + +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif + return JOB_STATUS_END_HANG; } /* if hang timeout checking was enabled and we detected progress, will be fall down to this check */ @@ -932,8 +1002,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) _mali_osk_notification_t *notific; _mali_uk_gp_job_suspended_s * suspended_job; -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ #endif session = job->session; @@ -1013,8 +1083,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) /* Else there must be some error */ else { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ #endif MALI_DEBUG_PRINT(1, ("Mali GP: Core crashed? *IRQ: 0x%x Status: 0x%x\n", irq_readout, core_status )); @@ -1022,6 +1092,9 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) MALI_DEBUG_PRINT(1, ("Mali GP: Registers Before reset:\n")); maligp_print_regs(1, core); #endif +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif return JOB_STATUS_END_UNKNOWN_ERR; } } @@ -1032,7 +1105,7 @@ to a created mali_core_job object with the data given from userspace */ static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument) { maligp_job *jobgp; - mali_core_job *job; + mali_core_job *job = NULL; mali_core_job *previous_replaced_job; _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; _mali_uk_gp_start_job_s * user_ptr_job_input; @@ -1071,7 +1144,7 @@ static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_co jobgp->is_stalled_waiting_for_more_memory = 0; -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_TIMELINE_PROFILING_ENABLED jobgp->pid = _mali_osk_get_pid(); jobgp->tid = _mali_osk_get_tid(); #endif @@ -1154,6 +1227,16 @@ function_exit: { _mali_osk_free(jobgp); } +#if MALI_STATE_TRACKING + if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status) + { + if(job) + { + job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received); + } + } +#endif + MALI_ERROR(err); } @@ -1197,12 +1280,13 @@ static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_se mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG)); mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]); + mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]); + mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]); mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC); + _mali_osk_write_mem_barrier(); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); #endif MALI_DEBUG_PRINT(4, ("GP resumed with new heap\n")); @@ -1281,6 +1365,9 @@ static void subsystem_maligp_return_job_to_user( mali_core_job * job, mali_subsy job_out->perf_counter_l2_val1 = jobgp->perf_counter_l2_val1; #endif +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&session->jobs_returned); +#endif _mali_osk_notification_queue_send( session->notification_queue, jobgp->notification_obj); jobgp->notification_obj = NULL; @@ -1411,8 +1498,8 @@ _mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only ) #endif #if MALI_STATE_TRACKING -void maligp_subsystem_dump_state(void) +u32 maligp_subsystem_dump_state(char *buf, u32 size) { - mali_core_renderunit_dump_state(&subsystem_maligp); + return mali_core_renderunit_dump_state(&subsystem_maligp, buf, size); } #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c index 0ac49379bea..d861b2288d3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -15,8 +15,8 @@ #include "mali_kernel_core.h" #include "regs/mali_200_regs.h" #include "mali_kernel_rendercore.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" #endif #ifdef USING_MALI400_L2_CACHE #include "mali_kernel_l2_cache.h" @@ -71,8 +71,8 @@ typedef struct mali200_job u32 perf_counter_l2_val1_raw; #endif -#if MALI_TIMELINE_PROFILING_ENABLED - u32 pid; +#if MALI_TIMELINE_PROFILING_ENABLED + u32 pid; u32 tid; #endif } mali200_job; @@ -94,7 +94,7 @@ static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * reso static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data); #endif #if MALI_STATE_TRACKING -void mali200_subsystem_dump_state(void); +u32 mali200_subsystem_dump_state(char *buf, u32 size); #endif /* Internal support functions */ @@ -572,17 +572,49 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali &(job200->user_input.wb2_registers[0]), MALI200_NUM_REGS_WBx); +#if MALI_TIMELINE_PROFILING_ENABLED + /* + * If the hardware counters are not turned on, ask the external profiler + * if they should be. + */ + if (job200->user_input.perf_counter_flag == 0) + { + /* + * Work out the correct counter offset to use. Each fragment processor + * has two hardware counters. + */ + u32 counter0_offset = MALI_PROFILING_PP_CORE_COUNTER0_OFFSET(core->core_number); + u32 counter1_offset = MALI_PROFILING_PP_CORE_COUNTER1_OFFSET(core->core_number); + + mali_bool src0_enabled = _mali_osk_profiling_query_hw_counter(counter0_offset, + &(job200->user_input.perf_counter_src0)); + mali_bool src1_enabled = _mali_osk_profiling_query_hw_counter(counter1_offset, + &(job200->user_input.perf_counter_src1)); + + if (src0_enabled == MALI_TRUE) + { + job200->user_input.perf_counter_flag |= + _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE; + } + + if (src1_enabled == MALI_TRUE) + { + job200->user_input.perf_counter_flag |= + _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE; + } + } +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ /* This selects which performance counters we are reading */ if ( 0 != job200->user_input.perf_counter_flag ) { if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) { - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, job200->user_input.perf_counter_src0); @@ -591,11 +623,11 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) { - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); - mali_core_renderunit_register_write( + mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, job200->user_input.perf_counter_src1); @@ -630,16 +662,21 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali } subsystem_flush_mapped_mem_cache(); - _mali_osk_mem_barrier(); + +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_started); +#endif /* This is the command that starts the Core */ mali_core_renderunit_register_write( core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING); + _mali_osk_write_mem_barrier(); #if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job200->user_input.frame_builder_id, job200->user_input.flush_id, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid, 0, 0, 0); #endif MALI_SUCCESS; @@ -653,13 +690,17 @@ static u32 subsystem_mali200_irq_handler_upper_half(mali_core_renderunit * core) return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */ } - MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_irq_handler_upper_half: %s\n", core->description)) ; irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS); if ( MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout ) { /* Mask out all IRQs from this core until IRQ is handled */ mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); +#endif + return 1; } return 0; @@ -710,16 +751,24 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES); #endif -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ -#endif - if (0 != job200->user_input.perf_counter_flag ) { if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) ) { +#if MALI_TIMELINE_PROFILING_ENABLED + /* Work out the counter offsets for the core number */ + u32 counter0_offset = MALI_PROFILING_PP_CORE_COUNTER0_OFFSET(core->core_number); + u32 counter1_offset = MALI_PROFILING_PP_CORE_COUNTER1_OFFSET(core->core_number); +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ + job200->perf_counter0 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE); job200->perf_counter1 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE); + +#if MALI_TIMELINE_PROFILING_ENABLED + /* Report the counter values */ + _mali_osk_profiling_report_hw_counter(counter0_offset, job200->perf_counter0); + _mali_osk_profiling_report_hw_counter(counter1_offset, job200->perf_counter1); +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ } #if defined(USING_MALI400_L2_CACHE) @@ -757,6 +806,23 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit } +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), + job200->perf_counter0, job200->perf_counter1, + job200->user_input.perf_counter_src0 | (job200->user_input.perf_counter_src1 << 8) +#if defined(USING_MALI400_L2_CACHE) + | (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24), + job200->perf_counter_l2_val0, job200->perf_counter_l2_val1 +#else + , 0, 0 +#endif + ); +#endif + + +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif return JOB_STATUS_END_SUCCESS; /* reschedule */ } /* Overall SW watchdog timeout or (time to do hang checking and progress detected)? */ @@ -765,12 +831,17 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit ((CORE_HANG_CHECK_TIMEOUT == core->state) && (current_tile_addr == job200->last_tile_list_addr)) ) { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ #endif /* no progress detected, killed by the watchdog */ MALI_DEBUG_PRINT(2, ("M200: SW-Timeout Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x.\n", irq_readout ,current_tile_addr ,core_status) ); /* In this case will the system outside cleanup and reset the core */ + +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif + return JOB_STATUS_END_HANG; } /* HW watchdog triggered or an existing hang check passed? */ @@ -796,8 +867,8 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit } else { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ #endif MALI_DEBUG_PRINT(1, ("Mali PP: Job: 0x%08x CRASH? Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n", @@ -814,6 +885,9 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit (void)bus_error; } +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&job->session->jobs_ended); +#endif return JOB_STATUS_END_UNKNOWN_ERR; /* reschedule */ } } @@ -824,7 +898,7 @@ to a created mali_core_job object with the data given from userspace */ static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument) { mali200_job *job200; - mali_core_job *job; + mali_core_job *job = NULL; mali_core_job *previous_replaced_job; _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; _mali_uk_pp_start_job_s * user_ptr_job_input; @@ -872,7 +946,7 @@ static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_c job_priority_set(job, job200->user_input.priority); job_watchdog_set(job, job200->user_input.watchdog_msecs ); -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_TIMELINE_PROFILING_ENABLED job200->pid = _mali_osk_get_pid(); job200->tid = _mali_osk_get_tid(); #endif @@ -954,6 +1028,16 @@ function_exit: { _mali_osk_free(job200); } +#if MALI_STATE_TRACKING + if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status) + { + if(job) + { + job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received); + } + } +#endif + MALI_ERROR(err); } @@ -1026,6 +1110,9 @@ static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subs job_out->perf_counter_l2_val1_raw = job200->perf_counter_l2_val1_raw; #endif +#if MALI_STATE_TRACKING + _mali_osk_atomic_inc(&session->jobs_returned); +#endif _mali_osk_notification_queue_send( session->notification_queue, job200->notification_obj); job200->notification_obj = NULL; @@ -1180,8 +1267,8 @@ _mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_ #endif #if MALI_STATE_TRACKING -void mali200_subsystem_dump_state(void) +u32 mali200_subsystem_dump_state(char *buf, u32 size) { - mali_core_renderunit_dump_state(&subsystem_mali200); + return mali_core_renderunit_dump_state(&subsystem_mali200, buf, size); } #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h index 08516c56a9f..1a9459bff2b 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c index a40808bd2d8..f8ca4030fd8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c @@ -52,6 +52,7 @@ static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_sys static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); static _mali_osk_errcode_t build_system_info(void); +static void cleanup_system_info(_mali_system_info *cleanup); /** * @brief handler for MEM_VALIDATION resources @@ -105,15 +106,15 @@ static struct mali_kernel_subsystem mali_subsystem_core = static struct mali_kernel_subsystem * subsystems[] = { - /* always initialize the hw subsystems first */ - /* always included */ - &mali_subsystem_memory, #if USING_MALI_PMM /* The PMM must be initialized before any cores - including L2 cache */ &mali_subsystem_pmm, #endif + /* always included */ + &mali_subsystem_memory, + /* The rendercore subsystem must be initialized before any subsystem based on the * rendercores is started e.g. mali_subsystem_mali200 and mali_subsystem_gp2 */ &mali_subsystem_rendercore, @@ -154,7 +155,7 @@ _mali_osk_errcode_t mali_kernel_constructor( void ) { _mali_osk_errcode_t err; - err = mali_platform_init(NULL); + err = mali_platform_init(); if (_MALI_OSK_ERR_OK != err) goto error1; err = _mali_osk_init(); @@ -177,7 +178,7 @@ error3: _mali_osk_term(); error2: MALI_PRINT(("Mali device driver init failed\n")); - if (_MALI_OSK_ERR_OK != mali_platform_deinit(NULL)) + if (_MALI_OSK_ERR_OK != mali_platform_deinit()) { MALI_PRINT(("Failed to deinit platform\n")); } @@ -191,10 +192,13 @@ void mali_kernel_destructor( void ) { MALI_DEBUG_PRINT(2, ("\n")); MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION)); +#if USING_MALI_PMM + malipmm_force_powerup(); +#endif terminate_subsystems(); /* subsystems are responsible for their registered resources */ _mali_osk_term(); - if (_MALI_OSK_ERR_OK != mali_platform_deinit(NULL)) + if (_MALI_OSK_ERR_OK != mali_platform_deinit()) { MALI_PRINT(("Failed to deinit platform\n")); } @@ -304,6 +308,9 @@ static void terminate_subsystems(void) if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i); } if (system_info_lock) _mali_osk_lock_term( system_info_lock ); + + /* Free _mali_system_info struct */ + cleanup_system_info(system_info); } void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data) @@ -341,6 +348,30 @@ static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier _mali_osk_resources_term(&arch_configuration, num_resources); } +static void cleanup_system_info(_mali_system_info *cleanup) +{ + _mali_core_info * current_core; + _mali_mem_info * current_mem; + + /* delete all the core info structs */ + while (NULL != cleanup->core_info) + { + current_core = cleanup->core_info; + cleanup->core_info = cleanup->core_info->next; + _mali_osk_free(current_core); + } + + /* delete all the mem info struct */ + while (NULL != cleanup->mem_info) + { + current_mem = cleanup->mem_info; + cleanup->mem_info = cleanup->mem_info->next; + _mali_osk_free(current_mem); + } + + /* delete the system info struct itself */ + _mali_osk_free(cleanup); +} static _mali_osk_errcode_t build_system_info(void) { @@ -406,25 +437,7 @@ error_exit: if (NULL == cleanup) MALI_ERROR((_mali_osk_errcode_t)err); /* no cleanup needed, return what err contains */ /* cleanup */ - - /* delete all the core info structs */ - while (NULL != cleanup->core_info) - { - current_core = cleanup->core_info; - cleanup->core_info = cleanup->core_info->next; - _mali_osk_free(current_core); - } - - /* delete all the mem info struct */ - while (NULL != cleanup->mem_info) - { - current_mem = cleanup->mem_info; - cleanup->mem_info = cleanup->mem_info->next; - _mali_osk_free(current_mem); - } - - /* delete the system info struct itself */ - _mali_osk_free(cleanup); + cleanup_system_info(cleanup); /* return whatever err is, we could end up here in both the error and success cases */ MALI_ERROR((_mali_osk_errcode_t)err); @@ -873,20 +886,26 @@ _mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_boo #endif - #if MALI_STATE_TRACKING -void _mali_kernel_core_dump_state(void) +u32 _mali_kernel_core_dump_state(char* buf, u32 size) { - int i; + int i, n; + char *original_buf = buf; for (i = 0; i < SUBSYSTEMS_COUNT; ++i) - { + { if (NULL != subsystems[i]->dump_state) { - subsystems[i]->dump_state(); + n = subsystems[i]->dump_state(buf, size); + size -= n; + buf += n; } - } + } #if USING_MALI_PMM - mali_pmm_dump_os_thread_state(); + n = mali_pmm_dump_os_thread_state(buf, size); + size -= n; + buf += n; #endif + /* Return number of bytes written to buf */ + return (u32)(buf - original_buf); } #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h index 3819ecc5e1c..ced6b8fb118 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h @@ -88,9 +88,9 @@ _mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u3 * @brief Signal a power up on a Mali core. * * This function flags a core as powered up. - * For PP and GP cores it calls functions that move the core from a power off + * For PP and GP cores it calls functions that move the core from a power off * queue into the idle queue ready to run jobs. It also tries to schedule any - * pending jobs to run on it. + * pending jobs to run on it. * * This function will fail if the core is not powered off - either running or * already idle. @@ -100,7 +100,7 @@ _mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u3 * * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a * suitable _mali_osk_errcode_t error. - */ + */ _mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only ); /** @@ -108,9 +108,9 @@ _mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool * * This function flags a core as powered down. * For PP and GP cores it calls functions that move the core from an idle - * queue into the power off queue. + * queue into the power off queue. * - * This function will fail if the core is not idle - either running or + * This function will fail if the core is not idle - either running or * already powered down. * * @param core The PMM core id to power up. @@ -119,7 +119,7 @@ _mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool * * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a * suitable _mali_osk_errcode_t error. - */ + */ _mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only ); #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c index 45c280edd6a..8b2a97d1545 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h index f626aa59455..745be9235e7 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c index fded5c93ab9..3c4c68d74bd 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c @@ -495,6 +495,7 @@ void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 MALI_DEBUG_PRINT(5, ("L2 cache counters get: SRC0=%u, VAL0=%u, SRC1=%u, VAL1=%u\n", cur_src0, cur_val0, cur_src1, cur_val1)); + /* Only update the counter source once, with the value from the first L2 cache unit. */ if (first_time) { *src0 = cur_src0; @@ -502,6 +503,7 @@ void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 first_time = 0; } + /* Bail out if the L2 cache units have different counters set. */ if (*src0 == cur_src0 && *src1 == cur_src1) { *val0 += cur_val0; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c index 8277fd1e1c6..60f5ebd77ec 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c @@ -24,6 +24,8 @@ #include "mali_osk_indir_mmap.h" #endif +#error Support for non-MMU builds is no longer supported and is planned for removal. + /** * Minimum memory allocation size */ @@ -55,7 +57,7 @@ typedef struct mali_memory_bank _mali_osk_list_t list; /* links multiple banks together */ _mali_osk_lock_t *lock; u32 base_addr; /* Mali seen address of bank */ - u32 cpu_usage_adjust; /* Adjustmen factor for what the CPU sees */ + u32 cpu_usage_adjust; /* Adjustment factor for what the CPU sees */ u32 size; /* the effective size */ u32 real_size; /* the real size of the bank, as given by to the subsystem */ int min_order; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c index 7a48e27ede7..46eaea8eea5 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c @@ -18,6 +18,7 @@ #include "mali_kernel_mem_os.h" #include "mali_kernel_session_manager.h" #include "mali_kernel_core.h" +#include "mali_kernel_rendercore.h" #if defined USING_MALI400_L2_CACHE #include "mali_kernel_l2_cache.h" @@ -205,6 +206,7 @@ typedef struct mali_kernel_memory_mmu memory_session * active_session; /**< Active session, NULL if no session is active */ u32 usage_count; /**< Number of nested activations of the active session */ _mali_osk_list_t callbacks; /**< Callback registered for MMU idle notification */ + void *core; int in_page_fault_handler; @@ -329,10 +331,13 @@ static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resourc * also call this directly (depending on compilation options), having locked * the descriptor. * + * This function will fail if it is unable to put the MMU in stall mode (which + * might be the case if a page fault is also being processed). + * * @param args see _mali_uk_mem_munmap_s in "mali_uk_types.h" * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. */ -static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ); +static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ); /** * The MMU interrupt handler @@ -373,6 +378,30 @@ static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_regist */ static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val); +/** + * Issues the reset command to the MMU and waits for HW to be ready again + * @param mmu The MMU to reset + */ +static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu); + +/** + * Issues the enable paging command to the MMU and waits for HW to complete the request + * @param mmu The MMU to enable paging for + */ +static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu); + +/** + * Issues the enable stall command to the MMU and waits for HW to complete the request + * @param mmu The MMU to enable paging for + * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out) + */ +static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu); + +/** + * Issues the disable stall command to the MMU and waits for HW to complete the request + * @param mmu The MMU to enable paging for + */ +static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu); #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 static void ump_memory_release(void * ctx, void * handle); @@ -533,7 +562,7 @@ static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id) _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list) { /* reset to defaults */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); + mali_mmu_raw_reset(mmu); /* unregister the irq */ _mali_osk_irq_term(mmu->irq); @@ -544,6 +573,7 @@ static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id) /* release resources */ _mali_osk_mem_unmapioregion(mmu->base, mmu->mapping_size, mmu->mapped_registers); _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size); + _mali_osk_lock_term(mmu->lock); _mali_osk_free(mmu); } @@ -630,8 +660,9 @@ static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_da for (i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) { /* mark each page table as not present */ - _mali_osk_mem_iowrite32(session_data->page_directory_mapped, sizeof(u32) * i, 0); + _mali_osk_mem_iowrite32_relaxed(session_data->page_directory_mapped, sizeof(u32) * i, 0); } + _mali_osk_write_mem_barrier(); /* page_table_mapped[] is already set to NULL by _mali_osk_calloc call */ @@ -813,8 +844,9 @@ static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data) for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) { - _mali_osk_mem_iowrite32( mapping, i * sizeof(u32), data); + _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data); } + _mali_osk_mem_barrier(); MALI_SUCCESS; } @@ -887,7 +919,7 @@ static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_ _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list) { mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); + mali_mmu_enable_paging(mmu); } MALI_DEBUG_PRINT(4, ("MMUs activated\n")); @@ -992,7 +1024,7 @@ static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * /* setup MMU interrupt mask */ /* set all values to known defaults */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); + mali_mmu_raw_reset(mmu); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); /* setup MMU page directory pointer */ /* The mali_page_directory pointer is guaranteed to be 4kb aligned because we've used get_zeroed_page to accquire it */ @@ -1021,7 +1053,7 @@ static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * } /* set to a known state */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); + mali_mmu_raw_reset(mmu); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); MALI_DEBUG_PRINT(2, ("MMU registered\n")); @@ -1157,6 +1189,7 @@ static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(v { mali_kernel_memory_mmu * mmu; u32 int_stat; + mali_core_renderunit *core; if (mali_benchmark) MALI_SUCCESS; @@ -1164,15 +1197,19 @@ static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(v MALI_DEBUG_ASSERT_POINTER(mmu); + core = (mali_core_renderunit *)mmu->core; + if(core && (CORE_OFF == core->state)) + { + MALI_SUCCESS; + } + /* check if it was our device which caused the interrupt (we could be sharing the IRQ line) */ int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS); if (0 == int_stat) { - MALI_DEBUG_PRINT(5, ("Ignoring shared interrupt\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); /* no bits set, we are sharing the IRQ line and someone else caused the interrupt */ } - MALI_DEBUG_PRINT(1, ("mali_kernel_memory_mmu_interrupt_handler_upper_half\n")); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0); @@ -1180,13 +1217,10 @@ static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(v if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) { - MALI_PRINT(("Page fault on %s\n", mmu->description)); - _mali_osk_irq_schedulework(mmu->irq); } if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) { - MALI_PRINT(("Bus read error on %s\n", mmu->description)); /* clear interrupt flag */ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); /* reenable it */ @@ -1219,6 +1253,9 @@ static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu) /* no new request will come from any of the connected cores from now * we must now flush the playback buffer for any requests queued already */ + + _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(4, ("Switching to the special page fault flush page directory\n")); /* don't use the mali_mmu_activate_address_space function here as we can't stall the MMU */ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_page_fault_flush_page_directory); @@ -1239,16 +1276,23 @@ static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu) MALI_DEBUG_PRINT_IF(1, i == replay_buffer_max_number_of_checks, ("MMU: %s: Failed to flush replay buffer on page fault\n", mmu->description)); MALI_DEBUG_PRINT(1, ("Replay playback took %ld usec\n", i * replay_buffer_check_interval)); } + + _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); + #endif /* notify all subsystems that the core should be reset once the bus is actually stopped */ MALI_DEBUG_PRINT(4,("Sending job abort command to subsystems\n")); _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, (u32)mmu); + _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); + /* reprogram the MMU */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); + mali_mmu_raw_reset(mmu); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); + mali_mmu_enable_paging(mmu); + + _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); /* release the extra address space reference, will schedule */ mali_memory_core_mmu_release_address_space_reference(mmu); @@ -1258,6 +1302,101 @@ static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu) MALI_DEBUG_PRINT(4, ("Page fault handling complete\n")); } +static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 1; + + mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE); + mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); + + if (!mali_benchmark) + { + int i; + for (i = 0; i < max_loop_count; ++i) + { + if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_DTE_ADDR) == 0) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Reset request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); + } +} + +static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 1; + + mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); + + if (!mali_benchmark) + { + int i; + for (i = 0; i < max_loop_count; ++i) + { + if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable paging request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); + } +} + +static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 999; + int i; + + mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); + + if (!mali_benchmark) + { + for (i = 0; i < max_loop_count; ++i) + { + if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); + if (max_loop_count == i) + { + return MALI_FALSE; + } + } + + return MALI_TRUE; +} + +static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu) +{ + const int max_loop_count = 100; + const int delay_in_usecs = 1; + int i; + + mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); + + if (!mali_benchmark) + { + for (i = 0; i < max_loop_count; ++i) + { + if ((mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Disable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); + } +} + void mali_kernel_mmu_reset(void * input_mmu) { mali_kernel_memory_mmu * mmu; @@ -1273,10 +1412,10 @@ void mali_kernel_mmu_reset(void * input_mmu) return; } _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); + mali_mmu_raw_reset(mmu); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); + mali_mmu_enable_paging(mmu); _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); } @@ -1302,6 +1441,7 @@ static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data) { mali_kernel_memory_mmu * mmu; u32 raw, fault_address, status; + mali_core_renderunit *core; if (NULL == data) { @@ -1310,11 +1450,19 @@ static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data) } mmu = (mali_kernel_memory_mmu*)data; - MALI_DEBUG_PRINT(4, ("Locking subsystems\n")); /* lock all subsystems */ _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP0_LOCK_SUBSYSTEM, (u32)mmu); + /* Pointer to core holding this MMU */ + core = (mali_core_renderunit *)mmu->core; + + if(CORE_OFF == core->state) + { + _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu); + return; + } + raw = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_RAWSTAT); status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS); @@ -1404,7 +1552,6 @@ static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_regi _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val); } - #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) { @@ -1575,6 +1722,7 @@ _mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ) descriptor->mali_address = args->mali_address; descriptor->mali_addr_mapping_info = (void*)session_data; descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ + descriptor->lock = session_data->lock; if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; @@ -1594,14 +1742,19 @@ _mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ) external_memory_allocator.name = "UMP Memory"; external_memory_allocator.next = NULL; + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) { + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); mali_descriptor_mapping_free(session_data->descriptor_mapping, md); ump_dd_reference_release(ump_mem); _mali_osk_free(descriptor); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + args->cookie = md; MALI_DEBUG_PRINT(5,("Returning from UMP attach\n")); @@ -1629,7 +1782,13 @@ _mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args } mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); + + _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW ); + mali_allocation_engine_release_memory(memory_engine, descriptor); + + _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW ); + _mali_osk_free(descriptor); MALI_SUCCESS; @@ -1768,7 +1927,7 @@ _mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *arg descriptor->mali_address = args->mali_address; descriptor->mali_addr_mapping_info = (void*)session_data; descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ - descriptor->lock = NULL; + descriptor->lock = session_data->lock; if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; @@ -1781,13 +1940,18 @@ _mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *arg MALI_ERROR(_MALI_OSK_ERR_FAULT); } + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) { + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); mali_descriptor_mapping_free(session_data->descriptor_mapping, md); _mali_osk_free(descriptor); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + args->cookie = md; MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n")); @@ -1815,7 +1979,13 @@ _mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s } mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); + + _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW ); + mali_allocation_engine_release_memory(memory_engine, descriptor); + + _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW ); + _mali_osk_free(descriptor); MALI_SUCCESS; @@ -1870,6 +2040,8 @@ void mali_mmu_page_table_cache_destroy(void) _mali_osk_free(alloc->usage_map); _mali_osk_free(alloc); } + + _mali_osk_lock_term(page_table_cache.lock); } _mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping) @@ -1941,7 +2113,14 @@ _mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *ma _mali_osk_set_nonatomic_bit(0, alloc->usage_map); - _mali_osk_list_add(&alloc->list, &page_table_cache.partial); + if (alloc->num_pages > 1) + { + _mali_osk_list_add(&alloc->list, &page_table_cache.partial); + } + else + { + _mali_osk_list_add(&alloc->list, &page_table_cache.full); + } _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); *table_page = alloc->pages.phys_base; /* return the first page */ @@ -2001,8 +2180,21 @@ void mali_mmu_release_table_page(u32 pa) _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); - /* transfer to partial list */ - _mali_osk_list_move(&alloc->list, &page_table_cache.partial); + + if (0 == alloc->usage_count) + { + /* empty, release whole page alloc */ + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + else + { + /* transfer to partial list */ + _mali_osk_list_move(&alloc->list, &page_table_cache.partial); + } + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa)); return; @@ -2014,6 +2206,17 @@ void mali_mmu_release_table_page(u32 pa) _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); } +void mali_memory_core_mmu_owner(void *core, void *mmu_ptr) +{ + mali_kernel_memory_mmu *mmu; + + MALI_DEBUG_ASSERT_POINTER(mmu_ptr); + MALI_DEBUG_ASSERT_POINTER(core); + + mmu = (mali_kernel_memory_mmu *)mmu_ptr; + mmu->core = core; +} + void* mali_memory_core_mmu_lookup(u32 id) { mali_kernel_memory_mmu * mmu, * temp_mmu; @@ -2030,24 +2233,10 @@ void* mali_memory_core_mmu_lookup(u32 id) void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory) { - const int delay_in_usecs = 10; - const int max_loop_count = 10; - int i; - - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); - - if (!mali_benchmark) { - for (i = 0; i < max_loop_count; ++i) - { - if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) break; - _mali_osk_time_ubusydelay(delay_in_usecs); - } - MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Stall request failed, swapping anyway\n")); - } - + mali_mmu_enable_stall(mmu); /* this might fail, but changing the DTE address and ZAP should work anyway... */ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, page_directory); mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); + mali_mmu_disable_stall(mmu); } _mali_osk_errcode_t mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument) @@ -2517,8 +2706,9 @@ static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * des for ( ; mali_address < mali_address_end; mali_address += MALI_MMU_PAGE_SIZE, current_phys_addr += MALI_MMU_PAGE_SIZE) { MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]); - _mali_osk_mem_iowrite32(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); + _mali_osk_mem_iowrite32_relaxed(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); } + _mali_osk_write_mem_barrier(); #if defined USING_MALI400_L2_CACHE if (1 == has_active_mmus) @@ -2574,7 +2764,7 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) descriptor->lock = session_data->lock; _mali_osk_list_init( &descriptor->list ); - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head)) { @@ -2587,12 +2777,9 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); - if (!mali_benchmark) { - while ( (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0) _mali_osk_time_ubusydelay(1); - } + mali_mmu_enable_stall(mmu); /* this might fail, but ZAP should work anyway... */ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); + mali_mmu_disable_stall(mmu); _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); } @@ -2618,7 +2805,7 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) } } -static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) +static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) { memory_session * session_data; mali_kernel_memory_mmu * mmu, * temp_mmu; @@ -2641,24 +2828,34 @@ static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) */ _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) { - const int max_loop_count = 100; - const int sleep_duration = 1; /* must be below 1000 */ - int i; - + u32 status; + status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS); + if ( MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE == (status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) { + MALI_DEBUG_PRINT(2, ("Stopped stall attempt for mmu with id %d since it is in page fault mode.\n", mmu->id)); + continue; + } _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); - - if (!mali_benchmark) + /* + * If we're unable to stall, then make sure we tell our caller that, + * the caller should then release the session lock for a while, + * then this function again. + * This function will fail if we're in page fault mode, and to get + * out of page fault mode, the page fault handler must be able to + * take the session lock. + */ + if (!mali_mmu_enable_stall(mmu)) { - for ( i = 0; i < max_loop_count; i++) - { - if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) break; - _mali_osk_time_ubusydelay(sleep_duration); - } - - MALI_DEBUG_PRINT_IF(3, max_loop_count == i, ("Stall failed, trying zap anyway\n")); + _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_BUSY; } + + _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); + } + + _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) + { + _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); } /* This function also removes the memory from the session's memory list */ @@ -2671,10 +2868,12 @@ static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) { mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); + mali_mmu_disable_stall(mmu); _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); } + + return _MALI_OSK_ERR_OK; } /* Handler for unmapping memory for MMU builds */ @@ -2682,6 +2881,7 @@ _mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) { mali_memory_allocation * descriptor; _mali_osk_lock_t *descriptor_lock; + _mali_osk_errcode_t err; descriptor = (mali_memory_allocation *)args->cookie; MALI_DEBUG_ASSERT_POINTER(descriptor); @@ -2695,20 +2895,34 @@ _mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) descriptor_lock = descriptor->lock; /* should point to the session data lock... */ - if (descriptor_lock) + err = _MALI_OSK_ERR_BUSY; + while (err == _MALI_OSK_ERR_BUSY) { - _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); - } - /* Noninterruptable spinlock type, so must always have locked. Checking should've been done in OSK function. */ + if (descriptor_lock) + { + _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + } - _mali_ukk_mem_munmap_internal( args ); - /* descriptor is no longer valid - it may've been freed */ + err = _mali_ukk_mem_munmap_internal( args ); - if (descriptor_lock) - { - _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + if (descriptor_lock) + { + _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + } + + if (err == _MALI_OSK_ERR_BUSY) + { + /* + * Reason for this; + * We where unable to stall the MMU, probably because we are in page fault handling. + * Sleep for a while with the session lock released, then try again. + * Abnormal termination of programs with running Mali jobs is a normal reason for this. + */ + _mali_osk_time_ubusydelay(10); + } } - return _MALI_OSK_ERR_OK; + + return err; } /* Is called when the rendercore wants the mmu to give an interrupt */ @@ -2922,3 +3136,8 @@ _mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args ) MALI_IGNORE( args ); return _MALI_OSK_ERR_FAULT; } + +u32 _mali_ukk_report_memory_usage(void) +{ + return mali_allocation_engine_memory_usage(physical_memory_allocators); +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h index a199fd66b5a..98610803978 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h @@ -21,6 +21,15 @@ void* mali_memory_core_mmu_lookup(u32 id); /** + * Set the core pointer of MMU to core owner of MMU + * + * @param core Core holding this MMU + * @param mmu_ptr The MMU whose core pointer needs set to core holding the MMU + * + */ +void mali_memory_core_mmu_owner(void *core, void *mmu_ptr); + +/** * Activate a user session with its address space on the given MMU. * If the session can't be activated due to that the MMU is busy and * a callback pointer is given, the callback will be called once the MMU becomes idle. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c index 845de935ec9..65958576c7a 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c @@ -44,6 +44,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate_page_table_b static void os_allocator_release(void * ctx, void * handle); static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block ); static void os_allocator_destroy(mali_physical_memory_allocator * allocator); +static u32 os_allocator_stat(mali_physical_memory_allocator * allocator); mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name) { @@ -70,6 +71,7 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3 allocator->allocate = os_allocator_allocate; allocator->allocate_page_table_block = os_allocator_allocate_page_table_block; allocator->destroy = os_allocator_destroy; + allocator->stat = os_allocator_stat; allocator->ctx = info; allocator->name = name; @@ -83,6 +85,13 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3 return NULL; } +static u32 os_allocator_stat(mali_physical_memory_allocator * allocator) +{ + os_allocator * info; + info = (os_allocator*)allocator->ctx; + return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE; +} + static void os_allocator_destroy(mali_physical_memory_allocator * allocator) { os_allocator * info; @@ -158,6 +167,9 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m *offset += _MALI_OSK_CPU_PAGE_SIZE; } + if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB Configured maximum OS memory usage: %d kB\n", + (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024)); + /* Loop termination; decide on result */ if (pages_allocated) { @@ -167,7 +179,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m /* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. - * This is required for MALI to have the correct view of the memory. + * This is required for MALI to have the correct view of the memory. */ _mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE ); allocation->num_pages = pages_allocated; @@ -231,10 +243,9 @@ static void os_allocator_release(void * ctx, void * handle) static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block) { - const int allocation_order = 6; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */ - void *virt; - const u32 pages_to_allocate = 1 << allocation_order; - const u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; + int allocation_order = 6; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */ + void *virt = NULL; + u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; os_allocator * info; u32 cpu_phys_base; @@ -245,22 +256,48 @@ static mali_physical_memory_allocation_result os_allocator_allocate_page_table_b /* Ensure we don't allocate more than we're supposed to from the ctx */ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - if ( (info->num_pages_allocated + pages_to_allocate > info->num_pages_max) && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) ) + /* if the number of pages to be requested lead to exceeding the memory + * limit in info->num_pages_max, reduce the size that is to be requested. */ + while ( (info->num_pages_allocated + (1 << allocation_order) > info->num_pages_max) + && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) ) { - /* return OOM */ - _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); - return MALI_MEM_ALLOC_NONE; + if ( allocation_order > 0 ) { + --allocation_order; + } else { + /* return OOM */ + _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); + return MALI_MEM_ALLOC_NONE; + } } - virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size ); + /* try to allocate 2^(allocation_order) pages, if that fails, try + * allocation_order-1 to allocation_order 0 (inclusive) */ + while ( allocation_order >= 0 ) + { + size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; + virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size ); + + if (NULL != virt) break; + + --allocation_order; + } if ( NULL == virt ) { + MALI_DEBUG_PRINT(1, ("Failed to allocate consistent memory. Is CONSISTENT_DMA_SIZE set too low?\n")); /* return OOM */ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); return MALI_MEM_ALLOC_NONE; } + MALI_DEBUG_PRINT(5, ("os_allocator_allocate_page_table_block: Allocation of order %i succeeded\n", + allocation_order)); + + /* we now know the size of the allocation since we know for what + * allocation_order the allocation succeeded */ + size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order; + + block->release = os_allocator_page_table_block_release; block->ctx = ctx; block->handle = (void*)allocation_order; @@ -268,7 +305,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate_page_table_b block->phys_base = cpu_phys_base - info->cpu_usage_adjust; block->mapping = virt; - info->num_pages_allocated += pages_to_allocate; + info->num_pages_allocated += (1 << allocation_order); _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h index ff49f8a816a..0946169f79d 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c index 3b4ace05f01..f6860c78a0b 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c @@ -123,7 +123,7 @@ _mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engin } } - MALI_DEBUG_PRINT(3, ("Non-fatal OOM, have to cleanup, stopped at offset %d for size %d\n", offset, descriptor->size)); + MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024)); /* allocation failure, start cleanup */ /* loop over any potential partial allocations */ @@ -346,3 +346,18 @@ void mali_allocation_engine_report_allocators( mali_physical_memory_allocator * } } + +u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator) +{ + u32 sum = 0; + while(NULL != allocator) + { + /* Only count allocators that have set up a stat function. */ + if(allocator->stat) + sum += allocator->stat(allocator); + + allocator = allocator->next; + } + + return sum; +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h index 80a2b4bb3a7..1ef7a089e95 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h @@ -47,7 +47,7 @@ typedef enum /** * Supplying this 'magic' physical address requests that the OS allocate the - * physical address at page commit time, rather than commiting a specific page + * physical address at page commit time, rather than committing a specific page */ #define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1)) @@ -78,6 +78,7 @@ typedef struct mali_physical_memory_allocator mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */ void (*destroy)(struct mali_physical_memory_allocator * allocator); + u32 (*stat)(struct mali_physical_memory_allocator * allocator); void * ctx; const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */ u32 alloc_order; /**< Order in which the allocations should happen */ @@ -96,7 +97,7 @@ typedef struct mali_kernel_mem_address_manager * @param[in] off Offset from the start of range * @param[in,out] phys_addr A pointer to the physical address of the start of the * physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC - * is used, this requests the function must allocate the physical page + * is used, this requests the function to allocate the physical page * itself, and return it through the pointer provided. * @param[in] size Length in bytes of the physical block * @return _MALI_OSK_ERR_OK on success. @@ -142,4 +143,6 @@ int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_pag void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider); +u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator); + #endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h deleted file mode 100644 index 5d3aa6eb841..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MALI_KERNEL_PROFILING_H__ -#define __MALI_KERNEL_PROFILING_H__ - -#if MALI_TIMELINE_PROFILING_ENABLED - -#include <../../../include/cinstr/mali_cinstr_profiling_events_m200.h> - -/** - * Initialize the profiling module. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_init(void); - -/* - * Terminate the profiling module. - */ -void _mali_profiling_term(void); - -/** - * Add an profiling event - * - * @param event_id The event identificator. - * @param data0 - First data parameter, depending on event_id specified. - * @param data1 - Second data parameter, depending on event_id specified. - * @param data2 - Third data parameter, depending on event_id specified. - * @param data3 - Fourth data parameter, depending on event_id specified. - * @param data4 - Fifth data parameter, depending on event_id specified. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4); - -#endif /* MALI_TIMELINE_PROFILING_ENABLED */ - -#endif /* __MALI_KERNEL_PROFILING_H__ */ - - diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c index 1db8f3ad5ab..f06b17bcb31 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -11,7 +11,6 @@ #include "mali_kernel_common.h" #include "mali_kernel_core.h" #include "mali_osk.h" -#include "mali_kernel_pp.h" #include "mali_kernel_subsystem.h" #include "mali_kernel_rendercore.h" #include "mali_osk_list.h" @@ -19,7 +18,7 @@ #include "mali_kernel_utilization.h" #endif #if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" +#include "mali_osk_profiling.h" #endif #if USING_MMU #include "mali_kernel_mem_mmu.h" @@ -42,6 +41,10 @@ int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT; int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT; +#if MALI_TIMELINE_PROFILING_ENABLED +int mali_boot_profiling = 0; +#endif + /* Subsystem entrypoints: */ static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id); static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id); @@ -157,7 +160,7 @@ static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_id #endif #if MALI_TIMELINE_PROFILING_ENABLED - if (_mali_profiling_init() != _MALI_OSK_ERR_OK) + if (_mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE) != _MALI_OSK_ERR_OK) { /* No biggie if we wheren't able to initialize the profiling */ MALI_PRINT_ERROR(("Rendercore: Failed to initialize profiling, feature will be unavailable\n")) ; @@ -187,7 +190,7 @@ static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id) MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex ); #if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_term(); + _mali_osk_profiling_term(); #endif #if MALI_GPU_UTILIZATION @@ -258,104 +261,6 @@ static void rendercore_subsystem_broadcast_notification(mali_core_notification_m * Functions inherited by the subsystems that extend the ''rendercore''. */ -u32 mali_core_renderunit_register_read(mali_core_renderunit *core, u32 relative_address) -{ - u32 read_val; - - #if USING_MALI_PMM - if( core->state == CORE_OFF ) - { - MALI_PRINT_ERROR(("Core is OFF during read: Core:%s Addr:0x%04X\n", - core->description,relative_address)); - return 0xDEADBEEF; - } - #endif - - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - - if (mali_benchmark) return 0; - - if (relative_address >= core->size) - { - MALI_PRINT_ERROR(("Trying to read from illegal register: 0x%04x in core: %s\n", - relative_address, core->description)); - return 0xDEADBEEF; - } - - read_val = _mali_osk_mem_ioread32(core->registers_mapped, relative_address); - - MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read: Core:%s Addr:0x%04X Val:0x%08x\n", - core->description,relative_address, read_val)); - - return read_val; -} - -void mali_core_renderunit_register_read_array(mali_core_renderunit *core, - u32 relative_address, - u32 * result_array, - u32 nr_of_regs - ) -{ - /* NOTE Do not use burst reads against the registers */ - - u32 i; - - for(i=0; i<nr_of_regs; ++i) - { - result_array[i] = mali_core_renderunit_register_read(core, relative_address + i*4); - } - - MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read_array: Core:%s Addr:0x%04X Nr_regs: %u\n", - core->description,relative_address, nr_of_regs)); -} - -void mali_core_renderunit_register_write(mali_core_renderunit *core, u32 relative_address, u32 new_val) -{ - #if USING_MALI_PMM - if( core->state == CORE_OFF ) - { - MALI_PRINT_ERROR(("Core is OFF during write: Core:%s Addr:0x%04X Val:0x%08x\n", - core->description,relative_address, new_val)); - return; - } - #endif - - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - - if (mali_benchmark) return; - - if (relative_address >= core->size) - { - MALI_PRINT_ERROR(("Trying to write to illegal register: 0x%04x in core: %s", - relative_address, core->description)); - return; - } - - MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write: Core:%s Addr:0x%04X Val:0x%08x\n", - core->description,relative_address, new_val)); - - _mali_osk_mem_iowrite32(core->registers_mapped, relative_address, new_val); -} - - -void mali_core_renderunit_register_write_array(mali_core_renderunit *core, - u32 relative_address, - u32 * source_array, - u32 nr_of_regs) -{ - - u32 i; - MALI_DEBUG_PRINT(6, ("Core: renderunit_register_write_array: Core:%s Addr:0x%04X Nr_regs: %u\n", - core->description,relative_address, nr_of_regs)); - - /* Do not use burst writes against the registers */ - - for( i = 0; i< nr_of_regs; i++) - { - mali_core_renderunit_register_write(core, relative_address + i*4, source_array[i]); - } -} - void mali_core_renderunit_timeout_function_hang_detection(void *arg) { mali_bool action = MALI_FALSE; @@ -364,8 +269,8 @@ void mali_core_renderunit_timeout_function_hang_detection(void *arg) core = (mali_core_renderunit *) arg; if( !core ) return; - /* if NOT idle OR has TIMED_OUT */ - if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state)) ) + /* if NOT idle OR NOT powered off OR has TIMED_OUT */ + if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state) || (CORE_OFF == core->state)) ) { core->state = CORE_HANG_CHECK_TIMEOUT; action = MALI_TRUE; @@ -615,6 +520,7 @@ void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys) core = mali_core_renderunit_get_mali_core_nr(subsys,i); if ( NULL==core ) break; core->mmu = mali_memory_core_mmu_lookup(core->mmu_id); + mali_memory_core_mmu_owner(core,core->mmu); MALI_DEBUG_PRINT(2, ("Attach mmu: 0x%x to core: %s in subsystem: %s\n", core->mmu, core->description, subsys->name)); } @@ -871,11 +777,11 @@ _mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_sess if ( NULL != number_of_cores ) { *number_of_cores = subsystem->number_of_cores; - } - MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ; + MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ; + } - MALI_SUCCESS; + MALI_SUCCESS; } _mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data) @@ -1067,15 +973,7 @@ static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core) oldstatus = core->state; - if( core->pend_power_down ) - { - core->state = CORE_OFF ; - _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head ); - /* Done the move from the active queues, so the pending power down can be done */ - core->pend_power_down = MALI_FALSE; - malipmm_core_power_down_okay( core->pmm_id ); - } - else + if ( !core->pend_power_down ) { core->state = CORE_IDLE ; _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head ); @@ -1098,6 +996,15 @@ static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core) #endif /* USING_MMU */ } + if( core->pend_power_down ) + { + core->state = CORE_OFF ; + _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head ); + + /* Done the move from the active queues, so the pending power down can be done */ + core->pend_power_down = MALI_FALSE; + malipmm_core_power_down_okay( core->pmm_id ); + } #else /* !USING_MALI_PMM */ @@ -1398,6 +1305,13 @@ void mali_core_session_begin(mali_core_session * session) MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem); _mali_osk_list_add(&session->all_sessions_list, &session->subsystem->all_sessions_head); + +#if MALI_STATE_TRACKING + _mali_osk_atomic_init(&session->jobs_received, 0); + _mali_osk_atomic_init(&session->jobs_returned, 0); + session->pid = _mali_osk_get_pid(); +#endif + MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); MALI_DEBUG_PRINT(5, ("Core: session_begin: for %s DONE\n", session->subsystem->name) ) ; @@ -1440,7 +1354,6 @@ void mali_core_session_close(mali_core_session * session) core = _MALI_OSK_LIST_ENTRY(session->renderunits_working_head.next, mali_core_renderunit, list); MALI_DEBUG_PRINT(3, ("Core: session_close: Core was working: %s\n", core->description )) ; mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_SHUTDOWN ); - break; } _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head); /* Not necessary - we will _mali_osk_free session*/ @@ -1749,6 +1662,11 @@ static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data) core = (mali_core_renderunit * )data; + if(core && (CORE_OFF == core->state)) + { + MALI_SUCCESS; + } + if ( (NULL == core) || (NULL == core->subsystem) || (NULL == core->subsystem->irq_handler_upper_half) ) @@ -1785,7 +1703,7 @@ static void mali_core_irq_handler_bottom_half ( void *data ) MALI_CHECK_SUBSYSTEM(subsystem); MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem ); - if ( CORE_IDLE == core->state ) goto end_function; + if ( CORE_IDLE == core->state || CORE_OFF == core->state ) goto end_function; MALI_DEBUG_PRINT(5, ("IRQ: handling irq from core %s\n", core->description )) ; @@ -1856,7 +1774,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *s { /* Couldn't find the core */ MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 5, ("Core: Failed to find core to power down\n") ); + MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power down\n") ); MALI_ERROR(_MALI_OSK_ERR_FAULT); } else if ( core->state != CORE_IDLE ) @@ -1896,7 +1814,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub { /* Couldn't find the core */ MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 5, ("Core: Failed to find core to power up\n") ); + MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power up\n") ); MALI_ERROR(_MALI_OSK_ERR_FAULT); } else if( core->state != CORE_OFF ) @@ -1904,7 +1822,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub /* This will usually happen because we are trying to cancel a pending power down */ core->pend_power_down = MALI_FALSE; MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 5, ("Core: No powered off core to power up (cancelled power down?)\n") ); + MALI_DEBUG_PRINT( 1, ("Core: No powered off core to power up (cancelled power down?)\n") ); MALI_ERROR(_MALI_OSK_ERR_BUSY); } @@ -1945,88 +1863,126 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub #endif /* USING_MALI_PMM */ #if MALI_STATE_TRACKING -void mali_core_renderunit_dump_state(mali_core_subsystem* subsystem) +u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size) { - u32 i; + u32 i, len = 0; mali_core_renderunit *core; mali_core_renderunit *tmp_core; mali_core_session* session; mali_core_session* tmp_session; + if (0 >= size) + { + return 0; + } + MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem ); - MALI_PRINT(("Subsystem;\n")); - MALI_PRINT((" Name: %s\n", subsystem->name)); + len += _mali_osk_snprintf(buf + len, size - len, "Subsystem:\n"); + len += _mali_osk_snprintf(buf + len, size - len, " Name: %s\n", subsystem->name); for (i = 0; i < subsystem->number_of_cores; i++) { - MALI_PRINT((" Core: #%u\n", subsystem->mali_core_array[i]->core_number)); - MALI_PRINT((" Description: %s\n", subsystem->mali_core_array[i]->description)); + len += _mali_osk_snprintf(buf + len, size - len, " Core: #%u\n", + subsystem->mali_core_array[i]->core_number); + len += _mali_osk_snprintf(buf + len, size - len, " Description: %s\n", + subsystem->mali_core_array[i]->description); switch(subsystem->mali_core_array[i]->state) { case CORE_IDLE: - MALI_PRINT((" State: CORE_IDLE\n")); + len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_IDLE\n"); break; case CORE_WORKING: - MALI_PRINT((" State: CORE_WORKING\n")); + len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WORKING\n"); break; case CORE_WATCHDOG_TIMEOUT: - MALI_PRINT((" State: CORE_WATCHDOG_TIMEOUT\n")); + len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WATCHDOG_TIMEOUT\n"); break; case CORE_POLL: - MALI_PRINT((" State: CORE_POLL\n")); + len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_POLL\n"); break; case CORE_HANG_CHECK_TIMEOUT: - MALI_PRINT((" State: CORE_HANG_CHECK_TIMEOUT\n")); + len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_HANG_CHECK_TIMEOUT\n"); break; case CORE_OFF: - MALI_PRINT((" State: CORE_OFF\n")); + len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_OFF\n"); break; default: - MALI_PRINT((" State: Unknown (0x%X)\n", subsystem->mali_core_array[i]->state)); + len += _mali_osk_snprintf(buf + len, size - len, " State: Unknown (0x%X)\n", + subsystem->mali_core_array[i]->state); break; } - MALI_PRINT((" Current job: 0x%x\n", (u32)(subsystem->mali_core_array[i]->current_job))); - MALI_PRINT((" Core version: 0x%x\n", subsystem->mali_core_array[i]->core_version)); + len += _mali_osk_snprintf(buf + len, size - len, " Current job: 0x%X\n", + (u32)(subsystem->mali_core_array[i]->current_job)); + if (subsystem->mali_core_array[i]->current_job) + { + len += _mali_osk_snprintf(buf + len, size - len, " Current job session: 0x%X\n", + subsystem->mali_core_array[i]->current_job->session); + len += _mali_osk_snprintf(buf + len, size - len, " Current job number: %d\n", + subsystem->mali_core_array[i]->current_job->job_nr); + len += _mali_osk_snprintf(buf + len, size - len, " Current job render_time jiffies: %d\n", + _mali_osk_time_tickcount()-subsystem->mali_core_array[i]->current_job->start_time_jiffies); + } + len += _mali_osk_snprintf(buf + len, size - len, " Core version: 0x%X\n", + subsystem->mali_core_array[i]->core_version); #if USING_MALI_PMM - MALI_PRINT((" PMM id: 0x%x\n", subsystem->mali_core_array[i]->pmm_id)); - MALI_PRINT((" Power down requested: %s\n", subsystem->mali_core_array[i]->pend_power_down ? "TRUE" : "FALSE")); + len += _mali_osk_snprintf(buf + len, size - len, " PMM id: 0x%X\n", + subsystem->mali_core_array[i]->pmm_id); + len += _mali_osk_snprintf(buf + len, size - len, " Power down requested: %s\n", + subsystem->mali_core_array[i]->pend_power_down ? "TRUE" : "FALSE"); #endif } - MALI_PRINT((" Cores on idle list:\n")); + len += _mali_osk_snprintf(buf + len, size - len, " Cores on idle list:\n"); _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_idle_head, mali_core_renderunit, list) { - MALI_PRINT((" Core #%u\n", core->core_number)); + len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number); } - MALI_PRINT((" Cores on off list:\n")); + len += _mali_osk_snprintf(buf + len, size - len, " Cores on off list:\n"); _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_off_head, mali_core_renderunit, list) { - MALI_PRINT((" Core #%u\n", core->core_number)); + len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number); } - MALI_PRINT((" Connected sessions:\n")); + len += _mali_osk_snprintf(buf + len, size - len, " Connected sessions:\n"); _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->all_sessions_head, mali_core_session, all_sessions_list) { - MALI_PRINT((" Session 0x%X:\n", (u32)session)); - MALI_PRINT((" Waiting job: 0x%X\n", (u32)session->job_waiting_to_run)); - MALI_PRINT((" Notification queue: %s\n", _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY")); - } - - MALI_PRINT((" Waiting sessions sum all priorities: %u\n", subsystem->awaiting_sessions_sum_all_priorities)); + len += _mali_osk_snprintf(buf + len, size - len, + " Session 0x%X:\n", (u32)session); + len += _mali_osk_snprintf(buf + len, size - len, + " Waiting job: 0x%X\n", (u32)session->job_waiting_to_run); + len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n", + _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY"); + len += _mali_osk_snprintf(buf + len, size - len, + " Jobs received:%4d\n", _mali_osk_atomic_read(&session->jobs_received)); + len += _mali_osk_snprintf(buf + len, size - len, + " Jobs started :%4d\n", _mali_osk_atomic_read(&session->jobs_started)); + len += _mali_osk_snprintf(buf + len, size - len, + " Jobs ended :%4d\n", _mali_osk_atomic_read(&session->jobs_ended)); + len += _mali_osk_snprintf(buf + len, size - len, + " Jobs returned:%4d\n", _mali_osk_atomic_read(&session->jobs_returned)); + len += _mali_osk_snprintf(buf + len, size - len, " PID: %d\n", session->pid); + } + + len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions sum all priorities: %u\n", + subsystem->awaiting_sessions_sum_all_priorities); for (i = 0; i < PRIORITY_LEVELS; i++) { - MALI_PRINT((" Waiting sessions with priority %u:\n", i)); - _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->awaiting_sessions_head[i], mali_core_session, awaiting_sessions_list) + len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions with priority %u:\n", i); + _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->awaiting_sessions_head[i], + mali_core_session, awaiting_sessions_list) { - MALI_PRINT((" Session 0x%X:\n", (u32)session)); - MALI_PRINT((" Waiting job: 0x%X\n", (u32)session->job_waiting_to_run)); - MALI_PRINT((" Notification queue: %s\n", _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY")); + len += _mali_osk_snprintf(buf + len, size - len, " Session 0x%X:\n", (u32)session); + len += _mali_osk_snprintf(buf + len, size - len, " Waiting job: 0x%X\n", + (u32)session->job_waiting_to_run); + len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n", + _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY"); } } MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem ); + return len; } #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h index 94bce94d4e1..c4a13796ba9 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h @@ -188,6 +188,13 @@ typedef struct mali_core_session struct mali_session_data * mmu_session; /* The session associated with the MMU page tables for this core */ #endif u32 magic_nr; +#if MALI_STATE_TRACKING + _mali_osk_atomic_t jobs_received; + _mali_osk_atomic_t jobs_started; + _mali_osk_atomic_t jobs_ended; + _mali_osk_atomic_t jobs_returned; + u32 pid; +#endif } mali_core_session; @@ -204,6 +211,7 @@ typedef struct mali_core_job u32 start_time_jiffies; unsigned long watchdog_jiffies; u32 abort_id; + u32 job_nr; } mali_core_job; /* @@ -309,11 +317,117 @@ typedef struct register_array_user if ( rendercores_global_mutex_owner != _mali_osk_get_tid() ) MALI_PRINT_ERROR(("Owner mismatch"));\ } while (0) +MALI_STATIC_INLINE _mali_osk_errcode_t mali_core_renderunit_register_rw_check(mali_core_renderunit *core, + u32 relative_address) +{ +#if USING_MALI_PMM + if( core->state == CORE_OFF ) + { + MALI_PRINT_ERROR(("Core is OFF during access: Core: %s Addr: 0x%04X\n", + core->description,relative_address)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } +#endif + + MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); + + if (mali_benchmark) MALI_ERROR(_MALI_OSK_ERR_FAULT); + + MALI_DEBUG_CODE(if (relative_address >= core->size) + { + MALI_PRINT_ERROR(("Trying to access illegal register: 0x%04x in core: %s", + relative_address, core->description)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + }) + + MALI_SUCCESS; +} -u32 mali_core_renderunit_register_read(struct mali_core_renderunit *core, u32 relative_address); -void mali_core_renderunit_register_read_array(struct mali_core_renderunit *core, u32 relative_address, u32 * result_array, u32 nr_of_regs); -void mali_core_renderunit_register_write(struct mali_core_renderunit *core, u32 relative_address, u32 new_val); -void mali_core_renderunit_register_write_array(struct mali_core_renderunit *core, u32 relative_address, u32 * write_array, u32 nr_of_regs); + +MALI_STATIC_INLINE u32 mali_core_renderunit_register_read(struct mali_core_renderunit *core, u32 relative_address) +{ + u32 read_val; + + if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address)) + return 0xDEADBEEF; + + read_val = _mali_osk_mem_ioread32(core->registers_mapped, relative_address); + + MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read: Core:%s Addr:0x%04X Val:0x%08x\n", + core->description,relative_address, read_val)); + + return read_val; +} + +MALI_STATIC_INLINE void mali_core_renderunit_register_read_array(struct mali_core_renderunit *core, + u32 relative_address, + u32 * result_array, + u32 nr_of_regs) +{ + /* NOTE Do not use burst reads against the registers */ + u32 i; + + MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read_array: Core:%s Addr:0x%04X Nr_regs: %u\n", + core->description,relative_address, nr_of_regs)); + + for(i=0; i<nr_of_regs; ++i) + { + result_array[i] = mali_core_renderunit_register_read(core, relative_address + i*4); + } +} + +/* + * Write to a core register, and bypass implied memory barriers. + * + * On some systems, _mali_osk_mem_iowrite32() implies a memory barrier. This + * can be a performance problem when doing many writes in sequence. + * + * When using this function, ensure proper barriers are put in palce. Most + * likely a _mali_osk_mem_barrier() is needed after all related writes are + * completed. + * + */ +MALI_STATIC_INLINE void mali_core_renderunit_register_write_relaxed(mali_core_renderunit *core, + u32 relative_address, + u32 new_val) +{ + if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address)) + return; + + MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write_relaxed: Core:%s Addr:0x%04X Val:0x%08x\n", + core->description,relative_address, new_val)); + + _mali_osk_mem_iowrite32_relaxed(core->registers_mapped, relative_address, new_val); +} + +MALI_STATIC_INLINE void mali_core_renderunit_register_write(struct mali_core_renderunit *core, + u32 relative_address, + u32 new_val) +{ + MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write: Core:%s Addr:0x%04X Val:0x%08x\n", + core->description,relative_address, new_val)); + + if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address)) + return; + + _mali_osk_mem_iowrite32(core->registers_mapped, relative_address, new_val); +} + +MALI_STATIC_INLINE void mali_core_renderunit_register_write_array(struct mali_core_renderunit *core, + u32 relative_address, + u32 * write_array, + u32 nr_of_regs) +{ + u32 i; + MALI_DEBUG_PRINT(6, ("Core: renderunit_register_write_array: Core:%s Addr:0x%04X Nr_regs: %u\n", + core->description,relative_address, nr_of_regs)); + + /* Do not use burst writes against the registers */ + for( i = 0; i< nr_of_regs; i++) + { + mali_core_renderunit_register_write_relaxed(core, relative_address + i*4, write_array[i]); + } +} _mali_osk_errcode_t mali_core_renderunit_init(struct mali_core_renderunit * core); void mali_core_renderunit_term(struct mali_core_renderunit * core); @@ -349,7 +463,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub #endif #if MALI_STATE_TRACKING -void mali_core_renderunit_dump_state(mali_core_subsystem* subsystem); +u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size); #endif #endif /* __MALI_RENDERCORE_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h index ce290d0c1c9..8cc41d7f937 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h index e8c6530668c..9efba566bd9 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h @@ -74,7 +74,7 @@ typedef struct mali_kernel_subsystem #if MALI_STATE_TRACKING /** Dump the current state of the subsystem */ - void (*dump_state)(void); + u32 (*dump_state)(char *buf, u32 size); #endif } mali_kernel_subsystem; @@ -100,7 +100,7 @@ void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_messag /** * Tell all subsystems to dump their current state */ -void _mali_kernel_core_dump_state(void); +u32 _mali_kernel_core_dump_state(char *buf, u32 size); #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h index c35d90577a3..35737e68cb3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -54,7 +54,7 @@ extern "C" /** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE */ typedef unsigned long mali_bool; - + #ifndef MALI_TRUE #define MALI_TRUE ((mali_bool)1) #endif @@ -700,6 +700,16 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ); * resource whose IRQ handling is to be terminated. */ void _mali_osk_irq_term( _mali_osk_irq_t *irq ); + +/** @brief flushing workqueue. + * + * This will flush the workqueue. + * + * @param irq a pointer to the _mali_osk_irq_t object corresponding to the + * resource whose IRQ handling is to be terminated. + */ +void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ); + /** @} */ /* end group _mali_osk_irq */ @@ -785,6 +795,10 @@ void _mali_osk_atomic_term( _mali_osk_atomic_t *atom ); * Returns a buffer capable of containing at least \a n elements of \a size * bytes each. The buffer is initialized to zero. * + * If there is a need for a bigger block of memory (16KB or bigger), then + * consider to use _mali_osk_vmalloc() instead, as this function might + * map down to a OS function with size limitations. + * * The buffer is suitably aligned for storage and subsequent access of every * type that the compiler supports. Therefore, the pointer to the start of the * buffer may be cast into any pointer type, and be subsequently accessed from @@ -807,6 +821,10 @@ void *_mali_osk_calloc( u32 n, u32 size ); * Returns a buffer capable of containing at least \a size bytes. The * contents of the buffer are undefined. * + * If there is a need for a bigger block of memory (16KB or bigger), then + * consider to use _mali_osk_vmalloc() instead, as this function might + * map down to a OS function with size limitations. + * * The buffer is suitably aligned for storage and subsequent access of every * type that the compiler supports. Therefore, the pointer to the start of the * buffer may be cast into any pointer type, and be subsequently accessed from @@ -840,6 +858,46 @@ void *_mali_osk_malloc( u32 size ); */ void _mali_osk_free( void *ptr ); +/** @brief Allocate memory. + * + * Returns a buffer capable of containing at least \a size bytes. The + * contents of the buffer are undefined. + * + * This function is potentially slower than _mali_osk_malloc() and _mali_osk_calloc(), + * but do support bigger sizes. + * + * The buffer is suitably aligned for storage and subsequent access of every + * type that the compiler supports. Therefore, the pointer to the start of the + * buffer may be cast into any pointer type, and be subsequently accessed from + * such a pointer, without loss of information. + * + * When the buffer is no longer in use, it must be freed with _mali_osk_free(). + * Failure to do so will cause a memory leak. + * + * @note Most toolchains supply memory allocation functions that meet the + * compiler's alignment requirements. + * + * Remember to free memory using _mali_osk_free(). + * @param size Number of bytes to allocate + * @return On success, the buffer allocated. NULL on failure. + */ +void *_mali_osk_valloc( u32 size ); + +/** @brief Free memory. + * + * Reclaims the buffer pointed to by the parameter \a ptr for the system. + * All memory returned from _mali_osk_valloc() must be freed before the + * application exits. Otherwise a memory leak will occur. + * + * Memory must be freed once. It is an error to free the same non-NULL pointer + * more than once. + * + * It is legal to free the NULL pointer. + * + * @param ptr Pointer to buffer to free + */ +void _mali_osk_vfree( void *ptr ); + /** @brief Copies memory. * * Copies the \a len bytes from the buffer pointed by the parameter \a src @@ -871,7 +929,7 @@ void *_mali_osk_memset( void *s, u32 c, u32 n ); /** @brief Checks the amount of memory allocated * - * Checks that not more than \a max_allocated bytes are allocated. + * Checks that not more than \a max_allocated bytes are allocated. * * Some OS bring up an interactive out of memory dialogue when the * system runs out of memory. This can stall non-interactive @@ -879,7 +937,7 @@ void *_mali_osk_memset( void *s, u32 c, u32 n ); * not trigger the OOM dialogue by keeping allocations * within a certain limit. * - * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE + * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE * when at least \a max_allocated bytes are in use. */ mali_bool _mali_osk_mem_check_allocated( u32 max_allocated ); @@ -971,12 +1029,18 @@ void _mali_osk_lock_term( _mali_osk_lock_t *lock ); /** @brief Issue a memory barrier * - * This defines an arbitrary memory barrier operation, which affects memory - * mapped by _mali_osk_mem_mapregion. It will not be needed for memory - * mapped through _mali_osk_mem_mapioregion. + * This defines an arbitrary memory barrier operation, which forces an ordering constraint + * on memory read and write operations. */ void _mali_osk_mem_barrier( void ); +/** @brief Issue a write memory barrier + * + * This defines an write memory barrier operation which forces an ordering constraint + * on memory write operations. + */ +void _mali_osk_write_mem_barrier( void ); + /** @brief Map a physically contiguous region into kernel space * * This is primarily used for mapping in registers from resources, and Mali-MMU @@ -1120,7 +1184,21 @@ void _mali_osk_mem_unreqregion( u32 phys, u32 size ); u32 _mali_osk_mem_ioread32( volatile mali_io_address mapping, u32 offset ); /** @brief Write to a location currently mapped in through - * _mali_osk_mem_mapioregion + * _mali_osk_mem_mapioregion without memory barriers + * + * This write a 32-bit word to a 32-bit aligned location without using memory barrier. + * It is a programming error to provide unaligned locations, or to write to memory that is not + * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or + * _mali_osk_mem_allocioregion(). + * + * @param mapping Mali IO address to write to + * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4 + * @param val the 32-bit word to write. + */ +void _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ); + +/** @brief Write to a location currently mapped in through + * _mali_osk_mem_mapioregion with write memory barrier * * This write a 32-bit word to a 32-bit aligned location. It is a programming * error to provide unaligned locations, or to write to memory that is not @@ -1147,7 +1225,7 @@ void _mali_osk_cache_flushall( void ); * * Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory. * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches. - * This is required for MALI to have the correct view of the memory. + * This is required for MALI to have the correct view of the memory. */ void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ); @@ -1522,7 +1600,7 @@ u32 _mali_osk_time_tickcount( void ); void _mali_osk_time_ubusydelay( u32 usecs ); /** @brief Return time in nano seconds, since any given reference. - * + * * @return Time in nano seconds */ u64 _mali_osk_time_get_ns( void ); @@ -1559,6 +1637,18 @@ u32 _mali_osk_clz( u32 val ); */ void _mali_osk_dbgmsg( const char *fmt, ... ); +/** @brief Print fmt into buf. + * + * The interpretation of \a fmt is the same as the \c format parameter in + * _mali_osu_vsnprintf(). + * + * @param buf a pointer to the result buffer + * @param size the total number of bytes allowed to write to \a buf + * @param fmt a _mali_osu_vsnprintf() style format string + * @param ... a variable-number of parameters suitable for \a fmt + */ +u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ); + /** @brief Abnormal process abort. * * Terminates the caller-process if this function is called. @@ -1594,8 +1684,13 @@ u32 _mali_osk_get_pid(void); */ u32 _mali_osk_get_tid(void); -/** @} */ /* end group _mali_osk_miscellaneous */ +/** @brief Return a handle to the current task. + * + * @return An OS-specific handle to the current task. + */ +void * _mali_osk_get_task(void); +/** @} */ /* end group _mali_osk_miscellaneous */ /** @} */ /* end group osuapi */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h index 28026ba1e6d..f262f7dad37 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h new file mode 100644 index 00000000000..a291bd1965b --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h @@ -0,0 +1,183 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_OSK_PROFILING_H__ +#define __MALI_OSK_PROFILING_H__ + +#if MALI_TIMELINE_PROFILING_ENABLED + +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */ + +#include "mali_cinstr_profiling_events_m200.h" + +#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 + +#define MALI_PROFILING_PP_CORE_COUNTER0_OFFSET(core_number) (((core_number) * 2) + COUNTER_FP0_C0) +#define MALI_PROFILING_PP_CORE_COUNTER1_OFFSET(core_number) (((core_number) * 2) + COUNTER_FP0_C1) + +/** @defgroup _mali_osk_profiling External profiling connectivity + * @{ */ + +/** + * Initialize the profiling module. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start); + +/* + * Terminate the profiling module. + */ +void _mali_osk_profiling_term(void); + +/** + * Start recording profiling data + * + * The specified limit will determine how large the capture buffer is. + * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver. + * + * @param limit The desired maximum number of events to record on input, the actual maximum on output. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit); + +/** + * Add an profiling event + * + * @param event_id The event identificator. + * @param data0 First data parameter, depending on event_id specified. + * @param data1 Second data parameter, depending on event_id specified. + * @param data2 Third data parameter, depending on event_id specified. + * @param data3 Fourth data parameter, depending on event_id specified. + * @param data4 Fifth data parameter, depending on event_id specified. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +/* + * On platforms where we are using Linux tracepoints and we aren't forcing + * internal profiling we can call through to the tracepoint directly and + * avoid the overhead of the function call. + */ +#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) \ + trace_mali_timeline_event((event_id), (data0), (data1), (u32)_mali_osk_get_task(), (data3), (data4)) +#else +void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4); +#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */ + +/** + * Report a hardware counter event. + * + * @param counter_id The ID of the counter. + * @param value The value of the counter. + */ +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +/* + * On platforms where we are using Linux tracepoints and we aren't forcing + * internal profiling we can call through to the tracepoint directly and + * avoid the overhead of the function call. + */ +#define _mali_osk_profiling_report_hw_counter trace_mali_hw_counter +#else +void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value); +#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */ + +/** + * Query a hardware counter. Given a counter ID, check which event the + * counter should report and update the given pointer with that event + * number before returning MALI_TRUE. If the counter has been disabled + * by the profiling tool, returns MALI_FALSE and does not update the + * pointer. + * + * MALI_FALSE is also returned if the counter is not a valid hardware + * counter ID. In this case the event value is not updated. + * + * @param counter_id The counter ID. + * @param event_id A pointer to a u32 value that will be updated with + * the event ID that should be counted, should the counter have been + * enabled by the profiling tool. + * + * @return MALI_TRUE if the counter should be enabled, MALI_FALSE otherwise. + */ +mali_bool _mali_osk_profiling_query_hw_counter(u32 counter_id, u32 *event_id); + +/** + * Stop recording profiling data + * + * @param count Returns the number of recorded events. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count); + +/** + * Retrieves the number of events that can be retrieved + * + * @return The number of recorded events that can be retrieved. + */ +u32 _mali_osk_profiling_get_count(void); + +/** + * Retrieve an event + * + * @param index Event index (start with 0 and continue until this function fails to retrieve all events) + * @param timestamp The timestamp for the retrieved event will be stored here. + * @param event_id The event ID for the retrieved event will be stored here. + * @param data The 5 data values for the retrieved event will be stored here. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]); + +/** + * Clear the recorded buffer. + * + * This is needed in order to start another recording. + * + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_clear(void); + +/** + * Checks if a recording of profiling data is in progress + * + * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not + */ +mali_bool _mali_osk_profiling_is_recording(void); + +/** + * Checks if profiling data is available for retrival + * + * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not + */ +mali_bool _mali_osk_profiling_have_recording(void); + +/** + * Enable or disable profiling events as default for new sessions (applications) + * + * @param enable MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE + */ +void _mali_osk_profiling_set_default_enable_state(mali_bool enable); + +/** + * Get current default enable state for new sessions (applications) + * + * @return MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE + */ +mali_bool _mali_osk_profiling_get_default_enable_state(void); + +/** @} */ /* end group _mali_osk_profiling */ + +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ + +#endif /* __MALI_OSK_PROFILING_H__ */ + + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h index 9a1583658c9..433de1fc537 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h @@ -121,6 +121,7 @@ typedef enum _MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */ _MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */ _MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */ + _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */ #if USING_MALI_PMM /** Power Management Module Functions */ @@ -461,6 +462,8 @@ typedef struct u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */ u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */ u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */ + u32 frame_builder_id; /**< [in] id of the originating frame builder */ + u32 flush_id; /**< [in] flush id within the originating frame builder */ } _mali_uk_gp_start_job_s; #define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */ @@ -574,6 +577,8 @@ typedef struct u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */ u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */ u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */ + u32 frame_builder_id; /**< [in] id of the originating frame builder */ + u32 flush_id; /**< [in] flush id within the originating frame builder */ } _mali_uk_pp_start_job_s; /** @} */ /* end group _mali_uk_ppstartjob_s */ @@ -733,7 +738,7 @@ typedef struct * The 16bit integer is stored twice in a 32bit integer * For example, for version 1 the value would be 0x00010001 */ -#define _MALI_API_VERSION 8 +#define _MALI_API_VERSION 9 #define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION) /** @@ -1019,6 +1024,11 @@ typedef struct void *ctx; /**< [in,out] user-kernel context (trashed on output) */ } _mali_uk_profiling_clear_s; +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 enable_events; /**< [out]Â 1 if user space process should generate events, 0 if not */ +} _mali_uk_profiling_get_config_s; /** @} */ /* end group _mali_uk_gp */ @@ -1102,7 +1112,7 @@ typedef u32 mali_pmm_message_data; /** @brief Arguments to _mali_ukk_pmm_event_message() */ -typedef struct +typedef struct { void *ctx; /**< [in,out] user-kernel context (trashed on output) */ u32 id; /**< [in] event id */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h index d066046901d..c70dccc3c20 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h @@ -663,7 +663,7 @@ _mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args); _mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args); /** @brief Stop recording profiling events. - * + * * @param args see _mali_uk_profiling_stop_s in "mali_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args); @@ -680,6 +680,13 @@ _mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s */ _mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args); +/** @brief Get the profiling config applicable for calling process. + * + * @param args see _mali_uk_profiling_get_config_s in "mali_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args); + + /** @} */ /* end group _mali_uk_profiling */ #endif @@ -702,6 +709,7 @@ _mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s * /** @} */ /* end group uddapi */ +u32 _mali_ukk_report_memory_usage(void); #ifdef __cplusplus } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c index eeb29589ddc..1b17a9ffe95 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c @@ -23,6 +23,7 @@ #include "mali_pmm_system.h" #include "mali_pmm_state.h" #include "mali_pmm_policy.h" +#include "mali_pmm_pmu.h" #include "mali_platform.h" /* Internal PMM subsystem state */ @@ -64,7 +65,7 @@ _mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifi void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ); #if MALI_STATE_TRACKING - void malipmm_subsystem_dump_state( void ); +u32 malipmm_subsystem_dump_state( char *buf, u32 size ); #endif @@ -295,7 +296,7 @@ _mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy ) MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS ); } -#if MALI_PMM_TRACE +#if ( MALI_PMM_TRACE || MALI_STATE_TRACKING ) /* Event names - order must match mali_pmm_event_id enum */ static char *pmm_trace_events[] = { @@ -307,19 +308,6 @@ static char *pmm_trace_events[] = { "TIMEOUT", }; -/* UK event names - order must match mali_pmm_event_id enum */ -static char *pmm_trace_events_uk[] = { - "UKS", - "UK_EXAMPLE", -}; - -/* Internal event names - order must match mali_pmm_event_id enum */ -static char *pmm_trace_events_internal[] = { - "INTERNALS", - "INTERNAL_POWER_UP_ACK", - "INTERNAL_POWER_DOWN_ACK", -}; - /* State names - order must match mali_pmm_state enum */ static char *pmm_trace_state[] = { "UNAVAILABLE", @@ -335,6 +323,35 @@ static char *pmm_trace_policy[] = { "JOB CONTROL", }; +/* Status names - order must match mali_pmm_status enum */ +static char *pmm_trace_status[] = { + "MALI_PMM_STATUS_IDLE", /**< PMM is waiting next event */ + "MALI_PMM_STATUS_POLICY_POWER_DOWN", /**< Policy initiated power down */ + "MALI_PMM_STATUS_POLICY_POWER_UP", /**< Policy initiated power down */ + "MALI_PMM_STATUS_OS_WAITING", /**< PMM is waiting for OS power up */ + "MALI_PMM_STATUS_OS_POWER_DOWN", /**< OS initiated power down */ + "MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS", + "MALI_PMM_STATUS_DVFS_PAUSE", /**< PMM DVFS Status Pause */ + "MALI_PMM_STATUS_OS_POWER_UP", /**< OS initiated power up */ + "MALI_PMM_STATUS_OFF", /**< PMM is not active */ +}; + +#endif /* MALI_PMM_TRACE || MALI_STATE_TRACKING */ +#if MALI_PMM_TRACE + +/* UK event names - order must match mali_pmm_event_id enum */ +static char *pmm_trace_events_uk[] = { + "UKS", + "UK_EXAMPLE", +}; + +/* Internal event names - order must match mali_pmm_event_id enum */ +static char *pmm_trace_events_internal[] = { + "INTERNALS", + "INTERNAL_POWER_UP_ACK", + "INTERNAL_POWER_DOWN_ACK", +}; + void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate ) { const char *dname; @@ -480,11 +497,11 @@ _mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource) /* Set up assumes all values are initialized to NULL or MALI_FALSE, so * we can exit halfway through set up and perform clean up */ -#if !MALI_PMM_NO_PMU - if( mali_platform_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup; - pmm_state->pmu_initialized = MALI_TRUE; -#endif +#if USING_MALI_PMU + if( mali_pmm_pmu_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup; + pmm_state->pmu_initialized = MALI_TRUE; +#endif pmm_state->queue = _mali_osk_notification_queue_init(); if( !pmm_state->queue ) goto pmm_fail_cleanup; @@ -518,12 +535,18 @@ pmm_fail_cleanup: MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") ); if( pmm_state ) { - _mali_osk_resource_type_t t = PMU; if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock ); if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq ); if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue ); if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue ); - if( pmm_state->pmu_initialized ) ( mali_platform_deinit(&t) ); +#if USING_MALI_PMU + if( pmm_state->pmu_initialized ) + { + _mali_osk_resource_type_t t = PMU; + mali_pmm_pmu_deinit(&t); + } +#endif /* USING_MALI_PMU */ + _mali_osk_free(pmm_state); pmm_state = NULL; } @@ -547,6 +570,23 @@ _mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifi return pmm_policy_init( pmm ); } +void malipmm_force_powerup( void ) +{ + _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; + MALI_DEBUG_ASSERT_POINTER(pmm); + MALI_PMM_LOCK(pmm); + pmm->status = MALI_PMM_STATUS_OFF; + MALI_PMM_UNLOCK(pmm); + + /* flush PMM workqueue */ + _mali_osk_flush_workqueue( pmm->irq ); + + if (pmm->cores_powered == 0) + { + malipmm_powerup(pmm->cores_registered); + } +} + void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) { /* Check this is the right system */ @@ -555,7 +595,6 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) if( pmm_state ) { - _mali_osk_resource_type_t t = PMU; #if PMM_OS_TEST power_test_end(); #endif @@ -569,11 +608,20 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) pmm_state->mali_pmm_lock_acquired = 0; #endif /* MALI_STATE_TRACKING */ MALI_PMM_UNLOCK(pmm_state); + _mali_osk_pmm_ospmm_cleanup(); pmm_policy_term(pmm_state); _mali_osk_irq_term( pmm_state->irq ); _mali_osk_notification_queue_term( pmm_state->queue ); _mali_osk_notification_queue_term( pmm_state->iqueue ); - if( pmm_state->pmu_initialized ) mali_platform_deinit(&t); + if (pmm_state->cores_registered) malipmm_powerdown(pmm_state->cores_registered,MALI_POWER_MODE_LIGHT_SLEEP); +#if USING_MALI_PMU + if( pmm_state->pmu_initialized ) + { + _mali_osk_resource_type_t t = PMU; + mali_pmm_pmu_deinit(&t); + } +#endif /* USING_MALI_PMU */ + _mali_osk_atomic_term( &(pmm_state->messages_queued) ); MALI_PMM_LOCK_TERM(pmm_state); _mali_osk_free(pmm_state); @@ -583,6 +631,47 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") ); } +_mali_osk_errcode_t malipmm_powerup( u32 cores ) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; + + /* If all the cores are powered down, power up the MALI */ + if (pmm->cores_powered == 0) + { + mali_platform_power_mode_change(MALI_POWER_MODE_ON); +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + /* Initiate the power up */ + _mali_osk_pmm_dev_activate(); +#endif + } + +#if USING_MALI_PMU + err = mali_pmm_pmu_powerup( cores ); +#endif + return err; +} + +_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode ) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; +#if USING_MALI_PMU + err = mali_pmm_pmu_powerdown( cores ); +#endif + + /* If all cores are powered down, power off the MALI */ + if (pmm->cores_powered == 0) + { +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + /* Initiate the power down */ + _mali_osk_pmm_dev_idle(); +#endif + mali_platform_power_mode_change(power_mode); + } + return err; +} + _mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core ) { _mali_osk_errcode_t err; @@ -614,7 +703,7 @@ _mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core ) #if !MALI_PMM_NO_PMU /* Make sure the core is powered up */ - err = mali_platform_powerup( core ); + err = malipmm_powerup( core ); #else err = _MALI_OSK_ERR_OK; #endif @@ -668,18 +757,7 @@ void malipmm_core_unregister( mali_pmm_core_id core ) #if MALI_PMM_TRACE mali_pmm_core_mask old_power = pmm->cores_powered; #endif - -#if !MALI_PMM_NO_PMU - /* Turn off the core */ - if( mali_platform_powerdown( core ) != _MALI_OSK_ERR_OK ) - { - MALI_PRINT_ERROR( ("PMM: Error powering down unregistered core: (0x%x) %s\n", - core, pmm_trace_get_core_name(core)) ); - } -#endif - /* Remove the core from the system */ - pmm->cores_registered &= (~core); pmm->cores_idle &= (~core); pmm->cores_powered &= (~core); pmm->cores_pend_down &= (~core); @@ -740,7 +818,7 @@ void malipmm_irq_bhandler(void *data) #endif MALI_PMM_LOCK(pmm); -#ifdef MALI_STATE_TRACKING +#if MALI_STATE_TRACKING pmm->mali_pmm_lock_acquired = 1; #endif /* MALI_STATE_TRACKING */ @@ -825,10 +903,10 @@ static void pmm_event_process( void ) return; } else - { + { #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) pmm->messages_received++; - #endif + #endif } } else @@ -843,7 +921,7 @@ static void pmm_event_process( void ) { #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) pmm->imessages_received++; - #endif + #endif } MALI_DEBUG_ASSERT_POINTER( msg ); @@ -893,29 +971,36 @@ static void pmm_event_process( void ) } #if MALI_STATE_TRACKING -void malipmm_subsystem_dump_state(void) -{ - malipmm_state_dump(); -} -#endif - -#if (defined(DEBUG) || MALI_STATE_TRACKING) -void malipmm_state_dump() +u32 malipmm_subsystem_dump_state(char *buf, u32 size) { + int len = 0; _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; if( !pmm ) { - MALI_PRINT(("PMM: Null state\n")); + len += _mali_osk_snprintf(buf + len, size + len, "PMM: Null state\n"); } else { - MALI_PRINT(("Locks::\nPMM_LOCK_STATUS=%ld",pmm->mali_pmm_lock_acquired)); - MALI_PRINT(("PMM state:\nPrevious_status=%d\nstatus=%d\nCurrent_event=%d\npolicy=%d\ncheck_policy=%d\nstate=%d\n", pmm->mali_last_pmm_status,pmm->status, pmm->mali_new_event_status, pmm->policy, pmm->check_policy, pmm->state)); - MALI_PRINT(("PMM cores:\ncores_registered=%d\ncores_powered=%d\ncores_idle=%d\ncores_pend_down=%d\ncores_pend_up=%d\ncores_ack_down=%d\ncores_ack_up=%d\n", pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down, pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up)); - MALI_PRINT(("PMM misc:\npmu_init=%d\nmessages_queued=%d\nwaiting=%d\nno_events=%d\nmissed=%d\nfatal_power_err=%d\n", pmm->pmu_initialized, _mali_osk_atomic_read( &(pmm->messages_queued) ), pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err)); + len += _mali_osk_snprintf(buf+len, size+len, "Locks:\n PMM lock acquired: %s\n", + pmm->mali_pmm_lock_acquired ? "true" : "false"); + len += _mali_osk_snprintf(buf+len, size+len, + "PMM state:\n Previous status: %s\n Status: %s\n Current event: %s\n Policy: %s\n Check policy: %s\n State: %s\n", + pmm_trace_status[pmm->mali_last_pmm_status], pmm_trace_status[pmm->status], + pmm_trace_events[pmm->mali_new_event_status], pmm_trace_policy[pmm->policy], + pmm->check_policy ? "true" : "false", pmm_trace_state[pmm->state]); + len += _mali_osk_snprintf(buf+len, size+len, + "PMM cores:\n Cores registered: %d\n Cores powered: %d\n Cores idle: %d\n" + " Cores pending down: %d\n Cores pending up: %d\n Cores ack down: %d\n Cores ack up: %d\n", + pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down, + pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up); + len += _mali_osk_snprintf(buf+len, size+len, "PMM misc:\n PMU init: %s\n Messages queued: %d\n" + " Waiting: %d\n No events: %d\n Missed events: %d\n Fatal power error: %s\n", + pmm->pmu_initialized ? "true" : "false", _mali_osk_atomic_read(&(pmm->messages_queued)), + pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err ? "true" : "false"); } + return len; } -#endif +#endif /* MALI_STATE_TRACKING */ #endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h index fe7a046cb47..6157746da0c 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h @@ -18,6 +18,7 @@ /* For mali_pmm_message_data and MALI_PMM_EVENT_UK_* defines */ #include "mali_uk_types.h" +#include "mali_platform.h" #ifdef __cplusplus extern "C" @@ -40,7 +41,7 @@ extern "C" /** @brief Compile option to switch between always on or job control PMM policy */ #define MALI_PMM_ALWAYS_ON 0 -/** @brief Overrides hardware PMU and uses software simulation instead +/** @brief Overrides hardware PMU and uses software simulation instead * @note This even stops intialization of PMU and cores being powered on at start up */ #define MALI_PMM_NO_PMU 0 @@ -52,7 +53,7 @@ extern "C" /** @brief power management event message identifiers. */ -/* These must match up with the pmm_trace_events & pmm_trace_events_internal +/* These must match up with the pmm_trace_events & pmm_trace_events_internal * arrays */ typedef enum mali_pmm_event_id @@ -95,6 +96,7 @@ typedef enum mali_pmm_core_id_tag MALI_PMM_CORE_PP_ALL = 0x0000003C /**< Mali 200 pixel processors 0-3 */ } mali_pmm_core_id; + /* @brief PMM bitmask of mali_pmm_core_ids */ typedef u32 mali_pmm_core_mask; @@ -137,6 +139,23 @@ typedef enum mali_pmm_policy_tag MALI_PMM_POLICY_RUNTIME_JOB_CONTROL = 3 /**< Run time power management control policy */ } mali_pmm_policy; +/** @brief Function to power up MALI + * + * @param cores core mask to power up the cores + * + * @return error code if MALI fails to power up + */ +_mali_osk_errcode_t malipmm_powerup( u32 cores ); + +/** @brief Function to power down MALI + * + * @param cores core mask to power down the cores + * @param The power mode to which MALI transitions + * + * @return error code if MALI fails to power down + */ +_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode ); + /** @brief Function to report to the OS when the power down has finished * * @param data The event message data that initiated the power down @@ -149,7 +168,7 @@ void _mali_osk_pmm_power_down_done(mali_pmm_message_data data); */ void _mali_osk_pmm_power_up_done(mali_pmm_message_data data); -/** @brief Function to report that DVFS operation done +/** @brief Function to report that DVFS operation done * * @param data The event message data */ @@ -164,6 +183,12 @@ void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id event_id); #endif +/** @brief Function to power up MALI + * + * @note powers up the MALI during MALI device driver is unloaded + */ +void malipmm_force_powerup( void ); + /** @brief Function to report the OS that device is idle * * @note inform the OS that device is idle @@ -176,6 +201,12 @@ _mali_osk_errcode_t _mali_osk_pmm_dev_idle( void ); */ void _mali_osk_pmm_dev_activate( void ); +/** @brief Function to report OS PMM for cleanup + * + * @note Function to report OS PMM for cleanup + */ +void _mali_osk_pmm_ospmm_cleanup( void ); + /** @brief Queries the current state of the PMM software * * @note the state of the PMM can change after this call has returned @@ -305,15 +336,9 @@ void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool receive /** @brief Dumps the current state of OS PMM thread */ #if MALI_STATE_TRACKING -void mali_pmm_dump_os_thread_state( void ); +u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ); #endif /* MALI_STATE_TRACKING */ -#if (defined(DEBUG) || MALI_STATE_TRACKING) -/** @brief Dumps the current state of the PMM - */ -void malipmm_state_dump( void ); -#endif - /** @} */ /* end group pmmapi */ #ifdef __cplusplus diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali400-pmu/mali_platform.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c index cf95b8ae09e..da8957724e8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali400-pmu/mali_platform.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c @@ -9,13 +9,14 @@ */ /** - * @file mali_platform.c - * Platform specific Mali driver functions for Mali 400 PMU hardware + * @file mali_pmm_pmu.c + * Mali driver functions for Mali 400 PMU hardware */ #include "mali_kernel_common.h" #include "mali_osk.h" #include "mali_platform.h" +#if USING_MALI_PMU #if USING_MALI_PMM #include "mali_pmm.h" @@ -23,6 +24,10 @@ /* Internal test on/off */ #define PMU_TEST 0 +#if MALI_POWER_MGMT_TEST_SUITE +#include "mali_platform_pmu_internal_testing.h" +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + /** @brief PMU hardware info */ typedef struct platform_pmu @@ -53,25 +58,18 @@ typedef enum { } pmu_reg_addr_mgmt_addr; /* Internal functions */ -u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address); -void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val); -mali_pmm_core_mask pmu_translate_cores_to_pmu(mali_pmm_core_mask cores); +static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address); +static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val); +static mali_pmm_core_mask pmu_translate_cores_to_pmu(mali_pmm_core_mask cores); #if PMU_TEST -void pmm_pmu_dump_regs( platform_pmu_t *pmu ); -void pmm_pmu_test( platform_pmu_t *pmu, u32 cores ); +static void pmm_pmu_dump_regs( platform_pmu_t *pmu ); +static pmm_pmu_test( platform_pmu_t *pmu, u32 cores ); #endif -#endif /* USING_MALI_PMM */ - - -_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource) +_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource) { -#if USING_MALI_PMM - if( resource == NULL ) - { - /* Nothing to set up for the system */ - } - else if( resource->type == PMU ) + + if( resource->type == PMU ) { if( (resource->base == 0) || (resource->description == NULL) ) @@ -80,8 +78,6 @@ _mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource) MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } - - MALI_DEBUG_ASSERT( pmu_info == NULL ); pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info)); MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM ); @@ -142,22 +138,11 @@ cleanup: _mali_osk_free(pmu_info); pmu_info = NULL; MALI_ERROR(_MALI_OSK_ERR_NOMEM); - -#else - /* Nothing to do when not using PMM - as mali already on */ - MALI_SUCCESS; -#endif - } -_mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type) +_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type) { -#if USING_MALI_PMM - if( type == NULL ) - { - /* Nothing to tear down for the system */ - } - else if (*type == PMU) + if (*type == PMU) { if( pmu_info ) { @@ -165,7 +150,6 @@ _mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type) _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size); _mali_osk_free(pmu_info); pmu_info = NULL; - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") ); } } @@ -177,15 +161,10 @@ _mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type) MALI_SUCCESS; -#else - /* Nothing to do when not using PMM */ - MALI_SUCCESS; -#endif } -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) +_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores) { -#if USING_MALI_PMM u32 stat; u32 timeout; u32 cores_pmu; @@ -212,16 +191,10 @@ _mali_osk_errcode_t mali_platform_powerdown(u32 cores) if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); MALI_SUCCESS; - -#else - /* Nothing to do when not using PMM */ - MALI_SUCCESS; -#endif } -_mali_osk_errcode_t mali_platform_powerup(u32 cores) +_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores) { -#if USING_MALI_PMM u32 cores_pmu; u32 stat; u32 timeout; @@ -249,18 +222,8 @@ _mali_osk_errcode_t mali_platform_powerup(u32 cores) if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); MALI_SUCCESS; - -#else - /* Nothing to do when not using PMM */ - MALI_SUCCESS; -#endif } -void mali_gpu_utilization_handler(u32 utilization) -{ -} - -#if USING_MALI_PMM /***** INTERNAL *****/ @@ -270,7 +233,7 @@ void mali_gpu_utilization_handler(u32 utilization) * @param cores PMM cores bitmask * @return PMU hardware cores bitmask */ -u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores) +static u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores) { /* For Mali 400 PMU the cores mask is already the same as what * the hardware PMU expects. @@ -287,7 +250,7 @@ u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores) * @param relative_address relative PMU hardware address to read from * @return 32-bit value that was read from the address */ -u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address) +static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address) { u32 read_val; @@ -309,7 +272,7 @@ u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address) * @param relative_address relative PMU hardware address to write to * @param new_val new 32-bit value to write into the address */ -void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val) +static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val) { MALI_DEBUG_ASSERT_POINTER(pmu); MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); @@ -321,23 +284,11 @@ void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val) _mali_osk_mem_iowrite32(pmu->reg_mapped, relative_address, new_val); } -#if MALI_POWER_MGMT_TEST_SUITE - -u32 pmu_get_power_up_down_info(void) -{ - return pmu_reg_read(pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS); -} - -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - -#endif /* USING_MALI_PMM */ - - -#if USING_MALI_PMM && PMU_TEST +#if PMU_TEST /***** TEST *****/ -void pmu_dump_regs( platform_pmu_t *pmu ) +static void pmu_dump_regs( platform_pmu_t *pmu ) { u32 addr; for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 ) @@ -347,7 +298,7 @@ void pmu_dump_regs( platform_pmu_t *pmu ) } /* This function is an internal test for the PMU without any Mali h/w interaction */ -void pmu_test( platform_pmu_t *pmu, u32 cores ) +static void pmu_test( platform_pmu_t *pmu, u32 cores ) { u32 stat; u32 timeout; @@ -385,4 +336,15 @@ void pmu_test( platform_pmu_t *pmu, u32 cores ) MALI_PRINT( ("PMU_TEST: Finish\n") ); } -#endif /* USING_MALI_PMM && PMU_TEST */ +#endif /* PMU_TEST */ + +#if MALI_POWER_MGMT_TEST_SUITE + +u32 pmu_get_power_up_down_info(void) +{ + return pmu_reg_read(pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS); +} + +#endif /* MALI_POWER_MGMT_TEST_SUITE */ +#endif /* USING_MALI_PMM */ +#endif /* USING_MALI_PMU */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h new file mode 100644 index 00000000000..112074b2010 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_platform.h + * Platform specific Mali driver functions + */ + +#include "mali_osk.h" + +#if !USING_MALI_PMM +/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */ +#define MALI_PLATFORM_SYSTEM 0 +#endif + +#if USING_MALI_PMM +#if USING_MALI_PMU +#include "mali_pmm.h" + +/** @brief Platform specific setup and initialisation of MALI + * + * This is called from the entrypoint of the driver to initialize the platform + * When using PMM, it is also called from the PMM start up to initialise the + * system PMU + * + * @param resource This is NULL when called on first driver start up, else it will + * be a pointer to a PMU resource + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource); + +/** @brief Platform specific deinitialisation of MALI + * + * This is called on the exit of the driver to terminate the platform + * When using PMM, it is also called from the PMM termination code to clean up the + * system PMU + * + * @param type This is NULL when called on driver exit, else it will + * be a pointer to a PMU resource type (not the full resource) + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type); + +/** @brief Platform specific powerdown sequence of MALI + * + * Called as part of platform init if there is no PMM support, else the + * PMM will call it. + * + * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will + * be a mask of cores to power down based on the mali_pmm_core_id enum + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores); + +/** @brief Platform specific powerup sequence of MALI + * + * Called as part of platform deinit if there is no PMM support, else the + * PMM will call it. + * + * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will + * be a mask of cores to power down based on the mali_pmm_core_id enum + * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. + */ +_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores); + +#if MALI_POWER_MGMT_TEST_SUITE +#if USING_MALI_PMM +#if USING_MALI_PMU +/** @brief function to get status of individual cores + * + * This function is used by power management test suite to get the status of powered up/down the number + * of cores + * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. + */ +u32 pmu_get_power_up_down_info(void); +#endif +#endif +#endif +#endif +#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h index 83cb7f29a92..739c4c4ef17 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h @@ -46,7 +46,7 @@ typedef struct _pmm_policy_timer /** @brief Policy timer initialization * * This will create a timer for use in policies, but won't start it - * + * * @param pptimer An empty timer structure to be initialized * @param timeout Timeout in ticks for the timer * @param id Event id that will be raised on timeout @@ -59,7 +59,7 @@ _mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 tim * * This will clean up a timer that was previously used in policies, it * will also stop it if started - * + * * @param pptimer An initialized timer structure to be terminated */ void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer ); @@ -67,10 +67,10 @@ void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer start * * This will start a previously created timer for use in policies - * When the timer expires after the initialized timeout it will raise + * When the timer expires after the initialized timeout it will raise * a PMM event of the event id given on initialization * As data for the event it will pass the start time of the timer - * + * * @param pptimer A previously initialized policy timer * @return MALI_TRUE if the timer was started, MALI_FALSE if it is already started */ @@ -79,7 +79,7 @@ mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer stop * * This will stop a previously created timer for use in policies - * + * * @param pptimer A previously started policy timer * @return MALI_TRUE if the timer was stopped, MALI_FALSE if it is already stopped */ @@ -88,7 +88,7 @@ mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer stop * * This raise an event for an expired timer - * + * * @param pptimer An expired policy timer * @return MALI_TRUE if an event was raised, else MALI_FALSE */ @@ -97,7 +97,7 @@ mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer ); /** @brief Policy timer valid checker * * This will check that a timer was started after a given time - * + * * @param timer_start Time the timer was started * @param other_start Time when another event or action occurred * @return MALI_TRUE if the timer was started after the other time, else MALI_FALSE @@ -106,7 +106,7 @@ mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start ); /** @brief Common policy initialization - * + * * This will initialize the current policy * * @note Any previously initialized policy should be terminated first diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c index 643bb04553b..a4b893b21e6 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c @@ -21,7 +21,6 @@ #include "mali_pmm.h" #include "mali_pmm_system.h" #include "mali_pmm_state.h" -#include "mali_pmm_policy.h" #include "mali_pmm_policy_alwayson.h" _mali_osk_errcode_t pmm_policy_init_always_on(void) diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h index a158b09f610..da13224d955 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c index 8450bd722f4..7f339718354 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c @@ -231,7 +231,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * if( cores_subset != 0 ) { /* There are some cores that need powering down */ - if( !pmm_invoke_power_down( pmm ) ) + if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) { /* We need to wait until they are idle */ @@ -242,6 +242,11 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * break; } } + else + { + mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); + + } /* Set waiting status */ pmm->status = MALI_PMM_STATUS_OS_WAITING; /* All cores now down - respond to OS power event */ @@ -280,7 +285,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * /* Check if we can really power down, if not then we are not * really in-active */ - if( !pmm_invoke_power_down( pmm ) ) + if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_LIGHT_SLEEP ) ) { pmm_power_down_cancel( pmm ); } @@ -322,12 +327,16 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * pmm->status = MALI_PMM_STATUS_OS_WAITING; if ( pmm->cores_powered != 0 ) { - if ( pmm_invoke_power_down( pmm ) ) + if ( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) { _mali_osk_pmm_power_down_done( 0 ); break; } } + else + { + mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); + } _mali_osk_pmm_power_down_done( 0 ); break; default: @@ -384,7 +393,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t * } /* Now check if we can power down */ - if( pmm_invoke_power_down( pmm ) ) + if( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) { if( pmm->status == MALI_PMM_STATUS_OS_POWER_DOWN ) { diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h index 455234b80bc..f1e7c2d9a82 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h @@ -27,10 +27,10 @@ extern "C" * @{ */ -/** @brief The jobcontrol policy inactivity latency timeout (in ticks) +/** @brief The jobcontrol policy inactivity latency timeout (in ticks) * before the hardware is switched off * - * @note Setting this low whilst tracing or producing debug output can + * @note Setting this low whilst tracing or producing debug output can * cause alot of timeouts to fire which can affect the PMM behaviour */ #define MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT 50 diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c index a0ac1c7790c..2e05555cf29 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c @@ -199,6 +199,7 @@ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mal } else { + MALI_DEBUG_PRINT(1,("The error in PMM is ...%x...%x",err,*ppowered)); MALI_DEBUG_ASSERT( err == _MALI_OSK_ERR_BUSY || (err == _MALI_OSK_ERR_FAULT && (*ppowered & cores_list[n]) == 0) ); @@ -297,7 +298,7 @@ mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm ) return ( pmm->cores_pend_down == pmm->cores_ack_down ? MALI_TRUE : MALI_FALSE ); } -mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) +mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode ) { _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(pmm); @@ -315,8 +316,9 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) } else { + pmm->cores_powered &= ~(pmm->cores_pend_down); #if !MALI_PMM_NO_PMU - err = mali_platform_powerdown( pmm->cores_pend_down ); + err = malipmm_powerdown( pmm->cores_pend_down, power_mode); #else err = _MALI_OSK_ERR_OK; #endif @@ -327,7 +329,6 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) mali_pmm_core_mask old_power = pmm->cores_powered; #endif /* Remove powered down cores from idle and powered list */ - pmm->cores_powered &= ~(pmm->cores_pend_down); pmm->cores_idle &= ~(pmm->cores_pend_down); /* Reset pending/acknowledged status */ pmm->cores_pend_down = 0; @@ -338,6 +339,7 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ) } else { + pmm->cores_powered |= pmm->cores_pend_down; MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power down cores - (0x%x) %s", pmm->cores_pend_down, pmm_trace_get_core_name(pmm->cores_pend_down)) ); pmm->fatal_power_err = MALI_TRUE; @@ -429,7 +431,7 @@ mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm ) { #if !MALI_PMM_NO_PMU /* Power up must now be done */ - err = mali_platform_powerup( pmm->cores_pend_up ); + err = malipmm_powerup( pmm->cores_pend_up ); #else err = _MALI_OSK_ERR_OK; #endif @@ -537,7 +539,7 @@ void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm ) int n; volatile mali_pmm_core_mask *pregistered = &(pmm->cores_registered); #if !MALI_PMM_NO_PMU - err = mali_platform_powerup( pmm->cores_registered ); + err = malipmm_powerup( pmm->cores_registered ); #endif if( err != _MALI_OSK_ERR_OK ) { diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h index 3c8c31f066d..849fe8b8048 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h @@ -55,8 +55,7 @@ typedef enum mali_pmm_status_tag MALI_PMM_STATUS_POLICY_POWER_DOWN, /**< Policy initiated power down */ MALI_PMM_STATUS_POLICY_POWER_UP, /**< Policy initiated power down */ MALI_PMM_STATUS_OS_WAITING, /**< PMM is waiting for OS power up */ - MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */ - MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS, + MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */ MALI_PMM_STATUS_DVFS_PAUSE, /**< PMM DVFS Status Pause */ MALI_PMM_STATUS_OS_POWER_UP, /**< OS initiated power up */ MALI_PMM_STATUS_OFF, /**< PMM is not active */ @@ -96,12 +95,12 @@ typedef struct _mali_pmm_internal_state mali_bool fatal_power_err; /**< PMM has had a fatal power error? */ u32 is_dvfs_active; /**< PMM DVFS activity */ -#if (defined(DEBUG) || MALI_STATE_TRACKING) - u32 mali_last_pmm_status; - u32 mali_new_event_status; - u32 mali_pmm_lock_acquired; +#if MALI_STATE_TRACKING + mali_pmm_status mali_last_pmm_status; /**< The previous PMM status */ + mali_pmm_event_id mali_new_event_status;/**< The type of the last PMM event */ + mali_bool mali_pmm_lock_acquired; /**< Is the PMM lock held somewhere or not */ #endif - + #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) u32 messages_sent; /**< Total event messages sent */ u32 messages_received; /**< Total event messages received */ @@ -133,11 +132,11 @@ mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, m /** @brief Sort out which cores need to be powered up from the given core mask * - * All cores that can be powered up will be put into a pending state + * All cores that can be powered up will be put into a pending state * * @param pmm internal PMM state * @param cores mask of cores to check if they need to be powered up - * @return mask of cores that need to be powered up, this can be 0 if all cores + * @return mask of cores that need to be powered up, this can be 0 if all cores * are powered up already */ mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); @@ -153,7 +152,7 @@ mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_ * @param cores mask of cores to check if they need to be powered down * @param immediate_only MALI_TRUE means that only cores that can power down now will * be put into a pending state - * @return mask of cores that need to be powered down, this can be 0 if all cores + * @return mask of cores that need to be powered down, this can be 0 if all cores * are powered down already */ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only ); @@ -177,13 +176,13 @@ mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm ); /** @brief Try to make all the pending cores power down * - * If all the pending cores have acknowledged they can power down, this will call the + * If all the pending cores have acknowledged they can power down, this will call the * PMU power down function to turn them off * * @param pmm internal PMM state * @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE */ -mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm ); +mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode ); /** @brief Check if all the pending cores to power up have done so * @@ -230,7 +229,7 @@ mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm /** @brief Set the cores that have acknowledged a pending power down * - * Updates which cores have acknowledged the pending power down and are now ready + * Updates which cores have acknowledged the pending power down and are now ready * to be turned off * * @param pmm internal PMM state @@ -253,15 +252,15 @@ mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_p /** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues * - * This will try and make all the cores powered up and reset the PMM state - * to its initial state after core registration - all cores powered but not + * This will try and make all the cores powered up and reset the PMM state + * to its initial state after core registration - all cores powered but not * pending or active. * All events in the event queues will be thrown away. * * @note: Any pending power down will be cancelled including the OS calling for power down */ void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm ); - + /** @brief Save the OS specific data for an OS power up/down event * * @param pmm internal PMM state diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c index 1c1bf306688..7a69ae95011 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c @@ -31,13 +31,8 @@ int mali_dev_pause() { int err = 0; _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND) -#ifdef CONFIG_HAS_EARLYSUSPEND - || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) -#else - ) -#endif + if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) + || (mali_device_state == _MALI_DEVICE_SUSPEND) ) { err = -EPERM; } @@ -56,13 +51,8 @@ int mali_dev_resume() { int err = 0; _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND) -#ifdef CONFIG_HAS_EARLYSUSPEND - || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) -#else - ) -#endif + if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) + || (mali_device_state == _MALI_DEVICE_SUSPEND) ) { err = -EPERM; } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h index 5362f88cdbd..155a3e69d48 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h index 30a6fa041db..47b67cccb82 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h @@ -68,6 +68,7 @@ extern "C" #define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *) #define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *) #define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *) +#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_profiling_get_config_s *) #define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *) #ifdef __cplusplus diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c index a5144faae2b..96ebacced0f 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -16,16 +16,13 @@ #include <linux/fs.h> /* file system operations */ #include <linux/cdev.h> /* character device definitions */ #include <linux/mm.h> /* memory mananger definitions */ -#include <asm/uaccess.h> /* user space access */ #include <linux/device.h> -#include <linux/proc_fs.h> /* the mali kernel subsystem types */ #include "mali_kernel_subsystem.h" /* A memory subsystem always exists, so no need to conditionally include it */ #include "mali_kernel_common.h" -#include "mali_kernel_mem.h" #include "mali_kernel_session_manager.h" #include "mali_kernel_core.h" @@ -36,9 +33,21 @@ #include "mali_ukk_wrappers.h" #include "mali_kernel_pm.h" +#include "mali_kernel_sysfs.h" + /* */ #include "mali_kernel_license.h" +/* Streamline support for the Mali driver */ +#if defined(CONFIG_TRACEPOINTS) +/* Ask Linux to create the tracepoints */ +#define CREATE_TRACE_POINTS +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS */ + +/* from the __malidrv_build_info.c file that is generated during build */ +extern const char *__malidrv_build_info(void); + /* Setting this parameter will override memory settings in arch/config.h */ char *mali_mem = ""; module_param(mali_mem, charp, S_IRUSR | S_IWUSR | S_IWGRP | S_IROTH); /* rw-r--r-- */ @@ -72,24 +81,17 @@ module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache"); #endif -struct mali_dev -{ - struct cdev cdev; -#if MALI_LICENSE_IS_GPL - struct class * mali_class; +#if MALI_TIMELINE_PROFILING_ENABLED +extern int mali_boot_profiling; +module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization"); #endif -}; static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */ /* the mali device */ static struct mali_dev device; -#if MALI_STATE_TRACKING -static struct proc_dir_entry *proc_entry; -static int mali_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data); -#endif - static int mali_open(struct inode *inode, struct file *filp); static int mali_release(struct inode *inode, struct file *filp); @@ -144,33 +146,15 @@ int mali_driver_init(void) return -EFAULT; } + /* print build options */ + MALI_DEBUG_PRINT(2, ("%s\n", __malidrv_build_info())); + return 0; } void mali_driver_exit(void) { - -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - - _mali_osk_pmm_dev_activate(); -#endif -#endif -#endif -#endif - mali_kernel_destructor(); - -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - _mali_osk_pmm_dev_idle(); -#endif -#endif -#endif -#endif + mali_kernel_destructor(); #if USING_MALI_PMM #if MALI_LICENSE_IS_GPL @@ -199,60 +183,39 @@ int initialize_kernel_device(void) err = register_chrdev_region(dev, 1/*count*/, mali_dev_name); } - if (0 == err) + if (err) { - memset(&device, 0, sizeof(device)); - - /* initialize our char dev data */ - cdev_init(&device.cdev, &mali_fops); - device.cdev.owner = THIS_MODULE; - device.cdev.ops = &mali_fops; - - /* register char dev with the kernel */ - err = cdev_add(&device.cdev, dev, 1/*count*/); - - if (0 == err) - { -#if MALI_STATE_TRACKING - proc_entry = create_proc_entry(mali_dev_name, 0444, NULL); - if (proc_entry != NULL) - { - proc_entry->read_proc = mali_proc_read; -#endif -#if MALI_LICENSE_IS_GPL - device.mali_class = class_create(THIS_MODULE, mali_dev_name); - if (IS_ERR(device.mali_class)) - { - err = PTR_ERR(device.mali_class); - } - else - { - struct device * mdev; - mdev = device_create(device.mali_class, NULL, dev, NULL, mali_dev_name); - if (!IS_ERR(mdev)) - { - return 0; - } - - err = PTR_ERR(mdev); - } - cdev_del(&device.cdev); -#else - return 0; -#endif -#if MALI_STATE_TRACKING - remove_proc_entry(mali_dev_name, NULL); - } - else - { - err = EFAULT; - } -#endif - } - unregister_chrdev_region(dev, 1/*count*/); + goto init_chrdev_err; } + memset(&device, 0, sizeof(device)); + + /* initialize our char dev data */ + cdev_init(&device.cdev, &mali_fops); + device.cdev.owner = THIS_MODULE; + device.cdev.ops = &mali_fops; + /* register char dev with the kernel */ + err = cdev_add(&device.cdev, dev, 1/*count*/); + if (err) + { + goto init_cdev_err; + } + + err = mali_sysfs_register(&device, dev, mali_dev_name); + if (err) + { + goto init_sysfs_err; + } + + /* Success! */ + return 0; + +init_sysfs_err: + cdev_del(&device.cdev); +init_cdev_err: + unregister_chrdev_region(dev, 1/*count*/); +init_chrdev_err: return err; } @@ -261,14 +224,7 @@ void terminate_kernel_device(void) { dev_t dev = MKDEV(mali_major, 0); -#if MALI_LICENSE_IS_GPL - device_destroy(device.mali_class, dev); - class_destroy(device.mali_class); -#endif - -#if MALI_STATE_TRACKING - remove_proc_entry(mali_dev_name, NULL); -#endif + mali_sysfs_unregister(&device, dev, mali_dev_name); /* unregister char device */ cdev_del(&device.cdev); @@ -360,8 +316,8 @@ static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) #endif { - int err; - struct mali_session_data *session_data; + int err; + struct mali_session_data *session_data; #ifndef HAVE_UNLOCKED_IOCTL /* inode not used */ @@ -370,93 +326,98 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg)); - session_data = (struct mali_session_data *)filp->private_data; - if (NULL == session_data) + session_data = (struct mali_session_data *)filp->private_data; + if (NULL == session_data) { MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n")); return -ENOTTY; } - if (NULL == (void *)arg) + + if (NULL == (void *)arg) { MALI_DEBUG_PRINT(7, ("arg was NULL\n")); return -ENOTTY; } - switch(cmd) - { - case MALI_IOC_GET_SYSTEM_INFO_SIZE: - err = get_system_info_size_wrapper(session_data, (_mali_uk_get_system_info_size_s __user *)arg); - break; + switch(cmd) + { + case MALI_IOC_GET_SYSTEM_INFO_SIZE: + err = get_system_info_size_wrapper(session_data, (_mali_uk_get_system_info_size_s __user *)arg); + break; - case MALI_IOC_GET_SYSTEM_INFO: - err = get_system_info_wrapper(session_data, (_mali_uk_get_system_info_s __user *)arg); - break; + case MALI_IOC_GET_SYSTEM_INFO: + err = get_system_info_wrapper(session_data, (_mali_uk_get_system_info_s __user *)arg); + break; - case MALI_IOC_WAIT_FOR_NOTIFICATION: - err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); - break; + case MALI_IOC_WAIT_FOR_NOTIFICATION: + err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); + break; - case MALI_IOC_GET_API_VERSION: - err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); - break; + case MALI_IOC_GET_API_VERSION: + err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); + break; - case MALI_IOC_POST_NOTIFICATION: - err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); - break; + case MALI_IOC_POST_NOTIFICATION: + err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); + break; #if MALI_TIMELINE_PROFILING_ENABLED - case MALI_IOC_PROFILING_START: - err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); - break; + case MALI_IOC_PROFILING_START: + err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); + break; case MALI_IOC_PROFILING_ADD_EVENT: - err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); - break; + err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); + break; case MALI_IOC_PROFILING_STOP: - err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); - break; + err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); + break; case MALI_IOC_PROFILING_GET_EVENT: - err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); - break; + err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); + break; case MALI_IOC_PROFILING_CLEAR: - err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); - break; + err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); + break; + + case MALI_IOC_PROFILING_GET_CONFIG: + err = profiling_get_config_wrapper(session_data, (_mali_uk_profiling_get_config_s __user *)arg); + break; #endif - case MALI_IOC_MEM_INIT: - err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); - break; + case MALI_IOC_MEM_INIT: + err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); + break; - case MALI_IOC_MEM_TERM: - err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); - break; + case MALI_IOC_MEM_TERM: + err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); + break; - case MALI_IOC_MEM_MAP_EXT: - err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); - break; + case MALI_IOC_MEM_MAP_EXT: + err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); + break; - case MALI_IOC_MEM_UNMAP_EXT: - err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); - break; + case MALI_IOC_MEM_UNMAP_EXT: + err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); + break; - case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: - err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); - break; + case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: + err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); + break; - case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: - err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); - break; + case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: + err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); + break; - case MALI_IOC_MEM_GET_BIG_BLOCK: - err = mem_get_big_block_wrapper(filp, (_mali_uk_get_big_block_s __user *)arg); - break; + case MALI_IOC_MEM_GET_BIG_BLOCK: + err = mem_get_big_block_wrapper(filp, (_mali_uk_get_big_block_s __user *)arg); + break; - case MALI_IOC_MEM_FREE_BIG_BLOCK: - err = mem_free_big_block_wrapper(session_data, (_mali_uk_free_big_block_s __user *)arg); - break; + case MALI_IOC_MEM_FREE_BIG_BLOCK: + err = mem_free_big_block_wrapper(session_data, (_mali_uk_free_big_block_s __user *)arg); + break; #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 @@ -472,89 +433,58 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case MALI_IOC_MEM_ATTACH_UMP: case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */ - MALI_DEBUG_PRINT(2, ("UMP not supported\n")); - err = -ENOTTY; + MALI_DEBUG_PRINT(2, ("UMP not supported\n")); + err = -ENOTTY; break; #endif - case MALI_IOC_PP_START_JOB: - err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); - break; + case MALI_IOC_PP_START_JOB: + err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); + break; - case MALI_IOC_PP_ABORT_JOB: - err = pp_abort_job_wrapper(session_data, (_mali_uk_pp_abort_job_s __user *)arg); - break; + case MALI_IOC_PP_ABORT_JOB: + err = pp_abort_job_wrapper(session_data, (_mali_uk_pp_abort_job_s __user *)arg); + break; - case MALI_IOC_PP_NUMBER_OF_CORES_GET: - err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); - break; + case MALI_IOC_PP_NUMBER_OF_CORES_GET: + err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); + break; - case MALI_IOC_PP_CORE_VERSION_GET: - err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); - break; + case MALI_IOC_PP_CORE_VERSION_GET: + err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); + break; - case MALI_IOC_GP2_START_JOB: - err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); - break; + case MALI_IOC_GP2_START_JOB: + err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); + break; - case MALI_IOC_GP2_ABORT_JOB: - err = gp_abort_job_wrapper(session_data, (_mali_uk_gp_abort_job_s __user *)arg); - break; + case MALI_IOC_GP2_ABORT_JOB: + err = gp_abort_job_wrapper(session_data, (_mali_uk_gp_abort_job_s __user *)arg); + break; - case MALI_IOC_GP2_NUMBER_OF_CORES_GET: - err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); - break; + case MALI_IOC_GP2_NUMBER_OF_CORES_GET: + err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); + break; - case MALI_IOC_GP2_CORE_VERSION_GET: - err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); - break; + case MALI_IOC_GP2_CORE_VERSION_GET: + err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); + break; - case MALI_IOC_GP2_SUSPEND_RESPONSE: - err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); - break; + case MALI_IOC_GP2_SUSPEND_RESPONSE: + err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); + break; case MALI_IOC_VSYNC_EVENT_REPORT: - err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); - break; - - default: - MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); - err = -ENOTTY; - }; - - return err; -} - -#if MALI_STATE_TRACKING -static int mali_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - int len = 0; - - MALI_DEBUG_PRINT(1, ("mali_proc_read(page=%p, start=%p, off=%u, count=%d, eof=%p, data=%p\n", page, start, off, count, eof, data)); - - if (off > 0) - { - return 0; - } - - if (count < 1024) - { - return 0; - } - - len = sprintf(page + len, "Mali device driver %s\n", SVN_REV_STRING); - len += sprintf(page + len, "License: %s\n", MALI_KERNEL_LINUX_LICENSE); + err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); + break; - /* - * A more elegant solution would be to gather information from all subsystems and - * then report it all in the /proc/mali file, but this would require a bit more work. - * Use MALI_PRINT for now so we get the information in the dmesg log at least. - */ - _mali_kernel_core_dump_state(); + default: + MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); + err = -ENOTTY; + }; - return len; + return err; } -#endif module_init(mali_driver_init); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h index 969449d8ef4..c362a7c77c5 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h @@ -16,6 +16,18 @@ extern "C" { #endif +#include <linux/cdev.h> /* character device definitions */ +#include "mali_kernel_license.h" +#include "mali_osk.h" + +struct mali_dev +{ + struct cdev cdev; +#if MALI_LICENSE_IS_GPL + struct class * mali_class; +#endif +}; + _mali_osk_errcode_t initialize_kernel_device(void); void terminate_kernel_device(void); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c index aaafc151077..ebc519a743b 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c @@ -12,12 +12,9 @@ * @file mali_kernel_pm.c * Implementation of the Linux Power Management for Mali GPU kernel driver */ -#undef CONFIG_HAS_EARLYSUSPEND /*ARM will remove .early_suspend support for r2p2_rel*/ + #if USING_MALI_PMM #include <linux/sched.h> -#ifdef CONFIG_HAS_EARLYSUSPEND -#include <linux/earlysuspend.h> -#endif /* CONFIG_HAS_EARLYSUSPEND */ #ifdef CONFIG_PM_RUNTIME #include <linux/pm_runtime.h> @@ -27,7 +24,6 @@ #include <linux/platform_device.h> #include <linux/version.h> #include <asm/current.h> -#include <asm/delay.h> #include <linux/suspend.h> #include "mali_platform.h" @@ -48,13 +44,12 @@ #if MALI_POWER_MGMT_TEST_SUITE #ifdef CONFIG_PM #include "mali_linux_pm_testsuite.h" +#include "mali_platform_pmu_internal_testing.h" unsigned int pwr_mgmt_status_reg = 0; #endif /* CONFIG_PM */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ -#if MALI_STATE_TRACKING - int is_os_pmm_thread_waiting = -1; -#endif /* MALI_STATE_TRACKING */ +static int is_os_pmm_thread_waiting = 0; /* kernel should be configured with power management support */ #ifdef CONFIG_PM @@ -75,29 +70,19 @@ unsigned int pwr_mgmt_status_reg = 0; static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = { [_MALI_DEVICE_SUSPEND] = "suspend", [_MALI_DEVICE_RESUME] = "resume", -#ifdef CONFIG_HAS_EARLYSUSPEND - [_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB] = "early_suspend_level_disable_framebuffer", - [_MALI_DEVICE_LATERESUME] = "late_resume", -#endif /* CONFIG_HAS_EARLYSUSPEND */ [_MALI_DVFS_PAUSE_EVENT] = "dvfs_pause", [_MALI_DVFS_RESUME_EVENT] = "dvfs_resume", }; #endif /* CONFIG_PM_DEBUG */ -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -extern void set_mali_parent_power_domain(struct platform_device* dev); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ - #ifdef CONFIG_PM_RUNTIME #if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#ifndef CONFIG_HAS_EARLYSUSPEND static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); static struct notifier_block mali_pwr_notif_block = { .notifier_call = mali_pwr_suspend_notifier }; -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ @@ -148,12 +133,6 @@ static int mali_device_runtime_resume(struct device *dev); #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ -/* Early suspend functions */ -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mali_pm_early_suspend(struct early_suspend *mali_dev); -static void mali_pm_late_resume(struct early_suspend *mali_dev); -#endif /* CONFIG_HAS_EARLYSUSPEND */ - /* OS suspend and resume callbacks */ #if !MALI_PMM_RUNTIME_JOB_CONTROL_ON #ifndef CONFIG_PM_RUNTIME @@ -236,15 +215,6 @@ static struct platform_driver mali_plat_driver = { }, }; -#ifdef CONFIG_HAS_EARLYSUSPEND -/* Early suspend hooks */ -static struct early_suspend mali_dev_early_suspend = { - .suspend = mali_pm_early_suspend, - .resume = mali_pm_late_resume, - .level = EARLY_SUSPEND_LEVEL_DISABLE_FB, -}; -#endif /* CONFIG_HAS_EARLYSUSPEND */ - /* Mali GPU platform device */ struct platform_device mali_gpu_device = { .name = "mali_dev", @@ -313,13 +283,9 @@ int mali_device_suspend(unsigned int event_id, struct task_struct **pwr_mgmt_thr *pwr_mgmt_thread = current; MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being suspended\n" )); _mali_ukk_pmm_event_message(&event); -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 1; -#endif /* MALI_STATE_TRACKING */ err = mali_wait_for_power_management_policy_event(); -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 0; -#endif /* MALI_STATE_TRACKING */ return err; } @@ -333,17 +299,11 @@ static int mali_pm_suspend(struct device *dev) #if MALI_GPU_UTILIZATION mali_utilization_suspend(); #endif /* MALI_GPU_UTILIZATION */ - if ((mali_device_state == _MALI_DEVICE_SUSPEND) -#ifdef CONFIG_HAS_EARLYSUSPEND - || mali_device_state == (_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) -#else - ) -#endif /* CONFIG_HAS_EARLYSUSPEND */ + if ((mali_device_state == _MALI_DEVICE_SUSPEND)) { _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); return err; } - mali_device_state = _MALI_DEVICE_SUSPEND_IN_PROGRESS; err = mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread); mali_device_state = _MALI_DEVICE_SUSPEND; _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); @@ -367,7 +327,6 @@ static int mali_pm_os_suspend(struct device *dev) #ifdef CONFIG_PM_RUNTIME #if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#ifndef CONFIG_HAS_EARLYSUSPEND static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) { int err = 0; @@ -385,7 +344,6 @@ static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long eve } return 0; } -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ @@ -402,17 +360,9 @@ int mali_device_resume(unsigned int event_id, struct task_struct **pwr_mgmt_thre MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being resumed\n" )); _mali_ukk_pmm_event_message(&event); MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power up event is scheduled\n" )); - -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 1; -#endif /* MALI_STATE_TRACKING */ - err = mali_wait_for_power_management_policy_event(); - -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 0; -#endif /* MALI_STATE_TRACKING */ - return err; } @@ -484,69 +434,6 @@ static int mali_device_runtime_resume(struct device *dev) #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ -#ifdef CONFIG_HAS_EARLYSUSPEND - -/* This function is called from android framework. - */ -static void mali_pm_early_suspend(struct early_suspend *mali_dev) -{ - switch(mali_dev->level) - { - /* Screen should be turned off but framebuffer will be accessible */ - case EARLY_SUSPEND_LEVEL_BLANK_SCREEN: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Screen is off\n" )); - break; - - case EARLY_SUSPEND_LEVEL_STOP_DRAWING: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Suspend level stop drawing\n" )); - break; - - /* Turn off the framebuffer. In our case No Mali GPU operation */ - case EARLY_SUSPEND_LEVEL_DISABLE_FB: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Suspend level Disable framebuffer\n" )); - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); -#if MALI_GPU_UTILIZATION - mali_utilization_suspend(); -#endif /* MALI_GPU_UTILIZATION */ - if ((mali_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return; - } - mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread); - mali_device_state = _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB; - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - break; - - default: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Invalid Suspend Mode\n" )); - break; - } -} - -/* This function is invoked from android framework when mali device needs to be - * resumed. - */ -static void mali_pm_late_resume(struct early_suspend *mali_dev) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if (mali_device_state == _MALI_DEVICE_RESUME) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return; - } - if (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB) - { - mali_device_resume(MALI_PMM_EVENT_OS_POWER_UP, &pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - mali_device_state = _MALI_DEVICE_RESUME; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - -} - -#endif /* CONFIG_HAS_EARLYSUSPEND */ - #ifdef CONFIG_PM_DEBUG /** This function is used for debugging purposes when the user want to see @@ -578,9 +465,6 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int err = 0; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend mali_dev; -#endif /* CONFIG_HAS_EARLYSUSPEND */ #if MALI_POWER_MGMT_TEST_SUITE int test_flag_dvfs = 0; @@ -618,19 +502,6 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" )); err = mali_pm_resume(NULL); } -#ifdef CONFIG_HAS_EARLYSUSPEND - else if (!strncmp(buf,mali_states[_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB],strlen(mali_states[_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB]))) - { - mali_dev.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Android early suspend operation is scheduled\n" )); - mali_pm_early_suspend(&mali_dev); - } - else if (!strncmp(buf,mali_states[_MALI_DEVICE_LATERESUME],strlen(mali_states[_MALI_DEVICE_LATERESUME]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" )); - mali_pm_late_resume(NULL); - } -#endif /* CONFIG_HAS_EARLYSUSPEND */ else if (!strncmp(buf,mali_states[_MALI_DVFS_PAUSE_EVENT],strlen(mali_states[_MALI_DVFS_PAUSE_EVENT]))) { MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Pause Power operation is scheduled\n" )); @@ -711,11 +582,10 @@ int _mali_dev_platform_register(void) { int err; #if MALI_PMM_RUNTIME_JOB_CONTROL_ON - set_mali_parent_power_domain(&mali_gpu_device); + set_mali_parent_power_domain((void *)&mali_gpu_device); #endif #ifdef CONFIG_PM_RUNTIME -#ifndef CONFIG_HAS_EARLYSUSPEND #if MALI_PMM_RUNTIME_JOB_CONTROL_ON err = register_pm_notifier(&mali_pwr_notif_block); if (err) @@ -723,28 +593,19 @@ int _mali_dev_platform_register(void) return err; } #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* CONFIG_PM_RUNTIME */ err = platform_device_register(&mali_gpu_device); lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if (!err) { err = platform_driver_register(&mali_plat_driver); - if (!err) - { -#ifdef CONFIG_HAS_EARLYSUSPEND - register_early_suspend(&mali_dev_early_suspend); -#endif /* CONFIG_HAS_EARLYSUSPEND */ - } - else + if (err) { _mali_osk_lock_term(lock); #ifdef CONFIG_PM_RUNTIME -#ifndef CONFIG_HAS_EARLYSUSPEND #if MALI_PMM_RUNTIME_JOB_CONTROL_ON unregister_pm_notifier(&mali_pwr_notif_block); #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* CONFIG_PM_RUNTIME */ platform_device_unregister(&mali_gpu_device); } @@ -758,29 +619,28 @@ void _mali_dev_platform_unregister(void) { _mali_osk_lock_term(lock); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&mali_dev_early_suspend); -#endif /* CONFIG_HAS_EARLYSUSPEND */ - #ifdef CONFIG_PM_RUNTIME -#ifndef CONFIG_HAS_EARLYSUSPEND #if MALI_PMM_RUNTIME_JOB_CONTROL_ON unregister_pm_notifier(&mali_pwr_notif_block); #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* CONFIG_PM_RUNTIME */ platform_driver_unregister(&mali_plat_driver); platform_device_unregister(&mali_gpu_device); } +int mali_get_ospmm_thread_state(void) +{ + return is_os_pmm_thread_waiting; +} + #endif /* MALI_LICENSE_IS_GPL */ #endif /* CONFIG_PM */ #if MALI_STATE_TRACKING -void mali_pmm_dump_os_thread_state( void ) +u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ) { - MALI_PRINTF(("\nOSPMM::The OS PMM thread state is...%d",is_os_pmm_thread_waiting)); + return snprintf(buf, size, "OSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false"); } #endif /* MALI_STATE_TRACKING */ #endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h index 6e879fea447..db910102d76 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c new file mode 100644 index 00000000000..b1dca5f7ba5 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c @@ -0,0 +1,402 @@ +/** + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +/** + * @file mali_kernel_sysfs.c + * Implementation of some sysfs data exports + */ + +#include <linux/fs.h> +#include <linux/device.h> +#include <linux/module.h> +#include "mali_kernel_license.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" + +#if MALI_LICENSE_IS_GPL + +#include <linux/seq_file.h> +#include <linux/debugfs.h> +#include <asm/uaccess.h> +#include <linux/slab.h> +#include "mali_kernel_subsystem.h" +#include "mali_kernel_sysfs.h" +#include "mali_osk_profiling.h" + +static struct dentry *mali_debugfs_dir = NULL; + +#if MALI_STATE_TRACKING +static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) +{ + u32 len = 0; + u32 size; + char *buf; + + size = seq_get_buf(seq_file, &buf); + + if(!size) + { + return -ENOMEM; + } + + /* Create the internal state dump. */ + len = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING); + len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE); + + len += _mali_kernel_core_dump_state(buf + len, size - len); + + seq_commit(seq_file, len); + + return 0; +} + +static int mali_seq_internal_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, mali_seq_internal_state_show, NULL); +} + +static const struct file_operations mali_seq_internal_state_fops = { + .owner = THIS_MODULE, + .open = mali_seq_internal_state_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* MALI_STATE_TRACKING */ + + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val != 0) + { + u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ + + /* check if we are already recording */ + if (MALI_TRUE == _mali_osk_profiling_is_recording()) + { + MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); + return -EFAULT; + } + + /* check if we need to clear out an old recording first */ + if (MALI_TRUE == _mali_osk_profiling_have_recording()) + { + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) + { + MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); + return -EFAULT; + } + } + + /* start recording profiling data */ + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) + { + MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit)); + } + else + { + /* stop recording profiling data */ + u32 count = 0; + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) + { + MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count)); + } + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_record_fops = { + .owner = THIS_MODULE, + .read = profiling_record_read, + .write = profiling_record_write, +}; + +static void *profiling_events_start(struct seq_file *s, loff_t *pos) +{ + loff_t *spos; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_osk_profiling_have_recording()) + { + return NULL; + } + + spos = kmalloc(sizeof(loff_t), GFP_KERNEL); + if (NULL == spos) + { + return NULL; + } + + *spos = *pos; + return spos; +} + +static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos) +{ + loff_t *spos = v; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_osk_profiling_have_recording()) + { + return NULL; + } + + /* check if the next entry actually is avaiable */ + if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) + { + return NULL; + } + + *pos = ++*spos; + return spos; +} + +static void profiling_events_stop(struct seq_file *s, void *v) +{ + kfree(v); +} + +static int profiling_events_show(struct seq_file *seq_file, void *v) +{ + loff_t *spos = v; + u32 index; + u64 timestamp; + u32 event_id; + u32 data[5]; + + index = (u32)*spos; + + /* Retrieve all events */ + if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, ×tamp, &event_id, data)) + { + seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]); + return 0; + } + + return 0; +} + +static const struct seq_operations profiling_events_seq_ops = { + .start = profiling_events_start, + .next = profiling_events_next, + .stop = profiling_events_stop, + .show = profiling_events_show +}; + +static int profiling_events_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &profiling_events_seq_ops); +} + +static const struct file_operations profiling_events_fops = { + .owner = THIS_MODULE, + .open = profiling_events_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_osk_profiling_get_default_enable_state() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_proc_default_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + _mali_osk_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_proc_default_enable_fops = { + .owner = THIS_MODULE, + .read = profiling_proc_default_enable_read, + .write = profiling_proc_default_enable_write, +}; +#endif + +static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 mem = _mali_ukk_report_memory_usage(); + + r = snprintf(buf, 64, "%u\n", mem); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations memory_usage_fops = { + .owner = THIS_MODULE, + .read = memory_used_read, +}; + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + int err = 0; + struct device * mdev; + + device->mali_class = class_create(THIS_MODULE, mali_dev_name); + if (IS_ERR(device->mali_class)) + { + err = PTR_ERR(device->mali_class); + goto init_class_err; + } + mdev = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name); + if (IS_ERR(mdev)) + { + err = PTR_ERR(mdev); + goto init_mdev_err; + } + + mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL); + if(ERR_PTR(-ENODEV) == mali_debugfs_dir) + { + /* Debugfs not supported. */ + mali_debugfs_dir = NULL; + } + else + { + if(NULL != mali_debugfs_dir) + { + /* Debugfs directory created successfully; create files now */ +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); + if (mali_profiling_dir != NULL) + { + struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); + if (mali_profiling_proc_dir != NULL) + { + struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); + if (mali_profiling_proc_default_dir != NULL) + { + debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, NULL, &profiling_proc_default_enable_fops); + } + } + debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); + debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops); + } +#endif + +#if MALI_STATE_TRACKING + debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); +#endif + + debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); + } + } + + /* Success! */ + return 0; + + /* Error handling */ +init_mdev_err: + class_destroy(device->mali_class); +init_class_err: + + return err; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + if(NULL != mali_debugfs_dir) + { + debugfs_remove_recursive(mali_debugfs_dir); + } + device_destroy(device->mali_class, dev); + class_destroy(device->mali_class); + + return 0; +} + +#else + +/* Dummy implementations for non-GPL */ + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + return 0; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + return 0; +} + + +#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h new file mode 100644 index 00000000000..d79a8862269 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_SYSFS_H__ +#define __MALI_KERNEL_SYSFS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MALI_PROC_DIR "driver/mali" + +int mali_sysfs_register(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); + +int mali_sysfs_unregister(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c deleted file mode 100644 index 3d60d18e005..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_linux_dvfs_pause_resume.c - * Implementation of the Mali pause/resume functionality - */ -#if USING_MALI_PMM -#include <linux/version.h> -#include <linux/sched.h> -#include <linux/module.h> -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_platform.h" -#include "mali_linux_pm.h" -#include "mali_linux_dvfs_pause_resume.h" -#include "mali_pmm.h" -#include "mali_kernel_license.h" -#ifdef CONFIG_PM -#if MALI_LICENSE_IS_GPL - -/* Mali Pause Resume APIs */ -int mali_dev_dvfs_pause() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND)) - { - err = -EPERM; - } - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err)) - { - mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_SUSPEND; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_dvfs_pause); - -int mali_dev_dvfs_resume() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND)) - { - err = -EPERM; - } - if (!err) - { - mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_dvfs_resume); - -#endif /* MALI_LICENSE_IS_GPL */ -#endif /* CONFIG_PM */ -#endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h index 614d5e1deee..d401697f2f4 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h @@ -20,18 +20,13 @@ typedef enum { _MALI_DEVICE_SUSPEND, /* Suspend */ _MALI_DEVICE_RESUME, /* Resume */ -#ifdef CONFIG_HAS_EARLYSUSPEND - _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB, /* Early suspend */ - _MALI_DEVICE_LATERESUME, /* Late resume */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ - _MALI_DEVICE_SUSPEND_IN_PROGRESS, /* Suspend in progress */ _MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */ } _mali_device_power_states; /* Number of DVFS events */ typedef enum { - _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES-1, /* DVFS Pause event */ + _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES, /* DVFS Pause event */ _MALI_DVFS_RESUME_EVENT, /* DVFS Resume event */ _MALI_MAX_DEBUG_OPERATIONS, } _mali_device_dvfs_events; @@ -51,6 +46,7 @@ extern struct task_struct *pm_thread; int mali_device_suspend(u32 event_id, struct task_struct **pwr_mgmt_thread); int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread); +int mali_get_ospmm_thread_state(void); #endif /* CONFIG_PM */ #endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h new file mode 100644 index 00000000000..64c2fd5269c --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ) +#define MALI_LINUX_TRACE_H + +#include <linux/stringify.h> +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mali +#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM) + +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE mali_linux_trace + +/** + * Define the tracepoint used to communicate the status of a GPU. Called + * when a GPU turns on or turns off. + * + * @param event_id The type of the event. This parameter is a bitfield + * encoding the type of the event. + * + * @param d0 First data parameter. + * @param d1 Second data parameter. + * @param d2 Third data parameter. + * @param d3 Fourth data parameter. + * @param d4 Fifth data parameter. + */ +TRACE_EVENT(mali_timeline_event, + + TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, + unsigned int d2, unsigned int d3, unsigned int d4), + + TP_ARGS(event_id, d0, d1, d2, d3, d4), + + TP_STRUCT__entry( + __field(unsigned int, event_id) + __field(unsigned int, d0) + __field(unsigned int, d1) + __field(unsigned int, d2) + __field(unsigned int, d3) + __field(unsigned int, d4) + ), + + TP_fast_assign( + __entry->event_id = event_id; + __entry->d0 = d0; + __entry->d1 = d1; + __entry->d2 = d2; + __entry->d3 = d3; + __entry->d4 = d4; + ), + + TP_printk("event=%d", __entry->event_id) +); + +/** + * Define a tracepoint used to regsiter the value of a hardware counter. + * Hardware counters belonging to the vertex or fragment processor are + * reported via this tracepoint each frame, whilst L2 cache hardware + * counters are reported continuously. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_hw_counter, + + TP_PROTO(unsigned int counter_id, unsigned int value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(unsigned int, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + __entry->value = value; + ), + + TP_printk("event %d = %d", __entry->counter_id, __entry->value) +); + +/** + * Define a tracepoint used to register the value of a software counter. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_sw_counter, + + TP_PROTO(unsigned int counter_id, signed long long value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(signed long long, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + __entry->value = value; + ), + + TP_printk("event %d = %lld", __entry->counter_id, __entry->value) +); + +#endif /* MALI_LINUX_TRACE_H */ + +/* This part must exist outside the header guard. */ +#include <trace/define_trace.h> + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c index cc029c4a8f8..05831c54272 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c index b60bf825897..7297218b9b6 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c index 1a4bbcecdce..b667961a0ac 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c @@ -149,7 +149,7 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) #if MALI_LICENSE_IS_GPL if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) { - queue_work(pmm_wq,&irq_object->work_queue_irq_handle); + queue_work( pmm_wq,&irq_object->work_queue_irq_handle ); } else { @@ -160,6 +160,17 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) #endif } +void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ) +{ +#if MALI_LICENSE_IS_GPL + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + flush_workqueue(pmm_wq); + } +#endif +} + void _mali_osk_irq_term( _mali_osk_irq_t *irq ) { mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c index 11285efc682..139dc5e3de3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c @@ -61,7 +61,6 @@ struct _mali_osk_lock_t_struct MALI_DEBUG_CODE( /** original flags for debug checking */ _mali_osk_lock_flags_t orig_flags; - _mali_osk_lock_mode_t locked_as; ); /* MALI_DEBUG_CODE */ }; @@ -130,7 +129,6 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial MALI_DEBUG_CODE( /* Debug tracking of flags */ lock->orig_flags = flags; - lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF; ); /* MALI_DEBUG_CODE */ return lock; @@ -190,17 +188,6 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_ break; } - /* DEBUG tracking of previously locked state - occurs after lock obtained */ - MALI_DEBUG_CODE( - if ( _MALI_OSK_ERR_OK == err ) - { - /* Assert that this is not currently locked */ - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_UNDEF == lock->locked_as ); - - lock->locked_as = mode; - } - ); /* MALI_DEBUG_CODE */ - return err; } @@ -218,12 +205,6 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); - /* For DEBUG only, assert that we previously locked this, and in the same way (RW/RO) */ - MALI_DEBUG_ASSERT( mode == lock->locked_as ); - - /* DEBUG tracking of previously locked state - occurs before lock released */ - MALI_DEBUG_CODE( lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF ); - switch ( lock->type ) { case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: @@ -263,9 +244,6 @@ void _mali_osk_lock_term( _mali_osk_lock_t *lock ) /* Parameter validation */ MALI_DEBUG_ASSERT_POINTER( lock ); - /* For DEBUG only, assert that this is not currently locked */ - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_UNDEF == lock->locked_as ); - /* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */ kfree(lock); } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c index 6454709caaf..c2475f24d7f 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c @@ -21,7 +21,6 @@ #include <linux/slab.h> #include <linux/mm.h> #include <linux/dma-mapping.h> -#include <asm/cacheflush.h> #include "mali_osk.h" #include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */ @@ -77,7 +76,11 @@ static void _allocation_list_item_release(AllocationList * item); /* Variable declarations */ -spinlock_t allocation_list_spinlock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +static DEFINE_SPINLOCK(allocation_list_spinlock); +#else +spinlock_t allocation_list_spinlock = SPIN_LOCK_UNLOCKED; +#endif static AllocationList * pre_allocated_memory = (AllocationList*) NULL ; static int pre_allocated_memory_size_current = 0; #ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB @@ -100,7 +103,6 @@ static struct vm_operations_struct mali_kernel_vm_ops = void mali_osk_low_level_mem_init(void) { - spin_lock_init( &allocation_list_spinlock ); pre_allocated_memory = (AllocationList*) NULL ; } @@ -277,6 +279,11 @@ void _mali_osk_mem_barrier( void ) mb(); } +void _mali_osk_write_mem_barrier( void ) +{ + wmb(); +} + mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ) { return (mali_io_address)ioremap_nocache(phys, size); @@ -303,8 +310,7 @@ mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) if ( NULL == virt ) { - MALI_DEBUG_PRINT(1, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size )); - MALI_DEBUG_PRINT(1, ("Solution: When configuring and building linux kernel, set CONSISTENT_DMA_SIZE to be 14 MB.\n")); + MALI_DEBUG_PRINT(5, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size )); return 0; } @@ -332,6 +338,11 @@ void inline _mali_osk_mem_unreqregion( u32 phys, u32 size ) release_mem_region(phys, size); } +void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ) +{ + __raw_writel(cpu_to_le32(val),((u8*)addr) + offset); +} + u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset ) { return ioread32(((u8*)addr) + offset); @@ -349,7 +360,7 @@ void _mali_osk_cache_flushall( void ) void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ) { - wmb(); + _mali_osk_write_mem_barrier(); } _mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ) @@ -481,6 +492,11 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri u32 linux_phys_frame_num; alloc_item = _allocation_list_item_get(); + if (NULL == alloc_item) + { + MALI_DEBUG_PRINT(1, ("Failed to allocate list item\n")); + return _MALI_OSK_ERR_NOMEM; + } linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c index 694d8eeaabc..015f5a28749 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c @@ -75,8 +75,7 @@ _mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config if (0 < mem_size) { int i; for (i = 0; i < *num_resources; ++i) { - if ((MEMORY == arch_configuration[i].type) || - (OS_MEMORY == arch_configuration[i].type)) { + if (MEMORY == arch_configuration[i].type) { MALI_DEBUG_PRINT( 1, ("Overriding arch resource[%d] :\n",i)); MALI_DEBUG_PRINT( 1, ("Type: %s, base: %x, size %x\n", (OS_MEMORY==mem_type?"OS_MEMORY":"MEMORY"),mem_base,mem_size)); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c index 2f7fc15847b..3e62e519cba 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c index bf6679f7bac..7bb470f8828 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c @@ -15,6 +15,7 @@ #include "mali_osk.h" #include <linux/slab.h> +#include <linux/vmalloc.h> void inline *_mali_osk_calloc( u32 n, u32 size ) { @@ -31,6 +32,16 @@ void inline _mali_osk_free( void *ptr ) kfree(ptr); } +void inline *_mali_osk_valloc( u32 size ) +{ + return vmalloc(size); +} + +void inline _mali_osk_vfree( void *ptr ) +{ + vfree(ptr); +} + void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len ) { return memcpy(dst, src, len); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c index 3afd2da736c..106308b58ba 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -27,6 +27,18 @@ void _mali_osk_dbgmsg( const char *fmt, ... ) va_end(args); } +u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ) +{ + int res; + va_list args; + va_start(args, fmt); + + res = vsnprintf(buf, (size_t)size, fmt, args); + + va_end(args); + return res; +} + void _mali_osk_abort(void) { /* make a simple fault by dereferencing a NULL pointer */ @@ -49,3 +61,9 @@ u32 _mali_osk_get_tid(void) /* pid is actually identifying the thread on Linux */ return (u32)current->pid; } + +void * _mali_osk_get_task(void) +{ + return current; +} + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c index 2efc140f60a..539f9ab68b0 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c @@ -20,7 +20,6 @@ #include <linux/version.h> #include <linux/sched.h> -#include <linux/mm.h> #include <linux/slab.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #include <linux/semaphore.h> diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c index 04fcd4572df..6fb587ef3df 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c @@ -25,19 +25,18 @@ #include "mali_osk.h" #include "mali_uk_types.h" #include "mali_pmm.h" -#include "mali_ukk.h" #include "mali_kernel_common.h" #include "mali_kernel_license.h" -#include "mali_kernel_pm.h" -#include "mali_device_pause_resume.h" #include "mali_linux_pm.h" #include "mali_linux_pm_testsuite.h" +#if MALI_LICENSE_IS_GPL #if MALI_PMM_RUNTIME_JOB_CONTROL_ON #ifdef CONFIG_PM_RUNTIME static int is_runtime =0; #endif /* CONFIG_PM_RUNTIME */ #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* MALI_LICENSE_IS_GPL */ #if MALI_POWER_MGMT_TEST_SUITE @@ -180,6 +179,20 @@ void _mali_osk_pmm_dev_activate(void) #endif /* MALI_LICENSE_IS_GPL */ } +void _mali_osk_pmm_ospmm_cleanup( void ) +{ +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + int thread_state; + thread_state = mali_get_ospmm_thread_state(); + if (thread_state) + { + _mali_osk_pmm_dvfs_operation_done(0); + } +#endif /* CONFIG_PM */ +#endif /* MALI_LICENSE_IS_GPL */ +} + void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data) { #if MALI_LICENSE_IS_GPL diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c new file mode 100644 index 00000000000..c4cd5826363 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c @@ -0,0 +1,247 @@ +/** + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <linux/module.h> + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_ukk.h" +#include "mali_osk_profiling.h" +#include "mali_linux_trace.h" + +#if defined(USING_MALI400_L2_CACHE) +#include "mali_kernel_l2_cache.h" +#endif /* USING_MALI400_L2_CACHE */ + +#define COUNTER_DISABLED (-1) + +/** + * Since there are only two physical hardware counters per GPU block, we + * need to multiplex the range of possible events that can be collected by + * each counter. This multiplexing is achieved by means of the following + * table, which holds the event ID that should be collected by each hardware + * counter. + * + * Note that this table should be updated with any change to the above + * _mali_osk_counter_id enumeration. + */ +s32 _mali_osk_hw_counter_table[] = { + COUNTER_DISABLED, /* ACTIVITY_VP */ + COUNTER_DISABLED, /* ACTIVITY_FP0 */ + COUNTER_DISABLED, /* ACTIVITY_FP1 */ + COUNTER_DISABLED, /* ACTIVITY_FP2 */ + COUNTER_DISABLED, /* ACTIVITY_FP3 */ + COUNTER_DISABLED, /* COUNTER_L2_C0 */ + COUNTER_DISABLED, /* COUNTER_L2_C1 */ + COUNTER_DISABLED, /* COUNTER_VP_C0 */ + COUNTER_DISABLED, /* COUNTER_VP_C1 */ + COUNTER_DISABLED, /* COUNTER_FP0_C0 */ + COUNTER_DISABLED, /* COUNTER_FP0_C1 */ + COUNTER_DISABLED, /* COUNTER_FP1_C0 */ + COUNTER_DISABLED, /* COUNTER_FP1_C1 */ + COUNTER_DISABLED, /* COUNTER_FP2_C0 */ + COUNTER_DISABLED, /* COUNTER_FP2_C1 */ + COUNTER_DISABLED, /* COUNTER_FP3_C0 */ + COUNTER_DISABLED, /* COUNTER_FP3_C1 */ +}; + +mali_bool _mali_osk_profiling_query_hw_counter(u32 counter_id, u32 *event_id) +{ + /* Check that the counter is in range... */ + if (counter_id >= FIRST_HW_COUNTER && counter_id <= LAST_HW_COUNTER) + { + s32 id = _mali_osk_hw_counter_table[counter_id]; + + /* ...and enabled */ + if (id != COUNTER_DISABLED) + { + /* Update the pointer to the event ID */ + *event_id = (u32)id; + + return MALI_TRUE; + } + } + + /* The counter was disabled or out of range */ + return MALI_FALSE; +} + +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_profiling_term(void) +{ + /* Nothing to do */ +} + +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +u32 _mali_osk_profiling_get_count(void) +{ + return 0; +} + +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, + u32* event_id, u32 data[5]) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +mali_bool _mali_osk_profiling_is_recording(void) +{ + return MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return MALI_FALSE; +} + +void _mali_osk_profiling_set_default_enable_state(mali_bool enable) +{ + /* Nothing to do */ +} + +mali_bool _mali_osk_profiling_get_default_enable_state(void) +{ + return MALI_FALSE; +} + +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) +{ + return _mali_osk_profiling_start(&args->limit); +} + +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +{ + /* Always add process and thread identificator in the first two data elements for events from user space */ + _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_osk_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); +} + +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +{ + return _mali_osk_profiling_clear(); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args) +{ + return _MALI_OSK_ERR_UNSUPPORTED; +} + +/** + * Called by gator.ko to populate the _mali_osk_hw_counter_table. + * + * @param counter_id The counter ID. + * @param event_id Event ID that the counter should count. + * + * @return 1 on success, 0 on failure. + */ +int _mali_profiling_set_event(u32 counter_id, s32 event_id) +{ +#if defined(USING_MALI400_L2_CACHE) + /* + * The L2 cache counters have special handling in the driver. Since we + * receive new event IDs for each counter one at a time, we need to know + * what the L2 counters are currently programmed to read. This way we + * can supply the current value to the counter we _aren't_ trying to + * program; mali_kernel_l2_cache_set_perf_counters will dutifully ignore + * that counter. + */ + u32 current_src0, current_src1, current_val0, current_val1; + + mali_kernel_l2_cache_get_perf_counters(¤t_src0, ¤t_val0, + ¤t_src1, ¤t_val1); + + if (counter_id == COUNTER_L2_C0) + { + mali_kernel_l2_cache_set_perf_counters(event_id, current_src1, 0); + + return 1; + } + else if (counter_id == COUNTER_L2_C1) + { + mali_kernel_l2_cache_set_perf_counters(current_src0, event_id, 0); + + return 1; + } +#endif /* USING_MALI400_L2_CACHE */ + + /* Check that the counter is in range */ + if (counter_id >= FIRST_HW_COUNTER && counter_id <= LAST_HW_COUNTER) + { + /* + * This does not actually update the hardware with the new event ID; + * it will query what event ID it should be counting on each frame + * via _mali_osk_profiling_query_hw_counter. + */ + _mali_osk_hw_counter_table[counter_id] = event_id; + + return 1; + } + + return 0; +} + +#if defined(USING_MALI400_L2_CACHE) +/** + * Called by gator.ko to retrieve the L2 cache counter values. The L2 cache + * counters are unique in that they are polled by gator, rather than being + * transmitted via the tracepoint mechanism. + * + * @param src0 First L2 cache counter ID. + * @param val0 First L2 cache counter value. + * @param src1 Second L2 cache counter ID. + * @param val1 Second L2 cache counter value. + */ +void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1) +{ + mali_kernel_l2_cache_get_perf_counters(src0, val0, src1, val1); +} + +EXPORT_SYMBOL(_mali_profiling_get_counters); +#endif /* USING_MALI400_L2_CACHE */ + +EXPORT_SYMBOL(_mali_profiling_set_event); + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_internal.c index 07bb894b1b4..589e2ace6d8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_internal.c @@ -1,11 +1,14 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. */ #include "mali_kernel_common.h" @@ -13,8 +16,7 @@ #include "mali_osk_mali.h" #include "mali_ukk.h" #include "mali_timestamp.h" - -#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 +#include "mali_osk_profiling.h" typedef struct mali_profiling_entry { @@ -39,9 +41,9 @@ static mali_profiling_entry* profile_entries = NULL; static u32 profile_entry_count = 0; static _mali_osk_atomic_t profile_insert_index; static _mali_osk_atomic_t profile_entries_written; +static mali_bool mali_profiling_default_enable = MALI_FALSE; - -_mali_osk_errcode_t _mali_profiling_init(void) +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) { profile_entries = NULL; profile_entry_count = 0; @@ -56,10 +58,21 @@ _mali_osk_errcode_t _mali_profiling_init(void) prof_state = MALI_PROFILING_STATE_IDLE; + if (MALI_TRUE == auto_start) + { + u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */ + + mali_profiling_default_enable = MALI_TRUE; /* save this so user space can query this on their startup */ + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) + { + return _MALI_OSK_ERR_FAULT; + } + } + return _MALI_OSK_ERR_OK; } -void _mali_profiling_term(void) +void _mali_osk_profiling_term(void) { prof_state = MALI_PROFILING_STATE_UNINITIALIZED; @@ -71,7 +84,7 @@ void _mali_profiling_term(void) if (NULL != profile_entries) { - _mali_osk_free(profile_entries); + _mali_osk_vfree(profile_entries); profile_entries = NULL; } @@ -82,58 +95,33 @@ void _mali_profiling_term(void) } } -inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) +inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) { - u32 cur_index = _mali_osk_atomic_inc_return(&profile_insert_index) - 1; + _mali_osk_errcode_t ret; - if (prof_state != MALI_PROFILING_STATE_RUNNING || cur_index >= profile_entry_count) + mali_profiling_entry *new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry)); + + if(NULL == new_profile_entries) { - /* - * Not in recording mode, or buffer is full - * Decrement index again, and early out - */ - _mali_osk_atomic_dec(&profile_insert_index); - return _MALI_OSK_ERR_FAULT; + return _MALI_OSK_ERR_NOMEM; } - profile_entries[cur_index].timestamp = _mali_timestamp_get(); - profile_entries[cur_index].event_id = event_id; - profile_entries[cur_index].data[0] = data0; - profile_entries[cur_index].data[1] = data1; - profile_entries[cur_index].data[2] = data2; - profile_entries[cur_index].data[3] = data3; - profile_entries[cur_index].data[4] = data4; - - _mali_osk_atomic_inc(&profile_entries_written); - - return _MALI_OSK_ERR_OK; -} - - -_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) -{ - _mali_osk_errcode_t ret; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); if (prof_state != MALI_PROFILING_STATE_IDLE) { _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_vfree(new_profile_entries); return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ } - if (args->limit > MALI_PROFILING_MAX_BUFFER_ENTRIES) + if (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES) { - args->limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; + *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; } - profile_entries = _mali_osk_malloc(args->limit * sizeof(mali_profiling_entry)); - profile_entry_count = args->limit; - if (NULL == profile_entries) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_NOMEM; - } + profile_entries = new_profile_entries; + profile_entry_count = *limit; ret = _mali_timestamp_reset(); @@ -143,7 +131,7 @@ _mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) } else { - _mali_osk_free(profile_entries); + _mali_osk_vfree(profile_entries); profile_entries = NULL; } @@ -151,13 +139,42 @@ _mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) return ret; } -_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +inline void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) { - /* Always add process and thread identificator in the first two data elements for events from user space */ - return _mali_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + u32 cur_index = _mali_osk_atomic_inc_return(&profile_insert_index) - 1; + + if (prof_state != MALI_PROFILING_STATE_RUNNING || cur_index >= profile_entry_count) + { + /* + * Not in recording mode, or buffer is full + * Decrement index again, and early out + */ + _mali_osk_atomic_dec(&profile_insert_index); + return; + } + + profile_entries[cur_index].timestamp = _mali_timestamp_get(); + profile_entries[cur_index].event_id = event_id; + profile_entries[cur_index].data[0] = data0; + profile_entries[cur_index].data[1] = data1; + profile_entries[cur_index].data[2] = data2; + profile_entries[cur_index].data[3] = data3; + profile_entries[cur_index].data[4] = data4; + + _mali_osk_atomic_inc(&profile_entries_written); } -_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +inline void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value) +{ + /* Not implemented */ +} + +inline mali_bool _mali_osk_profiling_query_hw_counter(u32 counter_id, u32 *event_id) +{ + return _MALI_OSK_ERR_UNSUPPORTED; +} + +inline _mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count) { _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); @@ -178,17 +195,28 @@ _mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) /* do nothing */; } - args->count = _mali_osk_atomic_read(&profile_insert_index); + *count = _mali_osk_atomic_read(&profile_insert_index); return _MALI_OSK_ERR_OK; } - -_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +inline u32 _mali_osk_profiling_get_count(void) { - u32 index = args->index; + u32 retval = 0; _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + if (prof_state == MALI_PROFILING_STATE_RETURN) + { + retval = _mali_osk_atomic_read(&profile_entries_written); + } + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + + return retval; +} + +inline _mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) +{ + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); if (prof_state != MALI_PROFILING_STATE_RETURN) { @@ -202,19 +230,19 @@ _mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s return _MALI_OSK_ERR_FAULT; } - args->timestamp = profile_entries[index].timestamp; - args->event_id = profile_entries[index].event_id; - args->data[0] = profile_entries[index].data[0]; - args->data[1] = profile_entries[index].data[1]; - args->data[2] = profile_entries[index].data[2]; - args->data[3] = profile_entries[index].data[3]; - args->data[4] = profile_entries[index].data[4]; + *timestamp = profile_entries[index].timestamp; + *event_id = profile_entries[index].event_id; + data[0] = profile_entries[index].data[0]; + data[1] = profile_entries[index].data[1]; + data[2] = profile_entries[index].data[2]; + data[3] = profile_entries[index].data[3]; + data[4] = profile_entries[index].data[4]; _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); return _MALI_OSK_ERR_OK; } -_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +inline _mali_osk_errcode_t _mali_osk_profiling_clear(void) { _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); @@ -230,7 +258,7 @@ _mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) _mali_osk_atomic_init(&profile_entries_written, 0); if (NULL != profile_entries) { - _mali_osk_free(profile_entries); + _mali_osk_vfree(profile_entries); profile_entries = NULL; } @@ -238,3 +266,55 @@ _mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) return _MALI_OSK_ERR_OK; } +mali_bool _mali_osk_profiling_is_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; +} + +void _mali_osk_profiling_set_default_enable_state(mali_bool enable) +{ + mali_profiling_default_enable = enable; +} + +mali_bool _mali_osk_profiling_get_default_enable_state(void) +{ + return mali_profiling_default_enable; +} + +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) +{ + return _mali_osk_profiling_start(&args->limit); +} + +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +{ + /* Always add process and thread identificator in the first two data elements for events from user space */ + _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_osk_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); +} + +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +{ + return _mali_osk_profiling_clear(); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args) +{ + args->enable_events = mali_profiling_default_enable; + return _MALI_OSK_ERR_OK; +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h index 54acfdd138c..fbf1dd59e27 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -29,4 +29,102 @@ extern "C" } #endif +/** The list of events supported by the Mali DDK. */ +typedef enum +{ + /* Vertex processor activity */ + ACTIVITY_VP = 0, + + /* Fragment processor activity */ + ACTIVITY_FP0, + ACTIVITY_FP1, + ACTIVITY_FP2, + ACTIVITY_FP3, + + /* L2 cache counters */ + COUNTER_L2_C0, + COUNTER_L2_C1, + + /* Vertex processor counters */ + COUNTER_VP_C0, + COUNTER_VP_C1, + + /* Fragment processor counters */ + COUNTER_FP0_C0, + COUNTER_FP0_C1, + COUNTER_FP1_C0, + COUNTER_FP1_C1, + COUNTER_FP2_C0, + COUNTER_FP2_C1, + COUNTER_FP3_C0, + COUNTER_FP3_C1, + + /* + * If more hardware counters are added, the _mali_osk_hw_counter_table + * below should also be updated. + */ + + /* EGL software counters */ + COUNTER_EGL_BLIT_TIME, + + /* GLES software counters */ + COUNTER_GLES_DRAW_ELEMENTS_CALLS, + COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, + COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_ARRAYS_CALLS, + COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_POINTS, + COUNTER_GLES_DRAW_LINES, + COUNTER_GLES_DRAW_LINE_LOOP, + COUNTER_GLES_DRAW_LINE_STRIP, + COUNTER_GLES_DRAW_TRIANGLES, + COUNTER_GLES_DRAW_TRIANGLE_STRIP, + COUNTER_GLES_DRAW_TRIANGLE_FAN, + COUNTER_GLES_NON_VBO_DATA_COPY_TIME, + COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, + COUNTER_GLES_UPLOAD_TEXTURE_TIME, + COUNTER_GLES_UPLOAD_VBO_TIME, + COUNTER_GLES_NUM_FLUSHES, + COUNTER_GLES_NUM_VSHADERS_GENERATED, + COUNTER_GLES_NUM_FSHADERS_GENERATED, + COUNTER_GLES_VSHADER_GEN_TIME, + COUNTER_GLES_FSHADER_GEN_TIME, + COUNTER_GLES_INPUT_TRIANGLES, + COUNTER_GLES_VXCACHE_HIT, + COUNTER_GLES_VXCACHE_MISS, + COUNTER_GLES_VXCACHE_COLLISION, + COUNTER_GLES_CULLED_TRIANGLES, + COUNTER_GLES_CULLED_LINES, + COUNTER_GLES_BACKFACE_TRIANGLES, + COUNTER_GLES_GBCLIP_TRIANGLES, + COUNTER_GLES_GBCLIP_LINES, + COUNTER_GLES_TRIANGLES_DRAWN, + COUNTER_GLES_DRAWCALL_TIME, + COUNTER_GLES_TRIANGLES_COUNT, + COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, + COUNTER_GLES_STRIP_TRIANGLES_COUNT, + COUNTER_GLES_FAN_TRIANGLES_COUNT, + COUNTER_GLES_LINES_COUNT, + COUNTER_GLES_INDEPENDENT_LINES_COUNT, + COUNTER_GLES_STRIP_LINES_COUNT, + COUNTER_GLES_LOOP_LINES_COUNT, + + /* Framebuffer capture pseudo-counter */ + COUNTER_FILMSTRIP, + + NUMBER_OF_EVENTS +} _mali_osk_counter_id; + +#define FIRST_ACTIVITY_EVENT ACTIVITY_VP +#define LAST_ACTIVITY_EVENT ACTIVITY_FP3 + +#define FIRST_HW_COUNTER COUNTER_L2_C0 +#define LAST_HW_COUNTER COUNTER_FP3_C1 + +#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME +#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT + +#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP +#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP + #endif /* __MALI_OSK_SPECIFIC_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c index aa7962380e6..da9b8656b70 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c index a6f355fd459..58ff1de5108 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c index 3f67a1e3328..05214b703d3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c index f77a177d865..31e2a6ac065 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c index 636bd03580e..b9c5ef3aec8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c @@ -133,3 +133,25 @@ int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_pro return 0; } +int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs) +{ + _mali_uk_profiling_get_config_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_profiling_get_config(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.enable_events, &uargs->enable_events)) + { + return -EFAULT; + } + + return 0; +} + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h index 54e3f656b37..57108a27a61 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h @@ -58,6 +58,7 @@ int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs); int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs); int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs); +int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs); int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/default/mali_platform.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/default/mali_platform.c index 36301a93a2c..9e64ce75344 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/default/mali_platform.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/default/mali_platform.c @@ -17,34 +17,27 @@ #include "mali_platform.h" -_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource) +_mali_osk_errcode_t mali_platform_init(void) { MALI_SUCCESS; } -_mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type) +_mali_osk_errcode_t mali_platform_deinit(void) { MALI_SUCCESS; } -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) { MALI_SUCCESS; } -_mali_osk_errcode_t mali_platform_powerup(u32 cores) +void mali_gpu_utilization_handler(u32 utilization) { - MALI_SUCCESS; } -void mali_gpu_utilization_handler(u32 utilization) +void set_mali_parent_power_domain(void* dev) { } -#if MALI_POWER_MGMT_TEST_SUITE -u32 pmu_get_power_up_down_info(void) -{ - return 4095; -} -#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali-runtimepm/mali_platform.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali-runtimepm/mali_platform.c deleted file mode 100644 index b8c47094177..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali-runtimepm/mali_platform.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_platform.c - * Platform specific Mali driver functions for a default platform - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" -#include "mali_pmm.h" - -static int is_run_time = 0; -_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource) -{ - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type) -{ - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) -{ - if(is_run_time == 1) - { - _mali_osk_pmm_dev_idle(); - is_run_time =0; - } - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerup(u32 cores) -{ - if(is_run_time == 0) - { - _mali_osk_pmm_dev_activate(); - is_run_time = 1; - } - MALI_SUCCESS; -} - -void mali_gpu_utilization_handler(u32 utilization) -{ -} - -#if MALI_POWER_MGMT_TEST_SUITE -u32 pmu_get_power_up_down_info(void) -{ - return 4095; - -} -#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali_platform.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali_platform.h index 575c1fb6113..5e4deeb47c8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali_platform.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali_platform.h @@ -13,11 +13,10 @@ * Platform specific Mali driver functions */ -#include "mali_osk.h" +#ifndef __MALI_PLATFORM_H__ +#define __MALI_PLATFORM_H__ -#if USING_MALI_PMM -#include "mali_pmm.h" -#endif +#include "mali_osk.h" #if !USING_MALI_PMM /* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */ @@ -28,51 +27,54 @@ extern "C" { #endif +/** @brief description of power change reasons + */ +typedef enum mali_power_mode_tag +{ + MALI_POWER_MODE_ON, + MALI_POWER_MODE_LIGHT_SLEEP, + MALI_POWER_MODE_DEEP_SLEEP, +} mali_power_mode; + /** @brief Platform specific setup and initialisation of MALI - * + * * This is called from the entrypoint of the driver to initialize the platform - * When using PMM, it is also called from the PMM start up to initialise the - * system PMU * - * @param resource This is NULL when called on first driver start up, else it will - * be a pointer to a PMU resource * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. */ -_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource); +_mali_osk_errcode_t mali_platform_init(void); /** @brief Platform specific deinitialisation of MALI - * + * * This is called on the exit of the driver to terminate the platform - * When using PMM, it is also called from the PMM termination code to clean up the - * system PMU * - * @param type This is NULL when called on driver exit, else it will - * be a pointer to a PMU resource type (not the full resource) * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. */ -_mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type); +_mali_osk_errcode_t mali_platform_deinit(void); /** @brief Platform specific powerdown sequence of MALI - * - * Called as part of platform init if there is no PMM support, else the - * PMM will call it. * - * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will - * be a mask of cores to power down based on the mali_pmm_core_id enum + * Call as part of platform init if there is no PMM support, else the + * PMM will call it. + * There are three power modes defined: + * 1) MALI_POWER_MODE_ON + * 2) MALI_POWER_MODE_LIGHT_SLEEP + * 3) MALI_POWER_MODE_DEEP_SLEEP + * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle + * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions + * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued. + * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power + * off. + * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP + * mode. + * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during + * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from + * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well. + * @param power_mode defines the power modes * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. */ -_mali_osk_errcode_t mali_platform_powerdown(u32 cores); +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode); -/** @brief Platform specific powerup sequence of MALI - * - * Called as part of platform deinit if there is no PMM support, else the - * PMM will call it. - * - * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will - * be a mask of cores to power down based on the mali_pmm_core_id enum - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_platform_powerup(u32 cores); /** @brief Platform specific handling of GPU utilization data * @@ -83,18 +85,15 @@ _mali_osk_errcode_t mali_platform_powerup(u32 cores); */ void mali_gpu_utilization_handler(u32 utilization); -#if USING_MALI_PMM -#if MALI_POWER_MGMT_TEST_SUITE -/** @brief function to get status of individual cores +/** @brief Setting the power domain of MALI * - * This function is used by power management test suite to get the status of powered up/down the number - * of cores - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. + * This function sets the power domain of MALI if Linux run time power management is enabled + * + * @param dev Reference to struct platform_device (defined in linux) used by MALI GPU */ -u32 pmu_get_power_up_down_info(void); -#endif -#endif +void set_mali_parent_power_domain(void* dev); #ifdef __cplusplus } #endif +#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/ux500/mali_platform.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/ux500/mali_platform.c index 481e6e76c54..f9343def5d6 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/ux500/mali_platform.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/ux500/mali_platform.c @@ -21,18 +21,71 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/workqueue.h> +#include <linux/wakelock.h> +#include <linux/version.h> +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) +#include <mach/prcmu.h> +#else #include <linux/mfd/dbx500-prcmu.h> +#endif #define MALI_HIGH_TO_LOW_LEVEL_UTILIZATION_LIMIT 64 #define MALI_LOW_TO_HIGH_LEVEL_UTILIZATION_LIMIT 192 -static int is_running; +static bool is_running; +static bool is_initialized; static struct regulator *regulator; static struct clk *clk_sga; static u32 last_utilization; static struct work_struct mali_utilization_work; static struct workqueue_struct *mali_utilization_workqueue; +static struct wake_lock wakelock; + +static _mali_osk_errcode_t mali_platform_powerdown() +{ + if (is_running) { + wake_unlock(&wakelock); + clk_disable(clk_sga); + if (regulator) { + int ret = regulator_disable(regulator); + if (ret < 0) { + MALI_DEBUG_PRINT(2, ("%s: Failed to disable regulator %s\n", __func__, "v-mali")); + is_running = false; + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + } + is_running = false; + } + MALI_DEBUG_PRINT(4, ("mali_platform_powerdown is_running: %u\n", is_running)); + MALI_SUCCESS; +} + +static _mali_osk_errcode_t mali_platform_powerup() +{ + if (!is_running) { + int ret = regulator_enable(regulator); + if (ret < 0) { + MALI_DEBUG_PRINT(2, ("%s: Failed to enable regulator %s\n", __func__, "v-mali")); + goto error; + } + + ret = clk_enable(clk_sga); + if (ret < 0) { + regulator_disable(regulator); + MALI_DEBUG_PRINT(2, ("%s: Failed to enable clock %s\n", __func__, "mali")); + goto error; + } + + wake_lock(&wakelock); + is_running = true; + } + MALI_DEBUG_PRINT(4, ("mali_platform_powerup is_running:%u\n", is_running)); + MALI_SUCCESS; +error: + MALI_DEBUG_PRINT(1, ("Failed to power up.\n")); + MALI_ERROR(_MALI_OSK_ERR_FAULT); +} /* Rationale behind the values for: * MALI_HIGH_LEVEL_UTILIZATION_LIMIT and MALI_LOW_LEVEL_UTILIZATION_LIMIT @@ -91,29 +144,35 @@ void mali_utilization_function(struct work_struct *ptr) MALI_DEBUG_PRINT(5, ("MALI GPU utilization: %u\n", last_utilization)); } -_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource) +_mali_osk_errcode_t mali_platform_init() { - is_running = 0; + is_running = false; last_utilization = 0; - mali_utilization_workqueue = create_singlethread_workqueue("mali_utilization_workqueue"); - if (NULL == mali_utilization_workqueue) { - MALI_DEBUG_PRINT(2, ("%s: Failed to setup workqueue %s\n", __func__, "v-mali")); - goto error; - } - INIT_WORK(&mali_utilization_work, mali_utilization_function); + if(!is_initialized) { - regulator = regulator_get(NULL, "v-mali"); - if (IS_ERR(regulator)) { - MALI_DEBUG_PRINT(2, ("%s: Failed to get regulator %s\n", __func__, "v-mali")); + mali_utilization_workqueue = create_singlethread_workqueue("mali_utilization_workqueue"); + if (NULL == mali_utilization_workqueue) { + MALI_DEBUG_PRINT(2, ("%s: Failed to setup workqueue %s\n", __func__, "mali_utilization_workqueue")); goto error; - } + } + INIT_WORK(&mali_utilization_work, mali_utilization_function); - clk_sga = clk_get_sys("mali", NULL); - if (IS_ERR(clk_sga)) { - regulator_put(regulator); - MALI_DEBUG_PRINT(2, ("%s: Failed to get clock %s\n", __func__, "mali")); - goto error; + regulator = regulator_get(NULL, "v-mali"); + if (IS_ERR(regulator)) { + MALI_DEBUG_PRINT(2, ("%s: Failed to get regulator %s\n", __func__, "v-mali")); + goto error; + } + + clk_sga = clk_get_sys("mali", NULL); + if (IS_ERR(clk_sga)) { + regulator_put(regulator); + MALI_DEBUG_PRINT(2, ("%s: Failed to get clock %s\n", __func__, "mali")); + goto error; + } + + wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "mali_wakelock"); + is_initialized = true; } MALI_SUCCESS; @@ -122,55 +181,26 @@ error: MALI_ERROR(_MALI_OSK_ERR_FAULT); } -_mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type) +_mali_osk_errcode_t mali_platform_deinit() { destroy_workqueue(mali_utilization_workqueue); regulator_put(regulator); clk_put(clk_sga); + wake_lock_destroy(&wakelock); + is_running = false; + last_utilization = 0; + is_initialized = false; MALI_DEBUG_PRINT(2, ("SGA terminated.\n")); MALI_SUCCESS; } -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) +_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) { - if (is_running) { - clk_disable(clk_sga); - if (regulator) { - int ret = regulator_disable(regulator); - if (ret < 0) { - MALI_DEBUG_PRINT(2, ("%s: Failed to disable regulator %s\n", __func__, "v-mali")); - is_running = 0; - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - } - is_running = 0; - } - MALI_DEBUG_PRINT(4, ("mali_platform_powerdown is_running: %u cores: %u\n", is_running, cores)); - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_platform_powerup(u32 cores) -{ - if (!is_running) { - int ret = regulator_enable(regulator); - if (ret < 0) { - MALI_DEBUG_PRINT(2, ("%s: Failed to enable regulator %s\n", __func__, "v-mali")); - goto error; - } - - ret = clk_enable(clk_sga); - if (ret < 0) { - regulator_disable(regulator); - MALI_DEBUG_PRINT(2, ("%s: Failed to enable clock %s\n", __func__, "mali")); - goto error; - } - is_running = 1; - } - MALI_DEBUG_PRINT(4, ("mali_platform_powerup is_running:%u cores: %u\n", is_running, cores)); - MALI_SUCCESS; -error: - MALI_DEBUG_PRINT(1, ("Failed to power up.\n")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); + if (MALI_POWER_MODE_ON == power_mode) { + return mali_platform_powerup(); + } + /*We currently don't make any distinction between MALI_POWER_MODE_LIGHT_SLEEP and MALI_POWER_MODE_DEEP_SLEEP*/ + return mali_platform_powerdown(); } void mali_gpu_utilization_handler(u32 utilization) @@ -187,4 +217,7 @@ void mali_gpu_utilization_handler(u32 utilization) queue_work(mali_utilization_workqueue, &mali_utilization_work); } - +void set_mali_parent_power_domain(void* dev) +{ + MALI_DEBUG_PRINT(1, ("This function should not be called since we are not using run time pm\n")); +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/readme.txt b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/readme.txt index af40fddd20f..fadafe67a97 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/readme.txt +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/readme.txt @@ -3,17 +3,19 @@ Building the Mali Device Driver for Linux Build the Mali Device Driver for Linux by running the following make command: -KDIR=<kdir_path> USING_MMU=<mmu_option> USING_UMP=<ump_option> \ -BUILD=<build_option> CONFIG=<your_config> make +KDIR=<kdir_path> USING_UMP=<ump_option> USING_PMM=<pmm_option> BUILD=<build_option> \ +TARGET_PLATFORM=<target_platform> CONFIG=<your_config> make where kdir_path: Path to your Linux Kernel directory - mmu_option: 1 = Mali MMU(s) on - 0 = Mali MMU(s) off ump_option: 1 = Enable UMP support(*) 0 = disable UMP support + pmm_option: 1 = Enable power management + 0 = Disable power management build_option: debug = debug build of driver release = release build of driver + target_platform: Name of the sub-folder in platform/ that contains the + required mali_platform.c file. your_config: Name of the sub-folder to find the required config.h(**) file ("arch-" will be prepended) diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_200_regs.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_200_regs.h index 6b30802bb2d..e9da7ab8110 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_200_regs.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_200_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_gp_regs.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_gp_regs.h index 11eb55c424e..14719a3efe9 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_gp_regs.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/regs/mali_gp_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-arm11-cc/mali_timestamp.h index 96b709bc166..3279daede45 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-arm11-cc/mali_timestamp.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-arm11-cc/mali_timestamp.h @@ -11,7 +11,7 @@ #ifndef __MALI_TIMESTAMP_H__ #define __MALI_TIMESTAMP_H__ -#include "mali_osk.h" +#include "mali_osk.h" MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void) { diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-default/mali_timestamp.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-default/mali_timestamp.h index 11031d675ca..94b842a1008 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-default/mali_timestamp.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/timestamp-default/mali_timestamp.h @@ -11,7 +11,7 @@ #ifndef __MALI_TIMESTAMP_H__ #define __MALI_TIMESTAMP_H__ -#include "mali_osk.h" +#include "mali_osk.h" MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void) { diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile index 97225bbbf0b..c42eb937e72 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile @@ -20,8 +20,12 @@ endif # For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH ARCH ?= arm -## @note Should allow overriding of building UMP for non-debug: +BUILD ?= debug + EXTRA_CFLAGS += -DDEBUG -DMALI_STATE_TRACKING=0 +ifeq ($(BUILD), debug) +EXTRA_CFLAGS += -DDEBUG +endif # linux build system integration diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_api.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_api.c index 719370c3de7..083910f5af9 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_api.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_api.c @@ -296,15 +296,21 @@ _mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction ) void _ump_ukk_msync( _ump_uk_msync_s *args ) { ump_dd_mem * mem = NULL; + void *virtual = NULL; + u32 size = 0; + u32 offset = 0; _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - if (NULL==mem) + if (NULL == mem) { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id)); return; } + /* Ensure the memory doesn't dissapear when we are flushing it. */ + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); /* Returns the cache settings back to Userspace */ args->is_cached=mem->is_cached; @@ -313,17 +319,44 @@ void _ump_ukk_msync( _ump_uk_msync_s *args ) if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op ) { DBG_MSG(3, ("_ump_ukk_msync READOUT ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached)); - return; + goto msync_release_and_return; } /* Nothing to do if the memory is not caches */ if ( 0==mem->is_cached ) { DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op)); - return ; + goto msync_release_and_return; + } + DBG_MSG(3, ("_ump_ukk_msync FLUSHING ID: %u Enabled: %d OP: %d Address: 0x%08x Mapping: 0x%08x\n", + (ump_secure_id)args->secure_id, mem->is_cached, args->op, args->address, args->mapping)); + + if ( args->address ) + { + virtual = (void *)((u32)args->address); + offset = (u32)((args->address) - (args->mapping)); + } else { + /* Flush entire mapping when no address is specified. */ + virtual = args->mapping; + } + if ( args->size ) + { + size = args->size; + } else { + /* Flush entire mapping when no size is specified. */ + size = mem->size_bytes - offset; + } + + if ( (offset + size) > mem->size_bytes ) + { + DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes)); + goto msync_release_and_return; } - DBG_MSG(3, ("_ump_ukk_msync FLUSHING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op)); /* The actual cache flush - Implemented for each OS*/ - _ump_osk_msync( mem , args->op); + _ump_osk_msync( mem, virtual, offset, size, args->op); + +msync_release_and_return: + ump_dd_reference_release(mem); + return; } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_common.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_common.c index b99c3e7c7d2..602e0bad340 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_common.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_common.c @@ -385,3 +385,11 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ) _ump_osk_mem_mapregion_term( descriptor ); _mali_osk_free(descriptor); } + +u32 _ump_ukk_report_memory_usage( void ) +{ + if(device.backend->stat) + return device.backend->stat(device.backend); + else + return 0; +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_memory_backend.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_memory_backend.h index 02a64707036..f45783d25bd 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_memory_backend.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_kernel_memory_backend.h @@ -37,6 +37,7 @@ typedef struct ump_memory_backend int (*allocate)(void* ctx, ump_dd_mem * descriptor); void (*release)(void* ctx, ump_dd_mem * descriptor); void (*shutdown)(struct ump_memory_backend * backend); + u32 (*stat)(struct ump_memory_backend *backend); int (*pre_allocate_physical_check)(void *ctx, u32 size); u32 (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys); void * ctx; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_osk.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_osk.h index 73284f02b47..7022da1fc79 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_osk.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_osk.h @@ -18,7 +18,7 @@ #include <mali_osk.h> #include <ump_kernel_memory_backend.h> -#include <ump_uk_types.h> +#include "ump_uk_types.h" #ifdef __cplusplus extern "C" @@ -39,7 +39,7 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor ); -void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op ); +void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op ); #ifdef __cplusplus } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_uk_types.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_uk_types.h index b08335f61f1..9e61b26a64f 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_uk_types.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_uk_types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_ukk.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_ukk.h index a3317fc7b21..1867cf4431f 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_ukk.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/common/ump_ukk.h @@ -44,6 +44,8 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ); void _ump_ukk_msync( _ump_uk_msync_s *args ); +u32 _ump_ukk_report_memory_usage( void ); + #ifdef __cplusplus } #endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ioctl.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ioctl.h index b11429816ab..0c0ff6f6272 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ioctl.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ioctl.h @@ -19,7 +19,7 @@ extern "C" #include <linux/types.h> #include <linux/ioctl.h> -#include "../common/ump_uk_types.h" +#include <ump_uk_types.h> #ifndef __user #define __user diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_linux.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_linux.c index 76d6b2f913a..5465c70ed77 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_linux.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_linux.c @@ -16,6 +16,8 @@ #include <asm/uaccess.h> /* user space access */ #include <asm/atomic.h> #include <linux/device.h> +#include <linux/debugfs.h> + #include "arch/config.h" /* Configuration for current platform. The symlinc for arch is set by Makefile */ #include "ump_ioctl.h" #include "ump_kernel_common.h" @@ -48,6 +50,9 @@ MODULE_PARM_DESC(ump_major, "Device major number"); static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */ +#if UMP_LICENSE_IS_GPL +static struct dentry *ump_debugfs_dir = NULL; +#endif /* * The data which we attached to each virtual memory mapping request we get. @@ -133,6 +138,21 @@ static void ump_cleanup_module(void) +static ssize_t ump_memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 mem = _ump_ukk_report_memory_usage(); + + r = snprintf(buf, 64, "%u\n", mem); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations ump_memory_usage_fops = { + .owner = THIS_MODULE, + .read = ump_memory_used_read, +}; + /* * Initialize the UMP device driver. */ @@ -140,6 +160,17 @@ int ump_kernel_device_initialize(void) { int err; dev_t dev = 0; +#if UMP_LICENSE_IS_GPL + ump_debugfs_dir = debugfs_create_dir(ump_dev_name, NULL); + if (ERR_PTR(-ENODEV) == ump_debugfs_dir) + { + ump_debugfs_dir = NULL; + } + else + { + debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops); + } +#endif if (0 == ump_major) { @@ -216,6 +247,11 @@ void ump_kernel_device_terminate(void) /* free major */ unregister_chrdev_region(dev, 1); + +#if UMP_LICENSE_IS_GPL + if(ump_debugfs_dir) + debugfs_remove_recursive(ump_debugfs_dir); +#endif } /* diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.c index 5c8a7f3783f..cdcf19bc13d 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.c @@ -52,6 +52,7 @@ static void block_allocator_shutdown(ump_memory_backend * backend); static int block_allocator_allocate(void* ctx, ump_dd_mem * mem); static void block_allocator_release(void * ctx, ump_dd_mem * handle); static inline u32 get_phys(block_allocator * allocator, block_info * block); +static u32 block_allocator_stat(struct ump_memory_backend *backend); @@ -104,6 +105,7 @@ ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size) backend->allocate = block_allocator_allocate; backend->release = block_allocator_release; backend->shutdown = block_allocator_shutdown; + backend->stat = block_allocator_stat; backend->pre_allocate_physical_check = NULL; backend->adjust_to_mali_phys = NULL; @@ -271,3 +273,13 @@ static inline u32 get_phys(block_allocator * allocator, block_info * block) { return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE); } + +static u32 block_allocator_stat(struct ump_memory_backend *backend) +{ + block_allocator *allocator; + BUG_ON(!backend); + allocator = (block_allocator*)backend->ctx; + BUG_ON(!allocator); + + return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE; +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.h index 58ebe15e5a2..fa4bdccfe32 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.c index 99c9c223036..cb557cfebc1 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.c @@ -40,6 +40,7 @@ typedef struct os_allocator static void os_free(void* ctx, ump_dd_mem * descriptor); static int os_allocate(void* ctx, ump_dd_mem * descriptor); static void os_memory_backend_destroy(ump_memory_backend * backend); +static u32 os_stat(struct ump_memory_backend *backend); @@ -73,6 +74,7 @@ ump_memory_backend * ump_os_memory_backend_create(const int max_allocation) backend->allocate = os_allocate; backend->release = os_free; backend->shutdown = os_memory_backend_destroy; + backend->stat = os_stat; backend->pre_allocate_physical_check = NULL; backend->adjust_to_mali_phys = NULL; @@ -243,3 +245,11 @@ static void os_free(void* ctx, ump_dd_mem * descriptor) vfree(descriptor->block_array); } + + +static u32 os_stat(struct ump_memory_backend *backend) +{ + os_allocator *info; + info = (os_allocator*)backend->ctx; + return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE; +} diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.h index d6083477d72..f924705cf74 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_memory_backend.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_memory_backend.c index 1c1190a537f..37a0fccd7d0 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_memory_backend.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_memory_backend.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_atomics.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_atomics.c index b3300ab691a..ef1902e5391 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_atomics.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_atomics.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.c index 7a1c5e97886..43183225d9c 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.c @@ -26,6 +26,7 @@ #include <linux/slab.h> #include <asm/memory.h> +#include <asm/uaccess.h> /* to verify pointers from user space */ #include <asm/cacheflush.h> #include <linux/dma-mapping.h> @@ -139,7 +140,11 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descrip } vma = (struct vm_area_struct*)descriptor->process_mapping_info; - if (NULL == vma ) return _MALI_OSK_ERR_FAULT; + if (NULL == vma ) + { + kfree(vma_usage_tracker); + return _MALI_OSK_ERR_FAULT; + } vma->vm_private_data = vma_usage_tracker; vma->vm_flags |= VM_IO; @@ -206,38 +211,92 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript } -void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op ) +void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op ) { int i; - DBG_MSG(3, ("Flushing nr of blocks: %u. First: paddr: 0x%08x vaddr: 0x%08x size:%dB\n", mem->nr_blocks, mem->block_array[0].addr, phys_to_virt(mem->block_array[0].addr), mem->block_array[0].size)); + const void *start_v, *end_v; + + DBG_MSG(3, ("Flushing nr of blocks: %u, size: %u. First: paddr: 0x%08x vaddr: 0x%08x offset: 0x%08x size:%uB\n", + mem->nr_blocks, mem->size_bytes, mem->block_array[0].addr, virt, offset, size)); + + /* Flush L1 using virtual address, the entire range in one go. + * Only flush if user space process has a valid write mapping on given address. */ + if(access_ok(VERIFY_WRITE, virt, size)) + { + start_v = (void *)virt; + end_v = (void *)(start_v + size - 1); + /* There is no dmac_clean_range, so the L1 is always flushed, + * also for UMP_MSYNC_CLEAN. */ + dmac_flush_range(start_v, end_v); + } + else + { + DBG_MSG(1, ("Attempt to flush %d@%x as part of ID %u rejected: there is no valid mapping.\n", + size, virt, mem->secure_id)); + return; + } - /* TODO: Use args->size and args->address to select a subrange of this allocation to flush */ - for (i=0 ; i<mem->nr_blocks; i++) + /* Flush L2 using physical addresses, block for block. */ + for (i=0 ; i < mem->nr_blocks; i++) { - /* TODO: Find out which flush method is best of 1)Dma OR 2)Normal flush functions */ - /* TODO: Use args->op to select the flushing method: CLEAN_AND_INVALIDATE or CLEAN */ - /*#define USING_DMA_FLUSH*/ - #ifdef USING_DMA_FLUSH - DEBUG_ASSERT( (PAGE_SIZE==mem->block_array[i].size)); - dma_map_page(NULL, pfn_to_page(mem->block_array[i].addr >> PAGE_SHIFT), 0, PAGE_SIZE, DMA_BIDIRECTIONAL ); - /*dma_unmap_page(NULL, mem->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL);*/ - #else - /* Normal style flush */ - ump_dd_physical_block *block; - u32 start_p, end_p; - const void *start_v, *end_v; - block = &mem->block_array[i]; - - start_p = (u32)block->addr; - start_v = phys_to_virt( start_p ) ; - - end_p = start_p + block->size-1; - end_v = phys_to_virt( end_p ) ; - - dmac_flush_range(start_v, end_v); - outer_flush_range(start_p, end_p); - #endif + u32 start_p, end_p; + ump_dd_physical_block *block; + block = &mem->block_array[i]; + + if(offset >= block->size) + { + offset -= block->size; + continue; + } + + if(offset) + { + start_p = (u32)block->addr + offset; + /* We'll zero the offset later, after using it to calculate end_p. */ + } + else + { + start_p = (u32)block->addr; + } + + if(size < block->size - offset) + { + end_p = start_p + size - 1; + size = 0; + } + else + { + if(offset) + { + end_p = start_p + (block->size - offset - 1); + size -= block->size - offset; + offset = 0; + } + else + { + end_p = start_p + block->size - 1; + size -= block->size; + } + } + + switch(op) + { + case _UMP_UK_MSYNC_CLEAN: + outer_clean_range(start_p, end_p); + break; + case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE: + outer_flush_range(start_p, end_p); + break; + default: + break; + } + + if(0 == size) + { + /* Nothing left to flush. */ + break; + } } - return ; + return; } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_misc.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_misc.c index 78569c4457b..12066eb7630 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_misc.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_osk_misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.c index 155635026aa..e701f1bc9ee 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.h index b2bef1152c3..9ebc3553397 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.c index d14b631246c..d986e9f51d6 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.c @@ -138,9 +138,9 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi } /* - * IOCTL operation; Return size for specified UMP memory. + * IOCTL operation; Do cache maintenance on specified UMP memory. */ - int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data) +int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data) { _ump_uk_msync_s user_interaction; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.h index 31afe2dca56..4892c31327e 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/linux/ump_ukk_wrappers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/readme.txt b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/readme.txt index bf1bf61d60e..c238cf0f2b1 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/readme.txt +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/readme.txt @@ -3,15 +3,26 @@ Building the UMP Device Driver for Linux Build the UMP Device Driver for Linux by running the following make command: -KDIR=<kdir_path> CONFIG=<your_config> make +KDIR=<kdir_path> CONFIG=<your_config> BUILD=<build_option> make where kdir_path: Path to your Linux Kernel directory your_config: Name of the sub-folder to find the required config.h file ("arch-" will be prepended) + build_option: debug or release. Debug is default. -The config.h file contains the configuration parameters needed, like the -memory backend to use, and the amount of memory. +The config.h contains following configuration parameters: + +ARCH_UMP_BACKEND_DEFAULT + 0 specifies the dedicated memory allocator. + 1 specifies the OS memory allocator. +ARCH_UMP_MEMORY_ADDRESS_DEFAULT + This is only required for the dedicated memory allocator, and specifies + the physical start address of the memory block reserved for UMP. +ARCH_UMP_MEMORY_SIZE_DEFAULT + This specified the size of the memory block reserved for UMP, or the + maximum limit for allocations from the OS. The result will be a ump.ko file, which can be loaded into the Linux kernel -by using the insmod command. +by using the insmod command. The driver can also be built as a part of the +kernel itself. diff --git a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface.h b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface.h index 3bd928aefdb..ba81a07fee0 100644 --- a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface.h +++ b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface_ref_drv.h b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h index 70eea22d3c3..eb57fd88f3f 100644 --- a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface_ref_drv.h +++ b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_platform.h b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_platform.h index 55c49885f06..1b5af40e963 100644 --- a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_platform.h +++ b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_platform.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/Makefile b/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/Makefile index 0f3ace966df..bed5d51cc58 100644 --- a/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/Makefile +++ b/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/Makefile @@ -12,6 +12,21 @@ # Makefile for the Mali drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -obj-y += mali_drm.o -mali_drm-objs := mali_drv.o -EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/../drm/include/ +# If KERNELRELEASE is defined, we've been invoked from the # kernel build system and can use its language. +ifneq ($(KERNELRELEASE),) + obj-m := mali_drm.o + mali_drm-objs := mali_drv.o + EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/../drm/include/ + +# Otherwise we were called directly from the command # line; invoke the kernel build system. +else + + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +all: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +endif diff --git a/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/mali_drv.c b/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/mali_drv.c index 571ab04e1e2..0d982e38d45 100644 --- a/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/mali_drv.c +++ b/drivers/gpu/mali/mali400ko/x11/mali_drm/mali/mali_drv.c @@ -18,6 +18,7 @@ #include "mali_drv.h" static struct platform_device *dev0; +static struct platform_device *dev1; void mali_drm_preclose(struct drm_device *dev, struct drm_file *file_priv) { @@ -60,6 +61,7 @@ static const struct file_operations mali_driver_fops = static struct drm_driver driver = { + .driver_features = DRIVER_USE_PLATFORM_DEVICE, .load = mali_drm_load, .unload = mali_drm_unload, .context_dtor = NULL, @@ -69,6 +71,8 @@ static struct drm_driver driver = .lastclose = mali_drm_lastclose, .suspend = mali_drm_suspend, .resume = mali_drm_resume, + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, .ioctls = NULL, .fops = &mali_driver_fops, .name = DRIVER_NAME, @@ -79,23 +83,60 @@ static struct drm_driver driver = .patchlevel = DRIVER_PATCHLEVEL, }; -static struct platform_driver platform_drm_driver; +static struct drm_driver driver1 = +{ + .driver_features = DRIVER_USE_PLATFORM_DEVICE, + .load = mali_drm_load, + .unload = mali_drm_unload, + .context_dtor = NULL, + .reclaim_buffers = NULL, + .reclaim_buffers_idlelocked = NULL, + .preclose = mali_drm_preclose, + .lastclose = mali_drm_lastclose, + .suspend = mali_drm_suspend, + .resume = mali_drm_resume, + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .ioctls = NULL, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, + }, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +}; int mali_drm_init(struct platform_device *dev) { printk(KERN_INFO "Mali DRM initialize, driver name: %s, version %d.%d\n", DRIVER_NAME, DRIVER_MAJOR, DRIVER_MINOR); if (dev == dev0) { driver.num_ioctls = 0; - return drm_platform_init(&driver, dev0); + driver.platform_device = dev; + return drm_init(&driver); + } else if (dev == dev1) { + driver1.num_ioctls = 0; + driver1.platform_device = dev; + return drm_init(&driver1); } return 0; - } void mali_drm_exit(struct platform_device *dev) { - if (dev0 == dev) - drm_platform_exit(&driver, dev); + if (driver.platform_device == dev) { + drm_exit(&driver); + } else if (driver1.platform_device == dev) { + drm_exit(&driver1); + } } static int __devinit mali_platform_drm_probe(struct platform_device *dev) @@ -120,6 +161,7 @@ static int mali_platform_drm_resume(struct platform_device *dev) return 0; } + static struct platform_driver platform_drm_driver = { .probe = mali_platform_drm_probe, .remove = __devexit_p(mali_platform_drm_remove), @@ -134,13 +176,15 @@ static struct platform_driver platform_drm_driver = { static int __init mali_platform_drm_init(void) { dev0 = platform_device_register_simple("mali_drm", 0, NULL, 0); - return platform_driver_register(&platform_drm_driver); + dev1 = platform_device_register_simple("mali_drm", 1, NULL, 0); + return platform_driver_register( &platform_drm_driver ); } static void __exit mali_platform_drm_exit(void) { - platform_driver_unregister(&platform_drm_driver); + platform_driver_unregister( &platform_drm_driver ); platform_device_unregister(dev0); + platform_device_unregister(dev1); } #ifdef MODULE |