diff options
Diffstat (limited to 'drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux')
32 files changed, 1519 insertions, 510 deletions
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c index 1c1bf306688..7a69ae95011 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.c @@ -31,13 +31,8 @@ int mali_dev_pause() { int err = 0; _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND) -#ifdef CONFIG_HAS_EARLYSUSPEND - || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) -#else - ) -#endif + if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) + || (mali_device_state == _MALI_DEVICE_SUSPEND) ) { err = -EPERM; } @@ -56,13 +51,8 @@ int mali_dev_resume() { int err = 0; _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND) -#ifdef CONFIG_HAS_EARLYSUSPEND - || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) -#else - ) -#endif + if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) + || (mali_device_state == _MALI_DEVICE_SUSPEND) ) { err = -EPERM; } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h index 5362f88cdbd..155a3e69d48 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_device_pause_resume.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h index 30a6fa041db..47b67cccb82 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h @@ -68,6 +68,7 @@ extern "C" #define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *) #define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *) #define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *) +#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_profiling_get_config_s *) #define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *) #ifdef __cplusplus diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c index a5144faae2b..96ebacced0f 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -16,16 +16,13 @@ #include <linux/fs.h> /* file system operations */ #include <linux/cdev.h> /* character device definitions */ #include <linux/mm.h> /* memory mananger definitions */ -#include <asm/uaccess.h> /* user space access */ #include <linux/device.h> -#include <linux/proc_fs.h> /* the mali kernel subsystem types */ #include "mali_kernel_subsystem.h" /* A memory subsystem always exists, so no need to conditionally include it */ #include "mali_kernel_common.h" -#include "mali_kernel_mem.h" #include "mali_kernel_session_manager.h" #include "mali_kernel_core.h" @@ -36,9 +33,21 @@ #include "mali_ukk_wrappers.h" #include "mali_kernel_pm.h" +#include "mali_kernel_sysfs.h" + /* */ #include "mali_kernel_license.h" +/* Streamline support for the Mali driver */ +#if defined(CONFIG_TRACEPOINTS) +/* Ask Linux to create the tracepoints */ +#define CREATE_TRACE_POINTS +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS */ + +/* from the __malidrv_build_info.c file that is generated during build */ +extern const char *__malidrv_build_info(void); + /* Setting this parameter will override memory settings in arch/config.h */ char *mali_mem = ""; module_param(mali_mem, charp, S_IRUSR | S_IWUSR | S_IWGRP | S_IROTH); /* rw-r--r-- */ @@ -72,24 +81,17 @@ module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache"); #endif -struct mali_dev -{ - struct cdev cdev; -#if MALI_LICENSE_IS_GPL - struct class * mali_class; +#if MALI_TIMELINE_PROFILING_ENABLED +extern int mali_boot_profiling; +module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization"); #endif -}; static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */ /* the mali device */ static struct mali_dev device; -#if MALI_STATE_TRACKING -static struct proc_dir_entry *proc_entry; -static int mali_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data); -#endif - static int mali_open(struct inode *inode, struct file *filp); static int mali_release(struct inode *inode, struct file *filp); @@ -144,33 +146,15 @@ int mali_driver_init(void) return -EFAULT; } + /* print build options */ + MALI_DEBUG_PRINT(2, ("%s\n", __malidrv_build_info())); + return 0; } void mali_driver_exit(void) { - -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - - _mali_osk_pmm_dev_activate(); -#endif -#endif -#endif -#endif - mali_kernel_destructor(); - -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - _mali_osk_pmm_dev_idle(); -#endif -#endif -#endif -#endif + mali_kernel_destructor(); #if USING_MALI_PMM #if MALI_LICENSE_IS_GPL @@ -199,60 +183,39 @@ int initialize_kernel_device(void) err = register_chrdev_region(dev, 1/*count*/, mali_dev_name); } - if (0 == err) + if (err) { - memset(&device, 0, sizeof(device)); - - /* initialize our char dev data */ - cdev_init(&device.cdev, &mali_fops); - device.cdev.owner = THIS_MODULE; - device.cdev.ops = &mali_fops; - - /* register char dev with the kernel */ - err = cdev_add(&device.cdev, dev, 1/*count*/); - - if (0 == err) - { -#if MALI_STATE_TRACKING - proc_entry = create_proc_entry(mali_dev_name, 0444, NULL); - if (proc_entry != NULL) - { - proc_entry->read_proc = mali_proc_read; -#endif -#if MALI_LICENSE_IS_GPL - device.mali_class = class_create(THIS_MODULE, mali_dev_name); - if (IS_ERR(device.mali_class)) - { - err = PTR_ERR(device.mali_class); - } - else - { - struct device * mdev; - mdev = device_create(device.mali_class, NULL, dev, NULL, mali_dev_name); - if (!IS_ERR(mdev)) - { - return 0; - } - - err = PTR_ERR(mdev); - } - cdev_del(&device.cdev); -#else - return 0; -#endif -#if MALI_STATE_TRACKING - remove_proc_entry(mali_dev_name, NULL); - } - else - { - err = EFAULT; - } -#endif - } - unregister_chrdev_region(dev, 1/*count*/); + goto init_chrdev_err; } + memset(&device, 0, sizeof(device)); + + /* initialize our char dev data */ + cdev_init(&device.cdev, &mali_fops); + device.cdev.owner = THIS_MODULE; + device.cdev.ops = &mali_fops; + /* register char dev with the kernel */ + err = cdev_add(&device.cdev, dev, 1/*count*/); + if (err) + { + goto init_cdev_err; + } + + err = mali_sysfs_register(&device, dev, mali_dev_name); + if (err) + { + goto init_sysfs_err; + } + + /* Success! */ + return 0; + +init_sysfs_err: + cdev_del(&device.cdev); +init_cdev_err: + unregister_chrdev_region(dev, 1/*count*/); +init_chrdev_err: return err; } @@ -261,14 +224,7 @@ void terminate_kernel_device(void) { dev_t dev = MKDEV(mali_major, 0); -#if MALI_LICENSE_IS_GPL - device_destroy(device.mali_class, dev); - class_destroy(device.mali_class); -#endif - -#if MALI_STATE_TRACKING - remove_proc_entry(mali_dev_name, NULL); -#endif + mali_sysfs_unregister(&device, dev, mali_dev_name); /* unregister char device */ cdev_del(&device.cdev); @@ -360,8 +316,8 @@ static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) #endif { - int err; - struct mali_session_data *session_data; + int err; + struct mali_session_data *session_data; #ifndef HAVE_UNLOCKED_IOCTL /* inode not used */ @@ -370,93 +326,98 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg)); - session_data = (struct mali_session_data *)filp->private_data; - if (NULL == session_data) + session_data = (struct mali_session_data *)filp->private_data; + if (NULL == session_data) { MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n")); return -ENOTTY; } - if (NULL == (void *)arg) + + if (NULL == (void *)arg) { MALI_DEBUG_PRINT(7, ("arg was NULL\n")); return -ENOTTY; } - switch(cmd) - { - case MALI_IOC_GET_SYSTEM_INFO_SIZE: - err = get_system_info_size_wrapper(session_data, (_mali_uk_get_system_info_size_s __user *)arg); - break; + switch(cmd) + { + case MALI_IOC_GET_SYSTEM_INFO_SIZE: + err = get_system_info_size_wrapper(session_data, (_mali_uk_get_system_info_size_s __user *)arg); + break; - case MALI_IOC_GET_SYSTEM_INFO: - err = get_system_info_wrapper(session_data, (_mali_uk_get_system_info_s __user *)arg); - break; + case MALI_IOC_GET_SYSTEM_INFO: + err = get_system_info_wrapper(session_data, (_mali_uk_get_system_info_s __user *)arg); + break; - case MALI_IOC_WAIT_FOR_NOTIFICATION: - err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); - break; + case MALI_IOC_WAIT_FOR_NOTIFICATION: + err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); + break; - case MALI_IOC_GET_API_VERSION: - err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); - break; + case MALI_IOC_GET_API_VERSION: + err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); + break; - case MALI_IOC_POST_NOTIFICATION: - err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); - break; + case MALI_IOC_POST_NOTIFICATION: + err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); + break; #if MALI_TIMELINE_PROFILING_ENABLED - case MALI_IOC_PROFILING_START: - err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); - break; + case MALI_IOC_PROFILING_START: + err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); + break; case MALI_IOC_PROFILING_ADD_EVENT: - err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); - break; + err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); + break; case MALI_IOC_PROFILING_STOP: - err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); - break; + err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); + break; case MALI_IOC_PROFILING_GET_EVENT: - err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); - break; + err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); + break; case MALI_IOC_PROFILING_CLEAR: - err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); - break; + err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); + break; + + case MALI_IOC_PROFILING_GET_CONFIG: + err = profiling_get_config_wrapper(session_data, (_mali_uk_profiling_get_config_s __user *)arg); + break; #endif - case MALI_IOC_MEM_INIT: - err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); - break; + case MALI_IOC_MEM_INIT: + err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); + break; - case MALI_IOC_MEM_TERM: - err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); - break; + case MALI_IOC_MEM_TERM: + err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); + break; - case MALI_IOC_MEM_MAP_EXT: - err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); - break; + case MALI_IOC_MEM_MAP_EXT: + err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); + break; - case MALI_IOC_MEM_UNMAP_EXT: - err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); - break; + case MALI_IOC_MEM_UNMAP_EXT: + err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); + break; - case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: - err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); - break; + case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: + err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); + break; - case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: - err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); - break; + case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: + err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); + break; - case MALI_IOC_MEM_GET_BIG_BLOCK: - err = mem_get_big_block_wrapper(filp, (_mali_uk_get_big_block_s __user *)arg); - break; + case MALI_IOC_MEM_GET_BIG_BLOCK: + err = mem_get_big_block_wrapper(filp, (_mali_uk_get_big_block_s __user *)arg); + break; - case MALI_IOC_MEM_FREE_BIG_BLOCK: - err = mem_free_big_block_wrapper(session_data, (_mali_uk_free_big_block_s __user *)arg); - break; + case MALI_IOC_MEM_FREE_BIG_BLOCK: + err = mem_free_big_block_wrapper(session_data, (_mali_uk_free_big_block_s __user *)arg); + break; #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 @@ -472,89 +433,58 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case MALI_IOC_MEM_ATTACH_UMP: case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */ - MALI_DEBUG_PRINT(2, ("UMP not supported\n")); - err = -ENOTTY; + MALI_DEBUG_PRINT(2, ("UMP not supported\n")); + err = -ENOTTY; break; #endif - case MALI_IOC_PP_START_JOB: - err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); - break; + case MALI_IOC_PP_START_JOB: + err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); + break; - case MALI_IOC_PP_ABORT_JOB: - err = pp_abort_job_wrapper(session_data, (_mali_uk_pp_abort_job_s __user *)arg); - break; + case MALI_IOC_PP_ABORT_JOB: + err = pp_abort_job_wrapper(session_data, (_mali_uk_pp_abort_job_s __user *)arg); + break; - case MALI_IOC_PP_NUMBER_OF_CORES_GET: - err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); - break; + case MALI_IOC_PP_NUMBER_OF_CORES_GET: + err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); + break; - case MALI_IOC_PP_CORE_VERSION_GET: - err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); - break; + case MALI_IOC_PP_CORE_VERSION_GET: + err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); + break; - case MALI_IOC_GP2_START_JOB: - err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); - break; + case MALI_IOC_GP2_START_JOB: + err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); + break; - case MALI_IOC_GP2_ABORT_JOB: - err = gp_abort_job_wrapper(session_data, (_mali_uk_gp_abort_job_s __user *)arg); - break; + case MALI_IOC_GP2_ABORT_JOB: + err = gp_abort_job_wrapper(session_data, (_mali_uk_gp_abort_job_s __user *)arg); + break; - case MALI_IOC_GP2_NUMBER_OF_CORES_GET: - err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); - break; + case MALI_IOC_GP2_NUMBER_OF_CORES_GET: + err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); + break; - case MALI_IOC_GP2_CORE_VERSION_GET: - err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); - break; + case MALI_IOC_GP2_CORE_VERSION_GET: + err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); + break; - case MALI_IOC_GP2_SUSPEND_RESPONSE: - err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); - break; + case MALI_IOC_GP2_SUSPEND_RESPONSE: + err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); + break; case MALI_IOC_VSYNC_EVENT_REPORT: - err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); - break; - - default: - MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); - err = -ENOTTY; - }; - - return err; -} - -#if MALI_STATE_TRACKING -static int mali_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - int len = 0; - - MALI_DEBUG_PRINT(1, ("mali_proc_read(page=%p, start=%p, off=%u, count=%d, eof=%p, data=%p\n", page, start, off, count, eof, data)); - - if (off > 0) - { - return 0; - } - - if (count < 1024) - { - return 0; - } - - len = sprintf(page + len, "Mali device driver %s\n", SVN_REV_STRING); - len += sprintf(page + len, "License: %s\n", MALI_KERNEL_LINUX_LICENSE); + err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); + break; - /* - * A more elegant solution would be to gather information from all subsystems and - * then report it all in the /proc/mali file, but this would require a bit more work. - * Use MALI_PRINT for now so we get the information in the dmesg log at least. - */ - _mali_kernel_core_dump_state(); + default: + MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); + err = -ENOTTY; + }; - return len; + return err; } -#endif module_init(mali_driver_init); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h index 969449d8ef4..c362a7c77c5 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_linux.h @@ -16,6 +16,18 @@ extern "C" { #endif +#include <linux/cdev.h> /* character device definitions */ +#include "mali_kernel_license.h" +#include "mali_osk.h" + +struct mali_dev +{ + struct cdev cdev; +#if MALI_LICENSE_IS_GPL + struct class * mali_class; +#endif +}; + _mali_osk_errcode_t initialize_kernel_device(void); void terminate_kernel_device(void); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c index aaafc151077..ebc519a743b 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.c @@ -12,12 +12,9 @@ * @file mali_kernel_pm.c * Implementation of the Linux Power Management for Mali GPU kernel driver */ -#undef CONFIG_HAS_EARLYSUSPEND /*ARM will remove .early_suspend support for r2p2_rel*/ + #if USING_MALI_PMM #include <linux/sched.h> -#ifdef CONFIG_HAS_EARLYSUSPEND -#include <linux/earlysuspend.h> -#endif /* CONFIG_HAS_EARLYSUSPEND */ #ifdef CONFIG_PM_RUNTIME #include <linux/pm_runtime.h> @@ -27,7 +24,6 @@ #include <linux/platform_device.h> #include <linux/version.h> #include <asm/current.h> -#include <asm/delay.h> #include <linux/suspend.h> #include "mali_platform.h" @@ -48,13 +44,12 @@ #if MALI_POWER_MGMT_TEST_SUITE #ifdef CONFIG_PM #include "mali_linux_pm_testsuite.h" +#include "mali_platform_pmu_internal_testing.h" unsigned int pwr_mgmt_status_reg = 0; #endif /* CONFIG_PM */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ -#if MALI_STATE_TRACKING - int is_os_pmm_thread_waiting = -1; -#endif /* MALI_STATE_TRACKING */ +static int is_os_pmm_thread_waiting = 0; /* kernel should be configured with power management support */ #ifdef CONFIG_PM @@ -75,29 +70,19 @@ unsigned int pwr_mgmt_status_reg = 0; static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = { [_MALI_DEVICE_SUSPEND] = "suspend", [_MALI_DEVICE_RESUME] = "resume", -#ifdef CONFIG_HAS_EARLYSUSPEND - [_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB] = "early_suspend_level_disable_framebuffer", - [_MALI_DEVICE_LATERESUME] = "late_resume", -#endif /* CONFIG_HAS_EARLYSUSPEND */ [_MALI_DVFS_PAUSE_EVENT] = "dvfs_pause", [_MALI_DVFS_RESUME_EVENT] = "dvfs_resume", }; #endif /* CONFIG_PM_DEBUG */ -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -extern void set_mali_parent_power_domain(struct platform_device* dev); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ - #ifdef CONFIG_PM_RUNTIME #if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#ifndef CONFIG_HAS_EARLYSUSPEND static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); static struct notifier_block mali_pwr_notif_block = { .notifier_call = mali_pwr_suspend_notifier }; -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ @@ -148,12 +133,6 @@ static int mali_device_runtime_resume(struct device *dev); #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ -/* Early suspend functions */ -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mali_pm_early_suspend(struct early_suspend *mali_dev); -static void mali_pm_late_resume(struct early_suspend *mali_dev); -#endif /* CONFIG_HAS_EARLYSUSPEND */ - /* OS suspend and resume callbacks */ #if !MALI_PMM_RUNTIME_JOB_CONTROL_ON #ifndef CONFIG_PM_RUNTIME @@ -236,15 +215,6 @@ static struct platform_driver mali_plat_driver = { }, }; -#ifdef CONFIG_HAS_EARLYSUSPEND -/* Early suspend hooks */ -static struct early_suspend mali_dev_early_suspend = { - .suspend = mali_pm_early_suspend, - .resume = mali_pm_late_resume, - .level = EARLY_SUSPEND_LEVEL_DISABLE_FB, -}; -#endif /* CONFIG_HAS_EARLYSUSPEND */ - /* Mali GPU platform device */ struct platform_device mali_gpu_device = { .name = "mali_dev", @@ -313,13 +283,9 @@ int mali_device_suspend(unsigned int event_id, struct task_struct **pwr_mgmt_thr *pwr_mgmt_thread = current; MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being suspended\n" )); _mali_ukk_pmm_event_message(&event); -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 1; -#endif /* MALI_STATE_TRACKING */ err = mali_wait_for_power_management_policy_event(); -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 0; -#endif /* MALI_STATE_TRACKING */ return err; } @@ -333,17 +299,11 @@ static int mali_pm_suspend(struct device *dev) #if MALI_GPU_UTILIZATION mali_utilization_suspend(); #endif /* MALI_GPU_UTILIZATION */ - if ((mali_device_state == _MALI_DEVICE_SUSPEND) -#ifdef CONFIG_HAS_EARLYSUSPEND - || mali_device_state == (_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) -#else - ) -#endif /* CONFIG_HAS_EARLYSUSPEND */ + if ((mali_device_state == _MALI_DEVICE_SUSPEND)) { _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); return err; } - mali_device_state = _MALI_DEVICE_SUSPEND_IN_PROGRESS; err = mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread); mali_device_state = _MALI_DEVICE_SUSPEND; _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); @@ -367,7 +327,6 @@ static int mali_pm_os_suspend(struct device *dev) #ifdef CONFIG_PM_RUNTIME #if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#ifndef CONFIG_HAS_EARLYSUSPEND static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) { int err = 0; @@ -385,7 +344,6 @@ static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long eve } return 0; } -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ @@ -402,17 +360,9 @@ int mali_device_resume(unsigned int event_id, struct task_struct **pwr_mgmt_thre MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being resumed\n" )); _mali_ukk_pmm_event_message(&event); MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power up event is scheduled\n" )); - -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 1; -#endif /* MALI_STATE_TRACKING */ - err = mali_wait_for_power_management_policy_event(); - -#if MALI_STATE_TRACKING is_os_pmm_thread_waiting = 0; -#endif /* MALI_STATE_TRACKING */ - return err; } @@ -484,69 +434,6 @@ static int mali_device_runtime_resume(struct device *dev) #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ -#ifdef CONFIG_HAS_EARLYSUSPEND - -/* This function is called from android framework. - */ -static void mali_pm_early_suspend(struct early_suspend *mali_dev) -{ - switch(mali_dev->level) - { - /* Screen should be turned off but framebuffer will be accessible */ - case EARLY_SUSPEND_LEVEL_BLANK_SCREEN: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Screen is off\n" )); - break; - - case EARLY_SUSPEND_LEVEL_STOP_DRAWING: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Suspend level stop drawing\n" )); - break; - - /* Turn off the framebuffer. In our case No Mali GPU operation */ - case EARLY_SUSPEND_LEVEL_DISABLE_FB: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Suspend level Disable framebuffer\n" )); - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); -#if MALI_GPU_UTILIZATION - mali_utilization_suspend(); -#endif /* MALI_GPU_UTILIZATION */ - if ((mali_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return; - } - mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread); - mali_device_state = _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB; - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - break; - - default: - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Invalid Suspend Mode\n" )); - break; - } -} - -/* This function is invoked from android framework when mali device needs to be - * resumed. - */ -static void mali_pm_late_resume(struct early_suspend *mali_dev) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if (mali_device_state == _MALI_DEVICE_RESUME) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return; - } - if (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB) - { - mali_device_resume(MALI_PMM_EVENT_OS_POWER_UP, &pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - mali_device_state = _MALI_DEVICE_RESUME; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - -} - -#endif /* CONFIG_HAS_EARLYSUSPEND */ - #ifdef CONFIG_PM_DEBUG /** This function is used for debugging purposes when the user want to see @@ -578,9 +465,6 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int err = 0; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend mali_dev; -#endif /* CONFIG_HAS_EARLYSUSPEND */ #if MALI_POWER_MGMT_TEST_SUITE int test_flag_dvfs = 0; @@ -618,19 +502,6 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" )); err = mali_pm_resume(NULL); } -#ifdef CONFIG_HAS_EARLYSUSPEND - else if (!strncmp(buf,mali_states[_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB],strlen(mali_states[_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB]))) - { - mali_dev.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Android early suspend operation is scheduled\n" )); - mali_pm_early_suspend(&mali_dev); - } - else if (!strncmp(buf,mali_states[_MALI_DEVICE_LATERESUME],strlen(mali_states[_MALI_DEVICE_LATERESUME]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" )); - mali_pm_late_resume(NULL); - } -#endif /* CONFIG_HAS_EARLYSUSPEND */ else if (!strncmp(buf,mali_states[_MALI_DVFS_PAUSE_EVENT],strlen(mali_states[_MALI_DVFS_PAUSE_EVENT]))) { MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Pause Power operation is scheduled\n" )); @@ -711,11 +582,10 @@ int _mali_dev_platform_register(void) { int err; #if MALI_PMM_RUNTIME_JOB_CONTROL_ON - set_mali_parent_power_domain(&mali_gpu_device); + set_mali_parent_power_domain((void *)&mali_gpu_device); #endif #ifdef CONFIG_PM_RUNTIME -#ifndef CONFIG_HAS_EARLYSUSPEND #if MALI_PMM_RUNTIME_JOB_CONTROL_ON err = register_pm_notifier(&mali_pwr_notif_block); if (err) @@ -723,28 +593,19 @@ int _mali_dev_platform_register(void) return err; } #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* CONFIG_PM_RUNTIME */ err = platform_device_register(&mali_gpu_device); lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if (!err) { err = platform_driver_register(&mali_plat_driver); - if (!err) - { -#ifdef CONFIG_HAS_EARLYSUSPEND - register_early_suspend(&mali_dev_early_suspend); -#endif /* CONFIG_HAS_EARLYSUSPEND */ - } - else + if (err) { _mali_osk_lock_term(lock); #ifdef CONFIG_PM_RUNTIME -#ifndef CONFIG_HAS_EARLYSUSPEND #if MALI_PMM_RUNTIME_JOB_CONTROL_ON unregister_pm_notifier(&mali_pwr_notif_block); #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* CONFIG_PM_RUNTIME */ platform_device_unregister(&mali_gpu_device); } @@ -758,29 +619,28 @@ void _mali_dev_platform_unregister(void) { _mali_osk_lock_term(lock); -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&mali_dev_early_suspend); -#endif /* CONFIG_HAS_EARLYSUSPEND */ - #ifdef CONFIG_PM_RUNTIME -#ifndef CONFIG_HAS_EARLYSUSPEND #if MALI_PMM_RUNTIME_JOB_CONTROL_ON unregister_pm_notifier(&mali_pwr_notif_block); #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ #endif /* CONFIG_PM_RUNTIME */ platform_driver_unregister(&mali_plat_driver); platform_device_unregister(&mali_gpu_device); } +int mali_get_ospmm_thread_state(void) +{ + return is_os_pmm_thread_waiting; +} + #endif /* MALI_LICENSE_IS_GPL */ #endif /* CONFIG_PM */ #if MALI_STATE_TRACKING -void mali_pmm_dump_os_thread_state( void ) +u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ) { - MALI_PRINTF(("\nOSPMM::The OS PMM thread state is...%d",is_os_pmm_thread_waiting)); + return snprintf(buf, size, "OSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false"); } #endif /* MALI_STATE_TRACKING */ #endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h index 6e879fea447..db910102d76 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c new file mode 100644 index 00000000000..b1dca5f7ba5 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c @@ -0,0 +1,402 @@ +/** + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +/** + * @file mali_kernel_sysfs.c + * Implementation of some sysfs data exports + */ + +#include <linux/fs.h> +#include <linux/device.h> +#include <linux/module.h> +#include "mali_kernel_license.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" + +#if MALI_LICENSE_IS_GPL + +#include <linux/seq_file.h> +#include <linux/debugfs.h> +#include <asm/uaccess.h> +#include <linux/slab.h> +#include "mali_kernel_subsystem.h" +#include "mali_kernel_sysfs.h" +#include "mali_osk_profiling.h" + +static struct dentry *mali_debugfs_dir = NULL; + +#if MALI_STATE_TRACKING +static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) +{ + u32 len = 0; + u32 size; + char *buf; + + size = seq_get_buf(seq_file, &buf); + + if(!size) + { + return -ENOMEM; + } + + /* Create the internal state dump. */ + len = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING); + len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE); + + len += _mali_kernel_core_dump_state(buf + len, size - len); + + seq_commit(seq_file, len); + + return 0; +} + +static int mali_seq_internal_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, mali_seq_internal_state_show, NULL); +} + +static const struct file_operations mali_seq_internal_state_fops = { + .owner = THIS_MODULE, + .open = mali_seq_internal_state_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* MALI_STATE_TRACKING */ + + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val != 0) + { + u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ + + /* check if we are already recording */ + if (MALI_TRUE == _mali_osk_profiling_is_recording()) + { + MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); + return -EFAULT; + } + + /* check if we need to clear out an old recording first */ + if (MALI_TRUE == _mali_osk_profiling_have_recording()) + { + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) + { + MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); + return -EFAULT; + } + } + + /* start recording profiling data */ + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) + { + MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit)); + } + else + { + /* stop recording profiling data */ + u32 count = 0; + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) + { + MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count)); + } + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_record_fops = { + .owner = THIS_MODULE, + .read = profiling_record_read, + .write = profiling_record_write, +}; + +static void *profiling_events_start(struct seq_file *s, loff_t *pos) +{ + loff_t *spos; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_osk_profiling_have_recording()) + { + return NULL; + } + + spos = kmalloc(sizeof(loff_t), GFP_KERNEL); + if (NULL == spos) + { + return NULL; + } + + *spos = *pos; + return spos; +} + +static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos) +{ + loff_t *spos = v; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_osk_profiling_have_recording()) + { + return NULL; + } + + /* check if the next entry actually is avaiable */ + if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) + { + return NULL; + } + + *pos = ++*spos; + return spos; +} + +static void profiling_events_stop(struct seq_file *s, void *v) +{ + kfree(v); +} + +static int profiling_events_show(struct seq_file *seq_file, void *v) +{ + loff_t *spos = v; + u32 index; + u64 timestamp; + u32 event_id; + u32 data[5]; + + index = (u32)*spos; + + /* Retrieve all events */ + if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, ×tamp, &event_id, data)) + { + seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]); + return 0; + } + + return 0; +} + +static const struct seq_operations profiling_events_seq_ops = { + .start = profiling_events_start, + .next = profiling_events_next, + .stop = profiling_events_stop, + .show = profiling_events_show +}; + +static int profiling_events_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &profiling_events_seq_ops); +} + +static const struct file_operations profiling_events_fops = { + .owner = THIS_MODULE, + .open = profiling_events_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_osk_profiling_get_default_enable_state() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_proc_default_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + _mali_osk_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_proc_default_enable_fops = { + .owner = THIS_MODULE, + .read = profiling_proc_default_enable_read, + .write = profiling_proc_default_enable_write, +}; +#endif + +static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 mem = _mali_ukk_report_memory_usage(); + + r = snprintf(buf, 64, "%u\n", mem); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations memory_usage_fops = { + .owner = THIS_MODULE, + .read = memory_used_read, +}; + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + int err = 0; + struct device * mdev; + + device->mali_class = class_create(THIS_MODULE, mali_dev_name); + if (IS_ERR(device->mali_class)) + { + err = PTR_ERR(device->mali_class); + goto init_class_err; + } + mdev = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name); + if (IS_ERR(mdev)) + { + err = PTR_ERR(mdev); + goto init_mdev_err; + } + + mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL); + if(ERR_PTR(-ENODEV) == mali_debugfs_dir) + { + /* Debugfs not supported. */ + mali_debugfs_dir = NULL; + } + else + { + if(NULL != mali_debugfs_dir) + { + /* Debugfs directory created successfully; create files now */ +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); + if (mali_profiling_dir != NULL) + { + struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); + if (mali_profiling_proc_dir != NULL) + { + struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); + if (mali_profiling_proc_default_dir != NULL) + { + debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, NULL, &profiling_proc_default_enable_fops); + } + } + debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); + debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops); + } +#endif + +#if MALI_STATE_TRACKING + debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); +#endif + + debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); + } + } + + /* Success! */ + return 0; + + /* Error handling */ +init_mdev_err: + class_destroy(device->mali_class); +init_class_err: + + return err; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + if(NULL != mali_debugfs_dir) + { + debugfs_remove_recursive(mali_debugfs_dir); + } + device_destroy(device->mali_class, dev); + class_destroy(device->mali_class); + + return 0; +} + +#else + +/* Dummy implementations for non-GPL */ + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + return 0; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + return 0; +} + + +#endif diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h new file mode 100644 index 00000000000..d79a8862269 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_SYSFS_H__ +#define __MALI_KERNEL_SYSFS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MALI_PROC_DIR "driver/mali" + +int mali_sysfs_register(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); + +int mali_sysfs_unregister(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c deleted file mode 100644 index 3d60d18e005..00000000000 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_dvfs_pause_resume.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_linux_dvfs_pause_resume.c - * Implementation of the Mali pause/resume functionality - */ -#if USING_MALI_PMM -#include <linux/version.h> -#include <linux/sched.h> -#include <linux/module.h> -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_platform.h" -#include "mali_linux_pm.h" -#include "mali_linux_dvfs_pause_resume.h" -#include "mali_pmm.h" -#include "mali_kernel_license.h" -#ifdef CONFIG_PM -#if MALI_LICENSE_IS_GPL - -/* Mali Pause Resume APIs */ -int mali_dev_dvfs_pause() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND)) - { - err = -EPERM; - } - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err)) - { - mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_SUSPEND; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_dvfs_pause); - -int mali_dev_dvfs_resume() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND)) - { - err = -EPERM; - } - if (!err) - { - mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_dvfs_resume); - -#endif /* MALI_LICENSE_IS_GPL */ -#endif /* CONFIG_PM */ -#endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h index 614d5e1deee..d401697f2f4 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_pm.h @@ -20,18 +20,13 @@ typedef enum { _MALI_DEVICE_SUSPEND, /* Suspend */ _MALI_DEVICE_RESUME, /* Resume */ -#ifdef CONFIG_HAS_EARLYSUSPEND - _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB, /* Early suspend */ - _MALI_DEVICE_LATERESUME, /* Late resume */ -#endif /* CONFIG_HAS_EARLYSUSPEND */ - _MALI_DEVICE_SUSPEND_IN_PROGRESS, /* Suspend in progress */ _MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */ } _mali_device_power_states; /* Number of DVFS events */ typedef enum { - _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES-1, /* DVFS Pause event */ + _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES, /* DVFS Pause event */ _MALI_DVFS_RESUME_EVENT, /* DVFS Resume event */ _MALI_MAX_DEBUG_OPERATIONS, } _mali_device_dvfs_events; @@ -51,6 +46,7 @@ extern struct task_struct *pm_thread; int mali_device_suspend(u32 event_id, struct task_struct **pwr_mgmt_thread); int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread); +int mali_get_ospmm_thread_state(void); #endif /* CONFIG_PM */ #endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h new file mode 100644 index 00000000000..64c2fd5269c --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_linux_trace.h @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ) +#define MALI_LINUX_TRACE_H + +#include <linux/stringify.h> +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mali +#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM) + +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE mali_linux_trace + +/** + * Define the tracepoint used to communicate the status of a GPU. Called + * when a GPU turns on or turns off. + * + * @param event_id The type of the event. This parameter is a bitfield + * encoding the type of the event. + * + * @param d0 First data parameter. + * @param d1 Second data parameter. + * @param d2 Third data parameter. + * @param d3 Fourth data parameter. + * @param d4 Fifth data parameter. + */ +TRACE_EVENT(mali_timeline_event, + + TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, + unsigned int d2, unsigned int d3, unsigned int d4), + + TP_ARGS(event_id, d0, d1, d2, d3, d4), + + TP_STRUCT__entry( + __field(unsigned int, event_id) + __field(unsigned int, d0) + __field(unsigned int, d1) + __field(unsigned int, d2) + __field(unsigned int, d3) + __field(unsigned int, d4) + ), + + TP_fast_assign( + __entry->event_id = event_id; + __entry->d0 = d0; + __entry->d1 = d1; + __entry->d2 = d2; + __entry->d3 = d3; + __entry->d4 = d4; + ), + + TP_printk("event=%d", __entry->event_id) +); + +/** + * Define a tracepoint used to regsiter the value of a hardware counter. + * Hardware counters belonging to the vertex or fragment processor are + * reported via this tracepoint each frame, whilst L2 cache hardware + * counters are reported continuously. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_hw_counter, + + TP_PROTO(unsigned int counter_id, unsigned int value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(unsigned int, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + __entry->value = value; + ), + + TP_printk("event %d = %d", __entry->counter_id, __entry->value) +); + +/** + * Define a tracepoint used to register the value of a software counter. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_sw_counter, + + TP_PROTO(unsigned int counter_id, signed long long value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(signed long long, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + __entry->value = value; + ), + + TP_printk("event %d = %lld", __entry->counter_id, __entry->value) +); + +#endif /* MALI_LINUX_TRACE_H */ + +/* This part must exist outside the header guard. */ +#include <trace/define_trace.h> + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c index cc029c4a8f8..05831c54272 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_atomics.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c index b60bf825897..7297218b9b6 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c index 1a4bbcecdce..b667961a0ac 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_irq.c @@ -149,7 +149,7 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) #if MALI_LICENSE_IS_GPL if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) { - queue_work(pmm_wq,&irq_object->work_queue_irq_handle); + queue_work( pmm_wq,&irq_object->work_queue_irq_handle ); } else { @@ -160,6 +160,17 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) #endif } +void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ) +{ +#if MALI_LICENSE_IS_GPL + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + flush_workqueue(pmm_wq); + } +#endif +} + void _mali_osk_irq_term( _mali_osk_irq_t *irq ) { mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c index 11285efc682..139dc5e3de3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_locks.c @@ -61,7 +61,6 @@ struct _mali_osk_lock_t_struct MALI_DEBUG_CODE( /** original flags for debug checking */ _mali_osk_lock_flags_t orig_flags; - _mali_osk_lock_mode_t locked_as; ); /* MALI_DEBUG_CODE */ }; @@ -130,7 +129,6 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial MALI_DEBUG_CODE( /* Debug tracking of flags */ lock->orig_flags = flags; - lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF; ); /* MALI_DEBUG_CODE */ return lock; @@ -190,17 +188,6 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_ break; } - /* DEBUG tracking of previously locked state - occurs after lock obtained */ - MALI_DEBUG_CODE( - if ( _MALI_OSK_ERR_OK == err ) - { - /* Assert that this is not currently locked */ - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_UNDEF == lock->locked_as ); - - lock->locked_as = mode; - } - ); /* MALI_DEBUG_CODE */ - return err; } @@ -218,12 +205,6 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); - /* For DEBUG only, assert that we previously locked this, and in the same way (RW/RO) */ - MALI_DEBUG_ASSERT( mode == lock->locked_as ); - - /* DEBUG tracking of previously locked state - occurs before lock released */ - MALI_DEBUG_CODE( lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF ); - switch ( lock->type ) { case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: @@ -263,9 +244,6 @@ void _mali_osk_lock_term( _mali_osk_lock_t *lock ) /* Parameter validation */ MALI_DEBUG_ASSERT_POINTER( lock ); - /* For DEBUG only, assert that this is not currently locked */ - MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_UNDEF == lock->locked_as ); - /* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */ kfree(lock); } diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c index 6454709caaf..c2475f24d7f 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c @@ -21,7 +21,6 @@ #include <linux/slab.h> #include <linux/mm.h> #include <linux/dma-mapping.h> -#include <asm/cacheflush.h> #include "mali_osk.h" #include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */ @@ -77,7 +76,11 @@ static void _allocation_list_item_release(AllocationList * item); /* Variable declarations */ -spinlock_t allocation_list_spinlock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +static DEFINE_SPINLOCK(allocation_list_spinlock); +#else +spinlock_t allocation_list_spinlock = SPIN_LOCK_UNLOCKED; +#endif static AllocationList * pre_allocated_memory = (AllocationList*) NULL ; static int pre_allocated_memory_size_current = 0; #ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB @@ -100,7 +103,6 @@ static struct vm_operations_struct mali_kernel_vm_ops = void mali_osk_low_level_mem_init(void) { - spin_lock_init( &allocation_list_spinlock ); pre_allocated_memory = (AllocationList*) NULL ; } @@ -277,6 +279,11 @@ void _mali_osk_mem_barrier( void ) mb(); } +void _mali_osk_write_mem_barrier( void ) +{ + wmb(); +} + mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ) { return (mali_io_address)ioremap_nocache(phys, size); @@ -303,8 +310,7 @@ mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) if ( NULL == virt ) { - MALI_DEBUG_PRINT(1, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size )); - MALI_DEBUG_PRINT(1, ("Solution: When configuring and building linux kernel, set CONSISTENT_DMA_SIZE to be 14 MB.\n")); + MALI_DEBUG_PRINT(5, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size )); return 0; } @@ -332,6 +338,11 @@ void inline _mali_osk_mem_unreqregion( u32 phys, u32 size ) release_mem_region(phys, size); } +void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val ) +{ + __raw_writel(cpu_to_le32(val),((u8*)addr) + offset); +} + u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset ) { return ioread32(((u8*)addr) + offset); @@ -349,7 +360,7 @@ void _mali_osk_cache_flushall( void ) void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ) { - wmb(); + _mali_osk_write_mem_barrier(); } _mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ) @@ -481,6 +492,11 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri u32 linux_phys_frame_num; alloc_item = _allocation_list_item_get(); + if (NULL == alloc_item) + { + MALI_DEBUG_PRINT(1, ("Failed to allocate list item\n")); + return _MALI_OSK_ERR_NOMEM; + } linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT; diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c index 694d8eeaabc..015f5a28749 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_mali.c @@ -75,8 +75,7 @@ _mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config if (0 < mem_size) { int i; for (i = 0; i < *num_resources; ++i) { - if ((MEMORY == arch_configuration[i].type) || - (OS_MEMORY == arch_configuration[i].type)) { + if (MEMORY == arch_configuration[i].type) { MALI_DEBUG_PRINT( 1, ("Overriding arch resource[%d] :\n",i)); MALI_DEBUG_PRINT( 1, ("Type: %s, base: %x, size %x\n", (OS_MEMORY==mem_type?"OS_MEMORY":"MEMORY"),mem_base,mem_size)); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c index 2f7fc15847b..3e62e519cba 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_math.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c index bf6679f7bac..7bb470f8828 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_memory.c @@ -15,6 +15,7 @@ #include "mali_osk.h" #include <linux/slab.h> +#include <linux/vmalloc.h> void inline *_mali_osk_calloc( u32 n, u32 size ) { @@ -31,6 +32,16 @@ void inline _mali_osk_free( void *ptr ) kfree(ptr); } +void inline *_mali_osk_valloc( u32 size ) +{ + return vmalloc(size); +} + +void inline _mali_osk_vfree( void *ptr ) +{ + vfree(ptr); +} + void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len ) { return memcpy(dst, src, len); diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c index 3afd2da736c..106308b58ba 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -27,6 +27,18 @@ void _mali_osk_dbgmsg( const char *fmt, ... ) va_end(args); } +u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ) +{ + int res; + va_list args; + va_start(args, fmt); + + res = vsnprintf(buf, (size_t)size, fmt, args); + + va_end(args); + return res; +} + void _mali_osk_abort(void) { /* make a simple fault by dereferencing a NULL pointer */ @@ -49,3 +61,9 @@ u32 _mali_osk_get_tid(void) /* pid is actually identifying the thread on Linux */ return (u32)current->pid; } + +void * _mali_osk_get_task(void) +{ + return current; +} + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c index 2efc140f60a..539f9ab68b0 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_notification.c @@ -20,7 +20,6 @@ #include <linux/version.h> #include <linux/sched.h> -#include <linux/mm.h> #include <linux/slab.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #include <linux/semaphore.h> diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c index 04fcd4572df..6fb587ef3df 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_pm.c @@ -25,19 +25,18 @@ #include "mali_osk.h" #include "mali_uk_types.h" #include "mali_pmm.h" -#include "mali_ukk.h" #include "mali_kernel_common.h" #include "mali_kernel_license.h" -#include "mali_kernel_pm.h" -#include "mali_device_pause_resume.h" #include "mali_linux_pm.h" #include "mali_linux_pm_testsuite.h" +#if MALI_LICENSE_IS_GPL #if MALI_PMM_RUNTIME_JOB_CONTROL_ON #ifdef CONFIG_PM_RUNTIME static int is_runtime =0; #endif /* CONFIG_PM_RUNTIME */ #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* MALI_LICENSE_IS_GPL */ #if MALI_POWER_MGMT_TEST_SUITE @@ -180,6 +179,20 @@ void _mali_osk_pmm_dev_activate(void) #endif /* MALI_LICENSE_IS_GPL */ } +void _mali_osk_pmm_ospmm_cleanup( void ) +{ +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + int thread_state; + thread_state = mali_get_ospmm_thread_state(); + if (thread_state) + { + _mali_osk_pmm_dvfs_operation_done(0); + } +#endif /* CONFIG_PM */ +#endif /* MALI_LICENSE_IS_GPL */ +} + void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data) { #if MALI_LICENSE_IS_GPL diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c new file mode 100644 index 00000000000..7ebc67346b4 --- /dev/null +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c @@ -0,0 +1,249 @@ +/** + * 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. + */ + +#define DONT_USE_L2_CACHE_COUNTERS /* These traces can cause lock-ups so disable them. */ + +#include <linux/module.h> + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_ukk.h" +#include "mali_osk_profiling.h" +#include "mali_linux_trace.h" + +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) +#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) && !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 + * 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) && !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 + * 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 54acfdd138c..fbf1dd59e27 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_specific.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -29,4 +29,102 @@ extern "C" } #endif +/** The list of events supported by the Mali DDK. */ +typedef enum +{ + /* Vertex processor activity */ + ACTIVITY_VP = 0, + + /* Fragment processor activity */ + ACTIVITY_FP0, + ACTIVITY_FP1, + ACTIVITY_FP2, + ACTIVITY_FP3, + + /* L2 cache counters */ + COUNTER_L2_C0, + COUNTER_L2_C1, + + /* Vertex processor counters */ + COUNTER_VP_C0, + COUNTER_VP_C1, + + /* Fragment processor counters */ + COUNTER_FP0_C0, + COUNTER_FP0_C1, + COUNTER_FP1_C0, + COUNTER_FP1_C1, + COUNTER_FP2_C0, + COUNTER_FP2_C1, + COUNTER_FP3_C0, + COUNTER_FP3_C1, + + /* + * If more hardware counters are added, the _mali_osk_hw_counter_table + * below should also be updated. + */ + + /* EGL software counters */ + COUNTER_EGL_BLIT_TIME, + + /* GLES software counters */ + COUNTER_GLES_DRAW_ELEMENTS_CALLS, + COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, + COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_ARRAYS_CALLS, + COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_POINTS, + COUNTER_GLES_DRAW_LINES, + COUNTER_GLES_DRAW_LINE_LOOP, + COUNTER_GLES_DRAW_LINE_STRIP, + COUNTER_GLES_DRAW_TRIANGLES, + COUNTER_GLES_DRAW_TRIANGLE_STRIP, + COUNTER_GLES_DRAW_TRIANGLE_FAN, + COUNTER_GLES_NON_VBO_DATA_COPY_TIME, + COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, + COUNTER_GLES_UPLOAD_TEXTURE_TIME, + COUNTER_GLES_UPLOAD_VBO_TIME, + COUNTER_GLES_NUM_FLUSHES, + COUNTER_GLES_NUM_VSHADERS_GENERATED, + COUNTER_GLES_NUM_FSHADERS_GENERATED, + COUNTER_GLES_VSHADER_GEN_TIME, + COUNTER_GLES_FSHADER_GEN_TIME, + COUNTER_GLES_INPUT_TRIANGLES, + COUNTER_GLES_VXCACHE_HIT, + COUNTER_GLES_VXCACHE_MISS, + COUNTER_GLES_VXCACHE_COLLISION, + COUNTER_GLES_CULLED_TRIANGLES, + COUNTER_GLES_CULLED_LINES, + COUNTER_GLES_BACKFACE_TRIANGLES, + COUNTER_GLES_GBCLIP_TRIANGLES, + COUNTER_GLES_GBCLIP_LINES, + COUNTER_GLES_TRIANGLES_DRAWN, + COUNTER_GLES_DRAWCALL_TIME, + COUNTER_GLES_TRIANGLES_COUNT, + COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, + COUNTER_GLES_STRIP_TRIANGLES_COUNT, + COUNTER_GLES_FAN_TRIANGLES_COUNT, + COUNTER_GLES_LINES_COUNT, + COUNTER_GLES_INDEPENDENT_LINES_COUNT, + COUNTER_GLES_STRIP_LINES_COUNT, + COUNTER_GLES_LOOP_LINES_COUNT, + + /* Framebuffer capture pseudo-counter */ + COUNTER_FILMSTRIP, + + NUMBER_OF_EVENTS +} _mali_osk_counter_id; + +#define FIRST_ACTIVITY_EVENT ACTIVITY_VP +#define LAST_ACTIVITY_EVENT ACTIVITY_FP3 + +#define FIRST_HW_COUNTER COUNTER_L2_C0 +#define LAST_HW_COUNTER COUNTER_FP3_C1 + +#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME +#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT + +#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP +#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP + #endif /* __MALI_OSK_SPECIFIC_H__ */ diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c index aa7962380e6..da9b8656b70 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_osk_time.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c index a6f355fd459..58ff1de5108 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_gp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c index 3f67a1e3328..05214b703d3 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c index f77a177d865..31e2a6ac065 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c index 636bd03580e..b9c5ef3aec8 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_profiling.c @@ -133,3 +133,25 @@ int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_pro return 0; } +int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs) +{ + _mali_uk_profiling_get_config_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_profiling_get_config(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.enable_events, &uargs->enable_events)) + { + return -EFAULT; + } + + return 0; +} + diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h index 54e3f656b37..57108a27a61 100644 --- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h +++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h @@ -58,6 +58,7 @@ int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs); int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs); int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs); +int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs); int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs); |