diff options
author | Chunsang Jeong <chunsang.jeong@linaro.org> | 2011-08-13 23:11:20 +0900 |
---|---|---|
committer | Tushar Behera <tushar.behera@linaro.org> | 2012-05-17 10:43:06 +0530 |
commit | f8e96dfd0e19c86074d4ce5cf1d2069b42619e80 (patch) | |
tree | b94ab1ce67ee9c44012b767efe00281c8b4676e1 /drivers/gpu/arm/mali/linux | |
parent | 4d011b466aca9808efb870c87d5c6581c86ebcff (diff) |
Update with r2p2-03release at 17th, Jul from malideveloper.com
Signed-off-by: Chunsang Jeong <chunsang.jeong@linaro.org>
Diffstat (limited to 'drivers/gpu/arm/mali/linux')
23 files changed, 634 insertions, 381 deletions
diff --git a/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h b/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h index e9e5e55a082..2220b3b35ef 100644 --- a/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h +++ b/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * 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. diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c index 1c1bf306688..7a69ae95011 100755 --- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h index 87d94db7886..30a6fa041db 100755 --- a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h @@ -37,6 +37,7 @@ extern "C" #define MALI_IOC_PP_BASE (_MALI_UK_PP_SUBSYSTEM + MALI_IOC_BASE) #define MALI_IOC_GP_BASE (_MALI_UK_GP_SUBSYSTEM + MALI_IOC_BASE) #define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_VSYNC_BASE (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE) #define MALI_IOC_GET_SYSTEM_INFO_SIZE _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO_SIZE, _mali_uk_get_system_info_s *) #define MALI_IOC_GET_SYSTEM_INFO _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO, _mali_uk_get_system_info_s *) @@ -67,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_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/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c index 70d9bfd5b83..382be6802b2 100755 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c @@ -16,7 +16,6 @@ #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> /* the mali kernel subsystem types */ @@ -24,7 +23,6 @@ /* 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" @@ -35,6 +33,8 @@ #include "mali_ukk_wrappers.h" #include "mali_kernel_pm.h" +#include "mali_kernel_sysfs.h" + /* */ #include "mali_kernel_license.h" @@ -60,19 +60,18 @@ extern int mali_max_job_runtime; module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what"); -struct mali_dev -{ - struct cdev cdev; -#if MALI_LICENSE_IS_GPL - struct class * mali_class; +#if defined(USING_MALI400_L2_CACHE) +extern int mali_l2_max_reads; +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 -}; 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; + static int mali_open(struct inode *inode, struct file *filp); static int mali_release(struct inode *inode, struct file *filp); #ifdef HAVE_UNLOCKED_IOCTL @@ -104,47 +103,40 @@ int mali_driver_init(void) #if USING_MALI_PMM #if MALI_LICENSE_IS_GPL #ifdef CONFIG_PM - err = _mali_dev_platform_register(); - if (err) - { - return err; - } + err = _mali_dev_platform_register(); + if (err) + { + return err; + } #endif #endif #endif - err = mali_kernel_constructor(); - if (_MALI_OSK_ERR_OK != err) - { - MALI_PRINT(("Failed to initialize driver (error %d)\n", err)); - return -EFAULT; - } + err = mali_kernel_constructor(); + if (_MALI_OSK_ERR_OK != err) + { +#if USING_MALI_PMM +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + _mali_dev_platform_unregister(); +#endif +#endif +#endif + MALI_PRINT(("Failed to initialize driver (error %d)\n", err)); + return -EFAULT; + } 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 + malipmm_force_powerup(); #endif -#endif -#endif - mali_kernel_destructor(); + 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 + malipmm_force_powerdown(); #endif #if USING_MALI_PMM @@ -174,45 +166,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)); + goto init_chrdev_err; + } - /* initialize our char dev data */ - cdev_init(&device.cdev, &mali_fops); - device.cdev.owner = THIS_MODULE; - device.cdev.ops = &mali_fops; + memset(&device, 0, sizeof(device)); - /* register char dev with the kernel */ - err = cdev_add(&device.cdev, dev, 1/*count*/); + /* initialize our char dev data */ + cdev_init(&device.cdev, &mali_fops); + device.cdev.owner = THIS_MODULE; + device.cdev.ops = &mali_fops; - if (0 == err) - { -#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 - } - unregister_chrdev_region(dev, 1/*count*/); + /* 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; } @@ -220,11 +206,9 @@ int initialize_kernel_device(void) void terminate_kernel_device(void) { dev_t dev = MKDEV(mali_major, 0); + + mali_sysfs_unregister(&device, dev, mali_dev_name); -#if MALI_LICENSE_IS_GPL - device_destroy(device.mali_class, dev); - class_destroy(device.mali_class); -#endif /* unregister char device */ cdev_del(&device.cdev); /* free major */ @@ -427,7 +411,7 @@ 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", cmd, arg)); + MALI_DEBUG_PRINT(2, ("UMP not supported\n")); err = -ENOTTY; break; #endif @@ -468,6 +452,10 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 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; @@ -476,6 +464,7 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return err; } + module_init(mali_driver_init); module_exit(mali_driver_exit); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h index 785eaca4889..485c27e1ecb 100755 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h @@ -16,9 +16,23 @@ extern "C" { #endif +#include <linux/cdev.h> /* character device definitions */ +#include "mali_kernel_license.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); +void mali_osk_low_level_mem_init(void); +void mali_osk_low_level_mem_term(void); + #ifdef __cplusplus } #endif diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c index e6c78c2f6e7..3969466f39e 100755 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c @@ -15,9 +15,6 @@ #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> @@ -51,6 +48,8 @@ unsigned int pwr_mgmt_status_reg = 0; #endif /* CONFIG_PM */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ +static int is_os_pmm_thread_waiting = 0; + /* kernel should be configured with power management support */ #ifdef CONFIG_PM @@ -70,10 +69,6 @@ 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", }; @@ -86,13 +81,11 @@ extern void set_mali_parent_power_domain(struct platform_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); 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 */ @@ -143,12 +136,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 @@ -231,15 +218,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", @@ -308,7 +286,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); + is_os_pmm_thread_waiting = 1; err = mali_wait_for_power_management_policy_event(); + is_os_pmm_thread_waiting = 0; return err; } @@ -322,17 +302,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); @@ -356,7 +330,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; @@ -374,7 +347,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 */ @@ -391,7 +363,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" )); + is_os_pmm_thread_waiting = 1; err = mali_wait_for_power_management_policy_event(); + is_os_pmm_thread_waiting = 0; return err; } @@ -463,69 +437,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 @@ -557,9 +468,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; @@ -597,19 +505,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" )); @@ -694,7 +589,6 @@ int _mali_dev_platform_register(void) #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) @@ -702,28 +596,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); } @@ -737,22 +622,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 +u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ) +{ + 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/arm/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c new file mode 100644 index 00000000000..62c7fba8791 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c @@ -0,0 +1,137 @@ +/** + * 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 <linux/fs.h> /* file system operations */ +#include <linux/device.h> +#include <linux/seq_file.h> +#include <linux/debugfs.h> + +/* the mali kernel subsystem types */ +#include "mali_kernel_subsystem.h" + +#include "mali_kernel_linux.h" +#include "mali_kernel_sysfs.h" + +#include "mali_kernel_license.h" + +#if MALI_LICENSE_IS_GPL +static struct dentry *mali_debugfs_dir; +#endif + + +#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 */ + +int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ + int err = 0; +#if MALI_LICENSE_IS_GPL + 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_STATE_TRACKING + debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); +#endif + } + } +#endif /* MALI_LICENSE_IS_GPL */ + + /* Success! */ + return 0; + + /* Error handling */ +#if MALI_LICENSE_IS_GPL + if(NULL != mali_debugfs_dir) + { + debugfs_remove_recursive(mali_debugfs_dir); + } + device_destroy(device->mali_class, dev); +init_mdev_err: + class_destroy(device->mali_class); +init_class_err: +#endif + return err; +} + +int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name) +{ +#if MALI_LICENSE_IS_GPL + if(NULL != mali_debugfs_dir) + { + debugfs_remove_recursive(mali_debugfs_dir); + } + device_destroy(device->mali_class, dev); + class_destroy(device->mali_class); +#endif + + return 0; +} + diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h new file mode 100644 index 00000000000..d79a8862269 --- /dev/null +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_linux_dvfs_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c new file mode 100644 index 00000000000..3d60d18e005 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c @@ -0,0 +1,72 @@ +/** + * 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/arm/mali/linux/mali_linux_pm.h b/drivers/gpu/arm/mali/linux/mali_linux_pm.h index 614d5e1deee..d401697f2f4 100755 --- a/drivers/gpu/arm/mali/linux/mali_linux_pm.h +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_linux_pm_testsuite.h b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h index d6a920827c9..c80b0b0a5e3 100755 --- a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h @@ -13,7 +13,6 @@ #if USING_MALI_PMM #if MALI_POWER_MGMT_TEST_SUITE #ifdef CONFIG_PM -#define MALI_PMM_INTERNAL_TESTING 1 typedef enum { @@ -28,10 +27,7 @@ extern unsigned int mali_timeout_event_recording_on; extern unsigned int mali_job_scheduling_events_recording_on; extern unsigned int pwr_mgmt_status_reg; extern unsigned int is_mali_pmm_testsuite_enabled; - -#if MALI_PMM_INTERNAL_TESTING extern unsigned int is_mali_pmu_present; -#endif /* MALI_PMM_INTERNAL_TESTING */ #endif /* CONFIG_PM */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ diff --git a/drivers/gpu/arm/mali/linux/mali_osk_irq.c b/drivers/gpu/arm/mali/linux/mali_osk_irq.c index 73ab8182815..b667961a0ac 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_irq.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_irq.c @@ -136,7 +136,7 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl #if MALI_LICENSE_IS_GPL if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum ) { - pmm_wq = create_workqueue("mali-pmm-wq"); + pmm_wq = create_singlethread_workqueue("mali-pmm-wq"); } #endif @@ -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/arm/mali/linux/mali_osk_locks.c b/drivers/gpu/arm/mali/linux/mali_osk_locks.c index 79010fcdc5a..139dc5e3de3 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_locks.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_locks.c @@ -29,12 +29,6 @@ #include "mali_osk.h" #include "mali_kernel_common.h" -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) -#define LOCK_INIT(x) sema_init(x,1) -#else -#define LOCK_INIT(x) init_MUTEX(x) -#endif - /* These are all the locks we implement: */ typedef enum { @@ -67,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 */ }; @@ -82,10 +75,10 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED - | _MALI_OSK_LOCKFLAG_ONELOCK)) ); + | _MALI_OSK_LOCKFLAG_ONELOCK )) ); /* Spinlocks are always non-interruptable */ MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) - || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK) ); + || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK)); /* Parameter initial SBZ - for future expansion */ MALI_DEBUG_ASSERT( 0 == initial ); @@ -130,13 +123,12 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial } /* Initially unlocked */ - LOCK_INIT( &lock->obj.sema ); + sema_init( &lock->obj.sema, 1 ); } MALI_DEBUG_CODE( /* Debug tracking of flags */ lock->orig_flags = flags; - lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF; ); /* MALI_DEBUG_CODE */ return lock; @@ -196,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; } @@ -224,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: @@ -269,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/arm/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c index 730ee814e38..40373427d44 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/gpu/arm/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 */ @@ -38,6 +37,7 @@ static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address); #endif + typedef struct mali_vma_usage_tracker { int references; @@ -50,9 +50,9 @@ typedef struct mali_vma_usage_tracker */ struct AllocationList { - struct AllocationList *next; - u32 offset; - u32 physaddr; + struct AllocationList *next; + u32 offset; + u32 physaddr; }; typedef struct AllocationList AllocationList; @@ -63,11 +63,28 @@ typedef struct AllocationList AllocationList; struct MappingInfo { struct vm_area_struct *vma; - struct AllocationList *list; + struct AllocationList *list; }; typedef struct MappingInfo MappingInfo; + +static u32 _kernel_page_allocate(void); +static void _kernel_page_release(u32 physical_address); +static AllocationList * _allocation_list_item_get(void); +static void _allocation_list_item_release(AllocationList * item); + + +/* Variable declarations */ +spinlock_t allocation_list_spinlock; +static AllocationList * pre_allocated_memory = (AllocationList*) NULL ; +static int pre_allocated_memory_size_current = 0; +#ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB + static int pre_allocated_memory_size_max = MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB * 1024 * 1024; +#else + static int pre_allocated_memory_size_max = 6 * 1024 * 1024; /* 6 MiB */ +#endif + static struct vm_operations_struct mali_kernel_vm_ops = { .open = mali_kernel_memory_vma_open, @@ -80,6 +97,108 @@ 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 ; +} + +void mali_osk_low_level_mem_term(void) +{ + while ( NULL != pre_allocated_memory ) + { + AllocationList *item; + item = pre_allocated_memory; + pre_allocated_memory = item->next; + _kernel_page_release(item->physaddr); + _mali_osk_free( item ); + } + pre_allocated_memory_size_current = 0; +} + +static u32 _kernel_page_allocate(void) +{ + struct page *new_page; + u32 linux_phys_addr; + + new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD); + + if ( NULL == new_page ) + { + return 0; + } + + /* Ensure page is flushed from CPU caches. */ + linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); + + return linux_phys_addr; +} + +static void _kernel_page_release(u32 physical_address) +{ + struct page *unmap_page; + + #if 1 + dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL); + #endif + + unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT ); + MALI_DEBUG_ASSERT_POINTER( unmap_page ); + __free_page( unmap_page ); +} + +static AllocationList * _allocation_list_item_get(void) +{ + AllocationList *item = NULL; + unsigned long flags; + + spin_lock_irqsave(&allocation_list_spinlock,flags); + if ( pre_allocated_memory ) + { + item = pre_allocated_memory; + pre_allocated_memory = pre_allocated_memory->next; + pre_allocated_memory_size_current -= PAGE_SIZE; + + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + return item; + } + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + + item = _mali_osk_malloc( sizeof(AllocationList) ); + if ( NULL == item) + { + return NULL; + } + + item->physaddr = _kernel_page_allocate(); + if ( 0 == item->physaddr ) + { + /* Non-fatal error condition, out of memory. Upper levels will handle this. */ + _mali_osk_free( item ); + return NULL; + } + return item; +} + +static void _allocation_list_item_release(AllocationList * item) +{ + unsigned long flags; + spin_lock_irqsave(&allocation_list_spinlock,flags); + if ( pre_allocated_memory_size_current < pre_allocated_memory_size_max) + { + item->next = pre_allocated_memory; + pre_allocated_memory = item; + pre_allocated_memory_size_current += PAGE_SIZE; + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + return; + } + spin_unlock_irqrestore(&allocation_list_spinlock,flags); + + _kernel_page_release(item->physaddr); + _mali_osk_free( item ); +} + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf) #else @@ -108,7 +227,7 @@ static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_st static void mali_kernel_memory_vma_open(struct vm_area_struct * vma) { mali_vma_usage_tracker * vma_usage_tracker; - MALI_DEBUG_PRINT(2, ("Open called on vma %p\n", vma)); + MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma)); vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; vma_usage_tracker->references++; @@ -154,17 +273,17 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) void _mali_osk_mem_barrier( void ) { - mb(); + mb(); } mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ) { - return (mali_io_address)ioremap_nocache(phys, size); + return (mali_io_address)ioremap_nocache(phys, size); } void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt ) { - iounmap((void*)virt); + iounmap((void*)virt); } mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) @@ -204,27 +323,27 @@ void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt ) _mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description ) { - return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK); + return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK); } void inline _mali_osk_mem_unreqregion( u32 phys, u32 size ) { - release_mem_region(phys, size); + release_mem_region(phys, size); } u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset ) { - return ioread32(((u8*)addr) + offset); + return ioread32(((u8*)addr) + offset); } void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val ) { - iowrite32(val, ((u8*)addr) + offset); + iowrite32(val, ((u8*)addr) + offset); } void _mali_osk_cache_flushall( void ) { - /** @note Cached memory is not currently supported in this implementation */ + /** @note Cached memory is not currently supported in this implementation */ } void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size ) @@ -274,6 +393,7 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descr */ vma->vm_flags |= VM_IO; vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_DONTCOPY; vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */ @@ -334,14 +454,14 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK)); - if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS; + if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS; - if (size > (descriptor->size - offset)) - { - MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n", - *phys_addr, size, descriptor->mapping, offset)); - return _MALI_OSK_ERR_FAULT; - } + if (size > (descriptor->size - offset)) + { + MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n", + *phys_addr, size, descriptor->mapping, offset)); + return _MALI_OSK_ERR_FAULT; + } mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; @@ -351,57 +471,35 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri if (NULL == vma ) return _MALI_OSK_ERR_FAULT; - MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", phys_addr, (long unsigned int)(descriptor->mapping + offset), size)); + MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", *phys_addr, (long unsigned int)(descriptor->mapping + offset), size)); if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr ) { _mali_osk_errcode_t ret; + AllocationList *alloc_item; u32 linux_phys_frame_num; - u32 linux_phys_addr; - AllocationList *allocItem; - struct page *new_page; - allocItem = _mali_osk_malloc( sizeof(AllocationList) ); - if ( NULL == allocItem ) - { - /* Out of memory. Try another allocator */ - return _MALI_OSK_ERR_NOMEM; - } + alloc_item = _allocation_list_item_get(); - { - new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD); - - if ( NULL == new_page ) - { - /* Non-fatal error condition, out of memory. Upper levels will handle this. */ - _mali_osk_free( allocItem ); - return _MALI_OSK_ERR_NOMEM; - } - - /* Ensure page is flushed from CPU caches. */ - linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - - linux_phys_frame_num = linux_phys_addr >> PAGE_SHIFT; - } + linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT; ret = ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, linux_phys_frame_num, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK; if ( ret != _MALI_OSK_ERR_OK) { - dma_unmap_page(NULL, linux_phys_addr, PAGE_SIZE, DMA_BIDIRECTIONAL); - __free_page( new_page ); - _mali_osk_free( allocItem ); + _allocation_list_item_release(alloc_item); return ret; } - /* Put our allocItem into the list of allocations on success */ - allocItem->next = mappingInfo->list; - allocItem->offset = offset; - allocItem->physaddr = linux_phys_addr; - mappingInfo->list = allocItem; + /* Put our alloc_item into the list of allocations on success */ + alloc_item->next = mappingInfo->list; + alloc_item->offset = offset; + + /*alloc_item->physaddr = linux_phys_addr;*/ + mappingInfo->list = alloc_item; /* Write out new physical address on success */ - *phys_addr = linux_phys_addr; + *phys_addr = alloc_item->physaddr; return ret; } @@ -427,56 +525,50 @@ void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 off MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) ); - if (NULL == descriptor->mapping) return; + if (NULL == descriptor->mapping) return; - if (size > (descriptor->size - offset)) - { - MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n", + if (size > (descriptor->size - offset)) + { + MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n", size, descriptor->mapping, offset)); - return; - } + return; + } mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; MALI_DEBUG_ASSERT_POINTER( mappingInfo ); if ( 0 != (flags & _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR) ) { - /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and - * so needs to be unmapped - */ - while (size) + /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and + * so needs to be unmapped + */ + while (size) { - /* First find the allocation in the list of allocations */ - AllocationList *alloc = mappingInfo->list; - AllocationList **prev = &(mappingInfo->list); - while (NULL != alloc && alloc->offset != offset) - { - prev = &(alloc->next); - alloc = alloc->next; - } - if (alloc == NULL) { - MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n")); - size -= _MALI_OSK_CPU_PAGE_SIZE; - offset += _MALI_OSK_CPU_PAGE_SIZE; - continue; - } - + /* First find the allocation in the list of allocations */ + AllocationList *alloc = mappingInfo->list; + AllocationList **prev = &(mappingInfo->list); + while (NULL != alloc && alloc->offset != offset) { - struct page *unmap_page; - unmap_page = pfn_to_page( alloc->physaddr >> PAGE_SHIFT ); - MALI_DEBUG_ASSERT_POINTER( unmap_page ); - dma_unmap_page(NULL, alloc->physaddr, PAGE_SIZE, DMA_BIDIRECTIONAL); - __free_page( unmap_page ); + prev = &(alloc->next); + alloc = alloc->next; } + if (alloc == NULL) { + MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n")); + size -= _MALI_OSK_CPU_PAGE_SIZE; + offset += _MALI_OSK_CPU_PAGE_SIZE; + continue; + } + + _kernel_page_release(alloc->physaddr); - /* Remove the allocation from the list */ - *prev = alloc->next; - _mali_osk_free( alloc ); + /* Remove the allocation from the list */ + *prev = alloc->next; + _mali_osk_free( alloc ); - /* Move onto the next allocation */ - size -= _MALI_OSK_CPU_PAGE_SIZE; - offset += _MALI_OSK_CPU_PAGE_SIZE; - } + /* Move onto the next allocation */ + size -= _MALI_OSK_CPU_PAGE_SIZE; + offset += _MALI_OSK_CPU_PAGE_SIZE; + } } /* Linux does the right thing as part of munmap to remove the mapping */ diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c index d6c4b41ebc0..5b84549ef86 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.c @@ -18,21 +18,24 @@ #include "mali_kernel_common.h" /* MALI_xxx macros */ #include "mali_osk.h" /* kernel side OS functions */ #include "mali_uk_types.h" -#include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() */ +#include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() definition of mali_osk_low_level_mem_init() and term */ #include <mach/irqs.h> -#include <mach/mali/config.h> /* contains the configuration of the arch we are compiling for */ +#include <mach/mali/config.h> /* contains the configuration of the arch we are compiling for */ /* is called from mali_kernel_constructor in common code */ _mali_osk_errcode_t _mali_osk_init( void ) { if (0 != initialize_kernel_device()) MALI_ERROR(_MALI_OSK_ERR_FAULT); + mali_osk_low_level_mem_init(); + MALI_SUCCESS; } /* is called from mali_kernel_deconstructor in common code */ void _mali_osk_term( void ) { + mali_osk_low_level_mem_term(); terminate_kernel_device(); } diff --git a/drivers/gpu/arm/mali/linux/mali_osk_misc.c b/drivers/gpu/arm/mali/linux/mali_osk_misc.c index 3afd2da736c..12f4299ee9b 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_misc.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_osk_notification.c b/drivers/gpu/arm/mali/linux/mali_osk_notification.c index 6eb277f3724..539f9ab68b0 100755..100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_notification.c +++ b/drivers/gpu/arm/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> @@ -28,12 +27,6 @@ #include <asm/semaphore.h> #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) -#define LOCK_INIT(x) sema_init(x,1) -#else -#define LOCK_INIT(x) init_MUTEX(x) -#endif - /** * Declaration of the notification queue object type * Contains a linked list of notification pending delivery to user space. @@ -60,7 +53,7 @@ _mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void ) result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL); if (NULL == result) return NULL; - LOCK_INIT(&result->mutex); + sema_init(&result->mutex, 1); init_waitqueue_head(&result->receive_queue); INIT_LIST_HEAD(&result->head); @@ -72,7 +65,7 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) /* OPT Recycling of notification objects */ _mali_osk_notification_wrapper_t *notification; - notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t), GFP_KERNEL ); + notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, GFP_KERNEL ); if (NULL == notification) { MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n")); @@ -82,21 +75,13 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) /* Init the list */ INIT_LIST_HEAD(¬ification->list); - /* allocate memory for the buffer requested */ if (0 != size) { - notification->data.result_buffer = kmalloc( size, GFP_KERNEL ); - if ( NULL == notification->data.result_buffer ) - { - /* failed to buffer, cleanup */ - MALI_DEBUG_PRINT(1, ("Failed to allocate memory for notification object buffer of size %d\n", size)); - kfree(notification); - return NULL; - } + notification->data.result_buffer = ((u8*)notification) + sizeof(_mali_osk_notification_wrapper_t); } else { - notification->data.result_buffer = 0; + notification->data.result_buffer = NULL; } /* set up the non-allocating fields */ @@ -116,8 +101,6 @@ void _mali_osk_notification_delete( _mali_osk_notification_t *object ) /* Remove from the list */ list_del(¬ification->list); - /* Free the buffer */ - kfree(notification->data.result_buffer); /* Free the container */ kfree(notification); } @@ -159,6 +142,13 @@ static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *qu return ret; } +#if MALI_STATE_TRACKING +mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ) +{ + return _mali_notification_queue_is_empty(queue) ? MALI_TRUE : MALI_FALSE; +} +#endif + _mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ) { _mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND; diff --git a/drivers/gpu/arm/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali/linux/mali_osk_pm.c index f1363167292..f9c9e5ce2e8 100755..100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_pm.c @@ -33,11 +33,13 @@ #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 @@ -118,12 +120,10 @@ void _mali_osk_pmm_power_down_done(mali_pmm_message_data data) #ifdef CONFIG_PM is_wake_up_needed = 1; #if MALI_POWER_MGMT_TEST_SUITE -#if MALI_PMM_INTERNAL_TESTING if (is_mali_pmu_present == 0) { pwr_mgmt_status_reg = _mali_pmm_cores_list(); } -#endif /* MALI_PMM_INTERNAL_TESTING */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ wake_up_process(pm_thread); MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power down Done\n" )); @@ -182,6 +182,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/arm/mali/linux/mali_osk_timers.c b/drivers/gpu/arm/mali/linux/mali_osk_timers.c index 1cffce37461..3dfba76bcb3 100755..100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_timers.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_timers.c @@ -51,7 +51,6 @@ void _mali_osk_timer_del( _mali_osk_timer_t *tim ) del_timer_sync(&(tim->timer)); } - void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data ) { MALI_DEBUG_ASSERT_POINTER(tim); diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_core.c b/drivers/gpu/arm/mali/linux/mali_ukk_core.c index a10d1ba8a5e..0f745492613 100755..100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_core.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_core.c @@ -105,7 +105,7 @@ int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_ err = _mali_ukk_wait_for_notification(&kargs); if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - if( !(_MALI_NOTIFICATION_CORE_TIMEOUT == kargs.type || _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS == kargs.type ) ) + if(_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS != kargs.type) { kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_wait_for_notification_s))) return -EFAULT; diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_gp.c b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c index 58ff1de5108..a6f355fd459 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_gp.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * 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. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c b/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c new file mode 100644 index 00000000000..965ee411535 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c @@ -0,0 +1,41 @@ +/* + * 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. + */ +#include <linux/fs.h> /* file system operations */ +#include <asm/uaccess.h> /* user space access */ + +#include "mali_ukk.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_kernel_session_manager.h" +#include "mali_ukk_wrappers.h" + + +int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs) +{ + _mali_uk_vsync_event_report_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_vsync_event_report_s))) + { + return -EFAULT; + } + + kargs.ctx = session_data; + err = _mali_ukk_vsync_event_report(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h index 0bc6b87e69c..54e3f656b37 100755 --- a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h +++ b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h @@ -59,6 +59,8 @@ int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_prof 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 vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs); + int map_errcode( _mali_osk_errcode_t err ); #ifdef __cplusplus |