From 0174fc04fdfd7a84c2655d84aa704fe173798241 Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Mon, 26 Sep 2011 11:19:39 -0600 Subject: Added Mali, UMP and Mali DRM kernel driver Conflicts: drivers/gpu/drm/Kconfig drivers/gpu/drm/Makefile Signed-off-by: Chunsang Jeong Signed-off-by: Tushar Behera --- .../mali/linux/license/gpl/mali_kernel_license.h | 31 + .../gpu/arm/mali/linux/mali_device_pause_resume.c | 72 ++ .../gpu/arm/mali/linux/mali_device_pause_resume.h | 19 + drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h | 74 +++ drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 481 ++++++++++++++ drivers/gpu/arm/mali/linux/mali_kernel_linux.h | 26 + drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 732 +++++++++++++++++++++ drivers/gpu/arm/mali/linux/mali_kernel_pm.h | 19 + drivers/gpu/arm/mali/linux/mali_linux_pm.h | 58 ++ .../gpu/arm/mali/linux/mali_linux_pm_testsuite.h | 41 ++ drivers/gpu/arm/mali/linux/mali_osk_atomics.c | 55 ++ drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c | 86 +++ drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h | 48 ++ drivers/gpu/arm/mali/linux/mali_osk_irq.c | 195 ++++++ drivers/gpu/arm/mali/linux/mali_osk_locks.c | 262 ++++++++ .../gpu/arm/mali/linux/mali_osk_low_level_mem.c | 485 ++++++++++++++ drivers/gpu/arm/mali/linux/mali_osk_mali.c | 48 ++ drivers/gpu/arm/mali/linux/mali_osk_math.c | 22 + drivers/gpu/arm/mali/linux/mali_osk_memory.c | 50 ++ drivers/gpu/arm/mali/linux/mali_osk_misc.c | 51 ++ drivers/gpu/arm/mali/linux/mali_osk_notification.c | 204 ++++++ drivers/gpu/arm/mali/linux/mali_osk_pm.c | 197 ++++++ drivers/gpu/arm/mali/linux/mali_osk_specific.h | 32 + drivers/gpu/arm/mali/linux/mali_osk_time.c | 51 ++ drivers/gpu/arm/mali/linux/mali_osk_timers.c | 66 ++ drivers/gpu/arm/mali/linux/mali_ukk_core.c | 121 ++++ drivers/gpu/arm/mali/linux/mali_ukk_gp.c | 128 ++++ drivers/gpu/arm/mali/linux/mali_ukk_mem.c | 336 ++++++++++ drivers/gpu/arm/mali/linux/mali_ukk_pp.c | 103 +++ drivers/gpu/arm/mali/linux/mali_ukk_profiling.c | 135 ++++ drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h | 67 ++ 31 files changed, 4295 insertions(+) create mode 100644 drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h create mode 100644 drivers/gpu/arm/mali/linux/mali_device_pause_resume.c create mode 100644 drivers/gpu/arm/mali/linux/mali_device_pause_resume.h create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_linux.c create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_linux.h create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_pm.c create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_pm.h create mode 100644 drivers/gpu/arm/mali/linux/mali_linux_pm.h create mode 100644 drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_atomics.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_irq.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_locks.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_mali.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_math.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_memory.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_misc.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_notification.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_pm.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_specific.h create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_time.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_timers.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_core.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_gp.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_mem.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_pp.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_profiling.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h (limited to 'drivers/gpu/arm/mali/linux') 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 new file mode 100644 index 00000000000..e9e5e55a082 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_license.h + * Defines for the macro MODULE_LICENSE. + */ + +#ifndef __MALI_KERNEL_LICENSE_H__ +#define __MALI_KERNEL_LICENSE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MALI_KERNEL_LINUX_LICENSE "GPL" +#define MALI_LICENSE_IS_GPL 1 + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LICENSE_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c new file mode 100644 index 00000000000..0b47efe18cf --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_device_pause_resume.c + * Implementation of the Mali pause/resume functionality + */ +#if USING_MALI_PMM +#include +#include +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_platform.h" +#include "mali_linux_pm.h" +#include "mali_device_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_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_pause); + +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)) + { + 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_resume); + +#endif /* MALI_LICENSE_IS_GPL */ +#endif /* CONFIG_PM */ +#endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h new file mode 100644 index 00000000000..155a3e69d48 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_DEVICE_PAUSE_RESUME_H__ +#define __MALI_DEVICE_PAUSE_RESUME_H__ + +#if USING_MALI_PMM +int mali_dev_pause(void); +int mali_dev_resume(void); +#endif /* USING_MALI_PMM */ + +#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h new file mode 100644 index 00000000000..d76841e5eba --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_IOCTL_H__ +#define __MALI_KERNEL_IOCTL_H__ + +#include +#include +#include /* file system operations */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @file mali_kernel_ioctl.h + * Interface to the Linux device driver. + * This file describes the interface needed to use the Linux device driver. + * Its interface is designed to used by the HAL implementation through a thin arch layer. + */ + +/** + * ioctl commands + */ + +#define MALI_IOC_BASE 0x82 +#define MALI_IOC_CORE_BASE (_MALI_UK_CORE_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_MEMORY_BASE (_MALI_UK_MEMORY_SUBSYSTEM + MALI_IOC_BASE) +#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_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 *) +#define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *) +#define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *) +#define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, _mali_uk_get_big_block_s *) +#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, _mali_uk_free_big_block_s *) +#define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *) +#define MALI_IOC_MEM_TERM _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *) +#define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *) +#define MALI_IOC_MEM_UNMAP_EXT _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_mem_s *) +#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s *) +#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s *) +#define MALI_IOC_MEM_ATTACH_UMP _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s *) +#define MALI_IOC_MEM_RELEASE_UMP _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s *) +#define MALI_IOC_PP_START_JOB _IOWR(MALI_IOC_PP_BASE, _MALI_UK_PP_START_JOB, _mali_uk_pp_start_job_s *) +#define MALI_IOC_PP_NUMBER_OF_CORES_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_NUMBER_OF_CORES, _mali_uk_get_pp_number_of_cores_s *) +#define MALI_IOC_PP_CORE_VERSION_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * ) +#define MALI_IOC_PP_ABORT_JOB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_ABORT_JOB, _mali_uk_pp_abort_job_s * ) +#define MALI_IOC_GP2_START_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *) +#define MALI_IOC_GP2_ABORT_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_ABORT_JOB, _mali_uk_gp_abort_job_s *) +#define MALI_IOC_GP2_NUMBER_OF_CORES_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *) +#define MALI_IOC_GP2_CORE_VERSION_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *) +#define MALI_IOC_GP2_SUSPEND_RESPONSE _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *) +#define MALI_IOC_PROFILING_START _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_START, _mali_uk_profiling_start_s *) +#define MALI_IOC_PROFILING_ADD_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_ADD_EVENT, _mali_uk_profiling_add_event_s*) +#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 *) + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_IOCTL_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c new file mode 100644 index 00000000000..3c38fadf59f --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c @@ -0,0 +1,481 @@ +/** + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_linux.c + * Implementation of the Linux device driver entrypoints + */ +#include /* kernel module definitions */ +#include /* file system operations */ +#include /* character device definitions */ +#include /* memory mananger definitions */ +#include /* user space access */ +#include + +/* the mali kernel subsystem types */ +#include "mali_kernel_subsystem.h" + +/* A memory subsystem always exists, so no need to conditionally include it */ +#include "mali_kernel_common.h" +#include "mali_kernel_mem.h" +#include "mali_kernel_session_manager.h" +#include "mali_kernel_core.h" + +#include "mali_osk.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" +#include "mali_kernel_ioctl.h" +#include "mali_ukk_wrappers.h" +#include "mali_kernel_pm.h" + +/* */ +#include "mali_kernel_license.h" + +/* Module parameter to control log level */ +int mali_debug_level = 2; +module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output"); + +/* By default the module uses any available major, but it's possible to set it at load time to a specific number */ +int mali_major = 0; +module_param(mali_major, int, S_IRUGO); /* r--r--r-- */ +MODULE_PARM_DESC(mali_major, "Device major number"); + +int mali_benchmark = 0; +module_param(mali_benchmark, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ +MODULE_PARM_DESC(mali_benchmark, "Bypass Mali hardware when non-zero"); + +extern int mali_hang_check_interval; +module_param(mali_hang_check_interval, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); +MODULE_PARM_DESC(mali_hang_check_interval, "Interval at which to check for progress after the hw watchdog has been triggered"); + +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; +#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 +static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#else +static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +#endif + +static int mali_mmap(struct file * filp, struct vm_area_struct * vma); + +/* Linux char file operations provided by the Mali module */ +struct file_operations mali_fops = +{ + .owner = THIS_MODULE, + .open = mali_open, + .release = mali_release, +#ifdef HAVE_UNLOCKED_IOCTL + .unlocked_ioctl = mali_ioctl, +#else + .ioctl = mali_ioctl, +#endif + .mmap = mali_mmap +}; + + +int mali_driver_init(void) +{ + int err; + err = mali_kernel_constructor(); + if (_MALI_OSK_ERR_OK != err) + { + 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 +#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 + +#if USING_MALI_PMM +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + _mali_dev_platform_unregister(); +#endif +#endif +#endif +} + +/* called from _mali_osk_init */ +int initialize_kernel_device(void) +{ + int err; + dev_t dev = 0; + +#if USING_MALI_PMM +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + err = _mali_dev_platform_register(); + if (err) + { + return err; + } +#endif +#endif +#endif + if (0 == mali_major) + { + /* auto select a major */ + err = alloc_chrdev_region(&dev, 0/*first minor*/, 1/*count*/, mali_dev_name); + mali_major = MAJOR(dev); + } + else + { + /* use load time defined major number */ + dev = MKDEV(mali_major, 0); + err = register_chrdev_region(dev, 1/*count*/, mali_dev_name); + } + + if (0 == 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_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*/); + } + + return err; +} + +/* called from _mali_osk_term */ +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 + /* unregister char device */ + cdev_del(&device.cdev); + /* free major */ + unregister_chrdev_region(dev, 1/*count*/); + return; +} + +/** @note munmap handler is done by vma close handler */ +static int mali_mmap(struct file * filp, struct vm_area_struct * vma) +{ + struct mali_session_data * session_data; + _mali_uk_mem_mmap_s args = {0, }; + + session_data = (struct mali_session_data *)filp->private_data; + if (NULL == session_data) + { + MALI_PRINT_ERROR(("mmap called without any session data available\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(3, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start)) ); + + /* Re-pack the arguments that mmap() packed for us */ + args.ctx = session_data; + args.phys_addr = vma->vm_pgoff << PAGE_SHIFT; + args.size = vma->vm_end - vma->vm_start; + args.ukk_private = vma; + + /* Call the common mmap handler */ + MALI_CHECK(_MALI_OSK_ERR_OK ==_mali_ukk_mem_mmap( &args ), -EFAULT); + + return 0; +} + +static int mali_open(struct inode *inode, struct file *filp) +{ + struct mali_session_data * session_data; + _mali_osk_errcode_t err; + + /* input validation */ + if (0 != MINOR(inode->i_rdev)) return -ENODEV; + + /* allocated struct to track this session */ + err = _mali_ukk_open((void **)&session_data); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + /* initialize file pointer */ + filp->f_pos = 0; + + /* link in our session data */ + filp->private_data = (void*)session_data; + + return 0; +} + +static int mali_release(struct inode *inode, struct file *filp) +{ + _mali_osk_errcode_t err; + + /* input validation */ + if (0 != MINOR(inode->i_rdev)) return -ENODEV; + + err = _mali_ukk_close((void **)&filp->private_data); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + return 0; +} + +int map_errcode( _mali_osk_errcode_t err ) +{ + switch(err) + { + case _MALI_OSK_ERR_OK : return 0; + case _MALI_OSK_ERR_FAULT: return -EFAULT; + case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY; + case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL; + case _MALI_OSK_ERR_NOMEM: return -ENOMEM; + case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT; + case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS; + case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT; + default: return -EFAULT; + } +} + +#ifdef HAVE_UNLOCKED_IOCTL +static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +#else +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; + +#ifndef HAVE_UNLOCKED_IOCTL + /* inode not used */ + (void)inode; +#endif + + 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) + { + MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n")); + return -ENOTTY; + } + 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; + + 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_GET_API_VERSION: + err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_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_ADD_EVENT: + 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; + + case MALI_IOC_PROFILING_GET_EVENT: + 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; +#endif + + 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_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_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_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; + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 + + case MALI_IOC_MEM_ATTACH_UMP: + err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg); + break; + + case MALI_IOC_MEM_RELEASE_UMP: + err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg); + break; + +#else + + case MALI_IOC_MEM_ATTACH_UMP: + case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */ + MALI_DEBUG_PRINT(2, ("UMP not supported\n", cmd, arg)); + 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_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_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_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_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; + + default: + MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); + err = -ENOTTY; + }; + + return err; +} + +module_init(mali_driver_init); +module_exit(mali_driver_exit); + +MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE); +MODULE_AUTHOR("ARM Ltd."); +MODULE_VERSION(SVN_REV_STRING); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h new file mode 100644 index 00000000000..bec0e24774a --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_LINUX_H__ +#define __MALI_KERNEL_LINUX_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +_mali_osk_errcode_t initialize_kernel_device(void); +void terminate_kernel_device(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_KERNEL_LINUX_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c new file mode 100644 index 00000000000..915f355af07 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c @@ -0,0 +1,732 @@ +/** + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_kernel_pm.c + * Implementation of the Linux Power Management for Mali GPU kernel driver + */ + +#if USING_MALI_PMM +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif /* CONFIG_HAS_EARLYSUSPEND */ + +#ifdef CONFIG_PM_RUNTIME +#include +#endif /* CONFIG_PM_RUNTIME */ + +#include +#include +#include +#include +#include + +#include "mali_platform.h" +#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" + +#if MALI_POWER_MGMT_TEST_SUITE +#ifdef CONFIG_PM +#include "mali_linux_pm_testsuite.h" +unsigned int pwr_mgmt_status_reg = 0; +#endif /* CONFIG_PM */ +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + +/* kernel should be configured with power management support */ +#ifdef CONFIG_PM + +/* License should be GPL */ +#if MALI_LICENSE_IS_GPL + +/* Linux kernel major version */ +#define LINUX_KERNEL_MAJOR_VERSION 2 + +/* Linux kernel minor version */ +#define LINUX_KERNEL_MINOR_VERSION 6 + +/* Linux kernel development version */ +#define LINUX_KERNEL_DEVELOPMENT_VERSION 29 + +#ifdef CONFIG_PM_DEBUG +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 */ + +/* Power management thread pointer */ +struct task_struct *pm_thread; + +/* dvfs power management thread */ +struct task_struct *dvfs_pm_thread; + +/* is wake up needed */ +short is_wake_up_needed = 0; +int timeout_fired = 2; +unsigned int is_mali_pmm_testsuite_enabled = 0; + +_mali_device_power_states mali_device_state = _MALI_DEVICE_RESUME; +_mali_device_power_states mali_dvfs_device_state = _MALI_DEVICE_RESUME; +_mali_osk_lock_t *lock; + +#if MALI_POWER_MGMT_TEST_SUITE + +const char* const mali_pmm_recording_events[_MALI_DEVICE_MAX_PMM_EVENTS] = { + [_MALI_DEVICE_PMM_TIMEOUT_EVENT] = "timeout", + [_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS] = "job_scheduling", + [_MALI_DEVICE_PMM_REGISTERED_CORES] = "cores", + +}; + +unsigned int mali_timeout_event_recording_on = 0; +unsigned int mali_job_scheduling_events_recording_on = 0; + +#if MALI_PMM_INTERNAL_TESTING +unsigned int is_mali_pmu_present = 0; +#endif /* MALI_PMM_INTERNAL_TESTING */ +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + +/* Function prototypes */ +static int mali_pm_probe(struct platform_device *pdev); +static int mali_pm_remove(struct platform_device *pdev); + +/* Mali device suspend function */ +static int mali_pm_suspend(struct device *dev); + +/* Mali device resume function */ +static int mali_pm_resume(struct device *dev); + +/* Run time suspend and resume functions */ +#ifdef CONFIG_PM_RUNTIME +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +static int mali_device_runtime_suspend(struct device *dev); +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 (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state); +#else +static int mali_pm_os_suspend(struct device *dev); +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +static int mali_pm_os_resume(struct platform_device *pdev); +#else +static int mali_pm_os_resume(struct device *dev); +#endif + +/* OS Hibernation suspend callback */ +static int mali_pm_os_suspend_on_hibernation(struct device *dev); + +/* OS Hibernation resume callback */ +static int mali_pm_os_resume_on_hibernation(struct device *dev); + +static void _mali_release_pm(struct device* device); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +static const struct dev_pm_ops mali_dev_pm_ops = { + +#ifdef CONFIG_PM_RUNTIME +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + .runtime_suspend = mali_device_runtime_suspend, + .runtime_resume = mali_device_runtime_resume, +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ + + .suspend = mali_pm_os_suspend, + .resume = mali_pm_os_resume, + .freeze = mali_pm_os_suspend_on_hibernation, + .poweroff = mali_pm_os_suspend_on_hibernation, + .thaw = mali_pm_os_resume_on_hibernation, + .restore = mali_pm_os_resume_on_hibernation, +}; +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +struct pm_ext_ops mali_pm_operations = { + .base = { + .freeze = mali_pm_os_suspend_on_hibernation, + .thaw = mali_pm_os_resume_on_hibernation, + .poweroff = mali_pm_os_resume_on_hibernation, + .restore = mali_pm_os_resume_on_hibernation, + }, +}; +#endif + +static struct platform_driver mali_plat_driver = { + .probe = mali_pm_probe, + .remove = mali_pm_remove, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) + .suspend = mali_pm_os_suspend, + .resume = mali_pm_os_resume, + .pm = &mali_pm_operations, +#endif + + .driver = { + .name = "mali_dev", + .owner = THIS_MODULE, + .bus = &platform_bus_type, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) + .pm = &mali_dev_pm_ops, +#endif + }, +}; + +#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", + .id = 0, + .dev.release = _mali_release_pm +}; + +/** This function is called when platform device is unregistered. This function + * is necessary when the platform device is unregistered. + */ +static void _mali_release_pm(struct device *device) +{ + MALI_DEBUG_PRINT(4, ("OSPMM: MALI Platform device removed\n" )); +} + +#if MALI_POWER_MGMT_TEST_SUITE +#if MALI_PMM_INTERNAL_TESTING +void mali_is_pmu_present(void) +{ + int temp = 0; + temp = pmu_get_power_up_down_info(); + if (4095 == temp) + { + is_mali_pmu_present = 0; + } + else + { + is_mali_pmu_present = 1; + } + +} +#endif /* MALI_PMM_INTERNAL_TESTING */ +#endif /* MALI_POWER_MGMT_TEST_SUITE */ +#endif /* MALI_LICENSE_IS_GPL */ + +#if MALI_LICENSE_IS_GPL + +static int mali_wait_for_power_management_policy_event(void) +{ + int err = 0; + for (; ;) + { + set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) + { + err = -EINTR; + break; + } + if (is_wake_up_needed == 1) + { + break; + } + schedule(); + } + __set_current_state(TASK_RUNNING); + is_wake_up_needed =0; + return err; +} + +/** This function is invoked when mali device is suspended + */ +int mali_device_suspend(unsigned int event_id, struct task_struct **pwr_mgmt_thread) +{ + int err = 0; + _mali_uk_pmm_message_s event = { + NULL, + event_id, + timeout_fired}; + *pwr_mgmt_thread = current; + MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being suspended\n" )); + _mali_ukk_pmm_event_message(&event); + err = mali_wait_for_power_management_policy_event(); + return err; +} + +/** This function is called when Operating system wants to power down + * the mali GPU device. + */ +static int mali_pm_suspend(struct device *dev) +{ + int err = 0; + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + if ((mali_device_state == _MALI_DEVICE_SUSPEND) +#ifdef CONFIG_HAS_EARLYSUSPEND + || mali_device_state == (_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) +#else + ) +#endif /* CONFIG_HAS_EARLYSUSPEND */ + { + _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); + return err; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state) +#else +static int mali_pm_os_suspend(struct device *dev) +#endif +{ + int err = 0; + err = mali_pm_suspend(NULL); + return err; +} +#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; + switch (event) + { + case PM_SUSPEND_PREPARE: + err = mali_pm_suspend(NULL); + break; + default: + break; + } + return 0; +} +#endif /* CONFIG_HAS_EARLYSUSPEND */ +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ + +/** This function is called when mali GPU device is to be resumed. + */ +int mali_device_resume(unsigned int event_id, struct task_struct **pwr_mgmt_thread) +{ + int err = 0; + _mali_uk_pmm_message_s event = { + NULL, + event_id, + timeout_fired}; + *pwr_mgmt_thread = current; + 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" )); + err = mali_wait_for_power_management_policy_event(); + return err; +} + +/** This function is called when mali GPU device is to be resumed + */ + +static int mali_pm_resume(struct device *dev) +{ + int err = 0; + _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 err; + } + err = mali_device_resume(MALI_PMM_EVENT_OS_POWER_UP, &pm_thread); + mali_device_state = _MALI_DEVICE_RESUME; + mali_dvfs_device_state = _MALI_DEVICE_RESUME; + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return err; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +static int mali_pm_os_resume(struct platform_device *pdev) +#else +static int mali_pm_os_resume(struct device *dev) +#endif +{ + int err = 0; + err = mali_pm_resume(NULL); + return err; +} + +static int mali_pm_os_suspend_on_hibernation(struct device *dev) +{ + int err = 0; + err = mali_pm_suspend(NULL); + return err; +} + +static int mali_pm_os_resume_on_hibernation(struct device *dev) +{ + int err = 0; + err = mali_pm_resume(NULL); + return err; +} + +#ifdef CONFIG_PM_RUNTIME +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON +/** This function is called when runtime suspend of mali device is required. + */ +static int mali_device_runtime_suspend(struct device *dev) +{ + MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time suspended \n" )); + return 0; +} + +/** This function is called when runtime resume of mali device is required. + */ +static int mali_device_runtime_resume(struct device *dev) +{ + MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time Resumed \n" )); + return 0; +} +#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_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_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 + * which power management operations are supported for + * mali device. + */ +static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) +{ + char *str = buf; +#if !MALI_POWER_MGMT_TEST_SUITE + int pm_counter = 0; + for (pm_counter = 0; pm_counter<_MALI_MAX_DEBUG_OPERATIONS; pm_counter++) + { + str += sprintf(str, "%s ", mali_states[pm_counter]); + } +#else + str += sprintf(str, "%d ",pwr_mgmt_status_reg); +#endif + if (str != buf) + { + *(str-1) = '\n'; + } + return (str-buf); +} + +/** This function is called when user wants to suspend the mali GPU device in order + * to simulate the power up and power down events. + */ +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; + pwr_mgmt_status_reg = 0; +#if MALI_PMM_INTERNAL_TESTING + mali_is_pmu_present(); +#endif /* MALI_PMM_INTERNAL_TESTING */ + +#endif + if (!strncmp(buf,mali_states[_MALI_DEVICE_SUSPEND],strlen(mali_states[_MALI_DEVICE_SUSPEND]))) + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI suspend Power operation is scheduled\n" )); + err = mali_pm_suspend(NULL); + } + +#if MALI_POWER_MGMT_TEST_SUITE + else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES]))) + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Device get number of registerd cores\n" )); + pwr_mgmt_status_reg = _mali_pmm_cores_list(); + return count; + } + else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT]))) + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI timeout event recording is enabled\n" )); + mali_timeout_event_recording_on = 1; + } + else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS]))) + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Job scheduling events recording is enabled\n" )); + mali_job_scheduling_events_recording_on = 1; + } +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + + else if (!strncmp(buf,mali_states[_MALI_DEVICE_RESUME],strlen(mali_states[_MALI_DEVICE_RESUME]))) + { + 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" )); + err = mali_dev_pause(); +#if MALI_POWER_MGMT_TEST_SUITE + test_flag_dvfs = 1; +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + } + else if (!strncmp(buf,mali_states[_MALI_DVFS_RESUME_EVENT],strlen(mali_states[_MALI_DVFS_RESUME_EVENT]))) + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Resume Power operation is scheduled\n" )); + err = mali_dev_resume(); +#if MALI_POWER_MGMT_TEST_SUITE + test_flag_dvfs = 1; +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + } + else + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: Invalid Power Mode Operation selected\n" )); + } +#if MALI_POWER_MGMT_TEST_SUITE + if (test_flag_dvfs == 1) + { + if (err) + { + pwr_mgmt_status_reg = 2; + } + else + { + pwr_mgmt_status_reg = 1; + } + } + else + { +#if MALI_PMM_INTERNAL_TESTING + if (1 == is_mali_pmu_present) + { +#endif /* MALI_PMM_INTERNAL_TESTING */ + pwr_mgmt_status_reg = pmu_get_power_up_down_info(); +#if MALI_PMM_INTERNAL_TESTING + } +#endif /* MALI_PMM_INTERNAL_TESTING */ + } +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + return count; +} + +/* Device attribute file */ +static DEVICE_ATTR(file, 0644, show_file, store_file); +#endif /* CONFIG_PM_DEBUG */ + +static int mali_pm_remove(struct platform_device *pdev) +{ +#ifdef CONFIG_PM_DEBUG + device_remove_file(&mali_gpu_device.dev, &dev_attr_file); +#endif /* CONFIG_PM_DEBUG */ +#ifdef CONFIG_PM_RUNTIME +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + pm_runtime_disable(&pdev->dev); +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ + return 0; +} + +/** This function is called when the device is probed */ +static int mali_pm_probe(struct platform_device *pdev) +{ +#ifdef CONFIG_PM_DEBUG + int err; + err = device_create_file(&mali_gpu_device.dev, &dev_attr_file); + if (err) + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: Error in creating device file\n" )); + } +#endif /* CONFIG_PM_DEBUG */ + return 0; +} + +/** This function is called when Mali GPU device is initialized + */ +int _mali_dev_platform_register(void) +{ + int err; +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + set_mali_parent_power_domain(&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) + { + 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 + { + _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); + } + } + return err; +} + +/** This function is called when Mali GPU device is unloaded + */ +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); +} + +#endif /* MALI_LICENSE_IS_GPL */ +#endif /* CONFIG_PM */ +#endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h b/drivers/gpu/arm/mali/linux/mali_kernel_pm.h new file mode 100644 index 00000000000..db910102d76 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_PM_H__ +#define __MALI_KERNEL_PM_H__ + +#ifdef USING_MALI_PMM +int _mali_dev_platform_register(void); +void _mali_dev_platform_unregister(void); +#endif /* USING_MALI_PMM */ + +#endif /* __MALI_KERNEL_PM_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm.h b/drivers/gpu/arm/mali/linux/mali_linux_pm.h new file mode 100644 index 00000000000..5871de9dfbf --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm.h @@ -0,0 +1,58 @@ + +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_LINUX_PM_H__ +#define __MALI_LINUX_PM_H__ + +#if USING_MALI_PMM + +#ifdef CONFIG_PM +/* Number of power states supported for making power up and down */ +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_RESUME_EVENT, /* DVFS Resume event */ + _MALI_MAX_DEBUG_OPERATIONS, +} _mali_device_dvfs_events; + + +extern _mali_device_power_states mali_device_state; +extern _mali_device_power_states mali_dvfs_device_state; +extern _mali_osk_lock_t *lock; +extern short is_wake_up_needed; +extern int timeout_fired; +extern struct platform_device mali_gpu_device; + +/* dvfs pm thread */ +extern struct task_struct *dvfs_pm_thread; + +/* Power management thread */ +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); + +#endif /* CONFIG_PM */ +#endif /* USING_MALI_PMM */ +#endif /* __MALI_LINUX_PM_H___ */ diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h new file mode 100644 index 00000000000..0def7ab77dc --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __MALI_LINUX_PM_TESTSUITE_H__ +#define __MALI_LINUX_PM_TESTSUITE_H__ + +#if USING_MALI_PMM +#if MALI_POWER_MGMT_TEST_SUITE +#ifdef CONFIG_PM +#define MALI_PMM_INTERNAL_TESTING 1 + +typedef enum +{ + _MALI_DEVICE_PMM_TIMEOUT_EVENT, + _MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS, + _MALI_DEVICE_PMM_REGISTERED_CORES, + _MALI_DEVICE_MAX_PMM_EVENTS + +} _mali_device_pmm_recording_events; + +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 */ +#endif /* USING_MALI_PMM */ +#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */ + + diff --git a/drivers/gpu/arm/mali/linux/mali_osk_atomics.c b/drivers/gpu/arm/mali/linux/mali_osk_atomics.c new file mode 100644 index 00000000000..05831c54272 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_atomics.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_atomics.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include +#include "mali_kernel_common.h" + +void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom ) +{ + atomic_dec((atomic_t *)&atom->u.val); +} + +u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom ) +{ + return atomic_dec_return((atomic_t *)&atom->u.val); +} + +void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom ) +{ + atomic_inc((atomic_t *)&atom->u.val); +} + +u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom ) +{ + return atomic_inc_return((atomic_t *)&atom->u.val); +} + +_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val ) +{ + MALI_CHECK_NON_NULL(atom, _MALI_OSK_ERR_INVALID_ARGS); + atomic_set((atomic_t *)&atom->u.val, val); + return _MALI_OSK_ERR_OK; +} + +u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom ) +{ + return atomic_read((atomic_t *)&atom->u.val); +} + +void _mali_osk_atomic_term( _mali_osk_atomic_t *atom ) +{ + MALI_IGNORE(atom); +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c new file mode 100644 index 00000000000..7297218b9b6 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mali_osk.h" +#include "mali_ukk.h" +#include "mali_kernel_common.h" + +/** + * @file mali_osk_specific.c + * Implementation of per-OS Kernel level specifics + */ + +_mali_osk_errcode_t _mali_osk_specific_indirect_mmap( _mali_uk_mem_mmap_s *args ) +{ + /* args->ctx ignored here; args->ukk_private required instead */ + /* we need to lock the mmap semaphore before calling the do_mmap function */ + down_write(¤t->mm->mmap_sem); + + args->mapping = (void __user *)do_mmap( + (struct file *)args->ukk_private, + 0, /* start mapping from any address after NULL */ + args->size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + args->phys_addr + ); + + /* and unlock it after the call */ + up_write(¤t->mm->mmap_sem); + + /* No cookie required here */ + args->cookie = 0; + /* uku_private meaningless, so zero */ + args->uku_private = NULL; + + if ( (NULL == args->mapping) || IS_ERR((void *)args->mapping) ) + { + return _MALI_OSK_ERR_FAULT; + } + + /* Success */ + return _MALI_OSK_ERR_OK; +} + + +_mali_osk_errcode_t _mali_osk_specific_indirect_munmap( _mali_uk_mem_munmap_s *args ) +{ + /* args->ctx and args->cookie ignored here */ + + if ((NULL != current) && (NULL != current->mm)) + { + /* remove mapping of mali memory from the process' view */ + /* lock mmap semaphore before call */ + /* lock mmap_sem before calling do_munmap */ + down_write(¤t->mm->mmap_sem); + do_munmap( + current->mm, + (unsigned long)args->mapping, + args->size + ); + /* and unlock after call */ + up_write(¤t->mm->mmap_sem); + MALI_DEBUG_PRINT(5, ("unmapped\n")); + } + else + { + MALI_DEBUG_PRINT(2, ("Freeing of a big block while no user process attached, assuming crash cleanup in progress\n")); + } + + return _MALI_OSK_ERR_OK; /* always succeeds */ +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h new file mode 100644 index 00000000000..41cb462e8e5 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_specific.h + * Defines per-OS Kernel level specifics, such as unusual workarounds for + * certain OSs. + */ + +#ifndef __MALI_OSK_INDIR_MMAP_H__ +#define __MALI_OSK_INDIR_MMAP_H__ + +#include "mali_uk_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Linux specific means for calling _mali_ukk_mem_mmap/munmap + * + * The presence of _MALI_OSK_SPECIFIC_INDIRECT_MMAP indicates that + * _mali_osk_specific_indirect_mmap and _mali_osk_specific_indirect_munmap + * should be used instead of _mali_ukk_mem_mmap/_mali_ukk_mem_munmap. + * + * The arguments are the same as _mali_ukk_mem_mmap/_mali_ukk_mem_munmap. + * + * In ALL operating system other than Linux, it is expected that common code + * should be able to call _mali_ukk_mem_mmap/_mali_ukk_mem_munmap directly. + * Such systems should NOT define _MALI_OSK_SPECIFIC_INDIRECT_MMAP. + */ +_mali_osk_errcode_t _mali_osk_specific_indirect_mmap( _mali_uk_mem_mmap_s *args ); +_mali_osk_errcode_t _mali_osk_specific_indirect_munmap( _mali_uk_mem_munmap_s *args ); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_OSK_INDIR_MMAP_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_osk_irq.c b/drivers/gpu/arm/mali/linux/mali_osk_irq.c new file mode 100644 index 00000000000..0343063f7b6 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_irq.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_irq.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include /* For memory allocation */ + +#include "mali_osk.h" +#include "mali_kernel_core.h" +#include "mali_kernel_common.h" +#include "linux/interrupt.h" + +typedef struct _mali_osk_irq_t_struct +{ + u32 irqnum; + void *data; + _mali_osk_irq_uhandler_t uhandler; + _mali_osk_irq_bhandler_t bhandler; + struct work_struct work_queue_irq_handle; /* Workqueue for the bottom half of the IRQ-handling. This job is activated when this core gets an IRQ.*/ +} mali_osk_irq_object_t; + +typedef void (*workqueue_func_t)(void *); +typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *); +static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/ + +#if defined(INIT_DELAYED_WORK) +static void irq_handler_bottom_half ( struct work_struct *work ); +#else +static void irq_handler_bottom_half ( void * input ); +#endif + +/** + * Linux kernel version has marked SA_SHIRQ as deprecated, IRQF_SHARED should be used. + * This is to handle older kernels which haven't done this swap. + */ +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif /* IRQF_SHARED */ + +_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description ) +{ + mali_osk_irq_object_t *irq_object; + + irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); + if (NULL == irq_object) return NULL; + + /* workqueue API changed in 2.6.20, support both versions: */ +#if defined(INIT_DELAYED_WORK) + /* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */ + INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half); +#else + /* Old syntax: INIT_WORK( struct work_struct *work, void (*function)(void *), void *data) */ + INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half, irq_object); +#endif /* defined(INIT_DELAYED_WORK) */ + + if (-1 == irqnum) + { + /* Probe for IRQ */ + if ( (NULL != trigger_func) && (NULL != ack_func) ) + { + unsigned long probe_count = 3; + _mali_osk_errcode_t err; + int irq; + + MALI_DEBUG_PRINT(2, ("Probing for irq\n")); + + do + { + unsigned long mask; + + mask = probe_irq_on(); + trigger_func(data); + + _mali_osk_time_ubusydelay(5); + + irq = probe_irq_off(mask); + err = ack_func(data); + } + while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--); + + if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1; + else irqnum = irq; + } + else irqnum = -1; /* no probe functions, fault */ + + if (-1 != irqnum) + { + /* found an irq */ + MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum)); + } + else + { + MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); + } + } + + /* Is this a real IRQ handler we need? */ + if (!mali_benchmark && irqnum != _MALI_OSK_IRQ_NUMBER_FAKE) { + if (-1 == irqnum) + { + MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); + kfree(irq_object); + return NULL; + } + + if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object)) + { + MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description)); + kfree(irq_object); + return NULL; + } + } + + irq_object->irqnum = irqnum; + irq_object->uhandler = uhandler; + irq_object->bhandler = bhandler; + irq_object->data = data; + + return irq_object; +} + +void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) +{ + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + schedule_work(&irq_object->work_queue_irq_handle); +} + +void _mali_osk_irq_term( _mali_osk_irq_t *irq ) +{ + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + if (!mali_benchmark) + { + free_irq(irq_object->irqnum, irq_object); + } + kfree(irq_object); + flush_scheduled_work(); +} + + +/** This function is called directly in interrupt context from the OS just after + * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel. + * It is registered one of these function for each mali core. When an interrupt + * arrives this function will be called equal times as registered mali cores. + * That means that we only check one mali core in one function call, and the + * core we check for each turn is given by the \a dev_id variable. + * If we detect an pending interrupt on the given core, we mask the interrupt + * out by settging the core's IRQ_MASK register to zero. + * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority + * work queue job. + */ +static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/ +{ + mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id; + + if (irq_object->uhandler(irq_object->data) == _MALI_OSK_ERR_OK) + { + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/* Is executed when an interrupt occur on one core */ +/* workqueue API changed in 2.6.20, support both versions: */ +#if defined(INIT_DELAYED_WORK) +static void irq_handler_bottom_half ( struct work_struct *work ) +#else +static void irq_handler_bottom_half ( void * input ) +#endif +{ + mali_osk_irq_object_t *irq_object; + +#if defined(INIT_DELAYED_WORK) + irq_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_irq_object_t, work_queue_irq_handle); +#else + if ( NULL == input ) + { + MALI_PRINT_ERROR(("IRQ: Null pointer! Illegal!")); + return; /* Error */ + } + irq_object = (mali_osk_irq_object_t *) input; +#endif + + irq_object->bhandler(irq_object->data); +} + diff --git a/drivers/gpu/arm/mali/linux/mali_osk_locks.c b/drivers/gpu/arm/mali/linux/mali_osk_locks.c new file mode 100644 index 00000000000..a896c62c023 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_locks.c @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_locks.c + * Implemenation of the OS abstraction layer for the kernel device driver + */ + +/* needed to detect kernel version specific code */ +#include + +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#endif + +#include +#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 +{ + _MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */ + _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use up()/down_interruptable() */ + _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use up()/down() */ + _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {up,down}{read,write}() */ + + /* Linux supports, but we do not support: + * Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off + */ + + /* Linux does not support: + * One-locks, of any sort - no optimization for this fact will be made. + */ + +} _mali_osk_internal_locktype; + +struct _mali_osk_lock_t_struct +{ + _mali_osk_internal_locktype type; + union + { + spinlock_t spinlock; + struct semaphore sema; + struct rw_semaphore rw_sema; + } obj; + 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 */ +}; + +_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order ) +{ + _mali_osk_lock_t *lock = NULL; + + /* Validate parameters: */ + /* Flags acceptable */ + MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE + | _MALI_OSK_LOCKFLAG_READERWRITER + | _MALI_OSK_LOCKFLAG_ORDERED + | _MALI_OSK_LOCKFLAG_ONELOCK)) ); + /* Spinlocks are always non-interruptable */ + MALI_DEBUG_ASSERT( ((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) + || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK) ); + /* Parameter initial SBZ - for future expansion */ + MALI_DEBUG_ASSERT( 0 == initial ); + + lock = kmalloc(sizeof(_mali_osk_lock_t), GFP_KERNEL); + + if ( NULL == lock ) + { + return lock; + } + + /* Determine type of mutex: */ + /* defaults to interruptable mutex if no flags are specified */ + + if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK) ) + { + /* Non-interruptable Spinlocks override all others */ + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN; + spin_lock_init( &lock->obj.spinlock ); + } + else if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) + && (flags & _MALI_OSK_LOCKFLAG_READERWRITER) ) + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW; + init_rwsem( &lock->obj.rw_sema ); + } + else + { + /* Usual mutex types */ + if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) ) + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT; + } + else + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX; + } + + /* Initially unlocked */ + LOCK_INIT( &lock->obj.sema ); + } + + MALI_DEBUG_CODE( + /* Debug tracking of flags */ + lock->orig_flags = flags; + lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF; + ); /* MALI_DEBUG_CODE */ + + return lock; +} + +_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( lock ); + + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || _MALI_OSK_LOCKMODE_RO == mode ); + + /* Only allow RO locks when the initial object was a Reader/Writer lock + * Since information is lost on the internal locktype, we use the original + * information, which is only stored when built for DEBUG */ + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); + + switch ( lock->type ) + { + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: + spin_lock(&lock->obj.spinlock); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: + if ( down_interruptible(&lock->obj.sema) ) + { + err = _MALI_OSK_ERR_RESTARTSYSCALL; + } + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT: + down(&lock->obj.sema); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW: + if (mode == _MALI_OSK_LOCKMODE_RO) + { + down_read(&lock->obj.rw_sema); + } + else + { + down_write(&lock->obj.rw_sema); + } + break; + + default: + /* Reaching here indicates a programming error, so you will not get here + * on non-DEBUG builds */ + MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) ); + 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; +} + +void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) +{ + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( lock ); + + MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode + || _MALI_OSK_LOCKMODE_RO == mode ); + + /* Only allow RO locks when the initial object was a Reader/Writer lock + * Since information is lost on the internal locktype, we use the original + * information, which is only stored when built for DEBUG */ + 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: + spin_unlock(&lock->obj.spinlock); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: + /* FALLTHROUGH */ + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT: + up(&lock->obj.sema); + break; + + case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW: + if (mode == _MALI_OSK_LOCKMODE_RO) + { + up_read(&lock->obj.rw_sema); + } + else + { + up_write(&lock->obj.rw_sema); + } + break; + + default: + /* Reaching here indicates a programming error, so you will not get here + * on non-DEBUG builds */ + MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) ); + break; + } +} + +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 new file mode 100644 index 00000000000..a3c812f7cf9 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c @@ -0,0 +1,485 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_low_level_mem.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +/* needed to detect kernel version specific code */ +#include + +#include +#include +#include +#include +#include +#include + +#include "mali_osk.h" +#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */ +#include "mali_kernel_common.h" +#include "mali_kernel_linux.h" + +static void mali_kernel_memory_vma_open(struct vm_area_struct * vma); +static void mali_kernel_memory_vma_close(struct vm_area_struct * vma); + + +#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 +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; + u32 cookie; +} mali_vma_usage_tracker; + + +/* Linked list structure to hold details of all OS allocations in a particular + * mapping + */ +struct AllocationList +{ + struct AllocationList *next; + u32 offset; + u32 physaddr; +}; + +typedef struct AllocationList AllocationList; + +/* Private structure to store details of a mapping region returned + * from _mali_osk_mem_mapregion_init + */ +struct MappingInfo +{ + struct vm_area_struct *vma; + struct AllocationList *list; +}; + +typedef struct MappingInfo MappingInfo; + +static struct vm_operations_struct mali_kernel_vm_ops = +{ + .open = mali_kernel_memory_vma_open, + .close = mali_kernel_memory_vma_close, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + .fault = mali_kernel_memory_cpu_page_fault_handler +#else + .nopfn = mali_kernel_memory_cpu_page_fault_handler +#endif +}; + + +#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 +static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + void __user * address; + address = vmf->virtual_address; +#endif + /* + * We always fail the call since all memory is pre-faulted when assigned to the process. + * Only the Mali cores can use page faults to extend buffers. + */ + + MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n")); + MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void*)address)); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + return VM_FAULT_SIGBUS; +#else + return NOPFN_SIGBUS; +#endif +} + +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)); + + vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; + vma_usage_tracker->references++; + + return; +} + +static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) +{ + _mali_uk_mem_munmap_s args = {0, }; + mali_memory_allocation * descriptor; + mali_vma_usage_tracker * vma_usage_tracker; + MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma)); + + vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; + + BUG_ON(!vma_usage_tracker); + BUG_ON(0 == vma_usage_tracker->references); + + vma_usage_tracker->references--; + + if (0 != vma_usage_tracker->references) + { + MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references)); + return; + } + + /** @note args->context unused, initialized to 0. + * Instead, we use the memory_session from the cookie */ + + descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie; + + args.cookie = (u32)descriptor; + args.mapping = descriptor->mapping; + args.size = descriptor->size; + + _mali_ukk_mem_munmap( &args ); + + /* vma_usage_tracker is free()d by _mali_osk_mem_mapregion_term(). + * In the case of the memory engine, it is called as the release function that has been registered with the engine*/ +} + + +void _mali_osk_mem_barrier( void ) +{ + mb(); +} + +mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description ) +{ + return (mali_io_address)ioremap_nocache(phys, size); +} + +void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt ) +{ + iounmap((void*)virt); +} + +mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) +{ + void * virt; + MALI_DEBUG_ASSERT_POINTER( phys ); + MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); + MALI_DEBUG_ASSERT( 0 != size ); + + /* dma_alloc_* uses a limited region of address space. On most arch/marchs + * 2 to 14 MiB is available. This should be enough for the page tables, which + * currently is the only user of this function. */ + virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA32 ); + + MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys)); + + 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")); + return 0; + } + + MALI_DEBUG_ASSERT( 0 == (*phys & ~_MALI_OSK_CPU_PAGE_MASK) ); + + return (mali_io_address)virt; +} + +void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt ) +{ + MALI_DEBUG_ASSERT_POINTER( (void*)virt ); + MALI_DEBUG_ASSERT( 0 != size ); + MALI_DEBUG_ASSERT( 0 == (phys & ( (1 << PAGE_SHIFT) - 1 )) ); + + dma_free_coherent(NULL, size, virt, phys); +} + +_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); +} + +void inline _mali_osk_mem_unreqregion( u32 phys, u32 size ) +{ + release_mem_region(phys, size); +} + +u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 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); +} + +void _mali_osk_cache_flushall( void ) +{ + /** @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 ) +{ + wmb(); +} + +_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor ) +{ + struct vm_area_struct *vma; + mali_vma_usage_tracker * vma_usage_tracker; + MappingInfo *mappingInfo; + + if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + vma = (struct vm_area_struct*)descriptor->process_addr_mapping_info; + + if (NULL == vma ) return _MALI_OSK_ERR_FAULT; + + /* Re-write the process_addr_mapping_info */ + mappingInfo = _mali_osk_calloc( 1, sizeof(MappingInfo) ); + + if ( NULL == mappingInfo ) return _MALI_OSK_ERR_FAULT; + + vma_usage_tracker = _mali_osk_calloc( 1, sizeof(mali_vma_usage_tracker) ); + + if (NULL == vma_usage_tracker) + { + MALI_DEBUG_PRINT(2, ("Failed to allocate memory to track memory usage\n")); + _mali_osk_free( mappingInfo ); + return _MALI_OSK_ERR_FAULT; + } + + mappingInfo->vma = vma; + descriptor->process_addr_mapping_info = mappingInfo; + + /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */ + descriptor->mapping = (void __user*)vma->vm_start; + /* list member is already NULL */ + + /* + set some bits which indicate that: + The memory is IO memory, meaning that no paging is to be performed and the memory should not be included in crash dumps + The memory is reserved, meaning that it's present and can never be paged out (see also previous entry) + */ + vma->vm_flags |= VM_IO; + vma->vm_flags |= VM_RESERVED; + + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */ + + vma_usage_tracker->references = 1; /* set initial reference count to be 1 as vma_open won't be called for the first mmap call */ + vma_usage_tracker->cookie = (u32)descriptor; /* cookie for munmap */ + + vma->vm_private_data = vma_usage_tracker; + + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor ) +{ + struct vm_area_struct* vma; + mali_vma_usage_tracker * vma_usage_tracker; + MappingInfo *mappingInfo; + + if (NULL == descriptor) return; + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; + + MALI_DEBUG_ASSERT_POINTER( mappingInfo ); + + /* Linux does the right thing as part of munmap to remove the mapping + * All that remains is that we remove the vma_usage_tracker setup in init() */ + vma = mappingInfo->vma; + + MALI_DEBUG_ASSERT_POINTER( vma ); + + /* ASSERT that there are no allocations on the list. Unmap should've been + * called on all OS allocations. */ + MALI_DEBUG_ASSERT( NULL == mappingInfo->list ); + + vma_usage_tracker = vma->vm_private_data; + + /* We only get called if mem_mapregion_init succeeded */ + _mali_osk_free(vma_usage_tracker); + + _mali_osk_free( mappingInfo ); + return; +} + +_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size ) +{ + struct vm_area_struct *vma; + MappingInfo *mappingInfo; + + if (NULL == descriptor) return _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_ASSERT_POINTER( phys_addr ); + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); + + MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK)); + + 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; + } + + mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; + + MALI_DEBUG_ASSERT_POINTER( mappingInfo ); + + vma = mappingInfo->vma; + + 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)); + + if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr ) + { + _mali_osk_errcode_t ret; + 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; + } + + { + 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; + } + + 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 ); + 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; + + /* Write out new physical address on success */ + *phys_addr = linux_phys_addr; + + return ret; + } + + /* Otherwise, Use the supplied physical address */ + + /* ASSERT that supplied phys_addr is page aligned */ + MALI_DEBUG_ASSERT( 0 == ((*phys_addr) & ~_MALI_OSK_CPU_PAGE_MASK) ); + + return ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, *phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK; + +} + +void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags ) +{ + MappingInfo *mappingInfo; + + if (NULL == descriptor) return; + + MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) ); + + MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) ); + + MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) ); + + 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", + size, descriptor->mapping, offset)); + 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) + { + /* 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; + } + + { + 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 ); + } + + /* 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; + } + } + + /* Linux does the right thing as part of munmap to remove the mapping */ + + return; +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c new file mode 100644 index 00000000000..67319db4335 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_mali.c + * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver + */ +#include +#include + +#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 "arch/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_SUCCESS; +} + +/* is called from mali_kernel_deconstructor in common code */ +void _mali_osk_term( void ) +{ + terminate_kernel_device(); +} + +_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources ) +{ + *num_resources = sizeof(arch_configuration) / sizeof(arch_configuration[0]); + *arch_config = arch_configuration; + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources ) +{ + /* Nothing to do */ +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_math.c b/drivers/gpu/arm/mali/linux/mali_osk_math.c new file mode 100644 index 00000000000..3e62e519cba --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_math.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_math.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include + +u32 inline _mali_osk_clz( u32 input ) +{ + return 32-fls(input); +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_memory.c b/drivers/gpu/arm/mali/linux/mali_osk_memory.c new file mode 100644 index 00000000000..b1a22abaa27 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_memory.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_memory.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include + +void inline *_mali_osk_calloc( u32 n, u32 size ) +{ + return kcalloc(n, size, GFP_KERNEL); +} + +void inline *_mali_osk_malloc( u32 size ) +{ + return kmalloc(size, GFP_KERNEL); +} + +void inline _mali_osk_free( void *ptr ) +{ + kfree(ptr); +} + +void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len ) +{ + return memcpy(dst, src, len); +} + +void inline *_mali_osk_memset( void *s, u32 c, u32 n ) +{ + return memset(s, c, n); +} + +mali_bool _mali_osk_mem_check_allocated( u32 max_allocated ) +{ + /* No need to prevent an out-of-memory dialogue appearing on Linux, + * so we always return MALI_TRUE. + */ + return MALI_TRUE; +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_misc.c b/drivers/gpu/arm/mali/linux/mali_osk_misc.c new file mode 100644 index 00000000000..239d9ffae41 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_misc.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_misc.c + * Implementation of the OS abstraction layer for the kernel device driver + */ +#include +#include +#include +#include +#include +#include "mali_osk.h" + +void _mali_osk_dbgmsg( const char *fmt, ... ) +{ + va_list args; + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); +} + +void _mali_osk_abort(void) +{ + /* make a simple fault by dereferencing a NULL pointer */ + *(int *)0 = 0; +} + +void _mali_osk_break(void) +{ + _mali_osk_abort(); +} + +u32 _mali_osk_get_pid(void) +{ + /* Thread group ID is the process ID on Linux */ + return (u32)current->tgid; +} + +u32 _mali_osk_get_tid(void) +{ + /* pid is actually identifying the thread on Linux */ + return (u32)current->pid; +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_notification.c b/drivers/gpu/arm/mali/linux/mali_osk_notification.c new file mode 100644 index 00000000000..8017d3ca587 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_notification.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_notification.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include "mali_kernel_common.h" + +/* needed to detect kernel version specific code */ +#include + +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#include +#else /* pre 2.6.26 the file was in the arch specific location */ +#include +#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. + * It also contains a wait queue of exclusive waiters blocked in the ioctl + * When a new notification is posted a single thread is resumed. + */ +struct _mali_osk_notification_queue_t_struct +{ + struct semaphore mutex; /**< Mutex protecting the list */ + wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */ + struct list_head head; /**< List of notifications waiting to be picked up */ +}; + +typedef struct _mali_osk_notification_wrapper_t_struct +{ + struct list_head list; /**< Internal linked list variable */ + _mali_osk_notification_t data; /**< Notification data */ +} _mali_osk_notification_wrapper_t; + +_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void ) +{ + _mali_osk_notification_queue_t * result; + + result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL); + if (NULL == result) return NULL; + + LOCK_INIT(&result->mutex); + init_waitqueue_head(&result->receive_queue); + INIT_LIST_HEAD(&result->head); + + return result; +} + +_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 ); + if (NULL == notification) + { + MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n")); + return NULL; + } + + /* Init the list */ + INIT_LIST_HEAD(¬ification->list); + + /* allocate memory for the buffer requested */ + 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; + } + /* set up the non-allocating fields */ + notification->data.notification_type = type; + notification->data.result_buffer_size = size; + + /* all ok */ + return &(notification->data); +} + +void _mali_osk_notification_delete( _mali_osk_notification_t *object ) +{ + _mali_osk_notification_wrapper_t *notification; + MALI_DEBUG_ASSERT_POINTER( object ); + + notification = container_of( object, _mali_osk_notification_wrapper_t, data ); + + /* Remove from the list */ + list_del(¬ification->list); + /* Free the buffer */ + kfree(notification->data.result_buffer); + /* Free the container */ + kfree(notification); +} + +void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue ) +{ + MALI_DEBUG_ASSERT_POINTER( queue ); + + /* not much to do, just free the memory */ + kfree(queue); +} + +void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object ) +{ + _mali_osk_notification_wrapper_t *notification; + MALI_DEBUG_ASSERT_POINTER( queue ); + MALI_DEBUG_ASSERT_POINTER( object ); + + notification = container_of( object, _mali_osk_notification_wrapper_t, data ); + + /* lock queue access */ + down(&queue->mutex); + /* add to list */ + list_add_tail(¬ification->list, &queue->head); + /* unlock the queue */ + up(&queue->mutex); + + /* and wake up one possible exclusive waiter */ + wake_up(&queue->receive_queue); +} + +_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, u32 timeout, _mali_osk_notification_t **result ) +{ + _mali_osk_notification_wrapper_t *wrapper_object; + /* check input */ + MALI_DEBUG_ASSERT_POINTER( queue ); + MALI_DEBUG_ASSERT_POINTER( result ); + + /* default result */ + *result = NULL; + + /* lock queue */ + if (down_interruptible(&queue->mutex)) return _MALI_OSK_ERR_RESTARTSYSCALL; /* handle the signal, then retry */ + + /* check for a pending notification */ + while (0 != list_empty(&queue->head)) + { + /* no notification ready, we have to wait for one */ + int schedule_result; + /* define a wait entry */ + DEFINE_WAIT(wait); + + if( timeout == 0 ) + { + /* Actually, don't wait for any time when nothing is in the queue */ + up(&queue->mutex); + return _MALI_OSK_ERR_TIMEOUT; + } + + /* prepare for exclusive wait, tag as interruptible (accept signals) */ + prepare_to_wait_exclusive(&queue->receive_queue, &wait, TASK_INTERRUPTIBLE); + + /* release the lock before waiting */ + up(&queue->mutex); + + /* if the check fails again schedule (sleep) */ + schedule_result = schedule_timeout(msecs_to_jiffies(timeout)); + + /* we're running again, wait finished (or never started) */ + finish_wait(&queue->receive_queue, &wait); + + /* check why we got scheduled */ + if (0 == schedule_result) return _MALI_OSK_ERR_TIMEOUT; /* timeout, ok, NULL will be returned */ + if (signal_pending(current)) return _MALI_OSK_ERR_RESTARTSYSCALL; /* handle the signal, then retry */ + + /* we were woken because of a new entry */ + /* lock the queue and check (with normal signal handling logic) */ + if (down_interruptible(&queue->mutex)) return _MALI_OSK_ERR_RESTARTSYSCALL; /* handle the signal, then retry */ + } + + /* + The while loop terminates when the list is non-empty and we hold the lock + Pop the head and release the lock + */ + wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list); + *result = &(wrapper_object->data); + list_del_init(&wrapper_object->list); + + up(&queue->mutex); + + return _MALI_OSK_ERR_OK; /* all ok */ +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali/linux/mali_osk_pm.c new file mode 100644 index 00000000000..60fee833098 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_pm.c @@ -0,0 +1,197 @@ +/** + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_pm.c + * Implementation of the callback functions from common power management + */ + +#include + +#ifdef CONFIG_PM_RUNTIME +#include +#endif /* CONFIG_PM_RUNTIME */ + +#include + +#include "mali_platform.h" +#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_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 */ + +#if MALI_POWER_MGMT_TEST_SUITE + +#ifdef CONFIG_PM +unsigned int mali_pmm_events_triggered_mask = 0; +#endif /* CONFIG_PM */ + +void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id mali_pmm_event) +{ +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + + switch (mali_pmm_event) + { + case MALI_PMM_EVENT_JOB_QUEUED: + if (mali_job_scheduling_events_recording_on == 1) + { + mali_pmm_events_triggered_mask |= (1<<0); + } + break; + + case MALI_PMM_EVENT_JOB_SCHEDULED: + if (mali_job_scheduling_events_recording_on == 1) + { + mali_pmm_events_triggered_mask |= (1<<1); + } + break; + + case MALI_PMM_EVENT_JOB_FINISHED: + if (mali_job_scheduling_events_recording_on == 1) + { + mali_pmm_events_triggered_mask |= (1<<2); + mali_job_scheduling_events_recording_on = 0; + pwr_mgmt_status_reg = mali_pmm_events_triggered_mask; + } + break; + + case MALI_PMM_EVENT_TIMEOUT: + if (mali_timeout_event_recording_on == 1) + { + pwr_mgmt_status_reg = (1<<3); + mali_timeout_event_recording_on = 0; + } + break; + + default: + + break; + + } +#endif /* CONFIG_PM */ + +#endif /* MALI_LICENSE_IS_GPL */ +} +#endif /* MALI_POWER_MGMT_TEST_SUITE */ + +/** This function is called when the Mali device has completed power up + * operation. + */ +void _mali_osk_pmm_power_up_done(mali_pmm_message_data data) +{ +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + is_wake_up_needed = 1; + wake_up_process(pm_thread); + MALI_DEBUG_PRINT(4, ("OSPMM: MALI OSK Power up Done\n" )); + return; +#endif /* CONFIG_PM */ +#endif /* MALI_LICENSE_IS_GPL */ +} + +/** This function is called when the Mali device has completed power down + * operation. + */ +void _mali_osk_pmm_power_down_done(mali_pmm_message_data data) +{ +#if MALI_LICENSE_IS_GPL +#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" )); + return; + +#endif /* CONFIG_PM */ +#endif /* MALI_LICENSE_IS_GPL */ +} + +/** This function is invoked when mali device is idle. +*/ +_mali_osk_errcode_t _mali_osk_pmm_dev_idle(void) +{ + _mali_osk_errcode_t err = 0; +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM_RUNTIME +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + + err = pm_runtime_put_sync(&(mali_gpu_device.dev)); + if(err) + { + MALI_DEBUG_PRINT(4, ("OSPMM: Error in _mali_osk_pmm_dev_idle\n" )); + } +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ +#endif /* MALI_LICENSE_IS_GPL */ + return err; +} + +/** This funtion is invoked when mali device needs to be activated. +*/ +void _mali_osk_pmm_dev_activate(void) +{ + +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM_RUNTIME +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + int err = 0; + if(is_runtime == 0) + { + pm_suspend_ignore_children(&(mali_gpu_device.dev), true); + pm_runtime_enable(&(mali_gpu_device.dev)); + pm_runtime_get_sync(&(mali_gpu_device.dev)); + is_runtime = 1; + } + else + { + err = pm_runtime_get_sync(&(mali_gpu_device.dev)); + } + if(err) + { + MALI_DEBUG_PRINT(4, ("OSPMM: Error in _mali_osk_pmm_dev_activate\n" )); + } +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ +#endif /* MALI_LICENSE_IS_GPL */ +} + +void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data) +{ +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + is_wake_up_needed = 1; + wake_up_process(dvfs_pm_thread); + MALI_DEBUG_PRINT(4, ("OSPMM: MALI OSK DVFS Operation done\n" )); + return; +#endif /* CONFIG_PM */ +#endif /* MALI_LICENSE_IS_GPL */ +} + + diff --git a/drivers/gpu/arm/mali/linux/mali_osk_specific.h b/drivers/gpu/arm/mali/linux/mali_osk_specific.h new file mode 100644 index 00000000000..6aacf17d387 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_specific.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_specific.h + * Defines per-OS Kernel level specifics, such as unusual workarounds for + * certain OSs. + */ + +#ifndef __MALI_OSK_SPECIFIC_H__ +#define __MALI_OSK_SPECIFIC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MALI_STATIC_INLINE static inline +#define MALI_NON_STATIC_INLINE inline + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_OSK_SPECIFIC_H__ */ diff --git a/drivers/gpu/arm/mali/linux/mali_osk_time.c b/drivers/gpu/arm/mali/linux/mali_osk_time.c new file mode 100644 index 00000000000..da9b8656b70 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_time.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_time.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include "mali_osk.h" +#include +#include +#include + +int _mali_osk_time_after( u32 ticka, u32 tickb ) +{ + return time_after((unsigned long)ticka, (unsigned long)tickb); +} + +u32 _mali_osk_time_mstoticks( u32 ms ) +{ + return msecs_to_jiffies(ms); +} + +u32 _mali_osk_time_tickstoms( u32 ticks ) +{ + return jiffies_to_msecs(ticks); +} + +u32 _mali_osk_time_tickcount( void ) +{ + return jiffies; +} + +void _mali_osk_time_ubusydelay( u32 usecs ) +{ + udelay(usecs); +} + +u64 _mali_osk_time_get_ns( void ) +{ + struct timespec tsval; + getnstimeofday(&tsval); + return (u64)timespec_to_ns(&tsval); +} diff --git a/drivers/gpu/arm/mali/linux/mali_osk_timers.c b/drivers/gpu/arm/mali/linux/mali_osk_timers.c new file mode 100644 index 00000000000..51f7028b1ee --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_timers.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_osk_timers.c + * Implementation of the OS abstraction layer for the kernel device driver + */ + +#include +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" + +struct _mali_osk_timer_t_struct +{ + struct timer_list timer; +}; + +typedef void (*timer_timeout_function_t)(unsigned long); + +_mali_osk_timer_t *_mali_osk_timer_init(void) +{ + _mali_osk_timer_t *t = (_mali_osk_timer_t*)kmalloc(sizeof(_mali_osk_timer_t), GFP_KERNEL); + if (NULL != t) init_timer(&t->timer); + return t; +} + +void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire ) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + tim->timer.expires = _mali_osk_time_tickcount() + ticks_to_expire; + add_timer(&(tim->timer)); +} + +void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + mod_timer(&(tim->timer), expiry_tick); +} + +void _mali_osk_timer_del( _mali_osk_timer_t *tim ) +{ + MALI_DEBUG_ASSERT_POINTER(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); + tim->timer.data = (unsigned long)data; + tim->timer.function = (timer_timeout_function_t)callback; +} + +void _mali_osk_timer_term( _mali_osk_timer_t *tim ) +{ + MALI_DEBUG_ASSERT_POINTER(tim); + kfree(tim); +} diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_core.c b/drivers/gpu/arm/mali/linux/mali_ukk_core.c new file mode 100644 index 00000000000..819977f8740 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_core.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* memort allocation functions */ +#include /* 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 get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs) +{ + _mali_uk_get_api_version_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != get_user(kargs.version, &uargs->version)) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_get_api_version(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; + if (0 != put_user(kargs.compatible, &uargs->compatible)) return -EFAULT; + + return 0; +} + +int get_system_info_size_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_size_s __user *uargs) +{ + _mali_uk_get_system_info_size_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_system_info_size(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT; + + return 0; +} + +int get_system_info_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_s __user *uargs) +{ + _mali_uk_get_system_info_s kargs; + _mali_osk_errcode_t err; + _mali_system_info *system_info_user; + _mali_system_info *system_info_kernel; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != get_user(kargs.system_info, &uargs->system_info)) return -EFAULT; + if (0 != get_user(kargs.size, &uargs->size)) return -EFAULT; + + /* A temporary kernel buffer for the system_info datastructure is passed through the system_info + * member. The ukk_private member will point to the user space destination of this buffer so + * that _mali_ukk_get_system_info() can correct the pointers in the system_info correctly + * for user space. + */ + system_info_kernel = kmalloc(kargs.size, GFP_KERNEL); + if (NULL == system_info_kernel) return -EFAULT; + + system_info_user = kargs.system_info; + kargs.system_info = system_info_kernel; + kargs.ukk_private = (u32)system_info_user; + kargs.ctx = session_data; + + err = _mali_ukk_get_system_info(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + kfree(system_info_kernel); + return map_errcode(err); + } + + if (0 != copy_to_user(system_info_user, system_info_kernel, kargs.size)) + { + kfree(system_info_kernel); + return -EFAULT; + } + + kfree(system_info_kernel); + return 0; +} + +int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs) +{ + _mali_uk_wait_for_notification_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != get_user(kargs.code.timeout, &uargs->code.timeout)) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_wait_for_notification(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if( !(_MALI_NOTIFICATION_CORE_TIMEOUT == kargs.code.type || _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS == kargs.code.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; + } + else + { + if (0 != put_user(kargs.code.type, &uargs->code.type)) return -EFAULT; + } + + return 0; +} diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_gp.c b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c new file mode 100644 index 00000000000..58ff1de5108 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* 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 gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs) +{ + _mali_uk_gp_start_job_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_gp_start_job_s))) + { + return -EFAULT; + } + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_start_job_s))) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_gp_start_job(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ + if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_gp_start_job_s))) + { + /* + * If this happens, then user space will not know that the job was actually started, + * and if we return a queued job, then user space will still think that one is still queued. + * This will typically lead to a deadlock in user space. + * This could however only happen if user space deliberately passes a user buffer which + * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user(). + * The official Mali driver will never attempt to do that, and kernel space should not be affected. + * That is why we do not bother to do a complex rollback in this very very very rare case. + */ + return -EFAULT; + } + + return 0; +} + +int gp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_abort_job_s __user *uargs) +{ + _mali_uk_gp_abort_job_s kargs; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_abort_job_s))) return -EFAULT; + + kargs.ctx = session_data; + _mali_ukk_gp_abort_job(&kargs); + + return 0; +} + + +int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs) +{ + _mali_uk_get_gp_core_version_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_gp_core_version(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + /* no known transactions to roll-back */ + + if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; + + return 0; +} + +int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs) +{ + _mali_uk_gp_suspend_response_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_suspend_response_s))) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_gp_suspend_response(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.cookie, &uargs->cookie)) return -EFAULT; + + /* no known transactions to roll-back */ + return 0; +} + +int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs) +{ + _mali_uk_get_gp_number_of_cores_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_gp_number_of_cores(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + /* no known transactions to roll-back */ + + if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT; + + return 0; +} diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_mem.c b/drivers/gpu/arm/mali/linux/mali_ukk_mem.c new file mode 100644 index 00000000000..05214b703d3 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_mem.c @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* 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 mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs) +{ + _mali_uk_init_mem_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_init_mem(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.mali_address_base, &uargs->mali_address_base)) goto mem_init_rollback; + if (0 != put_user(kargs.memory_size, &uargs->memory_size)) goto mem_init_rollback; + + return 0; + +mem_init_rollback: + { + _mali_uk_term_mem_s kargs; + kargs.ctx = session_data; + err = _mali_ukk_term_mem(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_init_mem, as a result of failing put_user(), failed\n")); + } + } + return -EFAULT; +} + +int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs) +{ + _mali_uk_term_mem_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_term_mem(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + +int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument) +{ + _mali_uk_map_external_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_map_external_mem( &uk_args ); + + if (0 != put_user(uk_args.cookie, &argument->cookie)) + { + if (_MALI_OSK_ERR_OK == err_code) + { + /* Rollback */ + _mali_uk_unmap_external_mem_s uk_args_unmap; + + uk_args_unmap.ctx = session_data; + uk_args_unmap.cookie = uk_args.cookie; + err_code = _mali_ukk_unmap_external_mem( &uk_args_unmap ); + if (_MALI_OSK_ERR_OK != err_code) + { + MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n")); + } + } + return -EFAULT; + } + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} + +int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument) +{ + _mali_uk_unmap_external_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_unmap_external_mem( &uk_args ); + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument) +{ + _mali_uk_release_ump_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_release_ump_mem( &uk_args ); + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} + +int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument) +{ + _mali_uk_attach_ump_mem_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s)) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_attach_ump_mem( &uk_args ); + + if (0 != put_user(uk_args.cookie, &argument->cookie)) + { + if (_MALI_OSK_ERR_OK == err_code) + { + /* Rollback */ + _mali_uk_release_ump_mem_s uk_args_unmap; + + uk_args_unmap.ctx = session_data; + uk_args_unmap.cookie = uk_args.cookie; + err_code = _mali_ukk_release_ump_mem( &uk_args_unmap ); + if (_MALI_OSK_ERR_OK != err_code) + { + MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n")); + } + } + return -EFAULT; + } + + /* Return the error that _mali_ukk_map_external_ump_mem produced */ + return map_errcode(err_code); +} +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ + +int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs) +{ + _mali_uk_query_mmu_page_table_dump_size_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + + err = _mali_ukk_query_mmu_page_table_dump_size(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT; + + return 0; +} + +int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs) +{ + _mali_uk_dump_mmu_page_table_s kargs; + _mali_osk_errcode_t err; + void *buffer; + int rc = -EFAULT; + + /* validate input */ + MALI_CHECK_NON_NULL(uargs, -EINVAL); + /* the session_data pointer was validated by caller */ + + kargs.buffer = NULL; + + /* get location of user buffer */ + if (0 != get_user(buffer, &uargs->buffer)) goto err_exit; + /* get size of mmu page table info buffer from user space */ + if ( 0 != get_user(kargs.size, &uargs->size) ) goto err_exit; + /* verify we can access the whole of the user buffer */ + if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit; + + /* allocate temporary buffer (kernel side) to store mmu page table info */ + kargs.buffer = _mali_osk_malloc(kargs.size); + if (NULL == kargs.buffer) + { + rc = -ENOMEM; + goto err_exit; + } + + kargs.ctx = session_data; + err = _mali_ukk_dump_mmu_page_table(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + rc = map_errcode(err); + goto err_exit; + } + + /* copy mmu page table info back to user space and update pointers */ + if (0 != copy_to_user(uargs->buffer, kargs.buffer, kargs.size) ) goto err_exit; + if (0 != put_user((kargs.register_writes - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->register_writes)) goto err_exit; + if (0 != put_user((kargs.page_table_dump - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->page_table_dump)) goto err_exit; + if (0 != put_user(kargs.register_writes_size, &uargs->register_writes_size)) goto err_exit; + if (0 != put_user(kargs.page_table_dump_size, &uargs->page_table_dump_size)) goto err_exit; + rc = 0; + +err_exit: + if (kargs.buffer) _mali_osk_free(kargs.buffer); + return rc; +} + + + +int mem_get_big_block_wrapper( struct file * filp, _mali_uk_get_big_block_s __user * argument ) +{ + _mali_uk_get_big_block_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL); + + /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ + if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_get_big_block_s)) ) + { + return -EFAULT; + } + + /* This interface inserts something into the ukk_private word */ + uk_args.ukk_private = (u32)filp; + uk_args.ctx = filp->private_data; + err_code = _mali_ukk_get_big_block( &uk_args ); + + /* Do not leak the private word back into user space */ + uk_args.ukk_private = 0; + + if ( _MALI_OSK_ERR_OK != err_code ) + { + return map_errcode(err_code); + } + + /* From this point on, we must roll-back any failing action to preserve the + * meaning of the U/K interface (e.g. when excluded) */ + + /* transfer response back to user space */ + if ( 0 != copy_to_user(argument, &uk_args, sizeof(_mali_uk_get_big_block_s)) ) + { + /* Roll-back - the _mali_uk_get_big_block call succeeded, so all + * values in uk_args will be correct */ + _mali_uk_free_big_block_s uk_args_rollback = {0, }; + + uk_args_rollback.ctx = uk_args.ctx; + uk_args_rollback.cookie = uk_args.cookie; + err_code = _mali_ukk_free_big_block( &uk_args_rollback ); + + if ( _MALI_OSK_ERR_OK != err_code ) + { + /* error in DEBUG and RELEASE */ + MALI_PRINT_ERROR( ("Failed to rollback get_big_block: %.8X\n", (u32)err_code) ); + } + return -EFAULT; + } + + return 0; +} + +int mem_free_big_block_wrapper(struct mali_session_data *session_data, _mali_uk_free_big_block_s __user * argument) +{ + _mali_uk_free_big_block_s uk_args; + _mali_osk_errcode_t err_code; + + /* validate input */ + /* the session_data pointer was validated by caller */ + MALI_CHECK_NON_NULL( argument, -EINVAL ); + + /* get call arguments from user space. get_user returns 0 on success */ + if ( 0 != get_user(uk_args.cookie, &argument->cookie) ) + { + return -EFAULT; + } + + uk_args.ctx = session_data; + err_code = _mali_ukk_free_big_block( &uk_args ); + + /* Return the error that _mali_ukk_free_big_block produced */ + return map_errcode(err_code); +} diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_pp.c b/drivers/gpu/arm/mali/linux/mali_ukk_pp.c new file mode 100644 index 00000000000..31e2a6ac065 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_pp.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* 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 pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs) +{ + _mali_uk_pp_start_job_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_pp_start_job_s))) + { + return -EFAULT; + } + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_start_job_s))) return -EFAULT; + + kargs.ctx = session_data; + err = _mali_ukk_pp_start_job(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.returned_user_job_ptr, &uargs->returned_user_job_ptr) || + 0 != put_user(kargs.status, &uargs->status)) + { + /* + * If this happens, then user space will not know that the job was actually started, + * and if we return a queued job, then user space will still think that one is still queued. + * This will typically lead to a deadlock in user space. + * This could however only happen if user space deliberately passes a user buffer which + * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user(). + * The official Mali driver will never attempt to do that, and kernel space should not be affected. + * That is why we do not bother to do a complex rollback in this very very very rare case. + */ + return -EFAULT; + } + + return 0; +} + +int pp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_abort_job_s __user *uargs) +{ + _mali_uk_pp_abort_job_s kargs; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_abort_job_s))) return -EFAULT; + + kargs.ctx = session_data; + _mali_ukk_pp_abort_job(&kargs); + + return 0; +} + +int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs) +{ + _mali_uk_get_pp_number_of_cores_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_pp_number_of_cores(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT; + + return 0; +} + +int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs) +{ + _mali_uk_get_pp_core_version_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_pp_core_version(&kargs); + if (_MALI_OSK_ERR_OK != err) return map_errcode(err); + + if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT; + + return 0; +} diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c new file mode 100644 index 00000000000..e2973bb5e34 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include /* file system operations */ +#include /* 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 profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs) +{ + _mali_uk_profiling_start_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_start_s))) + { + return -EFAULT; + } + + kargs.ctx = session_data; + err = _mali_ukk_profiling_start(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.limit, &uargs->limit)) + { + return -EFAULT; + } + + return 0; +} + +int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs) +{ + _mali_uk_profiling_add_event_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s))) + { + return -EFAULT; + } + + kargs.ctx = session_data; + err = _mali_ukk_profiling_add_event(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} + +int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs) +{ + _mali_uk_profiling_stop_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_profiling_stop(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + if (0 != put_user(kargs.count, &uargs->count)) + { + return -EFAULT; + } + + return 0; +} + +int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs) +{ + _mali_uk_profiling_get_event_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + if (0 != get_user(kargs.index, &uargs->index)) + { + return -EFAULT; + } + + kargs.ctx = session_data; + + err = _mali_ukk_profiling_get_event(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + kargs.ctx = NULL; /* prevent kernel address to be returned to user space */ + if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s))) + { + return -EFAULT; + } + + return 0; +} + +int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs) +{ + _mali_uk_profiling_clear_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_profiling_clear(&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 new file mode 100644 index 00000000000..bc0bd503a57 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_ukk_wrappers.h + * Defines the wrapper functions for each user-kernel function + */ + +#ifndef __MALI_UKK_WRAPPERS_H__ +#define __MALI_UKK_WRAPPERS_H__ + +#include "mali_uk_types.h" +#include "mali_osk.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +int get_system_info_size_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_size_s __user *uargs); +int get_system_info_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_s __user *uargs); +int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs); +int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs); +int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs); +int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs); +int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument); +int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument); +int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs); +int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs); + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument); +int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument); +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */ + +int mem_get_big_block_wrapper( struct file * filp, _mali_uk_get_big_block_s __user * argument ); +int mem_free_big_block_wrapper( struct mali_session_data *session_data, _mali_uk_free_big_block_s __user * argument); +int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs); +int pp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_abort_job_s __user *uargs); +int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs); +int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs); +int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs); +int gp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_abort_job_s __user *uargs); +int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs); +int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs); +int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs); + +int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs); +int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs); +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 map_errcode( _mali_osk_errcode_t err ); + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UKK_WRAPPERS_H__ */ -- cgit v1.2.3 From 68b6e300cab9f502d6085d3918ca1cb6f31e9f25 Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Mon, 26 Sep 2011 11:19:40 -0600 Subject: Moved Mali/UMP options to Kconfigs and moved each of config.h to /mach-xxx Signed-off-by: Chunsang Jeong --- drivers/gpu/arm/mali/linux/mali_osk_mali.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c index 67319db4335..d7ef94df0de 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.c @@ -19,7 +19,7 @@ #include "mali_osk.h" /* kernel side OS functions */ #include "mali_uk_types.h" #include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() */ -#include "arch/config.h" /* contains the configuration of the arch we are compiling for */ +#include /* 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 ) -- cgit v1.2.3 From 23581e6776a5df8b7971670b8324fd42c77f332a Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Mon, 26 Sep 2011 11:19:41 -0600 Subject: Updated Mali and UMP driver with r2p1-05rel1 released at 1st Apr from ARM. Signed-off-by: Chunsang Jeong --- .../gpu/arm/mali/linux/mali_device_pause_resume.c | 16 +++- .../gpu/arm/mali/linux/mali_device_pause_resume.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h | 3 +- drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 29 +++--- drivers/gpu/arm/mali/linux/mali_kernel_linux.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 84 +++++++++++------ drivers/gpu/arm/mali/linux/mali_kernel_pm.h | 2 +- drivers/gpu/arm/mali/linux/mali_linux_pm.h | 3 +- .../gpu/arm/mali/linux/mali_linux_pm_testsuite.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_atomics.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_irq.c | 47 ++++++++-- drivers/gpu/arm/mali/linux/mali_osk_locks.c | 19 +++- .../gpu/arm/mali/linux/mali_osk_low_level_mem.c | 4 +- drivers/gpu/arm/mali/linux/mali_osk_mali.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_math.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_memory.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_misc.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_notification.c | 100 ++++++++++----------- drivers/gpu/arm/mali/linux/mali_osk_pm.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_specific.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_time.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_timers.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_core.c | 31 +++++-- drivers/gpu/arm/mali/linux/mali_ukk_mem.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_pp.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_profiling.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h | 3 +- 29 files changed, 240 insertions(+), 135 deletions(-) mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_device_pause_resume.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_device_pause_resume.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_kernel_linux.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_kernel_linux.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_kernel_pm.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_kernel_pm.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_linux_pm.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_atomics.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_irq.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_locks.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_mali.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_math.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_memory.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_misc.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_notification.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_pm.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_specific.h mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_time.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_osk_timers.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_ukk_core.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_ukk_mem.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_ukk_pp.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_ukk_profiling.c mode change 100644 => 100755 drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c old mode 100644 new mode 100755 index 0b47efe18cf..1c1bf306688 --- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c +++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.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. @@ -32,7 +32,12 @@ 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)) + || (mali_device_state == _MALI_DEVICE_SUSPEND) +#ifdef CONFIG_HAS_EARLYSUSPEND + || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) +#else + ) +#endif { err = -EPERM; } @@ -52,7 +57,12 @@ 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)) + || (mali_device_state == _MALI_DEVICE_SUSPEND) +#ifdef CONFIG_HAS_EARLYSUSPEND + || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) +#else + ) +#endif { err = -EPERM; } diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h old mode 100644 new mode 100755 index 155a3e69d48..5362f88cdbd --- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h +++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.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_kernel_ioctl.h b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h old mode 100644 new mode 100755 index d76841e5eba..87d94db7886 --- a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.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. @@ -42,6 +42,7 @@ extern "C" #define MALI_IOC_GET_SYSTEM_INFO _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO, _mali_uk_get_system_info_s *) #define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *) #define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *) +#define MALI_IOC_POST_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *) #define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, _mali_uk_get_big_block_s *) #define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, _mali_uk_free_big_block_s *) #define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *) diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c old mode 100644 new mode 100755 index 3c38fadf59f..70d9bfd5b83 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.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. @@ -101,6 +101,17 @@ struct file_operations mali_fops = int mali_driver_init(void) { int err; +#if USING_MALI_PMM +#if MALI_LICENSE_IS_GPL +#ifdef CONFIG_PM + err = _mali_dev_platform_register(); + if (err) + { + return err; + } +#endif +#endif +#endif err = mali_kernel_constructor(); if (_MALI_OSK_ERR_OK != err) { @@ -150,18 +161,6 @@ int initialize_kernel_device(void) { int err; dev_t dev = 0; - -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - err = _mali_dev_platform_register(); - if (err) - { - return err; - } -#endif -#endif -#endif if (0 == mali_major) { /* auto select a major */ @@ -356,6 +355,10 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 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; + #if MALI_TIMELINE_PROFILING_ENABLED case MALI_IOC_PROFILING_START: err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h old mode 100644 new mode 100755 index bec0e24774a..785eaca4889 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.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_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c old mode 100644 new mode 100755 index 915f355af07..e6c78c2f6e7 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.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. @@ -40,6 +40,10 @@ #include "mali_device_pause_resume.h" #include "mali_linux_pm.h" +#if MALI_GPU_UTILIZATION +#include "mali_kernel_utilization.h" +#endif /* MALI_GPU_UTILIZATION */ + #if MALI_POWER_MGMT_TEST_SUITE #ifdef CONFIG_PM #include "mali_linux_pm_testsuite.h" @@ -73,6 +77,7 @@ static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = { [_MALI_DVFS_PAUSE_EVENT] = "dvfs_pause", [_MALI_DVFS_RESUME_EVENT] = "dvfs_resume", }; + #endif /* CONFIG_PM_DEBUG */ #if MALI_PMM_RUNTIME_JOB_CONTROL_ON @@ -109,18 +114,15 @@ _mali_osk_lock_t *lock; #if MALI_POWER_MGMT_TEST_SUITE const char* const mali_pmm_recording_events[_MALI_DEVICE_MAX_PMM_EVENTS] = { - [_MALI_DEVICE_PMM_TIMEOUT_EVENT] = "timeout", - [_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS] = "job_scheduling", + [_MALI_DEVICE_PMM_TIMEOUT_EVENT] = "timeout", + [_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS] = "job_scheduling", [_MALI_DEVICE_PMM_REGISTERED_CORES] = "cores", }; unsigned int mali_timeout_event_recording_on = 0; unsigned int mali_job_scheduling_events_recording_on = 0; - -#if MALI_PMM_INTERNAL_TESTING unsigned int is_mali_pmu_present = 0; -#endif /* MALI_PMM_INTERNAL_TESTING */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ /* Function prototypes */ @@ -148,6 +150,8 @@ 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 #if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state); #else @@ -159,6 +163,8 @@ static int mali_pm_os_resume(struct platform_device *pdev); #else static int mali_pm_os_resume(struct device *dev); #endif +#endif /* CONFIG_PM_RUNTIME */ +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ /* OS Hibernation suspend callback */ static int mali_pm_os_suspend_on_hibernation(struct device *dev); @@ -178,8 +184,12 @@ static const struct dev_pm_ops mali_dev_pm_ops = { #endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ #endif /* CONFIG_PM_RUNTIME */ +#ifndef CONFIG_PM_RUNTIME +#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON .suspend = mali_pm_os_suspend, .resume = mali_pm_os_resume, +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ .freeze = mali_pm_os_suspend_on_hibernation, .poweroff = mali_pm_os_suspend_on_hibernation, .thaw = mali_pm_os_resume_on_hibernation, @@ -190,10 +200,10 @@ static const struct dev_pm_ops mali_dev_pm_ops = { #if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) struct pm_ext_ops mali_pm_operations = { .base = { - .freeze = mali_pm_os_suspend_on_hibernation, - .thaw = mali_pm_os_resume_on_hibernation, - .poweroff = mali_pm_os_resume_on_hibernation, - .restore = mali_pm_os_resume_on_hibernation, + .freeze = mali_pm_os_suspend_on_hibernation, + .thaw = mali_pm_os_resume_on_hibernation, + .poweroff = mali_pm_os_resume_on_hibernation, + .restore = mali_pm_os_resume_on_hibernation, }, }; #endif @@ -202,8 +212,12 @@ static struct platform_driver mali_plat_driver = { .probe = mali_pm_probe, .remove = mali_pm_remove, #if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +#ifndef CONFIG_PM_RUNTIME +#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON .suspend = mali_pm_os_suspend, .resume = mali_pm_os_resume, +#endif /* CONFIG_PM_RUNTIME */ +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ .pm = &mali_pm_operations, #endif @@ -242,7 +256,6 @@ static void _mali_release_pm(struct device *device) } #if MALI_POWER_MGMT_TEST_SUITE -#if MALI_PMM_INTERNAL_TESTING void mali_is_pmu_present(void) { int temp = 0; @@ -255,9 +268,7 @@ void mali_is_pmu_present(void) { is_mali_pmu_present = 1; } - } -#endif /* MALI_PMM_INTERNAL_TESTING */ #endif /* MALI_POWER_MGMT_TEST_SUITE */ #endif /* MALI_LICENSE_IS_GPL */ @@ -308,6 +319,9 @@ static int mali_pm_suspend(struct device *dev) { int err = 0; _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) #ifdef CONFIG_HAS_EARLYSUSPEND || mali_device_state == (_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)) @@ -325,6 +339,8 @@ static int mali_pm_suspend(struct device *dev) return err; } +#ifndef CONFIG_PM_RUNTIME +#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON #if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state) #else @@ -335,6 +351,9 @@ static int mali_pm_os_suspend(struct device *dev) err = mali_pm_suspend(NULL); return err; } +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ + #ifdef CONFIG_PM_RUNTIME #if MALI_PMM_RUNTIME_JOB_CONTROL_ON #ifndef CONFIG_HAS_EARLYSUSPEND @@ -346,6 +365,10 @@ static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long eve case PM_SUSPEND_PREPARE: err = mali_pm_suspend(NULL); break; + + case PM_POST_SUSPEND: + err = mali_pm_resume(NULL); + break; default: break; } @@ -391,6 +414,8 @@ static int mali_pm_resume(struct device *dev) return err; } +#ifndef CONFIG_PM_RUNTIME +#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON #if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) static int mali_pm_os_resume(struct platform_device *pdev) #else @@ -401,6 +426,8 @@ static int mali_pm_os_resume(struct device *dev) err = mali_pm_resume(NULL); return err; } +#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ +#endif /* CONFIG_PM_RUNTIME */ static int mali_pm_os_suspend_on_hibernation(struct device *dev) { @@ -457,6 +484,9 @@ static void mali_pm_early_suspend(struct early_suspend *mali_dev) 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); @@ -487,6 +517,7 @@ static void mali_pm_late_resume(struct early_suspend *mali_dev) 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); @@ -533,9 +564,7 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con #if MALI_POWER_MGMT_TEST_SUITE int test_flag_dvfs = 0; pwr_mgmt_status_reg = 0; -#if MALI_PMM_INTERNAL_TESTING mali_is_pmu_present(); -#endif /* MALI_PMM_INTERNAL_TESTING */ #endif if (!strncmp(buf,mali_states[_MALI_DEVICE_SUSPEND],strlen(mali_states[_MALI_DEVICE_SUSPEND]))) @@ -546,21 +575,21 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con #if MALI_POWER_MGMT_TEST_SUITE else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Device get number of registerd cores\n" )); + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Device get number of registerd cores\n" )); pwr_mgmt_status_reg = _mali_pmm_cores_list(); return count; - } + } else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI timeout event recording is enabled\n" )); + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI timeout event recording is enabled\n" )); mali_timeout_event_recording_on = 1; - } + } else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Job scheduling events recording is enabled\n" )); - mali_job_scheduling_events_recording_on = 1; - } + { + MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Job scheduling events recording is enabled\n" )); + mali_job_scheduling_events_recording_on = 1; + } #endif /* MALI_POWER_MGMT_TEST_SUITE */ else if (!strncmp(buf,mali_states[_MALI_DEVICE_RESUME],strlen(mali_states[_MALI_DEVICE_RESUME]))) @@ -615,14 +644,10 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con } else { -#if MALI_PMM_INTERNAL_TESTING if (1 == is_mali_pmu_present) { -#endif /* MALI_PMM_INTERNAL_TESTING */ pwr_mgmt_status_reg = pmu_get_power_up_down_info(); -#if MALI_PMM_INTERNAL_TESTING } -#endif /* MALI_PMM_INTERNAL_TESTING */ } #endif /* MALI_POWER_MGMT_TEST_SUITE */ return count; @@ -711,6 +736,7 @@ int _mali_dev_platform_register(void) 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 */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h b/drivers/gpu/arm/mali/linux/mali_kernel_pm.h old mode 100644 new mode 100755 index db910102d76..6e879fea447 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.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_linux_pm.h b/drivers/gpu/arm/mali/linux/mali_linux_pm.h old mode 100644 new mode 100755 index 5871de9dfbf..614d5e1deee --- a/drivers/gpu/arm/mali/linux/mali_linux_pm.h +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm.h @@ -1,6 +1,6 @@ /* - * 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. @@ -36,7 +36,6 @@ typedef enum _MALI_MAX_DEBUG_OPERATIONS, } _mali_device_dvfs_events; - extern _mali_device_power_states mali_device_state; extern _mali_device_power_states mali_dvfs_device_state; extern _mali_osk_lock_t *lock; diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h old mode 100644 new mode 100755 index 0def7ab77dc..d6a920827c9 --- a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.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_osk_atomics.c b/drivers/gpu/arm/mali/linux/mali_osk_atomics.c old mode 100644 new mode 100755 index 05831c54272..cc029c4a8f8 --- a/drivers/gpu/arm/mali/linux/mali_osk_atomics.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_atomics.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_osk_indir_mmap.c b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c old mode 100644 new mode 100755 index 7297218b9b6..b60bf825897 --- a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.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_osk_indir_mmap.h b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h old mode 100644 new mode 100755 index 41cb462e8e5..f87739bb8f9 --- a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h +++ b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.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_osk_irq.c b/drivers/gpu/arm/mali/linux/mali_osk_irq.c old mode 100644 new mode 100755 index 0343063f7b6..73ab8182815 --- a/drivers/gpu/arm/mali/linux/mali_osk_irq.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_irq.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. @@ -14,10 +14,12 @@ */ #include /* For memory allocation */ +#include #include "mali_osk.h" #include "mali_kernel_core.h" #include "mali_kernel_common.h" +#include "mali_kernel_license.h" #include "linux/interrupt.h" typedef struct _mali_osk_irq_t_struct @@ -29,6 +31,10 @@ typedef struct _mali_osk_irq_t_struct struct work_struct work_queue_irq_handle; /* Workqueue for the bottom half of the IRQ-handling. This job is activated when this core gets an IRQ.*/ } mali_osk_irq_object_t; +#if MALI_LICENSE_IS_GPL +static struct workqueue_struct *pmm_wq=NULL; +#endif + typedef void (*workqueue_func_t)(void *); typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *); static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/ @@ -103,9 +109,15 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl MALI_DEBUG_PRINT(2, ("Probe for irq failed\n")); } } + + irq_object->irqnum = irqnum; + irq_object->uhandler = uhandler; + irq_object->bhandler = bhandler; + irq_object->data = data; /* Is this a real IRQ handler we need? */ - if (!mali_benchmark && irqnum != _MALI_OSK_IRQ_NUMBER_FAKE) { + if (!mali_benchmark && irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM) + { if (-1 == irqnum) { MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description)); @@ -121,10 +133,12 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl } } - irq_object->irqnum = irqnum; - irq_object->uhandler = uhandler; - irq_object->bhandler = bhandler; - irq_object->data = data; +#if MALI_LICENSE_IS_GPL + if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum ) + { + pmm_wq = create_workqueue("mali-pmm-wq"); + } +#endif return irq_object; } @@ -132,12 +146,31 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) { mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; - schedule_work(&irq_object->work_queue_irq_handle); +#if MALI_LICENSE_IS_GPL + if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + queue_work(pmm_wq,&irq_object->work_queue_irq_handle); + } + else + { +#endif + schedule_work(&irq_object->work_queue_irq_handle); +#if MALI_LICENSE_IS_GPL + } +#endif } void _mali_osk_irq_term( _mali_osk_irq_t *irq ) { mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; + +#if MALI_LICENSE_IS_GPL + if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) + { + flush_workqueue(pmm_wq); + destroy_workqueue(pmm_wq); + } +#endif if (!mali_benchmark) { free_irq(irq_object->irqnum, irq_object); diff --git a/drivers/gpu/arm/mali/linux/mali_osk_locks.c b/drivers/gpu/arm/mali/linux/mali_osk_locks.c old mode 100644 new mode 100755 index a896c62c023..79010fcdc5a --- a/drivers/gpu/arm/mali/linux/mali_osk_locks.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_locks.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. @@ -39,6 +39,7 @@ typedef enum { _MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */ + _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ, /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use up()/down_interruptable() */ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use up()/down() */ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {up,down}{read,write}() */ @@ -56,6 +57,7 @@ typedef enum struct _mali_osk_lock_t_struct { _mali_osk_internal_locktype type; + unsigned long flags; union { spinlock_t spinlock; @@ -76,12 +78,13 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial /* Validate parameters: */ /* Flags acceptable */ MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK + | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK)) ); /* Spinlocks are always non-interruptable */ - MALI_DEBUG_ASSERT( ((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) + MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK) ); /* Parameter initial SBZ - for future expansion */ MALI_DEBUG_ASSERT( 0 == initial ); @@ -102,6 +105,12 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN; spin_lock_init( &lock->obj.spinlock ); } + else if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ ) ) + { + lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ; + lock->flags = 0; + spin_lock_init( &lock->obj.spinlock ); + } else if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) && (flags & _MALI_OSK_LOCKFLAG_READERWRITER) ) { @@ -154,6 +163,9 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_ case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: spin_lock(&lock->obj.spinlock); break; + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ: + spin_lock_irqsave(&lock->obj.spinlock, lock->flags); + break; case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: if ( down_interruptible(&lock->obj.sema) ) @@ -223,6 +235,9 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: spin_unlock(&lock->obj.spinlock); break; + case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ: + spin_unlock_irqrestore(&lock->obj.spinlock, lock->flags); + break; case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: /* FALLTHROUGH */ 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 old mode 100644 new mode 100755 index a3c812f7cf9..730ee814e38 --- a/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.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. @@ -177,7 +177,7 @@ mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size ) /* dma_alloc_* uses a limited region of address space. On most arch/marchs * 2 to 14 MiB is available. This should be enough for the page tables, which * currently is the only user of this function. */ - virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA32 ); + virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA ); MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys)); diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c old mode 100644 new mode 100755 index d7ef94df0de..b765e315e14 --- a/drivers/gpu/arm/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.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_osk_math.c b/drivers/gpu/arm/mali/linux/mali_osk_math.c old mode 100644 new mode 100755 index 3e62e519cba..2f7fc15847b --- a/drivers/gpu/arm/mali/linux/mali_osk_math.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_math.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_osk_memory.c b/drivers/gpu/arm/mali/linux/mali_osk_memory.c old mode 100644 new mode 100755 index b1a22abaa27..bf6679f7bac --- a/drivers/gpu/arm/mali/linux/mali_osk_memory.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_memory.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_osk_misc.c b/drivers/gpu/arm/mali/linux/mali_osk_misc.c old mode 100644 new mode 100755 index 239d9ffae41..3afd2da736c --- a/drivers/gpu/arm/mali/linux/mali_osk_misc.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_misc.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_osk_notification.c b/drivers/gpu/arm/mali/linux/mali_osk_notification.c old mode 100644 new mode 100755 index 8017d3ca587..6eb277f3724 --- a/drivers/gpu/arm/mali/linux/mali_osk_notification.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_notification.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. @@ -83,14 +83,22 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) INIT_LIST_HEAD(¬ification->list); /* allocate memory for the buffer requested */ - notification->data.result_buffer = kmalloc( size, GFP_KERNEL ); - if ( NULL == notification->data.result_buffer ) + if (0 != size) { - /* 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 = 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; + } + } + else + { + notification->data.result_buffer = 0; } + /* set up the non-allocating fields */ notification->data.notification_type = type; notification->data.result_buffer_size = size; @@ -141,9 +149,38 @@ void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _ wake_up(&queue->receive_queue); } -_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, u32 timeout, _mali_osk_notification_t **result ) +static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *queue ) { + int ret; + + down(&queue->mutex); + ret = list_empty(&queue->head); + up(&queue->mutex); + return ret; +} + +_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; _mali_osk_notification_wrapper_t *wrapper_object; + + down(&queue->mutex); + + if (!list_empty(&queue->head)) + { + wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list); + *result = &(wrapper_object->data); + list_del_init(&wrapper_object->list); + ret = _MALI_OSK_ERR_OK; + } + + up(&queue->mutex); + + return ret; +} + +_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result ) +{ /* check input */ MALI_DEBUG_ASSERT_POINTER( queue ); MALI_DEBUG_ASSERT_POINTER( result ); @@ -151,54 +188,13 @@ _mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification /* default result */ *result = NULL; - /* lock queue */ - if (down_interruptible(&queue->mutex)) return _MALI_OSK_ERR_RESTARTSYSCALL; /* handle the signal, then retry */ - - /* check for a pending notification */ - while (0 != list_empty(&queue->head)) + while (_MALI_OSK_ERR_OK != _mali_osk_notification_queue_dequeue(queue, result)) { - /* no notification ready, we have to wait for one */ - int schedule_result; - /* define a wait entry */ - DEFINE_WAIT(wait); - - if( timeout == 0 ) + if (wait_event_interruptible(queue->receive_queue, !_mali_notification_queue_is_empty(queue))) { - /* Actually, don't wait for any time when nothing is in the queue */ - up(&queue->mutex); - return _MALI_OSK_ERR_TIMEOUT; + return _MALI_OSK_ERR_RESTARTSYSCALL; } - - /* prepare for exclusive wait, tag as interruptible (accept signals) */ - prepare_to_wait_exclusive(&queue->receive_queue, &wait, TASK_INTERRUPTIBLE); - - /* release the lock before waiting */ - up(&queue->mutex); - - /* if the check fails again schedule (sleep) */ - schedule_result = schedule_timeout(msecs_to_jiffies(timeout)); - - /* we're running again, wait finished (or never started) */ - finish_wait(&queue->receive_queue, &wait); - - /* check why we got scheduled */ - if (0 == schedule_result) return _MALI_OSK_ERR_TIMEOUT; /* timeout, ok, NULL will be returned */ - if (signal_pending(current)) return _MALI_OSK_ERR_RESTARTSYSCALL; /* handle the signal, then retry */ - - /* we were woken because of a new entry */ - /* lock the queue and check (with normal signal handling logic) */ - if (down_interruptible(&queue->mutex)) return _MALI_OSK_ERR_RESTARTSYSCALL; /* handle the signal, then retry */ } - /* - The while loop terminates when the list is non-empty and we hold the lock - Pop the head and release the lock - */ - wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list); - *result = &(wrapper_object->data); - list_del_init(&wrapper_object->list); - - up(&queue->mutex); - return _MALI_OSK_ERR_OK; /* all ok */ } diff --git a/drivers/gpu/arm/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali/linux/mali_osk_pm.c old mode 100644 new mode 100755 index 60fee833098..f1363167292 --- a/drivers/gpu/arm/mali/linux/mali_osk_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_pm.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_osk_specific.h b/drivers/gpu/arm/mali/linux/mali_osk_specific.h old mode 100644 new mode 100755 index 6aacf17d387..54acfdd138c --- a/drivers/gpu/arm/mali/linux/mali_osk_specific.h +++ b/drivers/gpu/arm/mali/linux/mali_osk_specific.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_osk_time.c b/drivers/gpu/arm/mali/linux/mali_osk_time.c old mode 100644 new mode 100755 index da9b8656b70..aa7962380e6 --- a/drivers/gpu/arm/mali/linux/mali_osk_time.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_time.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_osk_timers.c b/drivers/gpu/arm/mali/linux/mali_osk_timers.c old mode 100644 new mode 100755 index 51f7028b1ee..1cffce37461 --- a/drivers/gpu/arm/mali/linux/mali_osk_timers.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_timers.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_core.c b/drivers/gpu/arm/mali/linux/mali_ukk_core.c old mode 100644 new mode 100755 index 819977f8740..a10d1ba8a5e --- a/drivers/gpu/arm/mali/linux/mali_ukk_core.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_core.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. @@ -101,21 +101,42 @@ int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_ MALI_CHECK_NON_NULL(uargs, -EINVAL); - if (0 != get_user(kargs.code.timeout, &uargs->code.timeout)) return -EFAULT; - kargs.ctx = session_data; err = _mali_ukk_wait_for_notification(&kargs); if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - if( !(_MALI_NOTIFICATION_CORE_TIMEOUT == kargs.code.type || _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS == kargs.code.type ) ) + if( !(_MALI_NOTIFICATION_CORE_TIMEOUT == kargs.type || _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; } else { - if (0 != put_user(kargs.code.type, &uargs->code.type)) return -EFAULT; + if (0 != put_user(kargs.type, &uargs->type)) return -EFAULT; } return 0; } + +int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs) +{ + _mali_uk_post_notification_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + + if (0 != get_user(kargs.type, &uargs->type)) + { + return -EFAULT; + } + + err = _mali_ukk_post_notification(&kargs); + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } + + return 0; +} diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_mem.c b/drivers/gpu/arm/mali/linux/mali_ukk_mem.c old mode 100644 new mode 100755 index 05214b703d3..3f67a1e3328 --- a/drivers/gpu/arm/mali/linux/mali_ukk_mem.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_mem.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_pp.c b/drivers/gpu/arm/mali/linux/mali_ukk_pp.c old mode 100644 new mode 100755 index 31e2a6ac065..f77a177d865 --- a/drivers/gpu/arm/mali/linux/mali_ukk_pp.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_pp.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_profiling.c b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c old mode 100644 new mode 100755 index e2973bb5e34..636bd03580e --- a/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.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_wrappers.h b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h old mode 100644 new mode 100755 index bc0bd503a57..0bc6b87e69c --- a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h +++ b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.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. @@ -28,6 +28,7 @@ int get_system_info_size_wrapper(struct mali_session_data *session_data, _mali_u int get_system_info_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_s __user *uargs); int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs); int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs); +int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs); int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs); int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs); int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument); -- cgit v1.2.3 From 8d687f7f5be681747663570e57b4bda0b32b42ac Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Mon, 26 Sep 2011 11:19:43 -0600 Subject: Moved irq numbers to irqs.h for platform config file, i.e. config.h Signed-off-by: Chunsang Jeong --- drivers/gpu/arm/mali/linux/mali_osk_mali.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c index b765e315e14..d6c4b41ebc0 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.c @@ -19,6 +19,7 @@ #include "mali_osk.h" /* kernel side OS functions */ #include "mali_uk_types.h" #include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() */ +#include #include /* contains the configuration of the arch we are compiling for */ /* is called from mali_kernel_constructor in common code */ -- cgit v1.2.3 From f8e96dfd0e19c86074d4ce5cf1d2069b42619e80 Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Sat, 13 Aug 2011 23:11:20 +0900 Subject: Update with r2p2-03release at 17th, Jul from malideveloper.com Signed-off-by: Chunsang Jeong --- .../mali/linux/license/gpl/mali_kernel_license.h | 2 +- .../gpu/arm/mali/linux/mali_device_pause_resume.c | 18 +- drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h | 2 + drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 137 +++++----- drivers/gpu/arm/mali/linux/mali_kernel_linux.h | 14 ++ drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 149 ++--------- drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c | 137 ++++++++++ drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h | 30 +++ .../arm/mali/linux/mali_linux_dvfs_pause_resume.c | 72 ++++++ drivers/gpu/arm/mali/linux/mali_linux_pm.h | 8 +- .../gpu/arm/mali/linux/mali_linux_pm_testsuite.h | 4 - drivers/gpu/arm/mali/linux/mali_osk_irq.c | 15 +- drivers/gpu/arm/mali/linux/mali_osk_locks.c | 34 +-- .../gpu/arm/mali/linux/mali_osk_low_level_mem.c | 276 ++++++++++++++------- drivers/gpu/arm/mali/linux/mali_osk_mali.c | 7 +- drivers/gpu/arm/mali/linux/mali_osk_misc.c | 12 + drivers/gpu/arm/mali/linux/mali_osk_notification.c | 32 +-- drivers/gpu/arm/mali/linux/mali_osk_pm.c | 18 +- drivers/gpu/arm/mali/linux/mali_osk_timers.c | 1 - drivers/gpu/arm/mali/linux/mali_ukk_core.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_gp.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_vsync.c | 41 +++ drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h | 2 + 23 files changed, 634 insertions(+), 381 deletions(-) create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h create mode 100644 drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_notification.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_pm.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_timers.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_ukk_core.c create mode 100644 drivers/gpu/arm/mali/linux/mali_ukk_vsync.c (limited to 'drivers/gpu/arm/mali/linux') 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 /* file system operations */ #include /* character device definitions */ #include /* memory mananger definitions */ -#include /* user space access */ #include /* 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 /* 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 -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif /* CONFIG_HAS_EARLYSUSPEND */ #ifdef CONFIG_PM_RUNTIME #include @@ -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 /* file system operations */ +#include +#include +#include + +/* 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 +#include +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_platform.h" +#include "mali_linux_pm.h" +#include "mali_linux_dvfs_pause_resume.h" +#include "mali_pmm.h" +#include "mali_kernel_license.h" +#ifdef CONFIG_PM +#if MALI_LICENSE_IS_GPL + +/* Mali Pause Resume APIs */ +int mali_dev_dvfs_pause() +{ + int err = 0; + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) + || (mali_device_state == _MALI_DEVICE_SUSPEND)) + { + err = -EPERM; + } + if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err)) + { + mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread); + mali_dvfs_device_state = _MALI_DEVICE_SUSPEND; + } + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return err; +} + +EXPORT_SYMBOL(mali_dev_dvfs_pause); + +int mali_dev_dvfs_resume() +{ + int err = 0; + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) + || (mali_device_state == _MALI_DEVICE_SUSPEND)) + { + err = -EPERM; + } + if (!err) + { + mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread); + mali_dvfs_device_state = _MALI_DEVICE_RESUME; + } + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return err; +} + +EXPORT_SYMBOL(mali_dev_dvfs_resume); + +#endif /* MALI_LICENSE_IS_GPL */ +#endif /* CONFIG_PM */ +#endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/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 #include #include -#include #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 -#include /* contains the configuration of the arch we are compiling for */ +#include /* 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 old mode 100755 new mode 100644 index 6eb277f3724..539f9ab68b0 --- 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 #include -#include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) #include @@ -28,12 +27,6 @@ #include #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 old mode 100755 new mode 100644 index f1363167292..f9c9e5ce2e8 --- 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 old mode 100755 new mode 100644 index 1cffce37461..3dfba76bcb3 --- 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 old mode 100755 new mode 100644 index a10d1ba8a5e..0f745492613 --- 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 /* file system operations */ +#include /* 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 -- cgit v1.2.3 From 3e533759f7c713e7f30693615f234deba4ad9e6e Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Wed, 19 Oct 2011 09:27:07 +0900 Subject: Added /proc/mali for getting profiling information from driver. Signed-off-by: Chunsang Jeong --- drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 43 ++++++++++++++++++++++++-- drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 7 +++++ drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c | 4 +-- 3 files changed, 50 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c index 382be6802b2..ba8b9fa6183 100755 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c @@ -17,7 +17,9 @@ #include /* character device definitions */ #include /* memory mananger definitions */ #include - +#if MALI_STATE_TRACKING_USING_PROC +#include +#endif /* the mali kernel subsystem types */ #include "mali_kernel_subsystem.h" @@ -44,7 +46,7 @@ module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IR MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output"); /* By default the module uses any available major, but it's possible to set it at load time to a specific number */ -int mali_major = 0; +int mali_major = 244; module_param(mali_major, int, S_IRUGO); /* r--r--r-- */ MODULE_PARM_DESC(mali_major, "Device major number"); @@ -71,6 +73,10 @@ static char mali_dev_name[] = "mali"; /* should be const, but the functions we c /* the mali device */ static struct mali_dev device; +#if MALI_STATE_TRACKING_USING_PROC +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); @@ -185,6 +191,14 @@ int initialize_kernel_device(void) goto init_cdev_err; } +#if MALI_STATE_TRACKING_USING_PROC + proc_entry = create_proc_entry(mali_dev_name, 0644, NULL); + if (proc_entry != NULL) + { + proc_entry->read_proc = mali_proc_read; + } +#endif + err = mali_sysfs_register(&device, dev, mali_dev_name); if (err) { @@ -199,6 +213,9 @@ init_sysfs_err: init_cdev_err: unregister_chrdev_region(dev, 1/*count*/); init_chrdev_err: +#if MALI_STATE_TRACKING_USING_PROC + remove_proc_entry(mali_dev_name, NULL); +#endif return err; } @@ -209,6 +226,10 @@ void terminate_kernel_device(void) mali_sysfs_unregister(&device, dev, mali_dev_name); +#if MALI_STATE_TRACKING_USING_PROC + remove_proc_entry(mali_dev_name, NULL); +#endif + /* unregister char device */ cdev_del(&device.cdev); /* free major */ @@ -464,6 +485,24 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return err; } +#if MALI_STATE_TRACKING_USING_PROC +static int mali_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + + MALI_DEBUG_PRINT(0,("\n***in the mali_proc_read\n")); //zepplin + 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)); + + /* + * 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(); + + return 0; +} +#endif + module_init(mali_driver_init); module_exit(mali_driver_exit); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c index 3969466f39e..f323592f511 100755 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c @@ -641,9 +641,16 @@ int mali_get_ospmm_thread_state(void) #endif /* CONFIG_PM */ #if MALI_STATE_TRACKING +#if MALI_STATE_TRACKING_USING_PROC +void mali_pmm_dump_os_thread_state( void ) +{ + MALI_PRINTF(("\nOSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false")); +} +#else 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 #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 index 62c7fba8791..c03e9f2efbb 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c @@ -37,7 +37,7 @@ static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) u32 len = 0; u32 size; char *buf; - +#if (MALI_STATE_TRACKING_USING_PROC==0) size = seq_get_buf(seq_file, &buf); if(!size) @@ -52,7 +52,7 @@ static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) len += _mali_kernel_core_dump_state(buf + len, size - len); seq_commit(seq_file, len); - +#endif return 0; } -- cgit v1.2.3 From 31dd0f8af8458680e58b4269f10c7ce027d4946b Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Wed, 21 Dec 2011 16:04:01 -0700 Subject: Updated Mali kernel driver with r2p3-01rel, used for Android ICS Signed-off-by: Chunsang Jeong --- .../mali/linux/license/gpl/mali_kernel_license.h | 2 +- .../gpu/arm/mali/linux/mali_device_pause_resume.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h | 1 + drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 251 ++++++++-------- drivers/gpu/arm/mali/linux/mali_kernel_linux.h | 1 + drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 15 +- drivers/gpu/arm/mali/linux/mali_kernel_pm.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c | 316 +++++++++++++++++++-- drivers/gpu/arm/mali/linux/mali_osk_atomics.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c | 2 +- .../gpu/arm/mali/linux/mali_osk_low_level_mem.c | 20 +- drivers/gpu/arm/mali/linux/mali_osk_math.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_memory.c | 11 + drivers/gpu/arm/mali/linux/mali_osk_pm.c | 3 - drivers/gpu/arm/mali/linux/mali_osk_specific.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_time.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_gp.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_mem.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_pp.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_profiling.c | 22 ++ drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h | 1 + 21 files changed, 467 insertions(+), 196 deletions(-) mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_device_pause_resume.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_kernel_linux.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_kernel_linux.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_kernel_pm.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_kernel_pm.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_atomics.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_math.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_memory.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_specific.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_time.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_ukk_mem.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_ukk_pp.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_ukk_profiling.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h (limited to 'drivers/gpu/arm/mali/linux') 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 2220b3b35ef..e9e5e55a082 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-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/arm/mali/linux/mali_device_pause_resume.h b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h old mode 100755 new mode 100644 index 5362f88cdbd..155a3e69d48 --- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h old mode 100755 new mode 100644 index 30a6fa041db..47b67cccb82 --- a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c old mode 100755 new mode 100644 index ba8b9fa6183..3c0d4cc8cda --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c @@ -17,9 +17,7 @@ #include /* character device definitions */ #include /* memory mananger definitions */ #include -#if MALI_STATE_TRACKING_USING_PROC -#include -#endif + /* the mali kernel subsystem types */ #include "mali_kernel_subsystem.h" @@ -40,6 +38,9 @@ /* */ #include "mali_kernel_license.h" +/* from the __malidrv_build_info.c file that is generated during build */ +//extern const char *__malidrv_build_info(void); + /* Module parameter to control log level */ int mali_debug_level = 2; module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ @@ -68,15 +69,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 +#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_USING_PROC -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); @@ -131,20 +134,16 @@ 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 - malipmm_force_powerup(); -#endif mali_kernel_destructor(); -#if USING_MALI_PMM - malipmm_force_powerdown(); -#endif - #if USING_MALI_PMM #if MALI_LICENSE_IS_GPL #ifdef CONFIG_PM @@ -191,14 +190,6 @@ int initialize_kernel_device(void) goto init_cdev_err; } -#if MALI_STATE_TRACKING_USING_PROC - proc_entry = create_proc_entry(mali_dev_name, 0644, NULL); - if (proc_entry != NULL) - { - proc_entry->read_proc = mali_proc_read; - } -#endif - err = mali_sysfs_register(&device, dev, mali_dev_name); if (err) { @@ -213,9 +204,6 @@ init_sysfs_err: init_cdev_err: unregister_chrdev_region(dev, 1/*count*/); init_chrdev_err: -#if MALI_STATE_TRACKING_USING_PROC - remove_proc_entry(mali_dev_name, NULL); -#endif return err; } @@ -226,10 +214,6 @@ void terminate_kernel_device(void) mali_sysfs_unregister(&device, dev, mali_dev_name); -#if MALI_STATE_TRACKING_USING_PROC - remove_proc_entry(mali_dev_name, NULL); -#endif - /* unregister char device */ cdev_del(&device.cdev); /* free major */ @@ -320,8 +304,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 */ @@ -330,93 +314,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 @@ -432,76 +421,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_USING_PROC -static int mali_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - - MALI_DEBUG_PRINT(0,("\n***in the mali_proc_read\n")); //zepplin - 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)); + 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 0; + return err; } -#endif module_init(mali_driver_init); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h old mode 100755 new mode 100644 index 485c27e1ecb..c362a7c77c5 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h @@ -18,6 +18,7 @@ extern "C" #include /* character device definitions */ #include "mali_kernel_license.h" +#include "mali_osk.h" struct mali_dev { diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c old mode 100755 new mode 100644 index f323592f511..7b525142ac8 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "mali_platform.h" @@ -44,6 +43,7 @@ #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 */ @@ -75,10 +75,6 @@ static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = { #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 static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy); @@ -585,7 +581,7 @@ 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 @@ -641,16 +637,9 @@ int mali_get_ospmm_thread_state(void) #endif /* CONFIG_PM */ #if MALI_STATE_TRACKING -#if MALI_STATE_TRACKING_USING_PROC -void mali_pmm_dump_os_thread_state( void ) -{ - MALI_PRINTF(("\nOSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false")); -} -#else 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 #endif /* MALI_STATE_TRACKING */ #endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h b/drivers/gpu/arm/mali/linux/mali_kernel_pm.h old mode 100755 new mode 100644 index 6e879fea447..db910102d76 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c index c03e9f2efbb..60c77a7a359 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c @@ -13,23 +13,24 @@ * @file mali_kernel_sysfs.c * Implementation of some sysfs data exports */ -#include /* file system operations */ + +#include #include +#include "mali_kernel_license.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" + +#if MALI_LICENSE_IS_GPL + #include #include - -/* the mali kernel subsystem types */ +#include +#include #include "mali_kernel_subsystem.h" - -#include "mali_kernel_linux.h" #include "mali_kernel_sysfs.h" +#include "mali_kernel_profiling.h" -#include "mali_kernel_license.h" - -#if MALI_LICENSE_IS_GPL -static struct dentry *mali_debugfs_dir; -#endif - +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) @@ -37,7 +38,7 @@ static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) u32 len = 0; u32 size; char *buf; -#if (MALI_STATE_TRACKING_USING_PROC==0) + size = seq_get_buf(seq_file, &buf); if(!size) @@ -52,7 +53,7 @@ static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) len += _mali_kernel_core_dump_state(buf + len, size - len); seq_commit(seq_file, len); -#endif + return 0; } @@ -70,10 +71,243 @@ static const struct file_operations mali_seq_internal_state_fops = { }; #endif /* MALI_STATE_TRACKING */ + +#if MALI_TIMELINE_PROFILING_ENABLED +static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_profiling_is_recording() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val != 0) + { + u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ + + /* check if we are already recording */ + if (MALI_TRUE == _mali_profiling_is_recording()) + { + MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); + return -EFAULT; + } + + /* check if we need to clear out an old recording first */ + if (MALI_TRUE == _mali_profiling_have_recording()) + { + if (_MALI_OSK_ERR_OK != _mali_profiling_clear()) + { + MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); + return -EFAULT; + } + } + + /* start recording profiling data */ + if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) + { + MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit)); + } + else + { + /* stop recording profiling data */ + u32 count = 0; + if (_MALI_OSK_ERR_OK != _mali_profiling_stop(&count)) + { + MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); + return -EFAULT; + } + + MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count)); + } + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_record_fops = { + .owner = THIS_MODULE, + .read = profiling_record_read, + .write = profiling_record_write, +}; + +static void *profiling_events_start(struct seq_file *s, loff_t *pos) +{ + loff_t *spos; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_profiling_have_recording()) + { + return NULL; + } + + spos = kmalloc(sizeof(loff_t), GFP_KERNEL); + if (NULL == spos) + { + return NULL; + } + + *spos = *pos; + return spos; +} + +static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos) +{ + loff_t *spos = v; + + /* check if we have data avaiable */ + if (MALI_TRUE != _mali_profiling_have_recording()) + { + return NULL; + } + + /* check if the next entry actually is avaiable */ + if (_mali_profiling_get_count() <= (u32)(*spos + 1)) + { + return NULL; + } + + *pos = ++*spos; + return spos; +} + +static void profiling_events_stop(struct seq_file *s, void *v) +{ + kfree(v); +} + +static int profiling_events_show(struct seq_file *seq_file, void *v) +{ + loff_t *spos = v; + u32 index; + u64 timestamp; + u32 event_id; + u32 data[5]; + + index = (u32)*spos; + + /* Retrieve all events */ + if (_MALI_OSK_ERR_OK == _mali_profiling_get_event(index, ×tamp, &event_id, data)) + { + seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]); + return 0; + } + + return 0; +} + +static const struct seq_operations profiling_events_seq_ops = { + .start = profiling_events_start, + .next = profiling_events_next, + .stop = profiling_events_stop, + .show = profiling_events_show +}; + +static int profiling_events_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &profiling_events_seq_ops); +} + +static const struct file_operations profiling_events_fops = { + .owner = THIS_MODULE, + .open = profiling_events_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + int r; + + r = sprintf(buf, "%u\n", _mali_profiling_get_default_enable_state() ? 1 : 0); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t profiling_proc_default_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + unsigned long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + _mali_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); + + *ppos += cnt; + return cnt; +} + +static const struct file_operations profiling_proc_default_enable_fops = { + .owner = THIS_MODULE, + .read = profiling_proc_default_enable_read, + .write = profiling_proc_default_enable_write, +}; +#endif + +static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + char buf[64]; + size_t r; + u32 mem = _mali_ukk_report_memory_usage(); + + r = snprintf(buf, 64, "%u\n", mem); + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static const struct file_operations memory_usage_fops = { + .owner = THIS_MODULE, + .read = memory_used_read, +}; + int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) { int err = 0; -#if MALI_LICENSE_IS_GPL struct device * mdev; device->mali_class = class_create(THIS_MODULE, mali_dev_name); @@ -90,48 +324,78 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev } mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL); - if(ERR_PTR(-ENODEV) == mali_debugfs_dir) { + if(ERR_PTR(-ENODEV) == mali_debugfs_dir) + { /* Debugfs not supported. */ mali_debugfs_dir = NULL; - } else { + } + else + { if(NULL != mali_debugfs_dir) { /* Debugfs directory created successfully; create files now */ +#if MALI_TIMELINE_PROFILING_ENABLED + struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); + if (mali_profiling_dir != NULL) + { + struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); + if (mali_profiling_proc_dir != NULL) + { + struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); + if (mali_profiling_proc_default_dir != NULL) + { + debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, NULL, &profiling_proc_default_enable_fops); + } + } + debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); + debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops); + } +#endif + #if MALI_STATE_TRACKING debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); #endif + + debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); } } -#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; } +#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/arm/mali/linux/mali_osk_atomics.c b/drivers/gpu/arm/mali/linux/mali_osk_atomics.c old mode 100755 new mode 100644 index cc029c4a8f8..05831c54272 --- a/drivers/gpu/arm/mali/linux/mali_osk_atomics.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_osk_indir_mmap.c b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c old mode 100755 new mode 100644 index b60bf825897..7297218b9b6 --- a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c old mode 100755 new mode 100644 index 40373427d44..4cd9d7b56ee --- a/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c @@ -276,6 +276,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); @@ -302,8 +307,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; } @@ -331,6 +335,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); @@ -348,7 +357,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 ) @@ -480,6 +489,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/arm/mali/linux/mali_osk_math.c b/drivers/gpu/arm/mali/linux/mali_osk_math.c old mode 100755 new mode 100644 index 2f7fc15847b..3e62e519cba --- a/drivers/gpu/arm/mali/linux/mali_osk_math.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_osk_memory.c b/drivers/gpu/arm/mali/linux/mali_osk_memory.c old mode 100755 new mode 100644 index bf6679f7bac..7bb470f8828 --- a/drivers/gpu/arm/mali/linux/mali_osk_memory.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_memory.c @@ -15,6 +15,7 @@ #include "mali_osk.h" #include +#include void inline *_mali_osk_calloc( u32 n, u32 size ) { @@ -31,6 +32,16 @@ void inline _mali_osk_free( void *ptr ) kfree(ptr); } +void inline *_mali_osk_valloc( u32 size ) +{ + return vmalloc(size); +} + +void inline _mali_osk_vfree( void *ptr ) +{ + vfree(ptr); +} + void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len ) { return memcpy(dst, src, len); diff --git a/drivers/gpu/arm/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali/linux/mali_osk_pm.c index f9c9e5ce2e8..6fb587ef3df 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_pm.c @@ -25,11 +25,8 @@ #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" diff --git a/drivers/gpu/arm/mali/linux/mali_osk_specific.h b/drivers/gpu/arm/mali/linux/mali_osk_specific.h old mode 100755 new mode 100644 index 54acfdd138c..6aacf17d387 --- a/drivers/gpu/arm/mali/linux/mali_osk_specific.h +++ b/drivers/gpu/arm/mali/linux/mali_osk_specific.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_time.c b/drivers/gpu/arm/mali/linux/mali_osk_time.c old mode 100755 new mode 100644 index aa7962380e6..da9b8656b70 --- a/drivers/gpu/arm/mali/linux/mali_osk_time.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_ukk_gp.c b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c index a6f355fd459..58ff1de5108 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-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/arm/mali/linux/mali_ukk_mem.c b/drivers/gpu/arm/mali/linux/mali_ukk_mem.c old mode 100755 new mode 100644 index 3f67a1e3328..05214b703d3 --- a/drivers/gpu/arm/mali/linux/mali_ukk_mem.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_ukk_pp.c b/drivers/gpu/arm/mali/linux/mali_ukk_pp.c old mode 100755 new mode 100644 index f77a177d865..31e2a6ac065 --- a/drivers/gpu/arm/mali/linux/mali_ukk_pp.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_ukk_profiling.c b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c old mode 100755 new mode 100644 index 636bd03580e..b9c5ef3aec8 --- a/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h old mode 100755 new mode 100644 index 54e3f656b37..57108a27a61 --- a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h +++ b/drivers/gpu/arm/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); -- cgit v1.2.3 From 21f1c2c94769ec2983046f0a1898add5647215da Mon Sep 17 00:00:00 2001 From: Angus Ainslie Date: Wed, 21 Dec 2011 19:14:28 -0700 Subject: arm: mali: update drivers for 3.2-rc6 These are build fixes for the 3.2-rc6 kernel Signed-off-by: Angus Ainslie --- drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c index 60c77a7a359..5e2167e96f9 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c @@ -14,6 +14,7 @@ * Implementation of some sysfs data exports */ +#include #include #include #include "mali_kernel_license.h" -- cgit v1.2.3 From 49ec17b3d5874f92f010f821a60fa8478a736d74 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Thu, 22 Mar 2012 16:42:26 +0530 Subject: gpu: mali: Fixed build error by including linux/module.h Signed-off-by: Tushar Behera --- drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c index 7b525142ac8..570f899300e 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c @@ -13,6 +13,7 @@ * Implementation of the Linux Power Management for Mali GPU kernel driver */ +#include #if USING_MALI_PMM #include -- cgit v1.2.3 From c4171d8251e437100e8d5dea0e048aa7974a6534 Mon Sep 17 00:00:00 2001 From: Sangwook Lee Date: Wed, 21 Mar 2012 13:24:11 +0000 Subject: mali: Add Streamline Support for Mali DDK SUPPORTING SAMSUNG LANDING TEAM KERNEL To apply patches into Samsung Landing Team kernel, Makefile is updated manually from Tixy's patch as well as Mali directories: drivers/gpu/arm/mali/common/ drivers/gpu/arm/mali/linux/ ARM's Streamline Performance Analyzer now supports Mali graphics. This requires support from the Mali kernel module which this patch adds. These changes were delivered by ARM Ltd in a patch file called: r2p3-01rel0_gpl_driver_streamline_support.patch that came with a README.txt which included the following... BUILDING THE DRIVER The driver can be built as normal. Profiling instrumentation is enabled by default by the patch. To disable it, use USING_PROFILING=0 in your build command. To revert to the old-style profiling code, use USING_INTERNAL_PROFILING=1 this option will disable the Streamline profiling support. KNOWN ISSUES * Attempting to read L2 cache counters when the hardware block is powered down could potentially lead to a hang due to a lack of locking. This will be addressed in a future driver update. Signed-off-by: Jon Medhurst Signed-off-by: Sangwook Lee --- drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 9 +- drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c | 32 +-- drivers/gpu/arm/mali/linux/mali_linux_trace.h | 124 ++++++++ drivers/gpu/arm/mali/linux/mali_osk_misc.c | 7 +- .../gpu/arm/mali/linux/mali_osk_profiling_gator.c | 246 ++++++++++++++++ .../arm/mali/linux/mali_osk_profiling_internal.c | 320 +++++++++++++++++++++ drivers/gpu/arm/mali/linux/mali_osk_specific.h | 100 ++++++- 7 files changed, 819 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/arm/mali/linux/mali_linux_trace.h create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c create mode 100644 drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c index 3c0d4cc8cda..010e049f0d6 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -38,6 +38,13 @@ /* */ #include "mali_kernel_license.h" +/* Streamline support for the Mali driver */ +#if defined(CONFIG_TRACEPOINTS) +/* Ask Linux to create the tracepoints */ +#define CREATE_TRACE_POINTS +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS */ + /* from the __malidrv_build_info.c file that is generated during build */ //extern const char *__malidrv_build_info(void); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c index 5e2167e96f9..2ae6a74bdfa 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 ARM Limited. All rights reserved. + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -29,7 +29,7 @@ #include #include "mali_kernel_subsystem.h" #include "mali_kernel_sysfs.h" -#include "mali_kernel_profiling.h" +#include "mali_osk_profiling.h" static struct dentry *mali_debugfs_dir = NULL; @@ -73,13 +73,13 @@ static const struct file_operations mali_seq_internal_state_fops = { #endif /* MALI_STATE_TRACKING */ -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[64]; int r; - r = sprintf(buf, "%u\n", _mali_profiling_is_recording() ? 1 : 0); + r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -112,16 +112,16 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ /* check if we are already recording */ - if (MALI_TRUE == _mali_profiling_is_recording()) + if (MALI_TRUE == _mali_osk_profiling_is_recording()) { MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); return -EFAULT; } /* check if we need to clear out an old recording first */ - if (MALI_TRUE == _mali_profiling_have_recording()) + if (MALI_TRUE == _mali_osk_profiling_have_recording()) { - if (_MALI_OSK_ERR_OK != _mali_profiling_clear()) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) { MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); return -EFAULT; @@ -129,7 +129,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf } /* start recording profiling data */ - if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) { MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); return -EFAULT; @@ -141,7 +141,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf { /* stop recording profiling data */ u32 count = 0; - if (_MALI_OSK_ERR_OK != _mali_profiling_stop(&count)) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) { MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); return -EFAULT; @@ -165,7 +165,7 @@ static void *profiling_events_start(struct seq_file *s, loff_t *pos) loff_t *spos; /* check if we have data avaiable */ - if (MALI_TRUE != _mali_profiling_have_recording()) + if (MALI_TRUE != _mali_osk_profiling_have_recording()) { return NULL; } @@ -185,13 +185,13 @@ static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos) loff_t *spos = v; /* check if we have data avaiable */ - if (MALI_TRUE != _mali_profiling_have_recording()) + if (MALI_TRUE != _mali_osk_profiling_have_recording()) { return NULL; } /* check if the next entry actually is avaiable */ - if (_mali_profiling_get_count() <= (u32)(*spos + 1)) + if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) { return NULL; } @@ -216,7 +216,7 @@ static int profiling_events_show(struct seq_file *seq_file, void *v) index = (u32)*spos; /* Retrieve all events */ - if (_MALI_OSK_ERR_OK == _mali_profiling_get_event(index, ×tamp, &event_id, data)) + if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, ×tamp, &event_id, data)) { seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]); return 0; @@ -250,7 +250,7 @@ static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user char buf[64]; int r; - r = sprintf(buf, "%u\n", _mali_profiling_get_default_enable_state() ? 1 : 0); + r = sprintf(buf, "%u\n", _mali_osk_profiling_get_default_enable_state() ? 1 : 0); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -278,7 +278,7 @@ static ssize_t profiling_proc_default_enable_write(struct file *filp, const char return ret; } - _mali_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); + _mali_osk_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); *ppos += cnt; return cnt; @@ -335,7 +335,7 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev if(NULL != mali_debugfs_dir) { /* Debugfs directory created successfully; create files now */ -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); if (mali_profiling_dir != NULL) { diff --git a/drivers/gpu/arm/mali/linux/mali_linux_trace.h b/drivers/gpu/arm/mali/linux/mali_linux_trace.h new file mode 100644 index 00000000000..045e6da3d1a --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_linux_trace.h @@ -0,0 +1,124 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ) +#define MALI_LINUX_TRACE_H + +#include +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mali +#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM) + +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE mali_linux_trace + +/** + * Define the tracepoint used to communicate the status of a GPU. Called + * when a GPU turns on or turns off. + * + * @param event_id The type of the event. This parameter is a bitfield + * encoding the type of the event. + * + * @param d0 First data parameter. + * @param d1 Second data parameter. + * @param d2 Third data parameter. + * @param d3 Fourth data parameter. + * @param d4 Fifth data parameter. + */ +TRACE_EVENT(mali_timeline_event, + + TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, + unsigned int d2, unsigned int d3, unsigned int d4), + + TP_ARGS(event_id, d0, d1, d2, d3, d4), + + TP_STRUCT__entry( + __field(unsigned int, event_id) + __field(unsigned int, d0) + __field(unsigned int, d1) + __field(unsigned int, d2) + __field(unsigned int, d3) + __field(unsigned int, d4) + ), + + TP_fast_assign( + __entry->event_id = event_id; + __entry->d0 = d0; + __entry->d1 = d1; + __entry->d2 = d2; + __entry->d3 = d3; + __entry->d4 = d4; + ), + + TP_printk("event=%d", __entry->event_id) +); + +/** + * Define a tracepoint used to regsiter the value of a hardware counter. + * Hardware counters belonging to the vertex or fragment processor are + * reported via this tracepoint each frame, whilst L2 cache hardware + * counters are reported continuously. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_hw_counter, + + TP_PROTO(unsigned int counter_id, unsigned int value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(unsigned int, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + __entry->value = value; + ), + + TP_printk("event %d = %d", __entry->counter_id, __entry->value) +); + +/** + * Define a tracepoint used to register the value of a software counter. + * + * @param counter_id The counter ID. + * @param value The value of the counter. + */ +TRACE_EVENT(mali_sw_counter, + + TP_PROTO(unsigned int counter_id, signed long long value), + + TP_ARGS(counter_id, value), + + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(signed long long, value) + ), + + TP_fast_assign( + __entry->counter_id = counter_id; + __entry->value = value; + ), + + TP_printk("event %d = %lld", __entry->counter_id, __entry->value) +); + +#endif /* MALI_LINUX_TRACE_H */ + +/* This part must exist outside the header guard. */ +#include diff --git a/drivers/gpu/arm/mali/linux/mali_osk_misc.c b/drivers/gpu/arm/mali/linux/mali_osk_misc.c index 12f4299ee9b..286e45d0c08 100755 --- a/drivers/gpu/arm/mali/linux/mali_osk_misc.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -61,3 +61,8 @@ 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/arm/mali/linux/mali_osk_profiling_gator.c b/drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c new file mode 100644 index 00000000000..a3963678460 --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c @@ -0,0 +1,246 @@ +/** + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained + * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_ukk.h" +#include "mali_osk_profiling.h" +#include "mali_linux_trace.h" + +#if defined(USING_MALI400_L2_CACHE) +#include "mali_kernel_l2_cache.h" +#endif /* USING_MALI400_L2_CACHE */ + +#define COUNTER_DISABLED (-1) + +/** + * Since there are only two physical hardware counters per GPU block, we + * need to multiplex the range of possible events that can be collected by + * each counter. This multiplexing is achieved by means of the following + * table, which holds the event ID that should be collected by each hardware + * counter. + * + * Note that this table should be updated with any change to the above + * _mali_osk_counter_id enumeration. + */ +s32 _mali_osk_hw_counter_table[] = { + COUNTER_DISABLED, /* ACTIVITY_VP */ + COUNTER_DISABLED, /* ACTIVITY_FP0 */ + COUNTER_DISABLED, /* ACTIVITY_FP1 */ + COUNTER_DISABLED, /* ACTIVITY_FP2 */ + COUNTER_DISABLED, /* ACTIVITY_FP3 */ + COUNTER_DISABLED, /* COUNTER_L2_C0 */ + COUNTER_DISABLED, /* COUNTER_L2_C1 */ + COUNTER_DISABLED, /* COUNTER_VP_C0 */ + COUNTER_DISABLED, /* COUNTER_VP_C1 */ + COUNTER_DISABLED, /* COUNTER_FP0_C0 */ + COUNTER_DISABLED, /* COUNTER_FP0_C1 */ + COUNTER_DISABLED, /* COUNTER_FP1_C0 */ + COUNTER_DISABLED, /* COUNTER_FP1_C1 */ + COUNTER_DISABLED, /* COUNTER_FP2_C0 */ + COUNTER_DISABLED, /* COUNTER_FP2_C1 */ + COUNTER_DISABLED, /* COUNTER_FP3_C0 */ + COUNTER_DISABLED, /* COUNTER_FP3_C1 */ +}; + +mali_bool _mali_osk_profiling_query_hw_counter(u32 counter_id, u32 *event_id) +{ + /* Check that the counter is in range... */ + if (counter_id >= FIRST_HW_COUNTER && counter_id <= LAST_HW_COUNTER) + { + s32 id = _mali_osk_hw_counter_table[counter_id]; + + /* ...and enabled */ + if (id != COUNTER_DISABLED) + { + /* Update the pointer to the event ID */ + *event_id = (u32)id; + + return MALI_TRUE; + } + } + + /* The counter was disabled or out of range */ + return MALI_FALSE; +} + +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_profiling_term(void) +{ + /* Nothing to do */ +} + +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +u32 _mali_osk_profiling_get_count(void) +{ + return 0; +} + +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, + u32* event_id, u32 data[5]) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +mali_bool _mali_osk_profiling_is_recording(void) +{ + return MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return MALI_FALSE; +} + +void _mali_osk_profiling_set_default_enable_state(mali_bool enable) +{ + /* Nothing to do */ +} + +mali_bool _mali_osk_profiling_get_default_enable_state(void) +{ + return MALI_FALSE; +} + +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) +{ + return _mali_osk_profiling_start(&args->limit); +} + +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +{ + /* Always add process and thread identificator in the first two data elements for events from user space */ + _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_osk_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); +} + +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +{ + return _mali_osk_profiling_clear(); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args) +{ + return _MALI_OSK_ERR_UNSUPPORTED; +} + +/** + * Called by gator.ko to populate the _mali_osk_hw_counter_table. + * + * @param counter_id The counter ID. + * @param event_id Event ID that the counter should count. + * + * @return 1 on success, 0 on failure. + */ +int _mali_profiling_set_event(u32 counter_id, s32 event_id) +{ +#if defined(USING_MALI400_L2_CACHE) + /* + * The L2 cache counters have special handling in the driver. Since we + * receive new event IDs for each counter one at a time, we need to know + * what the L2 counters are currently programmed to read. This way we + * can supply the current value to the counter we _aren't_ trying to + * program; mali_kernel_l2_cache_set_perf_counters will dutifully ignore + * that counter. + */ + u32 current_src0, current_src1, current_val0, current_val1; + + mali_kernel_l2_cache_get_perf_counters(¤t_src0, ¤t_val0, + ¤t_src1, ¤t_val1); + + if (counter_id == COUNTER_L2_C0) + { + mali_kernel_l2_cache_set_perf_counters(event_id, current_src1, 0); + + return 1; + } + else if (counter_id == COUNTER_L2_C1) + { + mali_kernel_l2_cache_set_perf_counters(current_src0, event_id, 0); + + return 1; + } +#endif /* USING_MALI400_L2_CACHE */ + + /* Check that the counter is in range */ + if (counter_id >= FIRST_HW_COUNTER && counter_id <= LAST_HW_COUNTER) + { + /* + * This does not actually update the hardware with the new event ID; + * it will query what event ID it should be counting on each frame + * via _mali_osk_profiling_query_hw_counter. + */ + _mali_osk_hw_counter_table[counter_id] = event_id; + + return 1; + } + + return 0; +} + +#if defined(USING_MALI400_L2_CACHE) +/** + * Called by gator.ko to retrieve the L2 cache counter values. The L2 cache + * counters are unique in that they are polled by gator, rather than being + * transmitted via the tracepoint mechanism. + * + * @param src0 First L2 cache counter ID. + * @param val0 First L2 cache counter value. + * @param src1 Second L2 cache counter ID. + * @param val1 Second L2 cache counter value. + */ +void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1) +{ + mali_kernel_l2_cache_get_perf_counters(src0, val0, src1, val1); +} + +EXPORT_SYMBOL(_mali_profiling_get_counters); +#endif /* USING_MALI400_L2_CACHE */ + +EXPORT_SYMBOL(_mali_profiling_set_event); diff --git a/drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c b/drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c new file mode 100644 index 00000000000..538fe4e69fc --- /dev/null +++ b/drivers/gpu/arm/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/arm/mali/linux/mali_osk_specific.h b/drivers/gpu/arm/mali/linux/mali_osk_specific.h index 6aacf17d387..3e7d08959b1 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_specific.h +++ b/drivers/gpu/arm/mali/linux/mali_osk_specific.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -29,4 +29,102 @@ extern "C" } #endif +/** The list of events supported by the Mali DDK. */ +typedef enum +{ + /* Vertex processor activity */ + ACTIVITY_VP = 0, + + /* Fragment processor activity */ + ACTIVITY_FP0, + ACTIVITY_FP1, + ACTIVITY_FP2, + ACTIVITY_FP3, + + /* L2 cache counters */ + COUNTER_L2_C0, + COUNTER_L2_C1, + + /* Vertex processor counters */ + COUNTER_VP_C0, + COUNTER_VP_C1, + + /* Fragment processor counters */ + COUNTER_FP0_C0, + COUNTER_FP0_C1, + COUNTER_FP1_C0, + COUNTER_FP1_C1, + COUNTER_FP2_C0, + COUNTER_FP2_C1, + COUNTER_FP3_C0, + COUNTER_FP3_C1, + + /* + * If more hardware counters are added, the _mali_osk_hw_counter_table + * below should also be updated. + */ + + /* EGL software counters */ + COUNTER_EGL_BLIT_TIME, + + /* GLES software counters */ + COUNTER_GLES_DRAW_ELEMENTS_CALLS, + COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES, + COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_ARRAYS_CALLS, + COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED, + COUNTER_GLES_DRAW_POINTS, + COUNTER_GLES_DRAW_LINES, + COUNTER_GLES_DRAW_LINE_LOOP, + COUNTER_GLES_DRAW_LINE_STRIP, + COUNTER_GLES_DRAW_TRIANGLES, + COUNTER_GLES_DRAW_TRIANGLE_STRIP, + COUNTER_GLES_DRAW_TRIANGLE_FAN, + COUNTER_GLES_NON_VBO_DATA_COPY_TIME, + COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI, + COUNTER_GLES_UPLOAD_TEXTURE_TIME, + COUNTER_GLES_UPLOAD_VBO_TIME, + COUNTER_GLES_NUM_FLUSHES, + COUNTER_GLES_NUM_VSHADERS_GENERATED, + COUNTER_GLES_NUM_FSHADERS_GENERATED, + COUNTER_GLES_VSHADER_GEN_TIME, + COUNTER_GLES_FSHADER_GEN_TIME, + COUNTER_GLES_INPUT_TRIANGLES, + COUNTER_GLES_VXCACHE_HIT, + COUNTER_GLES_VXCACHE_MISS, + COUNTER_GLES_VXCACHE_COLLISION, + COUNTER_GLES_CULLED_TRIANGLES, + COUNTER_GLES_CULLED_LINES, + COUNTER_GLES_BACKFACE_TRIANGLES, + COUNTER_GLES_GBCLIP_TRIANGLES, + COUNTER_GLES_GBCLIP_LINES, + COUNTER_GLES_TRIANGLES_DRAWN, + COUNTER_GLES_DRAWCALL_TIME, + COUNTER_GLES_TRIANGLES_COUNT, + COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT, + COUNTER_GLES_STRIP_TRIANGLES_COUNT, + COUNTER_GLES_FAN_TRIANGLES_COUNT, + COUNTER_GLES_LINES_COUNT, + COUNTER_GLES_INDEPENDENT_LINES_COUNT, + COUNTER_GLES_STRIP_LINES_COUNT, + COUNTER_GLES_LOOP_LINES_COUNT, + + /* Framebuffer capture pseudo-counter */ + COUNTER_FILMSTRIP, + + NUMBER_OF_EVENTS +} _mali_osk_counter_id; + +#define FIRST_ACTIVITY_EVENT ACTIVITY_VP +#define LAST_ACTIVITY_EVENT ACTIVITY_FP3 + +#define FIRST_HW_COUNTER COUNTER_L2_C0 +#define LAST_HW_COUNTER COUNTER_FP3_C1 + +#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME +#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT + +#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP +#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP + #endif /* __MALI_OSK_SPECIFIC_H__ */ -- cgit v1.2.3 From c91708a60a41bccd6014ef32ceacc61648954d62 Mon Sep 17 00:00:00 2001 From: Sangwook Lee Date: Thu, 29 Mar 2012 12:17:24 +0100 Subject: origen: android: mali: Disable profiling of Mali L2 cache Add patch into Origen When connecting the ARM Streamline Performance Analyzer to Snowball Android this will cause a board lock-up if the screen is static (Bug #961962). The cause of this appears to be a know issue with reading the L2 cache performance counters whilst the hardware block is powered down. As the current code is written to access these counters even when they have not been explicitly selected then this issue prevents Streamline being used reliably for any purpose. To workaround this bug, this patch disables support for the L2 cache counters in Mali. This has no effect on the operation of the cache. Signed-off-by: Jon Medhurst Signed-off-by: Sangwook Lee --- drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c b/drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c index a3963678460..5c1618c2eb8 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_profiling_gator.c @@ -11,6 +11,8 @@ * Boston, MA 02110-1301, USA. */ +#define DONT_USE_L2_CACHE_COUNTERS /* These traces can cause lock-ups so disable them. */ + #include #include "mali_kernel_common.h" @@ -19,7 +21,7 @@ #include "mali_osk_profiling.h" #include "mali_linux_trace.h" -#if defined(USING_MALI400_L2_CACHE) +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) #include "mali_kernel_l2_cache.h" #endif /* USING_MALI400_L2_CACHE */ @@ -180,7 +182,7 @@ _mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config */ int _mali_profiling_set_event(u32 counter_id, s32 event_id) { -#if defined(USING_MALI400_L2_CACHE) +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) /* * The L2 cache counters have special handling in the driver. Since we * receive new event IDs for each counter one at a time, we need to know @@ -224,7 +226,7 @@ int _mali_profiling_set_event(u32 counter_id, s32 event_id) return 0; } -#if defined(USING_MALI400_L2_CACHE) +#if defined(USING_MALI400_L2_CACHE) && !defined(DONT_USE_L2_CACHE_COUNTERS) /** * Called by gator.ko to retrieve the L2 cache counter values. The L2 cache * counters are unique in that they are polled by gator, rather than being -- cgit v1.2.3 From 4b9c7882550e4e1e3461430c70abb652c8c1fa20 Mon Sep 17 00:00:00 2001 From: Chunsang Jeong Date: Thu, 29 Mar 2012 14:48:20 +0900 Subject: Updates r2p4-02rel, which was released Mar. 2nd at malideveloper.com Signed-off-by: Chunsang Jeong --- .../gpu/arm/mali/linux/mali_device_pause_resume.c | 2 +- .../gpu/arm/mali/linux/mali_device_pause_resume.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_linux.c | 6 +- drivers/gpu/arm/mali/linux/mali_kernel_linux.h | 7 ++- drivers/gpu/arm/mali/linux/mali_kernel_pm.c | 3 +- drivers/gpu/arm/mali/linux/mali_kernel_pm.h | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c | 2 +- drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h | 2 +- .../arm/mali/linux/mali_linux_dvfs_pause_resume.c | 72 ---------------------- drivers/gpu/arm/mali/linux/mali_linux_pm.h | 2 +- .../gpu/arm/mali/linux/mali_linux_pm_testsuite.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_atomics.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_irq.c | 31 ++++++++-- drivers/gpu/arm/mali/linux/mali_osk_locks.c | 2 +- .../gpu/arm/mali/linux/mali_osk_low_level_mem.c | 5 +- drivers/gpu/arm/mali/linux/mali_osk_mali.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_math.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_memory.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_misc.c | 0 drivers/gpu/arm/mali/linux/mali_osk_notification.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_pm.c | 2 +- .../arm/mali/linux/mali_osk_profiling_internal.c | 17 +++-- drivers/gpu/arm/mali/linux/mali_osk_specific.h | 2 +- drivers/gpu/arm/mali/linux/mali_osk_time.c | 2 +- drivers/gpu/arm/mali/linux/mali_osk_timers.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_core.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_gp.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_mem.c | 6 +- drivers/gpu/arm/mali/linux/mali_ukk_pp.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_profiling.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_vsync.c | 2 +- drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h | 2 +- 35 files changed, 77 insertions(+), 122 deletions(-) mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_device_pause_resume.c delete mode 100644 drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_linux_pm.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_irq.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_locks.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_mali.c mode change 100755 => 100644 drivers/gpu/arm/mali/linux/mali_osk_misc.c (limited to 'drivers/gpu/arm/mali/linux') diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c old mode 100755 new mode 100644 index 7a69ae95011..da9cdd99d27 --- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c +++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.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. diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h index 155a3e69d48..c770cb6f532 100644 --- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h +++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h index 47b67cccb82..5386566010a 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.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. diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c index 010e049f0d6..6d108ff7a37 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c @@ -151,12 +151,16 @@ void mali_driver_exit(void) { mali_kernel_destructor(); -#if USING_MALI_PMM #if MALI_LICENSE_IS_GPL +#if USING_MALI_PMM #ifdef CONFIG_PM _mali_dev_platform_unregister(); #endif #endif + + flush_workqueue(mali_wq); + destroy_workqueue(mali_wq); + mali_wq = NULL; #endif } diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h index c362a7c77c5..b63baa90b7f 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.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. @@ -28,6 +28,11 @@ struct mali_dev #endif }; +#if MALI_LICENSE_IS_GPL +/* Defined in mali_osk_irq.h */ +extern struct workqueue_struct * mali_wq; +#endif + _mali_osk_errcode_t initialize_kernel_device(void); void terminate_kernel_device(void); diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c index 570f899300e..ea92368ccae 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.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. @@ -54,7 +54,6 @@ static int is_os_pmm_thread_waiting = 0; /* kernel should be configured with power management support */ #ifdef CONFIG_PM -/* License should be GPL */ #if MALI_LICENSE_IS_GPL /* Linux kernel major version */ diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h b/drivers/gpu/arm/mali/linux/mali_kernel_pm.h index db910102d76..7ee1572a534 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c index 2ae6a74bdfa..2a61a87e6f3 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c @@ -386,7 +386,7 @@ int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_d #else -/* Dummy implementations for non-GPL */ +/* Dummy implementations for when the sysfs API isn't available. */ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) { diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h index d79a8862269..26a60745ffc 100644 --- a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h +++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 ARM Limited. All rights reserved. + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. 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 deleted file mode 100644 index 3d60d18e005..00000000000 --- a/drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained from Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** - * @file mali_linux_dvfs_pause_resume.c - * Implementation of the Mali pause/resume functionality - */ -#if USING_MALI_PMM -#include -#include -#include -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_platform.h" -#include "mali_linux_pm.h" -#include "mali_linux_dvfs_pause_resume.h" -#include "mali_pmm.h" -#include "mali_kernel_license.h" -#ifdef CONFIG_PM -#if MALI_LICENSE_IS_GPL - -/* Mali Pause Resume APIs */ -int mali_dev_dvfs_pause() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND)) - { - err = -EPERM; - } - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err)) - { - mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_SUSPEND; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_dvfs_pause); - -int mali_dev_dvfs_resume() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS) - || (mali_device_state == _MALI_DEVICE_SUSPEND)) - { - err = -EPERM; - } - if (!err) - { - mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_dvfs_resume); - -#endif /* MALI_LICENSE_IS_GPL */ -#endif /* CONFIG_PM */ -#endif /* USING_MALI_PMM */ diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm.h b/drivers/gpu/arm/mali/linux/mali_linux_pm.h old mode 100755 new mode 100644 index d401697f2f4..ad69853333e --- a/drivers/gpu/arm/mali/linux/mali_linux_pm.h +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm.h @@ -1,6 +1,6 @@ /* - * 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. diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h old mode 100755 new mode 100644 index c80b0b0a5e3..e88ce94281f --- a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h +++ b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_atomics.c b/drivers/gpu/arm/mali/linux/mali_osk_atomics.c index 05831c54272..32f8e6bdac7 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_atomics.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_atomics.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c index 7297218b9b6..883409ecf51 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h old mode 100755 new mode 100644 index f87739bb8f9..5c0b1f0340d --- a/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.h +++ b/drivers/gpu/arm/mali/linux/mali_osk_indir_mmap.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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_irq.c b/drivers/gpu/arm/mali/linux/mali_osk_irq.c old mode 100755 new mode 100644 index b667961a0ac..ed43b4fa0c4 --- a/drivers/gpu/arm/mali/linux/mali_osk_irq.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_irq.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -15,11 +15,13 @@ #include /* For memory allocation */ #include +#include #include "mali_osk.h" #include "mali_kernel_core.h" #include "mali_kernel_common.h" #include "mali_kernel_license.h" +#include "mali_kernel_linux.h" #include "linux/interrupt.h" typedef struct _mali_osk_irq_t_struct @@ -33,6 +35,7 @@ typedef struct _mali_osk_irq_t_struct #if MALI_LICENSE_IS_GPL static struct workqueue_struct *pmm_wq=NULL; +struct workqueue_struct *mali_wq = NULL; #endif typedef void (*workqueue_func_t)(void *); @@ -60,6 +63,22 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL); if (NULL == irq_object) return NULL; +#if MALI_LICENSE_IS_GPL + if (NULL == mali_wq) + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) + mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0); +#else + mali_wq = create_workqueue("mali"); +#endif + if(NULL == mali_wq) + { + MALI_PRINT_ERROR(("Unable to create Mali workqueue\n")); + return NULL; + } + } +#endif + /* workqueue API changed in 2.6.20, support both versions: */ #if defined(INIT_DELAYED_WORK) /* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */ @@ -153,10 +172,10 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) } else { -#endif - schedule_work(&irq_object->work_queue_irq_handle); -#if MALI_LICENSE_IS_GPL + queue_work(mali_wq, &irq_object->work_queue_irq_handle); } +#else + schedule_work(&irq_object->work_queue_irq_handle); #endif } @@ -168,6 +187,10 @@ void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq ) { flush_workqueue(pmm_wq); } + else + { + flush_workqueue(mali_wq); + } #endif } diff --git a/drivers/gpu/arm/mali/linux/mali_osk_locks.c b/drivers/gpu/arm/mali/linux/mali_osk_locks.c old mode 100755 new mode 100644 index 139dc5e3de3..30af91deb6f --- a/drivers/gpu/arm/mali/linux/mali_osk_locks.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_locks.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. 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 4cd9d7b56ee..210d8226074 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.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. @@ -76,7 +76,7 @@ static void _allocation_list_item_release(AllocationList * item); /* Variable declarations */ -spinlock_t allocation_list_spinlock; +static DEFINE_SPINLOCK(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 @@ -99,7 +99,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 ; } diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c old mode 100755 new mode 100644 index 5b84549ef86..06a27bc4f91 --- a/drivers/gpu/arm/mali/linux/mali_osk_mali.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_math.c b/drivers/gpu/arm/mali/linux/mali_osk_math.c index 3e62e519cba..bb25e7dc7dd 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_math.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_math.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_memory.c b/drivers/gpu/arm/mali/linux/mali_osk_memory.c index 7bb470f8828..5354e855e8d 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_memory.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_memory.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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_misc.c b/drivers/gpu/arm/mali/linux/mali_osk_misc.c old mode 100755 new mode 100644 diff --git a/drivers/gpu/arm/mali/linux/mali_osk_notification.c b/drivers/gpu/arm/mali/linux/mali_osk_notification.c index 539f9ab68b0..fb4907eefce 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_notification.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_notification.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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali/linux/mali_osk_pm.c index 6fb587ef3df..e5b8ea1a78a 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_pm.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_pm.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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c b/drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c index 538fe4e69fc..c162ffd8fd1 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_profiling_internal.c @@ -1,14 +1,11 @@ -/** +/* * Copyright (C) 2010-2012 ARM Limited. All rights reserved. - * - * This program is free software and is provided to you under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation, and any use by you of this program is subject to the terms of - * such GNU licence. - * - * A copy of the licence is included with the program, and can also be obtained - * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * + * This 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" diff --git a/drivers/gpu/arm/mali/linux/mali_osk_specific.h b/drivers/gpu/arm/mali/linux/mali_osk_specific.h index 3e7d08959b1..a7ad2fc0cb3 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_specific.h +++ b/drivers/gpu/arm/mali/linux/mali_osk_specific.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 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. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_time.c b/drivers/gpu/arm/mali/linux/mali_osk_time.c index da9b8656b70..b399b874880 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_time.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_time.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_osk_timers.c b/drivers/gpu/arm/mali/linux/mali_osk_timers.c index 3dfba76bcb3..2353fdb6ecf 100644 --- a/drivers/gpu/arm/mali/linux/mali_osk_timers.c +++ b/drivers/gpu/arm/mali/linux/mali_osk_timers.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. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_core.c b/drivers/gpu/arm/mali/linux/mali_ukk_core.c index 0f745492613..6c7fed5d0b6 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_core.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_core.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. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_gp.c b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c index 58ff1de5108..13a8e25bc41 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, 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. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_mem.c b/drivers/gpu/arm/mali/linux/mali_ukk_mem.c index 05214b703d3..6ec41a59339 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_mem.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -230,7 +230,7 @@ int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mal if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit; /* allocate temporary buffer (kernel side) to store mmu page table info */ - kargs.buffer = _mali_osk_malloc(kargs.size); + kargs.buffer = _mali_osk_valloc(kargs.size); if (NULL == kargs.buffer) { rc = -ENOMEM; @@ -254,7 +254,7 @@ int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mal rc = 0; err_exit: - if (kargs.buffer) _mali_osk_free(kargs.buffer); + if (kargs.buffer) _mali_osk_vfree(kargs.buffer); return rc; } diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_pp.c b/drivers/gpu/arm/mali/linux/mali_ukk_pp.c index 31e2a6ac065..98e01739de3 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_pp.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c index b9c5ef3aec8..ab71b75ff97 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_profiling.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_profiling.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. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c b/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c index 965ee411535..d27fac1dae8 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c +++ b/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 ARM Limited. All rights reserved. + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h index 57108a27a61..af56efdde43 100644 --- a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h +++ b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.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. -- cgit v1.2.3