From a816cdc01390a64a814d19d026cc23a0e09ee20b Mon Sep 17 00:00:00 2001 From: "Mathieu J. Poirier" Date: Thu, 8 Dec 2011 09:29:58 -0700 Subject: snowball: android: Upversioning mali driver to V9 This originates from: is12dac198c352df28890265d237f389f5ddda8c35 Signed-off-by: Mathieu Poirier --- drivers/gpu/mali/mali400ko/.gitignore | 32 -- drivers/gpu/mali/mali400ko/Makefile | 2 +- .../driver/include/ump/ump_kernel_interface.h | 236 ------------ .../include/ump/ump_kernel_interface_ref_drv.h | 31 -- .../driver/include/ump/ump_kernel_platform.h | 48 --- .../mali400ko/driver/src/devicedrv/mali/Kbuild | 258 +++++++++++++ .../mali400ko/driver/src/devicedrv/mali/Makefile | 294 +-------------- .../driver/src/devicedrv/mali/Makefile.common | 5 +- .../driver/src/devicedrv/mali/Makefile.platform | 17 - .../devicedrv/mali/arch-pb-virtex5-m300/config.h | 2 - .../mali/arch-pb-virtex5-m400-1-direct/config.h | 2 - .../mali/arch-pb-virtex5-m400-1-pmu/config.h | 2 - .../devicedrv/mali/arch-pb-virtex5-m400-1/config.h | 2 - .../devicedrv/mali/arch-pb-virtex5-m400-2/config.h | 4 +- .../devicedrv/mali/arch-pb-virtex5-m400-3/config.h | 2 - .../devicedrv/mali/arch-pb-virtex5-m400-4/config.h | 2 - .../driver/src/devicedrv/mali/arch-ux500/config.h | 218 +++++------ .../devicedrv/mali/common/mali_block_allocator.c | 23 +- .../devicedrv/mali/common/mali_block_allocator.h | 2 +- .../src/devicedrv/mali/common/mali_kernel_GP2.c | 95 +++-- .../devicedrv/mali/common/mali_kernel_MALI200.c | 71 +++- .../src/devicedrv/mali/common/mali_kernel_common.h | 2 +- .../src/devicedrv/mali/common/mali_kernel_core.c | 83 +++-- .../src/devicedrv/mali/common/mali_kernel_core.h | 12 +- .../mali/common/mali_kernel_descriptor_mapping.c | 2 +- .../mali/common/mali_kernel_descriptor_mapping.h | 2 +- .../devicedrv/mali/common/mali_kernel_l2_cache.c | 2 + .../devicedrv/mali/common/mali_kernel_mem_buddy.c | 4 +- .../devicedrv/mali/common/mali_kernel_mem_mmu.c | 361 +++++++++++++++---- .../devicedrv/mali/common/mali_kernel_mem_mmu.h | 9 + .../src/devicedrv/mali/common/mali_kernel_mem_os.c | 59 ++- .../src/devicedrv/mali/common/mali_kernel_mem_os.h | 2 +- .../mali/common/mali_kernel_memory_engine.c | 17 +- .../mali/common/mali_kernel_memory_engine.h | 7 +- .../devicedrv/mali/common/mali_kernel_profiling.c | 177 ++++++--- .../devicedrv/mali/common/mali_kernel_profiling.h | 87 ++++- .../devicedrv/mali/common/mali_kernel_rendercore.c | 260 ++++++------- .../devicedrv/mali/common/mali_kernel_rendercore.h | 124 ++++++- .../mali/common/mali_kernel_session_manager.h | 2 +- .../devicedrv/mali/common/mali_kernel_subsystem.h | 4 +- .../driver/src/devicedrv/mali/common/mali_osk.h | 108 +++++- .../src/devicedrv/mali/common/mali_osk_bitops.h | 2 +- .../src/devicedrv/mali/common/mali_uk_types.h | 14 +- .../driver/src/devicedrv/mali/common/mali_ukk.h | 10 +- .../src/devicedrv/mali/common/pmm/mali_pmm.c | 191 +++++++--- .../src/devicedrv/mali/common/pmm/mali_pmm.h | 45 ++- .../src/devicedrv/mali/common/pmm/mali_pmm_pmu.c | 350 ++++++++++++++++++ .../src/devicedrv/mali/common/pmm/mali_pmm_pmu.h | 87 +++++ .../devicedrv/mali/common/pmm/mali_pmm_policy.h | 16 +- .../mali/common/pmm/mali_pmm_policy_alwayson.c | 1 - .../mali/common/pmm/mali_pmm_policy_alwayson.h | 2 +- .../mali/common/pmm/mali_pmm_policy_jobcontrol.c | 17 +- .../mali/common/pmm/mali_pmm_policy_jobcontrol.h | 4 +- .../src/devicedrv/mali/common/pmm/mali_pmm_state.c | 12 +- .../src/devicedrv/mali/common/pmm/mali_pmm_state.h | 31 +- .../mali/linux/mali_device_pause_resume.c | 18 +- .../mali/linux/mali_device_pause_resume.h | 2 +- .../src/devicedrv/mali/linux/mali_kernel_ioctl.h | 1 + .../src/devicedrv/mali/linux/mali_kernel_linux.c | 359 ++++++++---------- .../src/devicedrv/mali/linux/mali_kernel_linux.h | 12 + .../src/devicedrv/mali/linux/mali_kernel_pm.c | 166 +-------- .../src/devicedrv/mali/linux/mali_kernel_pm.h | 2 +- .../src/devicedrv/mali/linux/mali_kernel_sysfs.c | 401 +++++++++++++++++++++ .../src/devicedrv/mali/linux/mali_kernel_sysfs.h | 30 ++ .../mali/linux/mali_linux_dvfs_pause_resume.c | 72 ---- .../src/devicedrv/mali/linux/mali_linux_pm.h | 8 +- .../src/devicedrv/mali/linux/mali_osk_atomics.c | 2 +- .../src/devicedrv/mali/linux/mali_osk_indir_mmap.c | 2 +- .../driver/src/devicedrv/mali/linux/mali_osk_irq.c | 13 +- .../src/devicedrv/mali/linux/mali_osk_locks.c | 22 -- .../devicedrv/mali/linux/mali_osk_low_level_mem.c | 28 +- .../src/devicedrv/mali/linux/mali_osk_mali.c | 3 +- .../src/devicedrv/mali/linux/mali_osk_math.c | 2 +- .../src/devicedrv/mali/linux/mali_osk_memory.c | 11 + .../src/devicedrv/mali/linux/mali_osk_misc.c | 12 + .../devicedrv/mali/linux/mali_osk_notification.c | 1 - .../driver/src/devicedrv/mali/linux/mali_osk_pm.c | 19 +- .../src/devicedrv/mali/linux/mali_osk_specific.h | 2 +- .../src/devicedrv/mali/linux/mali_osk_time.c | 2 +- .../driver/src/devicedrv/mali/linux/mali_ukk_gp.c | 2 +- .../driver/src/devicedrv/mali/linux/mali_ukk_mem.c | 2 +- .../driver/src/devicedrv/mali/linux/mali_ukk_pp.c | 2 +- .../src/devicedrv/mali/linux/mali_ukk_profiling.c | 22 ++ .../src/devicedrv/mali/linux/mali_ukk_wrappers.h | 1 + .../mali/platform/default/mali_platform.c | 17 +- .../mali/platform/mali-runtimepm/mali_platform.c | 61 ---- .../mali/platform/mali400-pmu/mali_platform.c | 388 -------------------- .../src/devicedrv/mali/platform/mali_platform.h | 81 ++--- .../devicedrv/mali/platform/ux500/mali_platform.c | 151 +++++--- .../mali400ko/driver/src/devicedrv/mali/readme.txt | 10 +- .../driver/src/devicedrv/mali/regs/mali_200_regs.h | 2 +- .../driver/src/devicedrv/mali/regs/mali_gp_regs.h | 2 +- .../mali/timestamp-arm11-cc/mali_timestamp.h | 2 +- .../mali/timestamp-default/mali_timestamp.h | 2 +- .../mali400ko/driver/src/devicedrv/ump/Makefile | 6 +- .../src/devicedrv/ump/common/ump_kernel_api.c | 45 ++- .../src/devicedrv/ump/common/ump_kernel_common.c | 8 + .../ump/common/ump_kernel_memory_backend.h | 1 + .../driver/src/devicedrv/ump/common/ump_osk.h | 4 +- .../driver/src/devicedrv/ump/common/ump_uk_types.h | 2 +- .../driver/src/devicedrv/ump/common/ump_ukk.h | 2 + .../driver/src/devicedrv/ump/linux/ump_ioctl.h | 2 +- .../src/devicedrv/ump/linux/ump_kernel_linux.c | 36 ++ .../linux/ump_kernel_memory_backend_dedicated.c | 12 + .../linux/ump_kernel_memory_backend_dedicated.h | 2 +- .../ump/linux/ump_kernel_memory_backend_os.c | 10 + .../ump/linux/ump_kernel_memory_backend_os.h | 2 +- .../src/devicedrv/ump/linux/ump_memory_backend.c | 2 +- .../src/devicedrv/ump/linux/ump_osk_atomics.c | 2 +- .../devicedrv/ump/linux/ump_osk_low_level_mem.c | 117 ++++-- .../driver/src/devicedrv/ump/linux/ump_osk_misc.c | 2 +- .../src/devicedrv/ump/linux/ump_ukk_ref_wrappers.c | 2 +- .../src/devicedrv/ump/linux/ump_ukk_ref_wrappers.h | 2 +- .../src/devicedrv/ump/linux/ump_ukk_wrappers.c | 4 +- .../src/devicedrv/ump/linux/ump_ukk_wrappers.h | 2 +- .../mali400ko/driver/src/devicedrv/ump/readme.txt | 19 +- .../src/ump/include/ump/ump_kernel_interface.h | 236 ++++++++++++ .../ump/include/ump/ump_kernel_interface_ref_drv.h | 31 ++ .../src/ump/include/ump/ump_kernel_platform.h | 48 +++ .../gpu/mali/mali400ko/x11/mali_drm/mali/Makefile | 21 +- .../mali/mali400ko/x11/mali_drm/mali/mali_drv.c | 58 ++- 121 files changed, 3652 insertions(+), 2415 deletions(-) delete mode 100644 drivers/gpu/mali/mali400ko/.gitignore delete mode 100644 drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface.h delete mode 100644 drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface_ref_drv.h delete mode 100644 drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_platform.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h delete mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c delete mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali-runtimepm/mali_platform.c delete mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali400-pmu/mali_platform.c create mode 100644 drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_platform.h 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/include/ump/ump_kernel_interface.h b/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface.h deleted file mode 100644 index 3bd928aefdb..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface.h +++ /dev/null @@ -1,236 +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 ump_kernel_interface.h - * - * This file contains the kernel space part of the UMP API. - */ - -#ifndef __UMP_KERNEL_INTERFACE_H__ -#define __UMP_KERNEL_INTERFACE_H__ - - -/** @defgroup ump_kernel_space_api UMP Kernel Space API - * @{ */ - - -#include "ump_kernel_platform.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/** - * External representation of a UMP handle in kernel space. - */ -typedef void * ump_dd_handle; - -/** - * Typedef for a secure ID, a system wide identificator for UMP memory buffers. - */ -typedef unsigned int ump_secure_id; - - -/** - * Value to indicate an invalid UMP memory handle. - */ -#define UMP_DD_HANDLE_INVALID ((ump_dd_handle)0) - - -/** - * Value to indicate an invalid secure Id. - */ -#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) - - -/** - * UMP error codes for kernel space. - */ -typedef enum -{ - UMP_DD_SUCCESS, /**< indicates success */ - UMP_DD_INVALID, /**< indicates failure */ -} ump_dd_status_code; - - -/** - * Struct used to describe a physical block used by UMP memory - */ -typedef struct ump_dd_physical_block -{ - unsigned long addr; /**< The physical address of the block */ - unsigned long size; /**< The length of the block, typically page aligned */ -} ump_dd_physical_block; - - -/** - * Retrieves the secure ID for the specified UMP memory. - * - * This identificator is unique across the entire system, and uniquely identifies - * the specified UMP memory. This identificator can later be used through the - * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" or - * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" - * functions in order to access this UMP memory, for instance from another process. - * - * @note There is a user space equivalent function called @ref ump_secure_id_get "ump_secure_id_get" - * - * @see ump_dd_handle_create_from_secure_id - * @see ump_handle_create_from_secure_id - * @see ump_secure_id_get - * - * @param mem Handle to UMP memory. - * - * @return Returns the secure ID for the specified UMP memory. - */ -UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle mem); - - -/** - * Retrieves a handle to allocated UMP memory. - * - * The usage of UMP memory is reference counted, so this will increment the reference - * count by one for the specified UMP memory. - * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any - * use for the retrieved handle. - * - * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" - * - * @see ump_dd_reference_release - * @see ump_handle_create_from_secure_id - * - * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. - * - * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. - */ -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id); - - -/** - * Retrieves the number of physical blocks used by the specified UMP memory. - * - * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed - * to describe the physical memory layout of the given UMP memory. This can later be used when calling - * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and - * @ref ump_dd_phys_block_get "ump_dd_phys_block_get". - * - * @see ump_dd_phys_blocks_get - * @see ump_dd_phys_block_get - * - * @param mem Handle to UMP memory. - * - * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory. - */ -UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem); - - -/** - * Retrieves all physical memory block information for specified UMP memory. - * - * This function can be used by other device drivers in order to create MMU tables. - * - * @note This function will fail if the num_blocks parameter is either to large or to small. - * - * @see ump_dd_phys_block_get - * - * @param mem Handle to UMP memory. - * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description. - * @param num_blocks The number of blocks to return in the blocks array. Use the function - * @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required. - * - * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. - */ -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * blocks, unsigned long num_blocks); - - -/** - * Retrieves the physical memory block information for specified block for the specified UMP memory. - * - * This function can be used by other device drivers in order to create MMU tables. - * - * @note This function will return UMP_DD_INVALID if the specified index is out of range. - * - * @see ump_dd_phys_blocks_get - * - * @param mem Handle to UMP memory. - * @param index Which physical info block to retrieve. - * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information. - * - * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. - */ -UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * block); - - -/** - * Retrieves the actual size of the specified UMP memory. - * - * The size is reported in bytes, and is typically page aligned. - * - * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get" - * - * @see ump_size_get - * - * @param mem Handle to UMP memory. - * - * @return Returns the allocated size of the specified UMP memory, in bytes. - */ -UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem); - - -/** - * Adds an extra reference to the specified UMP memory. - * - * This function adds an extra reference to the specified UMP memory. This function should - * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle - * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used - * to release each copy of the UMP memory handle. - * - * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add" - * for UMP handles returned from - * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id", - * because these handles are already reference counted by this function. - * - * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add" - * - * @see ump_reference_add - * - * @param mem Handle to UMP memory. - */ -UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem); - - -/** - * Releases a reference from the specified UMP memory. - * - * This function should be called once for every reference to the UMP memory handle. - * When the last reference is released, all resources associated with this UMP memory - * handle are freed. - * - * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release" - * - * @see ump_reference_release - * - * @param mem Handle to UMP memory. - */ -UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem); - - -#ifdef __cplusplus -} -#endif - - -/** @} */ /* end group ump_kernel_space_api */ - - -#endif /* __UMP_KERNEL_INTERFACE_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface_ref_drv.h b/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface_ref_drv.h deleted file mode 100644 index 70eea22d3c3..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_interface_ref_drv.h +++ /dev/null @@ -1,31 +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 ump_kernel_interface.h - */ - -#ifndef __UMP_KERNEL_INTERFACE_REF_DRV_H__ -#define __UMP_KERNEL_INTERFACE_REF_DRV_H__ - -#include "ump_kernel_interface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Turn specified physical memory into UMP memory. */ -UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks); - -#ifdef __cplusplus -} -#endif - -#endif /* __UMP_KERNEL_INTERFACE_REF_DRV_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_platform.h b/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_platform.h deleted file mode 100644 index 55c49885f06..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/include/ump/ump_kernel_platform.h +++ /dev/null @@ -1,48 +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 ump_kernel_platform.h - * - * This file should define UMP_KERNEL_API_EXPORT, - * which dictates how the UMP kernel API should be exported/imported. - * Modify this file, if needed, to match your platform setup. - */ - -#ifndef __UMP_KERNEL_PLATFORM_H__ -#define __UMP_KERNEL_PLATFORM_H__ - -/** @addtogroup ump_kernel_space_api - * @{ */ - -/** - * A define which controls how UMP kernel space API functions are imported and exported. - * This define should be set by the implementor of the UMP API. - */ - -#if defined(_WIN32) - -#if defined(UMP_BUILDING_UMP_LIBRARY) -#define UMP_KERNEL_API_EXPORT __declspec(dllexport) -#else -#define UMP_KERNEL_API_EXPORT __declspec(dllimport) -#endif - -#else - -#define UMP_KERNEL_API_EXPORT - -#endif - - -/** @} */ /* end group ump_kernel_space_api */ - - -#endif /* __UMP_KERNEL_PLATFORM_H__ */ 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..09418ab3124 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild @@ -0,0 +1,258 @@ +# +# 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. +# + +# 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 ?= 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 += -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 + +ifeq ($(USING_PROFILING),1) +SRC += \ + common/mali_kernel_profiling.c \ + timestamp-$(TIMESTAMP)/mali_timestamp.c +ccflags-y += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP) +endif + +# Selecting files to compile by parsing the config file + +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_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- 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 for - * ST-Ericsson. - * License terms: GNU General Public License (GPL) version 2. - */ - -#ifndef __ARCH_UX500_CONFIG_H__ -#define __ARCH_UX500_CONFIG_H__ - -/* #include */ - -#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 for + * ST-Ericsson. + * License terms: GNU General Public License (GPL) version 2. + */ + +#ifndef __ARCH_UX500_CONFIG_H__ +#define __ARCH_UX500_CONFIG_H__ + +/* #include */ + +#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_kernel_GP2.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c index e91abe120cb..70f07343e66 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 @@ -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(); } @@ -632,12 +633,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_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 +646,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 +690,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,13 +705,19 @@ 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_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_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 @@ -729,12 +736,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_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,10 +803,6 @@ 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) ) { @@ -832,16 +839,19 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) } #endif +#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 + 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); @@ -891,8 +901,25 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) #endif } +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_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 ? */ @@ -922,6 +949,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 */ @@ -1022,6 +1054,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 +1067,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; @@ -1154,6 +1189,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,9 +1242,10 @@ 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); @@ -1281,6 +1327,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 +1460,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..292c8f31f3d 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 @@ -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 */ @@ -578,11 +578,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_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 +591,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,15 +630,20 @@ 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_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_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 @@ -653,13 +658,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_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,10 +719,6 @@ 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) ) @@ -757,6 +762,23 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit } +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_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)? */ @@ -771,6 +793,11 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit /* 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? */ @@ -814,6 +841,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 +854,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; @@ -954,6 +984,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 +1066,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 +1223,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 @@ -20,6 +20,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 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.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c index 07bb894b1b4..1f3eb4aa778 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c @@ -13,8 +13,7 @@ #include "mali_osk_mali.h" #include "mali_ukk.h" #include "mali_timestamp.h" - -#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 +#include "mali_kernel_profiling.h" typedef struct mali_profiling_entry { @@ -39,9 +38,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_profiling_init(mali_bool auto_start) { profile_entries = NULL; profile_entry_count = 0; @@ -56,6 +55,17 @@ _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_profiling_start(&limit)) + { + return _MALI_OSK_ERR_FAULT; + } + } + return _MALI_OSK_ERR_OK; } @@ -71,7 +81,7 @@ void _mali_profiling_term(void) if (NULL != profile_entries) { - _mali_osk_free(profile_entries); + _mali_osk_vfree(profile_entries); profile_entries = NULL; } @@ -82,35 +92,7 @@ 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) -{ - 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 _MALI_OSK_ERR_FAULT; - } - - 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) +inline _mali_osk_errcode_t _mali_profiling_start(u32 * limit) { _mali_osk_errcode_t ret; @@ -122,13 +104,13 @@ _mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) 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; + profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry)); + profile_entry_count = *limit; if (NULL == profile_entries) { _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); @@ -143,7 +125,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 +133,34 @@ _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 _mali_osk_errcode_t _mali_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 _MALI_OSK_ERR_FAULT; + } + + 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_stop(_mali_uk_profiling_stop_s *args) +inline _mali_osk_errcode_t _mali_profiling_stop(u32 * count) { _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); @@ -178,16 +181,27 @@ _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_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_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 +216,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_profiling_clear(void) { _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); @@ -230,7 +244,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 +252,54 @@ _mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) return _MALI_OSK_ERR_OK; } +mali_bool _mali_profiling_is_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; +} + +mali_bool _mali_profiling_have_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; +} + +void _mali_profiling_set_default_enable_state(mali_bool enable) +{ + mali_profiling_default_enable = enable; +} + +mali_bool _mali_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_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 */ + 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]); +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_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_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/common/mali_kernel_profiling.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h index 5d3aa6eb841..fe650e81e41 100644 --- 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 @@ -15,30 +15,105 @@ #include <../../../include/cinstr/mali_cinstr_profiling_events_m200.h> +#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 + /** * Initialize the profiling module. * @return _MALI_OSK_ERR_OK on success, otherwise failure. */ -_mali_osk_errcode_t _mali_profiling_init(void); +_mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start); /* * Terminate the profiling module. */ void _mali_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_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. + * @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); +/** + * 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_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_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_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_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_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_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_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_profiling_get_default_enable_state(void); + #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..b123b4bc61b 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 @@ -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" @@ -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_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")) ; @@ -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; idescription,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; idescription,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..d1fb0a9a168 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 @@ -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. 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_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/common/pmm/mali_pmm_pmu.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c new file mode 100644 index 00000000000..da8957724e8 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c @@ -0,0 +1,350 @@ +/* + * 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_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" + +/* 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 +{ + u32 reg_base_addr; /**< PMU registers base address */ + u32 reg_size; /**< PMU registers size */ + const char *name; /**< PMU name */ + u32 irq_num; /**< PMU irq number */ + + mali_io_address reg_mapped; /**< IO-mapped pointer to registers */ +} platform_pmu_t; + +static platform_pmu_t *pmu_info = NULL; + +/** @brief Register layout for hardware PMU + */ +typedef enum { + PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */ + PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */ + PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */ + PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */ + PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */ + PMU_REG_ADDR_MGMT_INT_STAT = 0x14, /*< Interrupt status register */ + PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */ + PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Software delay register */ + PMU_REG_ADDR_MGMT_MASTER_PWR_UP = 0x24, /*< Master power up register */ + PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */ +} pmu_reg_addr_mgmt_addr; + +/* Internal functions */ +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 +static void pmm_pmu_dump_regs( platform_pmu_t *pmu ); +static pmm_pmu_test( platform_pmu_t *pmu, u32 cores ); +#endif + +_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource) +{ + + if( resource->type == PMU ) + { + if( (resource->base == 0) || + (resource->description == NULL) ) + { + /* NOTE: We currently don't care about any other resource settings */ + MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n")); + MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + } + pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info)); + MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM ); + + /* All values get 0 as default */ + _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info)); + + pmu_info->reg_base_addr = resource->base; + pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE; + pmu_info->name = resource->description; + pmu_info->irq_num = resource->irq; + + if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) ) + { + MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n", + pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); + goto cleanup; + } + else + { + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n", + pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); + } + + pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name ); + + if( 0 == pmu_info->reg_mapped ) + { + MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name)); + _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size ); + goto cleanup; + } + else + { + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n", + (u32) pmu_info->reg_mapped, + ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1, + pmu_info->name)); + } + + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name)); + +#if PMU_TEST + pmu_test(pmu_info, (MALI_PMM_CORE_GP)); + pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0)); +#endif + + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) ); + } + else + { + /* Didn't expect a different resource */ + MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + } + + MALI_SUCCESS; + +cleanup: + _mali_osk_free(pmu_info); + pmu_info = NULL; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); +} + +_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type) +{ + if (*type == PMU) + { + if( pmu_info ) + { + _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped); + _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") ); + } + } + else + { + /* Didn't expect a different resource */ + MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + } + + MALI_SUCCESS; + +} + +_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores) +{ + u32 stat; + u32 timeout; + u32 cores_pmu; + + MALI_DEBUG_ASSERT_POINTER(pmu_info); + MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power down (0x%x)\n", cores) ); + + cores_pmu = pmu_translate_cores_to_pmu(cores); + pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_DOWN, cores_pmu ); + + /* Wait for cores to be powered down */ + timeout = 10; /* 10ms */ + do + { + /* Get status of sleeping cores */ + stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); + stat &= cores_pmu; + if( stat == cores_pmu ) break; /* All cores we wanted are now asleep */ + _mali_osk_time_ubusydelay(1000); /* 1ms */ + timeout--; + } while( timeout > 0 ); + + if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores) +{ + u32 cores_pmu; + u32 stat; + u32 timeout; + + MALI_DEBUG_ASSERT_POINTER(pmu_info); + MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ + MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) ); + + /* Don't use interrupts - just poll status */ + pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 ); + cores_pmu = pmu_translate_cores_to_pmu(cores); + pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu ); + + timeout = 10; /* 10ms */ + do + { + /* Get status of sleeping cores */ + stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); + stat &= cores_pmu; + if( stat == 0 ) break; /* All cores we wanted are now awake */ + _mali_osk_time_ubusydelay(1000); /* 1ms */ + timeout--; + } while( timeout > 0 ); + + if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); + + MALI_SUCCESS; +} + + +/***** INTERNAL *****/ + +/** @brief Internal PMU function to translate the cores bit mask + * into something the hardware PMU understands + * + * @param cores PMM cores bitmask + * @return PMU hardware cores bitmask + */ +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. + * For other hardware, some translation can be done here, by + * translating the MALI_PMM_CORE_* bits into specific hardware + * bits + */ + return cores; +} + +/** @brief Internal PMU function to read a PMU register + * + * @param pmu handle that identifies the PMU hardware + * @param relative_address relative PMU hardware address to read from + * @return 32-bit value that was read from the address + */ +static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address) +{ + u32 read_val; + + MALI_DEBUG_ASSERT_POINTER(pmu); + MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); + MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); + + read_val = _mali_osk_mem_ioread32(pmu->reg_mapped, relative_address); + + MALI_DEBUG_PRINT( 5, ("PMU: reg_read: %s Addr:0x%04X Val:0x%08x\n", + pmu->name, relative_address, read_val)); + + return read_val; +} + +/** @brief Internal PMU function to write to a PMU register + * + * @param pmu handle that identifies the PMU hardware + * @param relative_address relative PMU hardware address to write to + * @param new_val new 32-bit value to write into the address + */ +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); + MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); + + MALI_DEBUG_PRINT( 5, ("PMU: reg_write: %s Addr:0x%04X Val:0x%08x\n", + pmu->name, relative_address, new_val)); + + _mali_osk_mem_iowrite32(pmu->reg_mapped, relative_address, new_val); +} + +#if PMU_TEST + +/***** TEST *****/ + +static void pmu_dump_regs( platform_pmu_t *pmu ) +{ + u32 addr; + for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 ) + { + MALI_PRINT( ("PMU_REG: 0x%08x: 0x%04x\n", (addr + pmu->reg_base_addr), pmu_reg_read( pmu, addr ) ) ); + } +} + +/* This function is an internal test for the PMU without any Mali h/w interaction */ +static void pmu_test( platform_pmu_t *pmu, u32 cores ) +{ + u32 stat; + u32 timeout; + + MALI_PRINT( ("PMU_TEST: Start\n") ); + + pmu_dump_regs( pmu ); + + MALI_PRINT( ("PMU_TEST: Power down cores: 0x%x\n", cores) ); + _mali_pmm_pmu_power_down( pmu, cores, MALI_TRUE ); + + stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); + MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == cores ? "SUCCESS" : "FAIL" ) ); + + pmu_dump_regs( pmu ); + + MALI_PRINT( ("PMU_TEST: Power up cores: 0x%x\n", cores) ); + _mali_pmm_pmu_power_up( pmu, cores, MALI_FALSE ); + + MALI_PRINT( ("PMU_TEST: Waiting for power up...\n") ); + timeout = 1000; /* 1 sec */ + while( !_mali_pmm_pmu_irq_power_up(pmu) && timeout > 0 ) + { + _mali_osk_time_ubusydelay(1000); /* 1ms */ + timeout--; + } + + MALI_PRINT( ("PMU_TEST: Waited %dms for interrupt\n", (1000-timeout)) ); + stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); + MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == 0 ? "SUCCESS" : "FAIL" ) ); + + _mali_pmm_pmu_irq_power_up_clear(pmu); + + pmu_dump_regs( pmu ); + + MALI_PRINT( ("PMU_TEST: Finish\n") ); +} +#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..25b08b5f661 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 @@ -16,16 +16,13 @@ #include /* file system operations */ #include /* character device definitions */ #include /* memory mananger definitions */ -#include /* user space access */ #include -#include /* 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,14 @@ #include "mali_ukk_wrappers.h" #include "mali_kernel_pm.h" +#include "mali_kernel_sysfs.h" + /* */ #include "mali_kernel_license.h" +/* 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 +74,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 +139,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 +176,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 +217,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 +309,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 +319,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 +426,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 /* 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 -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif /* CONFIG_HAS_EARLYSUSPEND */ #ifdef CONFIG_PM_RUNTIME #include @@ -27,7 +24,6 @@ #include #include #include -#include #include #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..60c77a7a359 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c @@ -0,0 +1,401 @@ +/** + * 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. + */ + + +/** + * @file mali_kernel_sysfs.c + * Implementation of some sysfs data exports + */ + +#include +#include +#include "mali_kernel_license.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" + +#if MALI_LICENSE_IS_GPL + +#include +#include +#include +#include +#include "mali_kernel_subsystem.h" +#include "mali_kernel_sysfs.h" +#include "mali_kernel_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_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_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_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_profiling_have_recording()) + { + if (_MALI_OSK_ERR_OK != _mali_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_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_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_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_profiling_have_recording()) + { + return NULL; + } + + /* check if the next entry actually is avaiable */ + if (_mali_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_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_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_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_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 -#include -#include -#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_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 #include #include -#include #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 +#include 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..12f4299ee9b 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 @@ -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 */ 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 #include -#include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #include 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_specific.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h index 54acfdd138c..6aacf17d387 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 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_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/mali400-pmu/mali_platform.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali400-pmu/mali_platform.c deleted file mode 100644 index cf95b8ae09e..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/platform/mali400-pmu/mali_platform.c +++ /dev/null @@ -1,388 +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 Mali 400 PMU hardware - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" - -#if USING_MALI_PMM - -#include "mali_pmm.h" - -/* Internal test on/off */ -#define PMU_TEST 0 - -/** @brief PMU hardware info - */ -typedef struct platform_pmu -{ - u32 reg_base_addr; /**< PMU registers base address */ - u32 reg_size; /**< PMU registers size */ - const char *name; /**< PMU name */ - u32 irq_num; /**< PMU irq number */ - - mali_io_address reg_mapped; /**< IO-mapped pointer to registers */ -} platform_pmu_t; - -static platform_pmu_t *pmu_info = NULL; - -/** @brief Register layout for hardware PMU - */ -typedef enum { - PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */ - PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */ - PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */ - PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */ - PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */ - PMU_REG_ADDR_MGMT_INT_STAT = 0x14, /*< Interrupt status register */ - PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */ - PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Software delay register */ - PMU_REG_ADDR_MGMT_MASTER_PWR_UP = 0x24, /*< Master power up register */ - PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */ -} 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); -#if PMU_TEST -void pmm_pmu_dump_regs( platform_pmu_t *pmu ); -void 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) -{ -#if USING_MALI_PMM - if( resource == NULL ) - { - /* Nothing to set up for the system */ - } - else if( resource->type == PMU ) - { - if( (resource->base == 0) || - (resource->description == NULL) ) - { - /* NOTE: We currently don't care about any other resource settings */ - 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 ); - - /* All values get 0 as default */ - _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info)); - - pmu_info->reg_base_addr = resource->base; - pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE; - pmu_info->name = resource->description; - pmu_info->irq_num = resource->irq; - - if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) ) - { - MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n", - pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); - goto cleanup; - } - else - { - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n", - pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); - } - - pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name ); - - if( 0 == pmu_info->reg_mapped ) - { - MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name)); - _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size ); - goto cleanup; - } - else - { - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n", - (u32) pmu_info->reg_mapped, - ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1, - pmu_info->name)); - } - - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name)); - -#if PMU_TEST - pmu_test(pmu_info, (MALI_PMM_CORE_GP)); - pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0)); -#endif - - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) ); - } - else - { - /* Didn't expect a different resource */ - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - MALI_SUCCESS; - -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) -{ -#if USING_MALI_PMM - if( type == NULL ) - { - /* Nothing to tear down for the system */ - } - else if (*type == PMU) - { - if( pmu_info ) - { - _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped); - _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") ); - } - } - else - { - /* Didn't expect a different resource */ - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - MALI_SUCCESS; - -#else - /* Nothing to do when not using PMM */ - MALI_SUCCESS; -#endif -} - -_mali_osk_errcode_t mali_platform_powerdown(u32 cores) -{ -#if USING_MALI_PMM - u32 stat; - u32 timeout; - u32 cores_pmu; - - MALI_DEBUG_ASSERT_POINTER(pmu_info); - MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power down (0x%x)\n", cores) ); - - cores_pmu = pmu_translate_cores_to_pmu(cores); - pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_DOWN, cores_pmu ); - - /* Wait for cores to be powered down */ - timeout = 10; /* 10ms */ - do - { - /* Get status of sleeping cores */ - stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); - stat &= cores_pmu; - if( stat == cores_pmu ) break; /* All cores we wanted are now asleep */ - _mali_osk_time_ubusydelay(1000); /* 1ms */ - timeout--; - } while( timeout > 0 ); - - 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) -{ -#if USING_MALI_PMM - u32 cores_pmu; - u32 stat; - u32 timeout; - - MALI_DEBUG_ASSERT_POINTER(pmu_info); - MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) ); - - /* Don't use interrupts - just poll status */ - pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 ); - cores_pmu = pmu_translate_cores_to_pmu(cores); - pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu ); - - timeout = 10; /* 10ms */ - do - { - /* Get status of sleeping cores */ - stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); - stat &= cores_pmu; - if( stat == 0 ) break; /* All cores we wanted are now awake */ - _mali_osk_time_ubusydelay(1000); /* 1ms */ - timeout--; - } while( timeout > 0 ); - - 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 *****/ - -/** @brief Internal PMU function to translate the cores bit mask - * into something the hardware PMU understands - * - * @param cores PMM cores bitmask - * @return PMU hardware cores bitmask - */ -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. - * For other hardware, some translation can be done here, by - * translating the MALI_PMM_CORE_* bits into specific hardware - * bits - */ - return cores; -} - -/** @brief Internal PMU function to read a PMU register - * - * @param pmu handle that identifies the PMU hardware - * @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) -{ - u32 read_val; - - MALI_DEBUG_ASSERT_POINTER(pmu); - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); - - read_val = _mali_osk_mem_ioread32(pmu->reg_mapped, relative_address); - - MALI_DEBUG_PRINT( 5, ("PMU: reg_read: %s Addr:0x%04X Val:0x%08x\n", - pmu->name, relative_address, read_val)); - - return read_val; -} - -/** @brief Internal PMU function to write to a PMU register - * - * @param pmu handle that identifies the PMU hardware - * @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) -{ - MALI_DEBUG_ASSERT_POINTER(pmu); - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); - - MALI_DEBUG_PRINT( 5, ("PMU: reg_write: %s Addr:0x%04X Val:0x%08x\n", - pmu->name, relative_address, 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 - -/***** TEST *****/ - -void pmu_dump_regs( platform_pmu_t *pmu ) -{ - u32 addr; - for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 ) - { - MALI_PRINT( ("PMU_REG: 0x%08x: 0x%04x\n", (addr + pmu->reg_base_addr), pmu_reg_read( pmu, addr ) ) ); - } -} - -/* This function is an internal test for the PMU without any Mali h/w interaction */ -void pmu_test( platform_pmu_t *pmu, u32 cores ) -{ - u32 stat; - u32 timeout; - - MALI_PRINT( ("PMU_TEST: Start\n") ); - - pmu_dump_regs( pmu ); - - MALI_PRINT( ("PMU_TEST: Power down cores: 0x%x\n", cores) ); - _mali_pmm_pmu_power_down( pmu, cores, MALI_TRUE ); - - stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); - MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == cores ? "SUCCESS" : "FAIL" ) ); - - pmu_dump_regs( pmu ); - - MALI_PRINT( ("PMU_TEST: Power up cores: 0x%x\n", cores) ); - _mali_pmm_pmu_power_up( pmu, cores, MALI_FALSE ); - - MALI_PRINT( ("PMU_TEST: Waiting for power up...\n") ); - timeout = 1000; /* 1 sec */ - while( !_mali_pmm_pmu_irq_power_up(pmu) && timeout > 0 ) - { - _mali_osk_time_ubusydelay(1000); /* 1ms */ - timeout--; - } - - MALI_PRINT( ("PMU_TEST: Waited %dms for interrupt\n", (1000-timeout)) ); - stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); - MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == 0 ? "SUCCESS" : "FAIL" ) ); - - _mali_pmm_pmu_irq_power_up_clear(pmu); - - pmu_dump_regs( pmu ); - - MALI_PRINT( ("PMU_TEST: Finish\n") ); -} -#endif /* USING_MALI_PMM && PMU_TEST */ 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 #include #include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) +#include +#else #include +#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= USING_MMU= USING_UMP= \ -BUILD= CONFIG= make +KDIR= USING_UMP= USING_PMM= BUILD= \ +TARGET_PLATFORM= 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 #include -#include +#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 #include -#include "../common/ump_uk_types.h" +#include #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 /* user space access */ #include #include +#include + #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 #include +#include /* to verify pointers from user space */ #include #include @@ -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 ; inr_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= CONFIG= make +KDIR= CONFIG= BUILD= 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/src/ump/include/ump/ump_kernel_interface.h b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface.h new file mode 100644 index 00000000000..ba81a07fee0 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface.h @@ -0,0 +1,236 @@ +/* + * 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. + * + * 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 ump_kernel_interface.h + * + * This file contains the kernel space part of the UMP API. + */ + +#ifndef __UMP_KERNEL_INTERFACE_H__ +#define __UMP_KERNEL_INTERFACE_H__ + + +/** @defgroup ump_kernel_space_api UMP Kernel Space API + * @{ */ + + +#include "ump_kernel_platform.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * External representation of a UMP handle in kernel space. + */ +typedef void * ump_dd_handle; + +/** + * Typedef for a secure ID, a system wide identificator for UMP memory buffers. + */ +typedef unsigned int ump_secure_id; + + +/** + * Value to indicate an invalid UMP memory handle. + */ +#define UMP_DD_HANDLE_INVALID ((ump_dd_handle)0) + + +/** + * Value to indicate an invalid secure Id. + */ +#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1) + + +/** + * UMP error codes for kernel space. + */ +typedef enum +{ + UMP_DD_SUCCESS, /**< indicates success */ + UMP_DD_INVALID, /**< indicates failure */ +} ump_dd_status_code; + + +/** + * Struct used to describe a physical block used by UMP memory + */ +typedef struct ump_dd_physical_block +{ + unsigned long addr; /**< The physical address of the block */ + unsigned long size; /**< The length of the block, typically page aligned */ +} ump_dd_physical_block; + + +/** + * Retrieves the secure ID for the specified UMP memory. + * + * This identificator is unique across the entire system, and uniquely identifies + * the specified UMP memory. This identificator can later be used through the + * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" or + * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" + * functions in order to access this UMP memory, for instance from another process. + * + * @note There is a user space equivalent function called @ref ump_secure_id_get "ump_secure_id_get" + * + * @see ump_dd_handle_create_from_secure_id + * @see ump_handle_create_from_secure_id + * @see ump_secure_id_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the secure ID for the specified UMP memory. + */ +UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle mem); + + +/** + * Retrieves a handle to allocated UMP memory. + * + * The usage of UMP memory is reference counted, so this will increment the reference + * count by one for the specified UMP memory. + * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any + * use for the retrieved handle. + * + * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id" + * + * @see ump_dd_reference_release + * @see ump_handle_create_from_secure_id + * + * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function. + * + * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned. + */ +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id); + + +/** + * Retrieves the number of physical blocks used by the specified UMP memory. + * + * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed + * to describe the physical memory layout of the given UMP memory. This can later be used when calling + * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and + * @ref ump_dd_phys_block_get "ump_dd_phys_block_get". + * + * @see ump_dd_phys_blocks_get + * @see ump_dd_phys_block_get + * + * @param mem Handle to UMP memory. + * + * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory. + */ +UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem); + + +/** + * Retrieves all physical memory block information for specified UMP memory. + * + * This function can be used by other device drivers in order to create MMU tables. + * + * @note This function will fail if the num_blocks parameter is either to large or to small. + * + * @see ump_dd_phys_block_get + * + * @param mem Handle to UMP memory. + * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description. + * @param num_blocks The number of blocks to return in the blocks array. Use the function + * @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required. + * + * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. + */ +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * blocks, unsigned long num_blocks); + + +/** + * Retrieves the physical memory block information for specified block for the specified UMP memory. + * + * This function can be used by other device drivers in order to create MMU tables. + * + * @note This function will return UMP_DD_INVALID if the specified index is out of range. + * + * @see ump_dd_phys_blocks_get + * + * @param mem Handle to UMP memory. + * @param index Which physical info block to retrieve. + * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information. + * + * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure. + */ +UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * block); + + +/** + * Retrieves the actual size of the specified UMP memory. + * + * The size is reported in bytes, and is typically page aligned. + * + * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get" + * + * @see ump_size_get + * + * @param mem Handle to UMP memory. + * + * @return Returns the allocated size of the specified UMP memory, in bytes. + */ +UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem); + + +/** + * Adds an extra reference to the specified UMP memory. + * + * This function adds an extra reference to the specified UMP memory. This function should + * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle + * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used + * to release each copy of the UMP memory handle. + * + * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add" + * for UMP handles returned from + * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id", + * because these handles are already reference counted by this function. + * + * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add" + * + * @see ump_reference_add + * + * @param mem Handle to UMP memory. + */ +UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem); + + +/** + * Releases a reference from the specified UMP memory. + * + * This function should be called once for every reference to the UMP memory handle. + * When the last reference is released, all resources associated with this UMP memory + * handle are freed. + * + * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release" + * + * @see ump_reference_release + * + * @param mem Handle to UMP memory. + */ +UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem); + + +#ifdef __cplusplus +} +#endif + + +/** @} */ /* end group ump_kernel_space_api */ + + +#endif /* __UMP_KERNEL_INTERFACE_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h new file mode 100644 index 00000000000..eb57fd88f3f --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h @@ -0,0 +1,31 @@ +/* + * 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. + * + * 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 ump_kernel_interface.h + */ + +#ifndef __UMP_KERNEL_INTERFACE_REF_DRV_H__ +#define __UMP_KERNEL_INTERFACE_REF_DRV_H__ + +#include "ump_kernel_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Turn specified physical memory into UMP memory. */ +UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks); + +#ifdef __cplusplus +} +#endif + +#endif /* __UMP_KERNEL_INTERFACE_REF_DRV_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_platform.h b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_platform.h new file mode 100644 index 00000000000..1b5af40e963 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/ump/include/ump/ump_kernel_platform.h @@ -0,0 +1,48 @@ +/* + * 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. + * + * 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 ump_kernel_platform.h + * + * This file should define UMP_KERNEL_API_EXPORT, + * which dictates how the UMP kernel API should be exported/imported. + * Modify this file, if needed, to match your platform setup. + */ + +#ifndef __UMP_KERNEL_PLATFORM_H__ +#define __UMP_KERNEL_PLATFORM_H__ + +/** @addtogroup ump_kernel_space_api + * @{ */ + +/** + * A define which controls how UMP kernel space API functions are imported and exported. + * This define should be set by the implementor of the UMP API. + */ + +#if defined(_WIN32) + +#if defined(UMP_BUILDING_UMP_LIBRARY) +#define UMP_KERNEL_API_EXPORT __declspec(dllexport) +#else +#define UMP_KERNEL_API_EXPORT __declspec(dllimport) +#endif + +#else + +#define UMP_KERNEL_API_EXPORT + +#endif + + +/** @} */ /* end group ump_kernel_space_api */ + + +#endif /* __UMP_KERNEL_PLATFORM_H__ */ 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 -- cgit v1.2.3 From a13a9531e937d32844a07e7ef8787a946bdb192f Mon Sep 17 00:00:00 2001 From: Vishal Bhoj Date: Wed, 14 Dec 2011 05:01:03 +0000 Subject: snowball: android: Add "CONFIG_MALI_DRM" config This config will help to selectively enable/disable drm support in the kernel Signed-off-by: Vishal Bhoj --- drivers/gpu/mali/Kconfig | 7 +++++++ drivers/gpu/mali/Makefile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) 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 += ./ -- cgit v1.2.3 From ea32f2b6dd4d6d0a785e42a2133a661da3634498 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Tue, 31 Jan 2012 11:18:23 +0100 Subject: mali: Add include Signed-off-by: Philippe Langlais --- .../mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c | 1 + 1 file changed, 1 insertion(+) 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 index 60c77a7a359..866598ca1c7 100644 --- 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 @@ -16,6 +16,7 @@ #include #include +#include #include "mali_kernel_license.h" #include "mali_kernel_linux.h" #include "mali_ukk.h" -- cgit v1.2.3 From 5f3c36076053d6b0d2bb45f80f3dd6747e419905 Mon Sep 17 00:00:00 2001 From: "Jon Medhurst (Tixy)" Date: Tue, 13 Mar 2012 11:02:24 +0100 Subject: snowball: android: mali: Add Streamline Support for Mali DDK ARM's Streamline Performance Analyzer now supports Mali graphics. This requires support from the Mali kernel module which this patch adds. These changes were delivered by ARM Ltd in a patch file called: r2p3-01rel0_gpl_driver_streamline_support.patch that came with a README.txt which included the following... BUILDING THE DRIVER The driver can be built as normal. Profiling instrumentation is enabled by default by the patch. To disable it, use USING_PROFILING=0 in your build command. To revert to the old-style profiling code, use USING_INTERNAL_PROFILING=1 this option will disable the Streamline profiling support. KNOWN ISSUES * Attempting to read L2 cache counters when the hardware block is powered down could potentially lead to a hang due to a lack of locking. This will be addressed in a future driver update. Signed-off-by: Jon Medhurst --- .../mali400ko/driver/src/devicedrv/mali/Kbuild | 24 +- .../common/mali_cinstr_profiling_events_m200.h | 117 ++++++++ .../src/devicedrv/mali/common/mali_kernel_GP2.c | 82 ++++-- .../devicedrv/mali/common/mali_kernel_MALI200.c | 76 +++-- .../devicedrv/mali/common/mali_kernel_profiling.c | 305 -------------------- .../devicedrv/mali/common/mali_kernel_profiling.h | 121 -------- .../devicedrv/mali/common/mali_kernel_rendercore.c | 8 +- .../driver/src/devicedrv/mali/common/mali_osk.h | 9 +- .../src/devicedrv/mali/common/mali_osk_profiling.h | 183 ++++++++++++ .../src/devicedrv/mali/linux/mali_kernel_linux.c | 9 +- .../src/devicedrv/mali/linux/mali_kernel_sysfs.c | 32 +-- .../src/devicedrv/mali/linux/mali_linux_trace.h | 125 ++++++++ .../src/devicedrv/mali/linux/mali_osk_misc.c | 8 +- .../mali/linux/mali_osk_profiling_gator.c | 247 ++++++++++++++++ .../mali/linux/mali_osk_profiling_internal.c | 320 +++++++++++++++++++++ .../src/devicedrv/mali/linux/mali_osk_specific.h | 100 ++++++- 16 files changed, 1272 insertions(+), 494 deletions(-) create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h delete mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c delete mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c create mode 100644 drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_internal.c diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild index 09418ab3124..e90137714d2 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Kbuild @@ -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. @@ -28,7 +28,8 @@ 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 ?= 0 +USING_PROFILING ?= 1 +USING_INTERNAL_PROFILING ?= 0 DISABLE_PP0 ?= 0 DISABLE_PP1 ?= 0 DISABLE_PP2 ?= 0 @@ -60,6 +61,7 @@ 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) @@ -142,14 +144,25 @@ SRC = \ $(UKKFILES) \ __malidrv_build_info.c +# Selecting files to compile by parsing the config file + +# Use Gator profiling by default ifeq ($(USING_PROFILING),1) -SRC += \ - common/mali_kernel_profiling.c \ +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 -# Selecting files to compile by parsing the config file +# Add the profiling sources +SRC += $(PROFILING_BACKEND_SOURCES) ifeq ($(USING_PMM),1) ifeq ($(USING_MALI_PMU),1) @@ -250,6 +263,7 @@ 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) 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 70f07343e66..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 @@ -628,6 +628,32 @@ 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 ) { @@ -715,10 +741,10 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_ startcmd); _mali_osk_write_mem_barrier(); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, +#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_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 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; @@ -742,8 +768,8 @@ static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core) /* 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); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_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); +#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 */ @@ -808,6 +834,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) @@ -839,8 +871,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) } #endif -#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(2, ("Mali GP: Job aborted - userspace would not provide more heap memory.\n")); @@ -869,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) @@ -901,8 +939,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) #endif } -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), +#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) @@ -937,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")); @@ -964,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; @@ -1045,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 )); @@ -1106,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 @@ -1247,8 +1285,8 @@ static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_se 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")); 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 292c8f31f3d..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; @@ -572,6 +572,38 @@ 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 ) @@ -643,8 +675,8 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali _mali_osk_write_mem_barrier(); #if MALI_TIMELINE_PROFILING_ENABLED - _mali_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_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; @@ -665,8 +697,8 @@ static u32 subsystem_mali200_irq_handler_upper_half(mali_core_renderunit * core) /* 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_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); +#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; @@ -723,8 +755,20 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit { 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) @@ -762,8 +806,8 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit } -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), +#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) @@ -787,8 +831,8 @@ 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) ); @@ -823,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", @@ -902,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 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/common/mali_kernel_profiling.c deleted file mode 100644 index 1f3eb4aa778..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c +++ /dev/null @@ -1,305 +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. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_ukk.h" -#include "mali_timestamp.h" -#include "mali_kernel_profiling.h" - -typedef struct mali_profiling_entry -{ - u64 timestamp; - u32 event_id; - u32 data[5]; -} mali_profiling_entry; - - -typedef enum mali_profiling_state -{ - MALI_PROFILING_STATE_UNINITIALIZED, - MALI_PROFILING_STATE_IDLE, - MALI_PROFILING_STATE_RUNNING, - MALI_PROFILING_STATE_RETURN, -} mali_profiling_state; - - -static _mali_osk_lock_t *lock = NULL; -static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED; -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(mali_bool auto_start) -{ - profile_entries = NULL; - profile_entry_count = 0; - _mali_osk_atomic_init(&profile_insert_index, 0); - _mali_osk_atomic_init(&profile_entries_written, 0); - - lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 ); - if (NULL == lock) - { - return _MALI_OSK_ERR_FAULT; - } - - 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_profiling_start(&limit)) - { - return _MALI_OSK_ERR_FAULT; - } - } - - return _MALI_OSK_ERR_OK; -} - -void _mali_profiling_term(void) -{ - prof_state = MALI_PROFILING_STATE_UNINITIALIZED; - - /* wait for all elements to be completely inserted into array */ - while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) - { - /* do nothing */; - } - - if (NULL != profile_entries) - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - if (NULL != lock) - { - _mali_osk_lock_term(lock); - lock = NULL; - } -} - -inline _mali_osk_errcode_t _mali_profiling_start(u32 * limit) -{ - _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); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - if (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES) - { - *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; - } - - profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry)); - profile_entry_count = *limit; - if (NULL == profile_entries) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_NOMEM; - } - - ret = _mali_timestamp_reset(); - - if (ret == _MALI_OSK_ERR_OK) - { - prof_state = MALI_PROFILING_STATE_RUNNING; - } - else - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return ret; -} - -inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) -{ - 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 _MALI_OSK_ERR_FAULT; - } - - 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; -} - -inline _mali_osk_errcode_t _mali_profiling_stop(u32 * count) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (prof_state != MALI_PROFILING_STATE_RUNNING) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - /* go into return state (user to retreive events), no more events will be added after this */ - prof_state = MALI_PROFILING_STATE_RETURN; - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - - /* wait for all elements to be completely inserted into array */ - while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) - { - /* do nothing */; - } - - *count = _mali_osk_atomic_read(&profile_insert_index); - - return _MALI_OSK_ERR_OK; -} - -inline u32 _mali_profiling_get_count(void) -{ - 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_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) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - if (index >= _mali_osk_atomic_read(&profile_entries_written)) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_FAULT; - } - - *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; -} - -inline _mali_osk_errcode_t _mali_profiling_clear(void) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (prof_state != MALI_PROFILING_STATE_RETURN) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - prof_state = MALI_PROFILING_STATE_IDLE; - profile_entry_count = 0; - _mali_osk_atomic_init(&profile_insert_index, 0); - _mali_osk_atomic_init(&profile_entries_written, 0); - if (NULL != profile_entries) - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_OK; -} - -mali_bool _mali_profiling_is_recording(void) -{ - return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; -} - -mali_bool _mali_profiling_have_recording(void) -{ - return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; -} - -void _mali_profiling_set_default_enable_state(mali_bool enable) -{ - mali_profiling_default_enable = enable; -} - -mali_bool _mali_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_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 */ - 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]); -} - -_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) -{ - return _mali_profiling_stop(&args->count); -} - -_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) -{ - return _mali_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_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/common/mali_kernel_profiling.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h deleted file mode 100644 index fe650e81e41..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h +++ /dev/null @@ -1,121 +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> - -#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 - -/** - * Initialize the profiling module. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start); - -/* - * Terminate the profiling module. - */ -void _mali_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_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. - */ -_mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4); - -/** - * 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_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_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_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_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_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_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_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_profiling_get_default_enable_state(void); - -#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 b123b4bc61b..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. @@ -18,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" @@ -160,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_boot_profiling ? MALI_TRUE : MALI_FALSE) != _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")) ; @@ -190,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 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 d1fb0a9a168..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. @@ -1684,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_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/linux/mali_kernel_linux.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c index 25b08b5f661..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. @@ -38,6 +38,13 @@ /* */ #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); 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 index 866598ca1c7..b1dca5f7ba5 100644 --- 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 @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 ARM Limited. All rights reserved. + * 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. @@ -29,7 +29,7 @@ #include #include "mali_kernel_subsystem.h" #include "mali_kernel_sysfs.h" -#include "mali_kernel_profiling.h" +#include "mali_osk_profiling.h" static struct dentry *mali_debugfs_dir = NULL; @@ -73,13 +73,13 @@ static const struct file_operations mali_seq_internal_state_fops = { #endif /* MALI_STATE_TRACKING */ -#if MALI_TIMELINE_PROFILING_ENABLED +#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_profiling_is_recording() ? 1 : 0); + r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -112,16 +112,16 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf 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_profiling_is_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_profiling_have_recording()) + if (MALI_TRUE == _mali_osk_profiling_have_recording()) { - if (_MALI_OSK_ERR_OK != _mali_profiling_clear()) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) { MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); return -EFAULT; @@ -129,7 +129,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf } /* start recording profiling data */ - if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) { MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); return -EFAULT; @@ -141,7 +141,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf { /* stop recording profiling data */ u32 count = 0; - if (_MALI_OSK_ERR_OK != _mali_profiling_stop(&count)) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) { MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); return -EFAULT; @@ -165,7 +165,7 @@ 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_profiling_have_recording()) + if (MALI_TRUE != _mali_osk_profiling_have_recording()) { return NULL; } @@ -185,13 +185,13 @@ 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_profiling_have_recording()) + if (MALI_TRUE != _mali_osk_profiling_have_recording()) { return NULL; } /* check if the next entry actually is avaiable */ - if (_mali_profiling_get_count() <= (u32)(*spos + 1)) + if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) { return NULL; } @@ -216,7 +216,7 @@ static int profiling_events_show(struct seq_file *seq_file, void *v) index = (u32)*spos; /* Retrieve all events */ - if (_MALI_OSK_ERR_OK == _mali_profiling_get_event(index, ×tamp, &event_id, data)) + 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; @@ -250,7 +250,7 @@ static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user char buf[64]; int r; - r = sprintf(buf, "%u\n", _mali_profiling_get_default_enable_state() ? 1 : 0); + r = sprintf(buf, "%u\n", _mali_osk_profiling_get_default_enable_state() ? 1 : 0); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -278,7 +278,7 @@ static ssize_t profiling_proc_default_enable_write(struct file *filp, const char return ret; } - _mali_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); + _mali_osk_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); *ppos += cnt; return cnt; @@ -335,7 +335,7 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev if(NULL != mali_debugfs_dir) { /* Debugfs directory created successfully; create files now */ -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); if (mali_profiling_dir != NULL) { 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 +#include + +#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 + 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 12f4299ee9b..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. @@ -61,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_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 + +#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/linux/mali_osk_profiling_internal.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_internal.c new file mode 100644 index 00000000000..589e2ace6d8 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_internal.c @@ -0,0 +1,320 @@ +/** + * 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. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_mali.h" +#include "mali_ukk.h" +#include "mali_timestamp.h" +#include "mali_osk_profiling.h" + +typedef struct mali_profiling_entry +{ + u64 timestamp; + u32 event_id; + u32 data[5]; +} mali_profiling_entry; + + +typedef enum mali_profiling_state +{ + MALI_PROFILING_STATE_UNINITIALIZED, + MALI_PROFILING_STATE_IDLE, + MALI_PROFILING_STATE_RUNNING, + MALI_PROFILING_STATE_RETURN, +} mali_profiling_state; + + +static _mali_osk_lock_t *lock = NULL; +static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED; +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_osk_profiling_init(mali_bool auto_start) +{ + profile_entries = NULL; + profile_entry_count = 0; + _mali_osk_atomic_init(&profile_insert_index, 0); + _mali_osk_atomic_init(&profile_entries_written, 0); + + lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 ); + if (NULL == lock) + { + return _MALI_OSK_ERR_FAULT; + } + + 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_osk_profiling_term(void) +{ + prof_state = MALI_PROFILING_STATE_UNINITIALIZED; + + /* wait for all elements to be completely inserted into array */ + while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) + { + /* do nothing */; + } + + if (NULL != profile_entries) + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + if (NULL != lock) + { + _mali_osk_lock_term(lock); + lock = NULL; + } +} + +inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) +{ + _mali_osk_errcode_t ret; + + mali_profiling_entry *new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry)); + + if(NULL == new_profile_entries) + { + return _MALI_OSK_ERR_NOMEM; + } + + _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 (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES) + { + *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; + } + + profile_entries = new_profile_entries; + profile_entry_count = *limit; + + ret = _mali_timestamp_reset(); + + if (ret == _MALI_OSK_ERR_OK) + { + prof_state = MALI_PROFILING_STATE_RUNNING; + } + else + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return ret; +} + +inline void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) +{ + 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); +} + +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); + + if (prof_state != MALI_PROFILING_STATE_RUNNING) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + /* go into return state (user to retreive events), no more events will be added after this */ + prof_state = MALI_PROFILING_STATE_RETURN; + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + + /* wait for all elements to be completely inserted into array */ + while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) + { + /* do nothing */; + } + + *count = _mali_osk_atomic_read(&profile_insert_index); + + return _MALI_OSK_ERR_OK; +} + +inline u32 _mali_osk_profiling_get_count(void) +{ + 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) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + if (index >= _mali_osk_atomic_read(&profile_entries_written)) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_FAULT; + } + + *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; +} + +inline _mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + + if (prof_state != MALI_PROFILING_STATE_RETURN) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + prof_state = MALI_PROFILING_STATE_IDLE; + profile_entry_count = 0; + _mali_osk_atomic_init(&profile_insert_index, 0); + _mali_osk_atomic_init(&profile_entries_written, 0); + if (NULL != profile_entries) + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + 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 6aacf17d387..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 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__ */ -- cgit v1.2.3 From fa6ae428813e50a80b8f4ed452566d964967c315 Mon Sep 17 00:00:00 2001 From: "Jon Medhurst (Tixy)" Date: Sat, 24 Mar 2012 12:47:01 +0000 Subject: snowball: android: mali: Disable profiling of Mali L2 cache When connecting the ARM Streamline Performance Analyzer to Snowball Android this will cause a board lock-up if the screen is static (Bug #961962). The cause of this appears to be a know issue with reading the L2 cache performance counters whilst the hardware block is powered down. As the current code is written to access these counters even when they have not been explicitly selected then this issue prevents Streamline being used reliably for any purpose. To workaround this bug, this patch disables support for the L2 cache counters in Mali. This has no effect on the operation of the cache. Signed-off-by: Jon Medhurst --- .../driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 index c4cd5826363..7ebc67346b4 100644 --- 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 @@ -11,6 +11,8 @@ * Boston, MA 02110-1301, USA. */ +#define DONT_USE_L2_CACHE_COUNTERS /* These traces can cause lock-ups so disable them. */ + #include #include "mali_kernel_common.h" @@ -19,7 +21,7 @@ #include "mali_osk_profiling.h" #include "mali_linux_trace.h" -#if defined(USING_MALI400_L2_CACHE) +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) #include "mali_kernel_l2_cache.h" #endif /* USING_MALI400_L2_CACHE */ @@ -180,7 +182,7 @@ _mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config */ int _mali_profiling_set_event(u32 counter_id, s32 event_id) { -#if defined(USING_MALI400_L2_CACHE) +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) /* * 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 @@ -224,7 +226,7 @@ int _mali_profiling_set_event(u32 counter_id, s32 event_id) return 0; } -#if defined(USING_MALI400_L2_CACHE) +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) /** * 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 -- cgit v1.2.3 From fcddfa7f1d6cbdd5b841665b2337422627394cff Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkranzer Date: Wed, 23 May 2012 15:50:02 +0200 Subject: android: compilation failure with new version of svn The line setting SVN_REV assumes "svnversion" will report either the svn revision of the directory or "exported". This assumption is no longer true for subversion 1.7.4, which reports "Unversioned directory" instead of "exported", causing the build to fail (gcc -DSVN_REV=Unversioned directory) Signed-off-by: Bernhard Rosenkranzer Submitted-by: Mathieu Poirier --- drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common | 2 +- drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile.common | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) 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 116afb6c75a..066daca61ed 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/Makefile.common @@ -40,7 +40,7 @@ MALI_PLATFORM_FILE=platform/default/mali_platform.c endif # Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available -SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -qv exported && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null ) +SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -qvE '(exported|Unversioned)' && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null ) ifeq ($(SVN_REV),) SVN_REV := $(MALI_RELEASE_NAME) else diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile.common b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile.common index c6aa6337f80..f797c85a6f2 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile.common +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/ump/Makefile.common @@ -14,7 +14,6 @@ SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \ $(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c # Get subversion revision number, fall back to 0000 if no svn info is available -SVN_REV:=$(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') - +SVN_REV:=$(shell ((svnversion | grep -qvE '(exported|Unversioned)' && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //') EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV) EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\" -- cgit v1.2.3