platform/$(MALI_PLATFORM)/mali_dvfs.o
endif
+ifeq ($(MALI_PLATFORM_FILES),)
+ifeq ($(CONFIG_ARCH_EXYNOS4),y)
+EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+export MALI_PLATFORM=exynos4
+export MALI_PLATFORM_FILES_BUILDIN = $(notdir $(wildcard $(src)/platform/$(MALI_PLATFORM)/*.c))
+export MALI_PLATFORM_FILES_ADD_PREFIX = $(addprefix platform/$(MALI_PLATFORM)/,$(MALI_PLATFORM_FILES_BUILDIN))
+endif
+endif
+
mali-y += \
linux/mali_osk_atomics.o \
linux/mali_osk_irq.o \
linux/mali_ukk_soft_job.o \
linux/mali_ukk_timeline.o
+mali-$(CONFIG_MALI_DEVFREQ) += \
+ linux/mali_devfreq.o \
+ common/mali_pm_metrics.o
+
# Source files which always are included in a build
mali-y += \
common/mali_kernel_core.o \
linux/mali_pmu_power_up_down.o \
__malidrv_build_info.o
+ifneq ($(wildcard $(src)/linux/mali_slp_global_lock.c),)
+ mali-y += linux/mali_slp_global_lock.o
+endif
+
ifneq ($(MALI_PLATFORM_FILES),)
mali-y += $(MALI_PLATFORM_FILES:.c=.o)
endif
+ifneq ($(MALI_PLATFORM_FILES_ADD_PREFIX),)
+ mali-y += $(MALI_PLATFORM_FILES_ADD_PREFIX:.c=.o)
+endif
+
mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o
mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o
ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(src)/timestamp-$(TIMESTAMP)
mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_memory_dma_buf.o
+mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_memory_secure.o
mali-$(CONFIG_SYNC) += linux/mali_sync.o
ccflags-$(CONFIG_SYNC) += -Idrivers/staging/android
ccflags-y += -DMALI_UPPER_HALF_SCHEDULING
endif
+#build-in include path is different
+ifeq ($(MALI_PLATFORM_FILES),)
+ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../ump/include/
+else
ccflags-$(CONFIG_MALI400_UMP) += -I$(src)/../../ump/include/ump
+endif
ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG
# Use our defines when compiling
config MALI_DVFS
bool "Enable Mali dynamically frequency change"
- depends on MALI400
+ depends on MALI400 && !MALI_DEVFREQ
default y
---help---
This enables support for dynamic change frequency of Mali with the goal of lowering power consumption.
device tree is enabled in kernel and corresponding hardware description is implemented
properly in device DTS file.
+config MALI_DEVFREQ
+ bool "Using devfreq to tuning frequency"
+ depends on MALI400 && PM_DEVFREQ
+ default n
+ ---help---
+ Support devfreq for Mali.
+
+ Using the devfreq framework and, by default, the simpleondemand
+ governor, the frequency of Mali will be dynamically selected from the
+ available OPPs.
+
config MALI_QUIET
bool "Make Mali driver very quiet"
depends on MALI400 && !MALI400_DEBUG
#
-# Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+# Copyright (C) 2010-2016 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.
MALI_PMU_PARALLEL_POWER_UP ?= 0
USING_DT ?= 0
MALI_MEM_SWAP_TRACKING ?= 0
+USING_DEVFREQ ?= 0
# The Makefile sets up "arch" based on the CONFIG, creates the version info
# string and the __malidrv_build_info.c file, and then call the Linux build
endif
endif
+ifeq ($(USING_DEVFREQ), 1)
+ifdef CONFIG_PM_DEVFREQ
+export CONFIG_MALI_DEVFREQ=y
+export EXTRA_DEFINES += -DCONFIG_MALI_DEVFREQ=1
+else
+$(warning "You want to support DEVFREQ but kernel didn't support DEVFREQ.")
+endif
+endif
+
ifneq ($(BUILD),release)
# Debug
export CONFIG_MALI400_DEBUG=y
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/*
- * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014-2016 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.
/*
- * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/*
- * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014, 2016 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.
/*
- * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014, 2016 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.
#include "mali_timeline.h"
#include "mali_osk_profiling.h"
#include "mali_session.h"
+#include "mali_osk_mali.h"
/*Add for voltage scan function*/
extern u32 mali_group_error;
return MALI_FALSE;
}
+static mali_bool mali_executor_schedule_is_early_out(mali_bool *gpu_secure_mode_is_needed)
+{
+ struct mali_pp_job *next_pp_job_to_start = NULL;
+ struct mali_group *group;
+ struct mali_group *tmp_group;
+ struct mali_pp_job *physical_pp_job_working = NULL;
+ struct mali_pp_job *virtual_pp_job_working = NULL;
+ mali_bool gpu_working_in_protected_mode = MALI_FALSE;
+ mali_bool gpu_working_in_non_protected_mode = MALI_FALSE;
+
+ MALI_DEBUG_ASSERT_LOCK_HELD(mali_scheduler_lock_obj);
+
+ *gpu_secure_mode_is_needed = MALI_FALSE;
+
+ /* Check if the gpu secure mode is supported, exit if not.*/
+ if (MALI_FALSE == _mali_osk_gpu_secure_mode_is_supported()) {
+ return MALI_FALSE;
+ }
+
+ /* Check if need to set gpu secure mode for the next pp job,
+ * get the next pp job that will be scheduled if exist.
+ */
+ next_pp_job_to_start = mali_scheduler_job_pp_next();
+
+ /* Check current pp physical/virtual running job is protected job or not if exist.*/
+ _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_working,
+ struct mali_group, executor_list) {
+ physical_pp_job_working = group->pp_running_job;
+ break;
+ }
+
+ if (EXEC_STATE_WORKING == virtual_group_state) {
+ virtual_pp_job_working = virtual_group->pp_running_job;
+ }
+
+ if (NULL != physical_pp_job_working) {
+ if (MALI_TRUE == mali_pp_job_is_protected_job(physical_pp_job_working)) {
+ gpu_working_in_protected_mode = MALI_TRUE;
+ } else {
+ gpu_working_in_non_protected_mode = MALI_TRUE;
+ }
+ } else if (NULL != virtual_pp_job_working) {
+ if (MALI_TRUE == mali_pp_job_is_protected_job(virtual_pp_job_working)) {
+ gpu_working_in_protected_mode = MALI_TRUE;
+ } else {
+ gpu_working_in_non_protected_mode = MALI_TRUE;
+ }
+ } else if (EXEC_STATE_WORKING == gp_group_state) {
+ gpu_working_in_non_protected_mode = MALI_TRUE;
+ }
+
+ /* If the next pp job is the protected pp job.*/
+ if ((NULL != next_pp_job_to_start) && MALI_TRUE == mali_pp_job_is_protected_job(next_pp_job_to_start)) {
+ /* if gp is working or any non-protected pp job is working now, unable to schedule protected pp job. */
+ if (MALI_TRUE == gpu_working_in_non_protected_mode)
+ return MALI_TRUE;
+
+ *gpu_secure_mode_is_needed = MALI_TRUE;
+ return MALI_FALSE;
+
+ }
+
+ if (MALI_TRUE == gpu_working_in_protected_mode) {
+ /* Unable to schedule non-protected pp job/gp job if exist protected pp running jobs*/
+ return MALI_TRUE;
+ }
+
+ return MALI_FALSE;
+}
/*
* This is where jobs are actually started.
*/
u32 num_physical_to_process = 0;
mali_bool trigger_pm_update = MALI_FALSE;
mali_bool deactivate_idle_group = MALI_TRUE;
+ mali_bool gpu_secure_mode_is_needed = MALI_FALSE;
/* Physical groups + jobs to start in this function */
struct mali_group *groups_to_start[MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS];
/* Lock needed in order to safely handle the job queues */
mali_scheduler_lock();
- /* 1. Activate gp firstly if have gp job queued. */
- if (EXEC_STATE_INACTIVE == gp_group_state &&
- 0 < mali_scheduler_job_gp_count()) {
+ /* 1. Check the schedule if need to early out. */
+ if (MALI_TRUE == mali_executor_schedule_is_early_out(&gpu_secure_mode_is_needed)) {
+ mali_scheduler_unlock();
+ return;
+ }
+
+ /* 2. Activate gp firstly if have gp job queued. */
+ if ((EXEC_STATE_INACTIVE == gp_group_state)
+ && (0 < mali_scheduler_job_gp_count())
+ && (gpu_secure_mode_is_needed == MALI_FALSE)) {
enum mali_group_state state =
mali_group_activate(gp_group);
}
}
- /* 2. Prepare as many physical groups as needed/possible */
+ /* 3. Prepare as many physical groups as needed/possible */
- num_physical_needed = mali_scheduler_job_physical_head_count();
+ num_physical_needed = mali_scheduler_job_physical_head_count(gpu_secure_mode_is_needed);
/* On mali-450 platform, we don't need to enter in this block frequently. */
if (0 < num_physical_needed) {
if (0 < num_physical_needed) {
- /* 2.1. Activate groups which are inactive */
+ /* 3.1. Activate groups which are inactive */
struct mali_group *group;
struct mali_group *temp;
if (mali_executor_virtual_group_is_usable()) {
/*
- * 2.2. And finally, steal and activate groups
+ * 3.2. And finally, steal and activate groups
* from virtual group if we need even more
*/
while (0 < num_physical_needed) {
}
}
- /* 2.3. Assign physical jobs to groups */
+ /* 3.3. Assign physical jobs to groups */
if (0 < num_physical_to_process) {
struct mali_group *group;
MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS);
MALI_DEBUG_ASSERT(0 <
- mali_scheduler_job_physical_head_count());
+ mali_scheduler_job_physical_head_count(gpu_secure_mode_is_needed));
- if (mali_executor_hint_is_enabled(
- MALI_EXECUTOR_HINT_GP_BOUND)) {
- if (MALI_TRUE == mali_executor_tackle_gp_bound()) {
- /*
- * We're gp bound,
- * don't start this right now.
- */
- deactivate_idle_group = MALI_FALSE;
- num_physical_to_process = 0;
- break;
- }
+ /* If the next pp job is non-protected, check if gp bound now. */
+ if ((MALI_FALSE == gpu_secure_mode_is_needed)
+ && (mali_executor_hint_is_enabled(MALI_EXECUTOR_HINT_GP_BOUND))
+ && (MALI_TRUE == mali_executor_tackle_gp_bound())) {
+ /*
+ * We're gp bound,
+ * don't start this right now.
+ */
+ deactivate_idle_group = MALI_FALSE;
+ num_physical_to_process = 0;
+ break;
}
job = mali_scheduler_job_pp_physical_get(
&sub_job);
+ if (MALI_FALSE == gpu_secure_mode_is_needed) {
+ MALI_DEBUG_ASSERT(MALI_FALSE == mali_pp_job_is_protected_job(job));
+ } else {
+ MALI_DEBUG_ASSERT(MALI_TRUE == mali_pp_job_is_protected_job(job));
+ }
+
MALI_DEBUG_ASSERT_POINTER(job);
MALI_DEBUG_ASSERT(sub_job <= MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS);
}
}
-
- /* 3. Deactivate idle pp group , must put deactive here before active vitual group
+ /* 4. Deactivate idle pp group , must put deactive here before active vitual group
* for cover case first only has physical job in normal queue but group inactive,
* so delay the job start go to active group, when group activated,
* call scheduler again, but now if we get high queue virtual job,
trigger_pm_update = MALI_TRUE;
}
- /* 4. Activate virtual group, if needed */
-
+ /* 5. Activate virtual group, if needed */
if (EXEC_STATE_INACTIVE == virtual_group_state &&
- 0 < mali_scheduler_job_next_is_virtual()) {
- enum mali_group_state state =
- mali_group_activate(virtual_group);
- if (MALI_GROUP_STATE_ACTIVE == state) {
- /* Set virtual group state to idle */
- virtual_group_state = EXEC_STATE_IDLE;
- } else {
- trigger_pm_update = MALI_TRUE;
+ MALI_TRUE == mali_scheduler_job_next_is_virtual()) {
+ struct mali_pp_job *virtual_job = mali_scheduler_job_pp_virtual_peek();
+ if ((MALI_FALSE == gpu_secure_mode_is_needed && MALI_FALSE == mali_pp_job_is_protected_job(virtual_job))
+ || (MALI_TRUE == gpu_secure_mode_is_needed && MALI_TRUE == mali_pp_job_is_protected_job(virtual_job))) {
+ enum mali_group_state state =
+ mali_group_activate(virtual_group);
+ if (MALI_GROUP_STATE_ACTIVE == state) {
+ /* Set virtual group state to idle */
+ virtual_group_state = EXEC_STATE_IDLE;
+ } else {
+ trigger_pm_update = MALI_TRUE;
+ }
}
}
- /* 5. To power up group asap, we trigger pm update here. */
+ /* 6. To power up group asap, we trigger pm update here. */
if (MALI_TRUE == trigger_pm_update) {
trigger_pm_update = MALI_FALSE;
mali_pm_update_async();
}
- /* 6. Assign jobs to idle virtual group (or deactivate if no job) */
+ /* 7. Assign jobs to idle virtual group (or deactivate if no job) */
if (EXEC_STATE_IDLE == virtual_group_state) {
- if (0 < mali_scheduler_job_next_is_virtual()) {
- virtual_job_to_start =
- mali_scheduler_job_pp_virtual_get();
- virtual_group_state = EXEC_STATE_WORKING;
+ if (MALI_TRUE == mali_scheduler_job_next_is_virtual()) {
+ struct mali_pp_job *virtual_job = mali_scheduler_job_pp_virtual_peek();
+ if ((MALI_FALSE == gpu_secure_mode_is_needed && MALI_FALSE == mali_pp_job_is_protected_job(virtual_job))
+ || (MALI_TRUE == gpu_secure_mode_is_needed && MALI_TRUE == mali_pp_job_is_protected_job(virtual_job))) {
+ virtual_job_to_start =
+ mali_scheduler_job_pp_virtual_get();
+ virtual_group_state = EXEC_STATE_WORKING;
+ }
} else if (!mali_timeline_has_virtual_pp_job()) {
virtual_group_state = EXEC_STATE_INACTIVE;
}
}
- /* 7. Assign job to idle GP group (or deactivate if no job) */
+ /* 8. Assign job to idle GP group (or deactivate if no job) */
- if (EXEC_STATE_IDLE == gp_group_state) {
+ if (EXEC_STATE_IDLE == gp_group_state && MALI_FALSE == gpu_secure_mode_is_needed) {
if (0 < mali_scheduler_job_gp_count()) {
gp_job_to_start = mali_scheduler_job_gp_get();
gp_group_state = EXEC_STATE_WORKING;
}
}
- /* 8. We no longer need the schedule/queue lock */
+ /* 9. We no longer need the schedule/queue lock */
mali_scheduler_unlock();
- /* 9. start jobs */
-
+ /* 10. start jobs */
if (NULL != virtual_job_to_start) {
MALI_DEBUG_ASSERT(!mali_group_pp_is_active(virtual_group));
mali_group_start_pp_job(virtual_group,
mali_group_start_gp_job(gp_group, gp_job_to_start);
}
- /* 10. Trigger any pending PM updates */
+ /* 11. Trigger any pending PM updates */
if (MALI_TRUE == trigger_pm_update) {
mali_pm_update_async();
}
#include "mali_hw_core.h"
#include "mali_group.h"
#include "mali_osk.h"
+#include "mali_osk_mali.h"
#include "regs/mali_gp_regs.h"
#include "mali_kernel_common.h"
#include "mali_kernel_core.h"
u32 counter_src0 = mali_gp_job_get_perf_counter_src0(job);
u32 counter_src1 = mali_gp_job_get_perf_counter_src1(job);
+ /* Disable gpu secure mode. */
+ if (MALI_TRUE == _mali_osk_gpu_secure_mode_is_enabled()) {
+ _mali_osk_gpu_secure_mode_disable();
+ }
+
MALI_DEBUG_ASSERT_POINTER(core);
if (mali_gp_job_has_vs_job(job)) {
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2014, 2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
INIT_LIST_HEAD(&job->vary_todo);
job->dmem = NULL;
- if (job->uargs.varying_alloc_num > session->allocation_mgr.mali_allocation_num) {
+ if (job->uargs.deferred_mem_num > session->allocation_mgr.mali_allocation_num) {
MALI_PRINT_ERROR(("Mali GP job: The number of varying buffer to defer bind is invalid !\n"));
goto fail1;
}
/* add varying allocation list*/
- if (job->uargs.varying_alloc_num > 0) {
+ if (job->uargs.deferred_mem_num > 0) {
/* copy varying list from user space*/
- job->varying_list = _mali_osk_calloc(1, sizeof(u32) * job->uargs.varying_alloc_num);
+ job->varying_list = _mali_osk_calloc(1, sizeof(u32) * job->uargs.deferred_mem_num);
if (!job->varying_list) {
- MALI_PRINT_ERROR(("Mali GP job: allocate varying_list failed varying_alloc_num = %d !\n", job->uargs.varying_alloc_num));
+ MALI_PRINT_ERROR(("Mali GP job: allocate varying_list failed varying_alloc_num = %d !\n", job->uargs.deferred_mem_num));
goto fail1;
}
if (0 != _mali_osk_copy_from_user(©_of_uargs, uargs, sizeof(_mali_uk_gp_start_job_s))) {
goto fail1;
}
+ memory_list = (u32 __user *)(uintptr_t)copy_of_uargs.deferred_mem_list;
- memory_list = (u32 __user *)(uintptr_t)copy_of_uargs.varying_alloc_list;
-
- if (0 != _mali_osk_copy_from_user(job->varying_list, memory_list, sizeof(u32) * job->uargs.varying_alloc_num)) {
+ if (0 != _mali_osk_copy_from_user(job->varying_list, memory_list, sizeof(u32) * job->uargs.deferred_mem_num)) {
MALI_PRINT_ERROR(("Mali GP job: Failed to copy varying list from user space!\n"));
goto fail;
}
if (unlikely(_mali_gp_add_varying_allocations(session, job, job->varying_list,
- job->uargs.varying_alloc_num))) {
+ job->uargs.deferred_mem_num))) {
MALI_PRINT_ERROR(("Mali GP job: _mali_gp_add_varying_allocations failed!\n"));
goto fail;
}
u32 bind_flag; /** < flag for deferbind*/
u32 *varying_list; /**< varying memory list need to to defer bind*/
struct list_head vary_todo; /**< list of backend list need to do defer bind*/
- u32 required_varying_memsize; /** < size of varying memory to reallocate*/
+ u32 required_varying_memsize; /** < size of varying memory to reallocate*/
u32 big_job; /** < if the gp job have large varying output and may take long time*/
};
/* group complete and on job shedule on it, it already power off */
if (NULL != group->gp_core) {
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
- 0, 0, /* No pid and tid for interrupt handler */
- MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
- 0xFFFFFFFF, 0);
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, /* No pid and tid for interrupt handler */
+ MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
+ 0xFFFFFFFF, 0);
} else {
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
- 0, 0, /* No pid and tid for interrupt handler */
- MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
- mali_pp_core_get_id(group->pp_core)),
- 0xFFFFFFFF, 0);
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, /* No pid and tid for interrupt handler */
+ MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
+ mali_pp_core_get_id(group->pp_core)),
+ 0xFFFFFFFF, 0);
}
mali_executor_unlock();
if (!mali_group_is_working(group) && (!mali_group_power_is_on(group))) {
/* group complete and on job shedule on it, it already power off */
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
- 0, 0, /* No pid and tid for interrupt handler */
- MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
- 0xFFFFFFFF, 0);
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, /* No pid and tid for interrupt handler */
+ MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
+ 0xFFFFFFFF, 0);
mali_executor_unlock();
return ret;
}
if (!mali_group_is_working(group) && (!mali_group_power_is_on(group))) {
/* group complete and on job shedule on it, it already power off */
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
- 0, 0, /* No pid and tid for interrupt handler */
- MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
- mali_pp_core_get_id(group->pp_core)),
- 0xFFFFFFFF, 0);
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, /* No pid and tid for interrupt handler */
+ MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
+ mali_pp_core_get_id(group->pp_core)),
+ 0xFFFFFFFF, 0);
mali_executor_unlock();
return ret;
}
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2014, 2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
return err;
}
+ /*Try to init gpu secure mode */
+ _mali_osk_gpu_secure_mode_init();
+
#if defined(CONFIG_MALI400_PROFILING)
err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
if (_MALI_OSK_ERR_OK != err) {
_mali_osk_profiling_term();
#endif
+ _mali_osk_gpu_secure_mode_deinit();
+
mali_memory_terminate();
mali_session_terminate();
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2014, 2016 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.
/*
- * Copyright (C) 2011-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2013, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
if (0 == rawstat_used) {
return MALI_INTERRUPT_RESULT_NONE;
}
+
return MALI_INTERRUPT_RESULT_ERROR;
}
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
#ifndef __MALI_OSK_H__
#define __MALI_OSK_H__
+#include <linux/seq_file.h>
#include "mali_osk_types.h"
#include "mali_osk_specific.h" /* include any per-os specifics */
#include "mali_osk_locks.h"
#define MALI_DEBUG_ASSERT_LOCK_HELD(l) do {} while(0)
#endif
+#define _mali_osk_ctxprintf seq_printf
+
/** @} */ /* end group _mali_osk_lock */
/** @addtogroup _mali_osk_miscellaneous
*/
u32 _mali_osk_snprintf(char *buf, u32 size, const char *fmt, ...);
-/** @brief Print fmt into print_ctx.
- *
- * The interpretation of \a fmt is the same as the \c format parameter in
- * _mali_osu_vsnprintf().
- *
- * @param print_ctx a pointer to the result file buffer
- * @param fmt a _mali_osu_vsnprintf() style format string
- * @param ... a variable-number of parameters suitable for \a fmt
- */
-void _mali_osk_ctxprintf(_mali_osk_print_ctx *print_ctx, const char *fmt, ...);
-
/** @brief Abnormal process abort.
*
* Terminates the caller-process if this function is called.
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
extern "C" {
#endif
+#ifdef CONFIG_MALI_DEVFREQ
+struct mali_device {
+ struct device *dev;
+#ifdef CONFIG_HAVE_CLK
+ struct clk *clock;
+#endif
+#ifdef CONFIG_REGULATOR
+ struct regulator *regulator;
+#endif
+#ifdef CONFIG_PM_DEVFREQ
+ struct devfreq_dev_profile devfreq_profile;
+ struct devfreq *devfreq;
+ unsigned long current_freq;
+ unsigned long current_voltage;
+#ifdef CONFIG_DEVFREQ_THERMAL
+ struct thermal_cooling_device *devfreq_cooling;
+#endif
+#endif
+ struct mali_pm_metrics_data mali_metrics;
+};
+#endif
+
/** @addtogroup _mali_osk_miscellaneous
* @{ */
*/
mali_bool _mali_osk_shared_interrupts(void);
+/** @brief Initialize the gpu secure mode.
+ * The gpu secure mode will initially be in a disabled state.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_init(void);
+
+/** @brief Deinitialize the gpu secure mode.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_deinit(void);
+
+/** @brief Enable the gpu secure mode.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_enable(void);
+
+/** @brief Disable the gpu secure mode.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_disable(void);
+
+/** @brief Check if the gpu secure mode has been enabled.
+ * @return MALI_TRUE if enabled, otherwise MALI_FALSE.
+ */
+mali_bool _mali_osk_gpu_secure_mode_is_enabled(void);
+
+/** @brief Check if the gpu secure mode is supported.
+ * @return MALI_TRUE if supported, otherwise MALI_FALSE.
+ */
+mali_bool _mali_osk_gpu_secure_mode_is_supported(void);
+
+
/** @} */ /* end group _mali_osk_miscellaneous */
#ifdef __cplusplus
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
--- /dev/null
+/*
+ * Copyright (C) 2010-2014, 2016 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_pm_metrics.h"
+#include "mali_osk_locks.h"
+#include "mali_osk_mali.h"
+#include <linux/ktime.h>
+
+#define MALI_PM_TIME_SHIFT 0
+#define MALI_UTILIZATION_MAX_PERIOD 80000000/* ns = 100ms */
+
+_mali_osk_errcode_t mali_pm_metrics_init(struct mali_device *mdev)
+{
+ int i = 0;
+
+ MALI_DEBUG_ASSERT(mdev != NULL);
+
+ mdev->mali_metrics.time_period_start = ktime_get();
+ mdev->mali_metrics.time_period_start_gp = mdev->mali_metrics.time_period_start;
+ mdev->mali_metrics.time_period_start_pp = mdev->mali_metrics.time_period_start;
+
+ mdev->mali_metrics.time_busy = 0;
+ mdev->mali_metrics.time_idle = 0;
+ mdev->mali_metrics.prev_busy = 0;
+ mdev->mali_metrics.prev_idle = 0;
+ mdev->mali_metrics.num_running_gp_cores = 0;
+ mdev->mali_metrics.num_running_pp_cores = 0;
+ mdev->mali_metrics.time_busy_gp = 0;
+ mdev->mali_metrics.time_idle_gp = 0;
+
+ for (i = 0; i < MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS; i++) {
+ mdev->mali_metrics.time_busy_pp[i] = 0;
+ mdev->mali_metrics.time_idle_pp[i] = 0;
+ }
+ mdev->mali_metrics.gpu_active = MALI_FALSE;
+
+ mdev->mali_metrics.lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_UNORDERED, _MALI_OSK_LOCK_ORDER_FIRST);
+ if (NULL == mdev->mali_metrics.lock) {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pm_metrics_term(struct mali_device *mdev)
+{
+ _mali_osk_spinlock_irq_term(mdev->mali_metrics.lock);
+}
+
+/*caller needs to hold mdev->mali_metrics.lock before calling this function*/
+void mali_pm_record_job_status(struct mali_device *mdev)
+{
+ ktime_t now;
+ ktime_t diff;
+ u64 ns_time;
+
+ MALI_DEBUG_ASSERT(mdev != NULL);
+
+ now = ktime_get();
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start);
+
+ ns_time = (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_busy += ns_time;
+ mdev->mali_metrics.time_period_start = now;
+}
+
+void mali_pm_record_gpu_idle(mali_bool is_gp)
+{
+ ktime_t now;
+ ktime_t diff;
+ u64 ns_time;
+ struct mali_device *mdev = dev_get_drvdata(&mali_platform_device->dev);
+
+ MALI_DEBUG_ASSERT(mdev != NULL);
+
+ _mali_osk_spinlock_irq_lock(mdev->mali_metrics.lock);
+ now = ktime_get();
+
+ if (MALI_TRUE == is_gp) {
+ --mdev->mali_metrics.num_running_gp_cores;
+ if (0 == mdev->mali_metrics.num_running_gp_cores) {
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start_gp);
+ ns_time = (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_busy_gp += ns_time;
+ mdev->mali_metrics.time_period_start_gp = now;
+
+ if (0 == mdev->mali_metrics.num_running_pp_cores) {
+ MALI_DEBUG_ASSERT(mdev->mali_metrics.gpu_active == MALI_TRUE);
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start);
+ ns_time = (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_busy += ns_time;
+ mdev->mali_metrics.time_period_start = now;
+ mdev->mali_metrics.gpu_active = MALI_FALSE;
+ }
+ }
+ } else {
+ --mdev->mali_metrics.num_running_pp_cores;
+ if (0 == mdev->mali_metrics.num_running_pp_cores) {
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start_pp);
+ ns_time = (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_busy_pp[0] += ns_time;
+ mdev->mali_metrics.time_period_start_pp = now;
+
+ if (0 == mdev->mali_metrics.num_running_gp_cores) {
+ MALI_DEBUG_ASSERT(mdev->mali_metrics.gpu_active == MALI_TRUE);
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start);
+ ns_time = (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_busy += ns_time;
+ mdev->mali_metrics.time_period_start = now;
+ mdev->mali_metrics.gpu_active = MALI_FALSE;
+ }
+ }
+ }
+
+ _mali_osk_spinlock_irq_unlock(mdev->mali_metrics.lock);
+}
+
+void mali_pm_record_gpu_active(mali_bool is_gp)
+{
+ ktime_t now;
+ ktime_t diff;
+ struct mali_device *mdev = dev_get_drvdata(&mali_platform_device->dev);
+
+ MALI_DEBUG_ASSERT(mdev != NULL);
+
+ _mali_osk_spinlock_irq_lock(mdev->mali_metrics.lock);
+ now = ktime_get();
+
+ if (MALI_TRUE == is_gp) {
+ mdev->mali_metrics.num_running_gp_cores++;
+ if (1 == mdev->mali_metrics.num_running_gp_cores) {
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start_gp);
+ mdev->mali_metrics.time_idle_gp += (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_period_start_gp = now;
+ if (0 == mdev->mali_metrics.num_running_pp_cores) {
+ MALI_DEBUG_ASSERT(mdev->mali_metrics.gpu_active == MALI_FALSE);
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start);
+ mdev->mali_metrics.time_idle += (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_period_start = now;
+ mdev->mali_metrics.gpu_active = MALI_TRUE;
+ }
+ } else {
+ MALI_DEBUG_ASSERT(mdev->mali_metrics.gpu_active == MALI_TRUE);
+ }
+ } else {
+ mdev->mali_metrics.num_running_pp_cores++;
+ if (1 == mdev->mali_metrics.num_running_pp_cores) {
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start_pp);
+ mdev->mali_metrics.time_idle_pp[0] += (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_period_start_pp = now;
+ if (0 == mdev->mali_metrics.num_running_gp_cores) {
+ MALI_DEBUG_ASSERT(mdev->mali_metrics.gpu_active == MALI_FALSE);
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start);
+ mdev->mali_metrics.time_idle += (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ mdev->mali_metrics.time_period_start = now;
+ mdev->mali_metrics.gpu_active = MALI_TRUE;
+ }
+ } else {
+ MALI_DEBUG_ASSERT(mdev->mali_metrics.gpu_active == MALI_TRUE);
+ }
+ }
+
+ _mali_osk_spinlock_irq_unlock(mdev->mali_metrics.lock);
+}
+
+
+/*caller needs to hold mdev->mali_metrics.lock before calling this function*/
+static void mali_pm_get_dvfs_utilisation_calc(struct mali_device *mdev, ktime_t now)
+{
+ ktime_t diff;
+
+ MALI_DEBUG_ASSERT(mdev != NULL);
+
+ diff = ktime_sub(now, mdev->mali_metrics.time_period_start);
+
+ if (mdev->mali_metrics.gpu_active) {
+ mdev->mali_metrics.time_busy += (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ } else {
+ mdev->mali_metrics.time_idle += (u64)(ktime_to_ns(diff) >> MALI_PM_TIME_SHIFT);
+ }
+}
+
+/* Caller needs to hold mdev->mali_metrics.lock before calling this function. */
+static void mali_pm_reset_dvfs_utilisation_unlocked(struct mali_device *mdev, ktime_t now)
+{
+ /* Store previous value */
+ mdev->mali_metrics.prev_idle = mdev->mali_metrics.time_idle;
+ mdev->mali_metrics.prev_busy = mdev->mali_metrics.time_busy;
+
+ /* Reset current values */
+ mdev->mali_metrics.time_period_start = now;
+ mdev->mali_metrics.time_period_start_gp = now;
+ mdev->mali_metrics.time_period_start_pp = now;
+ mdev->mali_metrics.time_idle = 0;
+ mdev->mali_metrics.time_busy = 0;
+
+ mdev->mali_metrics.time_busy_gp = 0;
+ mdev->mali_metrics.time_idle_gp = 0;
+ mdev->mali_metrics.time_busy_pp[0] = 0;
+ mdev->mali_metrics.time_idle_pp[0] = 0;
+}
+
+void mali_pm_reset_dvfs_utilisation(struct mali_device *mdev)
+{
+ _mali_osk_spinlock_irq_lock(mdev->mali_metrics.lock);
+ mali_pm_reset_dvfs_utilisation_unlocked(mdev, ktime_get());
+ _mali_osk_spinlock_irq_unlock(mdev->mali_metrics.lock);
+}
+
+void mali_pm_get_dvfs_utilisation(struct mali_device *mdev,
+ unsigned long *total_out, unsigned long *busy_out)
+{
+ ktime_t now = ktime_get();
+ u64 busy = 0;
+ u64 total = 0;
+
+ _mali_osk_spinlock_irq_lock(mdev->mali_metrics.lock);
+
+ mali_pm_get_dvfs_utilisation_calc(mdev, now);
+
+ busy = mdev->mali_metrics.time_busy;
+ total = busy + mdev->mali_metrics.time_idle;
+
+ /* Reset stats if older than MALI_UTILIZATION_MAX_PERIOD (default
+ * 100ms) */
+ if (total >= MALI_UTILIZATION_MAX_PERIOD) {
+ mali_pm_reset_dvfs_utilisation_unlocked(mdev, now);
+ } else if (total < (MALI_UTILIZATION_MAX_PERIOD / 2)) {
+ total += mdev->mali_metrics.prev_idle +
+ mdev->mali_metrics.prev_busy;
+ busy += mdev->mali_metrics.prev_busy;
+ }
+
+ *total_out = (unsigned long)total;
+ *busy_out = (unsigned long)busy;
+ _mali_osk_spinlock_irq_unlock(mdev->mali_metrics.lock);
+}
+
+void mali_pm_metrics_spin_lock(void)
+{
+ struct mali_device *mdev = dev_get_drvdata(&mali_platform_device->dev);
+ _mali_osk_spinlock_irq_lock(mdev->mali_metrics.lock);
+}
+
+void mali_pm_metrics_spin_unlock(void)
+{
+ struct mali_device *mdev = dev_get_drvdata(&mali_platform_device->dev);
+ _mali_osk_spinlock_irq_unlock(mdev->mali_metrics.lock);
+}
--- /dev/null
+/*
+ * Copyright (C) 2010-2014, 2016 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_PM_METRICS_H__
+#define __MALI_PM_METRICS_H__
+
+#ifdef CONFIG_MALI_DEVFREQ
+#include "mali_osk_locks.h"
+#include "mali_group.h"
+
+struct mali_device;
+
+/**
+ * Metrics data collected for use by the power management framework.
+ */
+struct mali_pm_metrics_data {
+ ktime_t time_period_start;
+ u64 time_busy;
+ u64 time_idle;
+ u64 prev_busy;
+ u64 prev_idle;
+ u32 num_running_gp_cores;
+ u32 num_running_pp_cores;
+ ktime_t time_period_start_gp;
+ u64 time_busy_gp;
+ u64 time_idle_gp;
+ ktime_t time_period_start_pp;
+ u64 time_busy_pp[MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS];
+ u64 time_idle_pp[MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS];
+ mali_bool gpu_active;
+ _mali_osk_spinlock_irq_t *lock;
+};
+
+/**
+ * Initialize/start the Mali GPU pm_metrics metrics reporting.
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t mali_pm_metrics_init(struct mali_device *mdev);
+
+/**
+ * Terminate the Mali GPU pm_metrics metrics reporting
+ */
+void mali_pm_metrics_term(struct mali_device *mdev);
+
+/**
+ * Should be called when a job is about to execute a GPU job
+ */
+void mali_pm_record_gpu_active(mali_bool is_gp);
+
+/**
+ * Should be called when a job is finished
+ */
+void mali_pm_record_gpu_idle(mali_bool is_gp);
+
+void mali_pm_reset_dvfs_utilisation(struct mali_device *mdev);
+
+void mali_pm_get_dvfs_utilisation(struct mali_device *mdev, unsigned long *total_out, unsigned long *busy_out);
+
+void mali_pm_metrics_spin_lock(void);
+
+void mali_pm_metrics_spin_unlock(void);
+#else
+void mali_pm_record_gpu_idle(mali_bool is_gp) {}
+void mali_pm_record_gpu_active(mali_bool is_gp) {}
+#endif
+#endif /* __MALI_PM_METRICS_H__ */
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
#include "regs/mali_200_regs.h"
#include "mali_kernel_common.h"
#include "mali_kernel_core.h"
+#include "mali_osk_mali.h"
+
#if defined(CONFIG_MALI400_PROFILING)
#include "mali_osk_profiling.h"
#endif
MALI_DEBUG_ASSERT_POINTER(core);
+ /* Change gpu secure mode if needed. */
+ if (MALI_TRUE == mali_pp_job_is_protected_job(job) && MALI_FALSE == _mali_osk_gpu_secure_mode_is_enabled()) {
+ _mali_osk_gpu_secure_mode_enable();
+ } else if (MALI_FALSE == mali_pp_job_is_protected_job(job) && MALI_TRUE == _mali_osk_gpu_secure_mode_is_enabled()) {
+ _mali_osk_gpu_secure_mode_disable();
+ }
+
/* Write frame registers */
/*
} else if (MALI200_REG_VAL_IRQ_END_OF_FRAME == rawstat_used) {
return MALI_INTERRUPT_RESULT_SUCCESS;
}
+
return MALI_INTERRUPT_RESULT_ERROR;
}
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
? MALI_TRUE : MALI_FALSE;
}
+MALI_STATIC_INLINE mali_bool mali_pp_job_is_protected_job(struct mali_pp_job *job)
+{
+ MALI_DEBUG_ASSERT_POINTER(job);
+ return (job->uargs.flags & _MALI_PP_JOB_FLAG_PROTECTED)
+ ? MALI_TRUE : MALI_FALSE;
+}
+
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
{
MALI_DEBUG_ASSERT_POINTER(job);
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
#include "mali_group.h"
#include <linux/wait.h>
#include <linux/sched.h>
-
+#include "mali_pm_metrics.h"
#if defined(CONFIG_DMA_SHARED_BUFFER)
#include "mali_memory_dma_buf.h"
_mali_osk_atomic_term(&mali_job_id_autonumber);
}
-u32 mali_scheduler_job_physical_head_count(void)
+u32 mali_scheduler_job_physical_head_count(mali_bool gpu_mode_is_secure)
{
/*
* Count how many physical sub jobs are present from the head of queue
* Remember; virtual jobs can't be queued and started
* at the same time, so this must be a physical job
*/
- count += mali_pp_job_unstarted_sub_job_count(job);
- if (MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS <= count) {
- return MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS;
+ if ((MALI_FALSE == gpu_mode_is_secure && MALI_FALSE == mali_pp_job_is_protected_job(job))
+ || (MALI_TRUE == gpu_mode_is_secure && MALI_TRUE == mali_pp_job_is_protected_job(job))) {
+
+ count += mali_pp_job_unstarted_sub_job_count(job);
+ if (MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS <= count) {
+ return MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS;
+ }
}
}
}
_MALI_OSK_LIST_FOREACHENTRY(job, temp, &job_queue_pp.high_pri,
struct mali_pp_job, list) {
- if (MALI_FALSE == mali_pp_job_is_virtual(job)) {
+ if ((MALI_FALSE == mali_pp_job_is_virtual(job))
+ && ((MALI_FALSE == gpu_mode_is_secure && MALI_FALSE == mali_pp_job_is_protected_job(job))
+ || (MALI_TRUE == gpu_mode_is_secure && MALI_TRUE == mali_pp_job_is_protected_job(job)))) {
+
count += mali_pp_job_unstarted_sub_job_count(job);
if (MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS <= count) {
return MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS;
_MALI_OSK_LIST_FOREACHENTRY(job, temp, &job_queue_pp.normal_pri,
struct mali_pp_job, list) {
- if (MALI_FALSE == mali_pp_job_is_virtual(job)) {
- /* any partially started is already counted */
- if (MALI_FALSE == mali_pp_job_has_started_sub_jobs(job)) {
- count += mali_pp_job_unstarted_sub_job_count(job);
- if (MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS <=
- count) {
- return MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS;
- }
+ if ((MALI_FALSE == mali_pp_job_is_virtual(job))
+ && (MALI_FALSE == mali_pp_job_has_started_sub_jobs(job))
+ && ((MALI_FALSE == gpu_mode_is_secure && MALI_FALSE == mali_pp_job_is_protected_job(job))
+ || (MALI_TRUE == gpu_mode_is_secure && MALI_TRUE == mali_pp_job_is_protected_job(job)))) {
+
+ count += mali_pp_job_unstarted_sub_job_count(job);
+ if (MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS <= count) {
+ return MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS;
}
} else {
/* Came across a virtual job, so stop counting */
return count;
}
}
-
return count;
}
+struct mali_pp_job *mali_scheduler_job_pp_next(void)
+{
+ struct mali_pp_job *job;
+ struct mali_pp_job *temp;
+
+ MALI_DEBUG_ASSERT_LOCK_HELD(mali_scheduler_lock_obj);
+
+ /* Check for partially started normal pri jobs */
+ if (!_mali_osk_list_empty(&job_queue_pp.normal_pri)) {
+ MALI_DEBUG_ASSERT(0 < job_queue_pp.depth);
+
+ job = _MALI_OSK_LIST_ENTRY(job_queue_pp.normal_pri.next,
+ struct mali_pp_job, list);
+
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+ if (MALI_TRUE == mali_pp_job_has_started_sub_jobs(job)) {
+ return job;
+ }
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(job, temp, &job_queue_pp.high_pri,
+ struct mali_pp_job, list) {
+ return job;
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(job, temp, &job_queue_pp.normal_pri,
+ struct mali_pp_job, list) {
+ return job;
+ }
+
+ return NULL;
+}
+
mali_bool mali_scheduler_job_next_is_virtual(void)
{
struct mali_pp_job *job;
if (mali_utilization_enabled()) {
mali_utilization_gp_end();
}
+ mali_pm_record_gpu_idle(MALI_TRUE);
}
mali_gp_job_delete(job);
if (mali_utilization_enabled()) {
mali_utilization_pp_end();
}
+ mali_pm_record_gpu_idle(MALI_FALSE);
}
/* With ZRAM feature enabled, all pp jobs will be force to use deferred delete. */
mali_utilization_gp_start();
}
+ mali_pm_record_gpu_active(MALI_TRUE);
+
/* Add profiling events for job enqueued */
_mali_osk_profiling_add_event(
MALI_PROFILING_EVENT_TYPE_SINGLE |
mali_utilization_pp_start();
}
- /* Add profiling events for job enqueued */
+ mali_pm_record_gpu_active(MALI_FALSE);
+ /* Add profiling events for job enqueued */
_mali_osk_profiling_add_event(
MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
return job_queue_gp.big_job_num;
}
-u32 mali_scheduler_job_physical_head_count(void);
+u32 mali_scheduler_job_physical_head_count(mali_bool gpu_mode_is_secure);
mali_bool mali_scheduler_job_next_is_virtual(void);
+struct mali_pp_job *mali_scheduler_job_pp_next(void);
struct mali_gp_job *mali_scheduler_job_gp_get(void);
struct mali_pp_job *mali_scheduler_job_pp_physical_peek(void);
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
_mali_osk_ctxprintf(print_ctx, " %-25s %-10u %-10u %-15u %-15u %-10u %-10u %-10u\n",
session->comm, session->pid,
(atomic_read(&session->mali_mem_allocated_pages)) * _MALI_OSK_MALI_PAGE_SIZE,
- session->max_mali_mem_allocated_size,
- (atomic_read(&session->mali_mem_array[MALI_MEM_EXTERNAL])) * _MALI_OSK_MALI_PAGE_SIZE,
- (atomic_read(&session->mali_mem_array[MALI_MEM_UMP])) * _MALI_OSK_MALI_PAGE_SIZE,
- (atomic_read(&session->mali_mem_array[MALI_MEM_DMA_BUF])) * _MALI_OSK_MALI_PAGE_SIZE,
- (atomic_read(&session->mali_mem_array[MALI_MEM_SWAP])) * _MALI_OSK_MALI_PAGE_SIZE
+ (unsigned int)session->max_mali_mem_allocated_size,
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_EXTERNAL])) * _MALI_OSK_MALI_PAGE_SIZE),
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_UMP])) * _MALI_OSK_MALI_PAGE_SIZE),
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_DMA_BUF])) * _MALI_OSK_MALI_PAGE_SIZE),
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_SWAP])) * _MALI_OSK_MALI_PAGE_SIZE)
);
#else
_mali_osk_ctxprintf(print_ctx, " %-25s %-10u %-10u %-15u %-15u %-10u %-10u \n",
session->comm, session->pid,
- (atomic_read(&session->mali_mem_allocated_pages)) * _MALI_OSK_MALI_PAGE_SIZE,
- session->max_mali_mem_allocated_size,
- (atomic_read(&session->mali_mem_array[MALI_MEM_EXTERNAL])) * _MALI_OSK_MALI_PAGE_SIZE,
- (atomic_read(&session->mali_mem_array[MALI_MEM_UMP])) * _MALI_OSK_MALI_PAGE_SIZE,
- (atomic_read(&session->mali_mem_array[MALI_MEM_DMA_BUF])) * _MALI_OSK_MALI_PAGE_SIZE
+ (unsigned int)((atomic_read(&session->mali_mem_allocated_pages)) * _MALI_OSK_MALI_PAGE_SIZE),
+ (unsigned int)session->max_mali_mem_allocated_size,
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_EXTERNAL])) * _MALI_OSK_MALI_PAGE_SIZE),
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_UMP])) * _MALI_OSK_MALI_PAGE_SIZE),
+ (unsigned int)((atomic_read(&session->mali_mem_array[MALI_MEM_DMA_BUF])) * _MALI_OSK_MALI_PAGE_SIZE)
);
#endif
}
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
is_waiting_on_timeline(tracker, MALI_TIMELINE_GP) ? "WaitGP" : " ", tracker->fence.points[0],
is_waiting_on_timeline(tracker, MALI_TIMELINE_PP) ? "WaitPP" : " ", tracker->fence.points[1],
is_waiting_on_timeline(tracker, MALI_TIMELINE_SOFT) ? "WaitSOFT" : " ", tracker->fence.points[2],
- tracker->fence.sync_fd, tracker->sync_fence, tracker->job);
+ tracker->fence.sync_fd, (unsigned int)(uintptr_t)(tracker->sync_fence), (unsigned int)(uintptr_t)(tracker->job));
} else {
_mali_osk_ctxprintf(print_ctx, "TL: %s %u %c fd:%d fence:(0x%08X) job:(0x%08X)\n",
tracker_type, tracker->point, state_char,
- tracker->fence.sync_fd, tracker->sync_fence, tracker->job);
+ tracker->fence.sync_fd, (unsigned int)(uintptr_t)(tracker->sync_fence), (unsigned int)(uintptr_t)(tracker->job));
}
#else
if (0 != tracker->trigger_ref_count) {
is_waiting_on_timeline(tracker, MALI_TIMELINE_GP) ? "WaitGP" : " ", tracker->fence.points[0],
is_waiting_on_timeline(tracker, MALI_TIMELINE_PP) ? "WaitPP" : " ", tracker->fence.points[1],
is_waiting_on_timeline(tracker, MALI_TIMELINE_SOFT) ? "WaitSOFT" : " ", tracker->fence.points[2],
- tracker->job);
+ (unsigned int)(uintptr_t)(tracker->job));
} else {
_mali_osk_ctxprintf(print_ctx, "TL: %s %u %c job:(0x%08X)\n",
tracker_type, tracker->point, state_char,
- tracker->job);
+ (unsigned int)(uintptr_t)(tracker->job));
}
#endif
}
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/**
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/**
- * Copyright (C) 2012-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
#define __MALI_UTGARD_H__
#include "mali_osk_types.h"
+#ifdef CONFIG_MALI_DEVFREQ
+#include <linux/devfreq.h>
+#include "mali_pm_metrics.h"
+#ifdef CONFIG_DEVFREQ_THERMAL
+#include <linux/devfreq_cooling.h>
+#endif
+#endif
#define MALI_GPU_NAME_UTGARD "mali-utgard"
void (*get_clock_info)(struct mali_gpu_clock **data);
/* Function that get the current clock info, needed when CONFIG_MALI_DVFS enabled */
int (*get_freq)(void);
+ /* Function that init the mali gpu secure mode */
+ int (*secure_mode_init)(void);
+ /* Function that deinit the mali gpu secure mode */
+ void (*secure_mode_deinit)(void);
+ /* Function that enable the mali gpu secure mode */
+ int (*secure_mode_enable)(void);
+ /* Function that disable the mali gpu secure mode */
+ int (*secure_mode_disable)(void);
+ /* ipa related interface customer need register */
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+ struct devfreq_cooling_power *gpu_cooling_ops;
+#endif
};
/**
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
* If you do not wish to do so, delete this exception statement from your version.
*/
+
#ifndef _MALI_UTGARD_PROFILING_EVENTS_H_
#define _MALI_UTGARD_PROFILING_EVENTS_H_
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
_mali_uk_fence_t fence; /**< [in] fence this job must wait on */
u64 timeline_point_ptr; /**< [in,out] pointer to u32: location where point on gp timeline for this job will be written */
u32 varying_memsize; /** < [in] size of varying memory to use deffer bind*/
- u32 varying_alloc_num;
- u64 varying_alloc_list; /** < [in] memory hanlde list of varying buffer to use deffer bind */
+ u32 deferred_mem_num;
+ u64 deferred_mem_list; /** < [in] memory hanlde list of varying buffer to use deffer bind */
} _mali_uk_gp_start_job_s;
#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */
/** Flag for _mali_uk_pp_start_job_s */
#define _MALI_PP_JOB_FLAG_NO_NOTIFICATION (1<<0)
#define _MALI_PP_JOB_FLAG_IS_WINDOW_SURFACE (1<<1)
+#define _MALI_PP_JOB_FLAG_PROTECTED (1<<2)
/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job
* @{ */
* The 16bit integer is stored twice in a 32bit integer
* For example, for version 1 the value would be 0x00010001
*/
-#define _MALI_API_VERSION 850
+#define _MALI_API_VERSION 900
#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
/**
#define _MALI_MEMORY_ALLOCATE_NO_BIND_GPU (1<<5) /*Not map to GPU when allocate, must call bind later*/
#define _MALI_MEMORY_ALLOCATE_SWAPPABLE (1<<6) /* Allocate swappale memory. */
#define _MALI_MEMORY_ALLOCATE_DEFER_BIND (1<<7) /*Not map to GPU when allocate, must call bind later*/
+#define _MALI_MEMORY_ALLOCATE_SECURE (1<<8) /* Allocate secure memory. */
typedef struct {
u32 psize; /**< [in] physical size of the allocation */
u32 flags;
u64 backend_handle; /**< [out] backend handle */
+ s32 secure_shared_fd; /** < [in] the mem handle for secure mem */
struct {
/* buffer types*/
/* CPU read/write info*/
/*
- * Copyright (C) 2010, 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013, 2016 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.
--- /dev/null
+/*
+ * Copyright (C) 2011-2016 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_osk_mali.h"
+#include "mali_kernel_common.h"
+
+#include <linux/clk.h>
+#include <linux/devfreq.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#ifdef CONFIG_DEVFREQ_THERMAL
+#include <linux/devfreq_cooling.h>
+#endif
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
+#include <linux/pm_opp.h>
+#else /* Linux >= 3.13 */
+/* In 3.13 the OPP include header file, types, and functions were all
+ * renamed. Use the old filename for the include, and define the new names to
+ * the old, when an old kernel is detected.
+ */
+#include <linux/opp.h>
+#define dev_pm_opp opp
+#define dev_pm_opp_get_voltage opp_get_voltage
+#define dev_pm_opp_get_opp_count opp_get_opp_count
+#define dev_pm_opp_find_freq_ceil opp_find_freq_ceil
+#endif /* Linux >= 3.13 */
+
+#include "mali_pm_metrics.h"
+
+static int
+mali_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags)
+{
+ struct mali_device *mdev = dev_get_drvdata(dev);
+ struct dev_pm_opp *opp;
+ unsigned long freq = 0;
+ unsigned long voltage;
+ int err;
+
+ freq = *target_freq;
+
+ rcu_read_lock();
+ opp = devfreq_recommended_opp(dev, &freq, flags);
+ voltage = dev_pm_opp_get_voltage(opp);
+ rcu_read_unlock();
+ if (IS_ERR_OR_NULL(opp)) {
+ MALI_PRINT_ERROR(("Failed to get opp (%ld)\n", PTR_ERR(opp)));
+ return PTR_ERR(opp);
+ }
+
+ MALI_DEBUG_PRINT(2, ("mali_devfreq_target:set_freq = %lld flags = 0x%x\n", freq, flags));
+ /*
+ * Only update if there is a change of frequency
+ */
+ if (mdev->current_freq == freq) {
+ *target_freq = freq;
+ mali_pm_reset_dvfs_utilisation(mdev);
+ return 0;
+ }
+
+#ifdef CONFIG_REGULATOR
+ if (mdev->regulator && mdev->current_voltage != voltage
+ && mdev->current_freq < freq) {
+ err = regulator_set_voltage(mdev->regulator, voltage, voltage);
+ if (err) {
+ MALI_PRINT_ERROR(("Failed to increase voltage (%d)\n", err));
+ return err;
+ }
+ }
+#endif
+
+ err = clk_set_rate(mdev->clock, freq);
+ if (err) {
+ MALI_PRINT_ERROR(("Failed to set clock %lu (target %lu)\n", freq, *target_freq));
+ return err;
+ }
+
+#ifdef CONFIG_REGULATOR
+ if (mdev->regulator && mdev->current_voltage != voltage
+ && mdev->current_freq > freq) {
+ err = regulator_set_voltage(mdev->regulator, voltage, voltage);
+ if (err) {
+ MALI_PRINT_ERROR(("Failed to decrease voltage (%d)\n", err));
+ return err;
+ }
+ }
+#endif
+
+ *target_freq = freq;
+ mdev->current_voltage = voltage;
+ mdev->current_freq = freq;
+
+ mali_pm_reset_dvfs_utilisation(mdev);
+
+ return err;
+}
+
+static int
+mali_devfreq_cur_freq(struct device *dev, unsigned long *freq)
+{
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ *freq = mdev->current_freq;
+
+ MALI_DEBUG_PRINT(2, ("mali_devfreq_cur_freq: freq = %d \n", *freq));
+ return 0;
+}
+
+static int
+mali_devfreq_status(struct device *dev, struct devfreq_dev_status *stat)
+{
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ stat->current_frequency = mdev->current_freq;
+
+ mali_pm_get_dvfs_utilisation(mdev,
+ &stat->total_time, &stat->busy_time);
+
+ stat->private_data = NULL;
+
+#ifdef CONFIG_DEVFREQ_THERMAL
+ memcpy(&mdev->devfreq->last_status, stat, sizeof(*stat));
+#endif
+
+ return 0;
+}
+
+/* setup platform specific opp in platform.c*/
+int __weak setup_opps(void)
+{
+ return 0;
+}
+
+/* term platform specific opp in platform.c*/
+int __weak term_opps(struct device *dev)
+{
+ return 0;
+}
+
+static int mali_devfreq_init_freq_table(struct mali_device *mdev,
+ struct devfreq_dev_profile *dp)
+{
+ int err, count;
+ int i = 0;
+ unsigned long freq = 0;
+ struct dev_pm_opp *opp;
+
+ err = setup_opps();
+ if (err)
+ return err;
+
+ rcu_read_lock();
+ count = dev_pm_opp_get_opp_count(mdev->dev);
+ if (count < 0) {
+ rcu_read_unlock();
+ return count;
+ }
+ rcu_read_unlock();
+
+ MALI_DEBUG_PRINT(2, ("mali devfreq table count %d\n", count));
+
+ dp->freq_table = kmalloc_array(count, sizeof(dp->freq_table[0]),
+ GFP_KERNEL);
+ if (!dp->freq_table)
+ return -ENOMEM;
+
+ rcu_read_lock();
+ for (i = 0; i < count; i++, freq++) {
+ opp = dev_pm_opp_find_freq_ceil(mdev->dev, &freq);
+ if (IS_ERR(opp))
+ break;
+
+ dp->freq_table[i] = freq;
+ MALI_DEBUG_PRINT(2, ("mali devfreq table array[%d] = %d\n", i, freq));
+ }
+ rcu_read_unlock();
+
+ if (count != i)
+ MALI_PRINT_ERROR(("Unable to enumerate all OPPs (%d!=%d)\n",
+ count, i));
+
+ dp->max_state = i;
+
+ return 0;
+}
+
+static void mali_devfreq_term_freq_table(struct mali_device *mdev)
+{
+ struct devfreq_dev_profile *dp = mdev->devfreq->profile;
+
+ kfree(dp->freq_table);
+ term_opps(mdev->dev);
+}
+
+static void mali_devfreq_exit(struct device *dev)
+{
+ struct mali_device *mdev = dev_get_drvdata(dev);
+
+ mali_devfreq_term_freq_table(mdev);
+}
+
+int mali_devfreq_init(struct mali_device *mdev)
+{
+#ifdef CONFIG_DEVFREQ_THERMAL
+ struct devfreq_cooling_power *callbacks = NULL;
+ _mali_osk_device_data data;
+#endif
+ struct devfreq_dev_profile *dp;
+ int err;
+
+ MALI_DEBUG_PRINT(2, ("Init Mali devfreq\n"));
+
+ if (!mdev->clock)
+ return -ENODEV;
+
+ mdev->current_freq = clk_get_rate(mdev->clock);
+
+ dp = &mdev->devfreq_profile;
+
+ dp->initial_freq = mdev->current_freq;
+ dp->polling_ms = 100;
+ dp->target = mali_devfreq_target;
+ dp->get_dev_status = mali_devfreq_status;
+ dp->get_cur_freq = mali_devfreq_cur_freq;
+ dp->exit = mali_devfreq_exit;
+
+ if (mali_devfreq_init_freq_table(mdev, dp))
+ return -EFAULT;
+
+ mdev->devfreq = devfreq_add_device(mdev->dev, dp,
+ "simple_ondemand", NULL);
+ if (IS_ERR(mdev->devfreq)) {
+ mali_devfreq_term_freq_table(mdev);
+ return PTR_ERR(mdev->devfreq);
+ }
+
+ err = devfreq_register_opp_notifier(mdev->dev, mdev->devfreq);
+ if (err) {
+ MALI_PRINT_ERROR(("Failed to register OPP notifier (%d)\n", err));
+ goto opp_notifier_failed;
+ }
+
+#ifdef CONFIG_DEVFREQ_THERMAL
+ /* Initilization last_status it will be used when first power allocate called */
+ mdev->devfreq->last_status.current_frequency = mdev->current_freq;
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
+ if (NULL != data.gpu_cooling_ops) {
+ callbacks = data.gpu_cooling_ops;
+ MALI_DEBUG_PRINT(2, ("Mali GPU Thermal: Callback handler installed \n"));
+ }
+ }
+
+ if (callbacks) {
+ mdev->devfreq_cooling = of_devfreq_cooling_register_power(
+ mdev->dev->of_node,
+ mdev->devfreq,
+ callbacks);
+ if (IS_ERR_OR_NULL(mdev->devfreq_cooling)) {
+ err = PTR_ERR(mdev->devfreq_cooling);
+ MALI_PRINT_ERROR(("Failed to register cooling device (%d)\n", err));
+ goto cooling_failed;
+ } else {
+ MALI_DEBUG_PRINT(2, ("Mali GPU Thermal Cooling installed \n"));
+ }
+ }
+#endif
+
+ return 0;
+
+#ifdef CONFIG_DEVFREQ_THERMAL
+cooling_failed:
+ devfreq_unregister_opp_notifier(mdev->dev, mdev->devfreq);
+#endif /* CONFIG_DEVFREQ_THERMAL */
+opp_notifier_failed:
+ err = devfreq_remove_device(mdev->devfreq);
+ if (err)
+ MALI_PRINT_ERROR(("Failed to terminate devfreq (%d)\n", err));
+ else
+ mdev->devfreq = NULL;
+
+ return err;
+}
+
+void mali_devfreq_term(struct mali_device *mdev)
+{
+ int err;
+
+ MALI_DEBUG_PRINT(2, ("Term Mali devfreq\n"));
+
+#ifdef CONFIG_DEVFREQ_THERMAL
+ devfreq_cooling_unregister(mdev->devfreq_cooling);
+#endif
+
+ devfreq_unregister_opp_notifier(mdev->dev, mdev->devfreq);
+
+ err = devfreq_remove_device(mdev->devfreq);
+ if (err)
+ MALI_PRINT_ERROR(("Failed to terminate devfreq (%d)\n", err));
+ else
+ mdev->devfreq = NULL;
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2016 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_DEVFREQ_H_
+#define _MALI_DEVFREQ_H_
+
+int mali_devfreq_init(struct mali_device *mdev);
+
+void mali_devfreq_term(struct mali_device *mdev);
+
+#endif
/**
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/**
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
#include <linux/miscdevice.h>
#include <linux/bug.h>
#include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
#include <linux/mali/mali_utgard.h>
#include "mali_kernel_common.h"
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_sw_counters);
#endif /* CONFIG_TRACEPOINTS */
+#ifdef CONFIG_MALI_DEVFREQ
+#include "mali_devfreq.h"
+#include "mali_osk_mali.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
+#include <linux/pm_opp.h>
+#else
+/* In 3.13 the OPP include header file, types, and functions were all
+ * renamed. Use the old filename for the include, and define the new names to
+ * the old, when an old kernel is detected.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
+#include <linux/pm_opp.h>
+#else
+#include <linux/opp.h>
+#endif /* Linux >= 3.13*/
+#define dev_pm_opp_of_add_table of_init_opp_table
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
+#define dev_pm_opp_of_remove_table of_free_opp_table
+#endif /* Linux >= 3.19 */
+#endif /* Linux >= 4.4.0 */
+#endif
+
/* from the __malidrv_build_info.c file that is generated during build */
extern const char *__malidrv_build_info(void);
MALI_PRINT(("Mali device driver unloaded\n"));
}
+#ifdef CONFIG_MALI_DEVFREQ
+struct mali_device *mali_device_alloc(void)
+{
+ return kzalloc(sizeof(struct mali_device), GFP_KERNEL);
+}
+
+void mali_device_free(struct mali_device *mdev)
+{
+ kfree(mdev);
+}
+#endif
+
static int mali_probe(struct platform_device *pdev)
{
int err;
+#ifdef CONFIG_MALI_DEVFREQ
+ struct mali_device *mdev;
+#endif
MALI_DEBUG_PRINT(2, ("mali_probe(): Called for platform device %s\n", pdev->name));
err = mali_platform_device_init(mali_platform_device);
if (0 != err) {
MALI_PRINT_ERROR(("mali_probe(): Failed to initialize platform device."));
+ mali_platform_device = NULL;
return -EFAULT;
}
#endif
+#ifdef CONFIG_MALI_DEVFREQ
+ mdev = mali_device_alloc();
+ if (!mdev) {
+ MALI_PRINT_ERROR(("Can't allocate mali device private data\n"));
+ return -ENOMEM;
+ }
+
+ mdev->dev = &pdev->dev;
+ dev_set_drvdata(mdev->dev, mdev);
+
+ /*Initilization clock and regulator*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \
+ && defined(CONFIG_REGULATOR)
+ mdev->regulator = regulator_get_optional(mdev->dev, "mali");
+ if (IS_ERR_OR_NULL(mdev->regulator)) {
+ MALI_DEBUG_PRINT(2, ("Continuing without Mali regulator control\n"));
+ mdev->regulator = NULL;
+ /* Allow probe to continue without regulator */
+ }
+#endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) && defined(CONFIG_OF) \
+ && defined(CONFIG_PM_OPP)
+ /* Register the OPPs if they are available in device tree */
+ if (dev_pm_opp_of_add_table(mdev->dev) < 0)
+ MALI_DEBUG_PRINT(3, ("OPP table not found\n"));
+#endif
+
+ /* Need to name the gpu clock "clk_mali" in the device tree */
+ mdev->clock = clk_get(mdev->dev, "clk_mali");
+ if (IS_ERR_OR_NULL(mdev->clock)) {
+ MALI_DEBUG_PRINT(2, ("Continuing without Mali clock control\n"));
+ mdev->clock = NULL;
+ /* Allow probe to continue without clock. */
+ } else {
+ err = clk_prepare_enable(mdev->clock);
+ if (err) {
+ MALI_PRINT_ERROR(("Failed to prepare and enable clock (%d)\n", err));
+ goto clock_prepare_failed;
+ }
+ }
+
+ /* initilize pm metrics related */
+ if (mali_pm_metrics_init(mdev) < 0) {
+ MALI_DEBUG_PRINT(2, ("mali pm metrics init failed\n"));
+ goto pm_metrics_init_failed;
+ }
+
+ if (mali_devfreq_init(mdev) < 0) {
+ MALI_DEBUG_PRINT(2, ("mali devfreq init failed\n"));
+ goto devfreq_init_failed;
+ }
+#endif
+
+
if (_MALI_OSK_ERR_OK == _mali_osk_wq_init()) {
/* Initialize the Mali GPU HW specified by pdev */
if (_MALI_OSK_ERR_OK == mali_initialize_subsystems()) {
_mali_osk_wq_term();
}
+#ifdef CONFIG_MALI_DEVFREQ
+ mali_devfreq_term(mdev);
+devfreq_init_failed:
+ mali_pm_metrics_term(mdev);
+pm_metrics_init_failed:
+ clk_disable_unprepare(mdev->clock);
+clock_prepare_failed:
+ clk_put(mdev->clock);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_OF) \
+ && defined(CONFIG_PM_OPP)
+ dev_pm_opp_of_remove_table(mdev->dev);
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \
+ && defined(CONFIG_REGULATOR)
+ regulator_put(mdev->regulator);
+#endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
+ mali_device_free(mdev);
+#endif
+
+#ifdef CONFIG_MALI_DT
+ mali_platform_device_deinit(mali_platform_device);
+#endif
mali_platform_device = NULL;
return -EFAULT;
}
static int mali_remove(struct platform_device *pdev)
{
+#ifdef CONFIG_MALI_DEVFREQ
+ struct mali_device *mdev = dev_get_drvdata(&pdev->dev);
+#endif
+
MALI_DEBUG_PRINT(2, ("mali_remove() called for platform device %s\n", pdev->name));
mali_sysfs_unregister();
mali_miscdevice_unregister();
mali_terminate_subsystems();
_mali_osk_wq_term();
+
+#ifdef CONFIG_MALI_DEVFREQ
+ mali_devfreq_term(mdev);
+
+ mali_pm_metrics_term(mdev);
+
+ if (mdev->clock) {
+ clk_disable_unprepare(mdev->clock);
+ clk_put(mdev->clock);
+ mdev->clock = NULL;
+ }
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_OF) \
+ && defined(CONFIG_PM_OPP)
+ dev_pm_opp_of_remove_table(mdev->dev);
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) && defined(CONFIG_OF) \
+ && defined(CONFIG_REGULATOR)
+ regulator_put(mdev->regulator);
+#endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
+ mali_device_free(mdev);
+#endif
+
#ifdef CONFIG_MALI_DT
mali_platform_device_deinit(mali_platform_device);
#endif
static int mali_driver_suspend_scheduler(struct device *dev)
{
+#ifdef CONFIG_MALI_DEVFREQ
+ struct mali_device *mdev = dev_get_drvdata(dev);
+ if (!mdev)
+ return -ENODEV;
+#endif
+
+#if defined(CONFIG_MALI_DEVFREQ) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
+ devfreq_suspend_device(mdev->devfreq);
+#endif
+
mali_pm_os_suspend(MALI_TRUE);
/* Tracing the frequency and voltage after mali is suspended */
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
static int mali_driver_resume_scheduler(struct device *dev)
{
+#ifdef CONFIG_MALI_DEVFREQ
+ struct mali_device *mdev = dev_get_drvdata(dev);
+ if (!mdev)
+ return -ENODEV;
+#endif
+
/* Tracing the frequency and voltage after mali is resumed */
#if defined(CONFIG_MALI400_PROFILING) && defined(CONFIG_MALI_DVFS)
/* Just call mali_get_current_gpu_clk_item() once,to record current clk info.*/
0, 0, 0);
#endif
mali_pm_os_resume();
+
+#if defined(CONFIG_MALI_DEVFREQ) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
+ devfreq_resume_device(mdev->devfreq);
+#endif
+
return 0;
}
#ifdef CONFIG_PM_RUNTIME
static int mali_driver_runtime_suspend(struct device *dev)
{
+#ifdef CONFIG_MALI_DEVFREQ
+ struct mali_device *mdev = dev_get_drvdata(dev);
+ if (!mdev)
+ return -ENODEV;
+#endif
+
if (MALI_TRUE == mali_pm_runtime_suspend()) {
/* Tracing the frequency and voltage after mali is suspended */
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
0,
0, 0, 0);
+#if defined(CONFIG_MALI_DEVFREQ) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
+ MALI_DEBUG_PRINT(4, ("devfreq_suspend_device: stop devfreq monitor\n"));
+ devfreq_suspend_device(mdev->devfreq);
+#endif
+
return 0;
} else {
return -EBUSY;
static int mali_driver_runtime_resume(struct device *dev)
{
+#ifdef CONFIG_MALI_DEVFREQ
+ struct mali_device *mdev = dev_get_drvdata(dev);
+ if (!mdev)
+ return -ENODEV;
+#endif
+
/* Tracing the frequency and voltage after mali is resumed */
#if defined(CONFIG_MALI400_PROFILING) && defined(CONFIG_MALI_DVFS)
/* Just call mali_get_current_gpu_clk_item() once,to record current clk info.*/
#endif
mali_pm_runtime_resume();
+
+#if defined(CONFIG_MALI_DEVFREQ) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
+ MALI_DEBUG_PRINT(4, ("devfreq_resume_device: start devfreq monitor\n"));
+ devfreq_resume_device(mdev->devfreq);
+#endif
return 0;
}
/**
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
/*
- * Copyright (C) 2011-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2013, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
#include "mali_memory_cow.h"
#include "mali_memory_swap_alloc.h"
#include "mali_memory_defer_bind.h"
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include "mali_memory_secure.h"
+#endif
extern unsigned int mali_dedicated_mem_size;
extern unsigned int mali_shared_mem_size;
}
} else {
MALI_PRINT_ERROR(("Mali vma fault! It never happen, indicating some logic errors in caller.\n"));
+ /*NOT support yet or OOM*/
+ return VM_FAULT_OOM;
}
return VM_FAULT_NOPAGE;
}
(MALI_MEM_BACKEND_FLAG_SWAP_COWED == (mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED)))) {
/*For swappable memory, CPU page table will be created by page fault handler. */
ret = 0;
+ } else if (mem_bkend->type == MALI_MEM_SECURE) {
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ ret = mali_mem_secure_cpu_map(mem_bkend, vma);
+#else
+ MALI_DEBUG_PRINT(1, ("DMA not supported for mali secure memory\n"));
+ return -EFAULT;
+#endif
} else {
/* Not support yet*/
MALI_DEBUG_PRINT_ERROR(("Invalid type of backend memory! \n"));
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010, 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013, 2015-2016 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.
alloc = mem_bkend->mali_allocation;\r
MALI_DEBUG_ASSERT_POINTER(alloc);\r
\r
- session = alloc->session;\r
- MALI_DEBUG_ASSERT_POINTER(session);\r
+ session = alloc->session;\r
+ MALI_DEBUG_ASSERT_POINTER(session);\r
\r
if (MALI_MEM_BACKEND_FLAG_SWAP_COWED != (MALI_MEM_BACKEND_FLAG_SWAP_COWED & mem_bkend->flags)) {\r
/* Unmap the memory from the mali virtual address space. */\r
/*\r
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
#include "mali_memory_os_alloc.h"
#if defined(CONFIG_DMA_SHARED_BUFFER)
#include "mali_memory_dma_buf.h"
+#include "mali_memory_secure.h"
#endif
#if defined(CONFIG_MALI400_UMP)
#include "mali_memory_ump.h"
} else if (args->flags & _MALI_MEMORY_ALLOCATE_RESIZEABLE) {
mali_allocation->type = MALI_MEM_OS;
mali_allocation->flags |= MALI_MEM_FLAG_CAN_RESIZE;
+ } else if (args->flags & _MALI_MEMORY_ALLOCATE_SECURE) {
+ mali_allocation->type = MALI_MEM_SECURE;
} else if (MALI_TRUE == mali_memory_have_dedicated_memory()) {
mali_allocation->type = MALI_MEM_BLOCK;
} else {
goto done;
}
- /**
- *allocate physical memory
- */
+
if (likely(mali_allocation->psize > 0)) {
- if (mem_backend->type == MALI_MEM_OS) {
- retval = mali_mem_os_alloc_pages(&mem_backend->os_mem, mem_backend->size);
- } else if (mem_backend->type == MALI_MEM_BLOCK) {
- /* try to allocated from BLOCK memory first, then try OS memory if failed.*/
- if (mali_mem_block_alloc(&mem_backend->block_mem, mem_backend->size)) {
- retval = mali_mem_os_alloc_pages(&mem_backend->os_mem, mem_backend->size);
- mem_backend->type = MALI_MEM_OS;
- mali_allocation->type = MALI_MEM_OS;
+ if (MALI_MEM_SECURE == mem_backend->type) {
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ ret = mali_mem_secure_attach_dma_buf(&mem_backend->secure_mem, mem_backend->size, args->secure_shared_fd);
+ if (_MALI_OSK_ERR_OK != ret) {
+ MALI_DEBUG_PRINT(1, ("Failed to attach dma buf for secure memory! \n"));
+ goto failed_alloc_pages;
}
- } else if (MALI_MEM_SWAP == mem_backend->type) {
- retval = mali_mem_swap_alloc_pages(&mem_backend->swap_mem, mali_allocation->mali_vma_node.vm_node.size, &mem_backend->start_idx);
+#else
+ ret = _MALI_OSK_ERR_UNSUPPORTED;
+ MALI_DEBUG_PRINT(1, ("DMA not supported for mali secure memory! \n"));
+ goto failed_alloc_pages;
+#endif
} else {
- /* ONLY support mem_os type */
- MALI_DEBUG_ASSERT(0);
- }
- if (retval) {
- ret = _MALI_OSK_ERR_NOMEM;
- MALI_DEBUG_PRINT(1, (" can't allocate enough pages! \n"));
- goto failed_alloc_pages;
+ /**
+ *allocate physical memory
+ */
+ if (mem_backend->type == MALI_MEM_OS) {
+ retval = mali_mem_os_alloc_pages(&mem_backend->os_mem, mem_backend->size);
+ } else if (mem_backend->type == MALI_MEM_BLOCK) {
+ /* try to allocated from BLOCK memory first, then try OS memory if failed.*/
+ if (mali_mem_block_alloc(&mem_backend->block_mem, mem_backend->size)) {
+ retval = mali_mem_os_alloc_pages(&mem_backend->os_mem, mem_backend->size);
+ mem_backend->type = MALI_MEM_OS;
+ mali_allocation->type = MALI_MEM_OS;
+ }
+ } else if (MALI_MEM_SWAP == mem_backend->type) {
+ retval = mali_mem_swap_alloc_pages(&mem_backend->swap_mem, mali_allocation->mali_vma_node.vm_node.size, &mem_backend->start_idx);
+ } else {
+ /* ONLY support mem_os type */
+ MALI_DEBUG_ASSERT(0);
+ }
+
+ if (retval) {
+ ret = _MALI_OSK_ERR_NOMEM;
+ MALI_DEBUG_PRINT(1, (" can't allocate enough pages! \n"));
+ goto failed_alloc_pages;
+ }
}
}
} else if (mem_backend->type == MALI_MEM_SWAP) {
ret = mali_mem_swap_mali_map(&mem_backend->swap_mem, session, args->gpu_vaddr,
mali_allocation->mali_mapping.properties);
+ } else if (mem_backend->type == MALI_MEM_SECURE) {
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ ret = mali_mem_secure_mali_map(&mem_backend->secure_mem, session, args->gpu_vaddr, mali_allocation->mali_mapping.properties);
+#endif
} else { /* unsupport type */
MALI_DEBUG_ASSERT(0);
}
atomic_add(mem_backend->os_mem.count, &session->mali_mem_allocated_pages);
} else if (MALI_MEM_BLOCK == mem_backend->type) {
atomic_add(mem_backend->block_mem.count, &session->mali_mem_allocated_pages);
+ } else if (MALI_MEM_SECURE == mem_backend->type) {
+ atomic_add(mem_backend->secure_mem.count, &session->mali_mem_allocated_pages);
} else {
MALI_DEBUG_ASSERT(MALI_MEM_SWAP == mem_backend->type);
atomic_add(mem_backend->swap_mem.count, &session->mali_mem_allocated_pages);
/*\r
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
--- /dev/null
+/*
+ * Copyright (C) 2010-2016 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_memory.h"
+#include "mali_memory_secure.h"
+#include "mali_osk.h"
+#include <linux/mutex.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-buf.h>
+
+_mali_osk_errcode_t mali_mem_secure_attach_dma_buf(mali_mem_secure *secure_mem, u32 size, int mem_fd)
+{
+ struct dma_buf *buf;
+ MALI_DEBUG_ASSERT_POINTER(secure_mem);
+
+ /* get dma buffer */
+ buf = dma_buf_get(mem_fd);
+ if (IS_ERR_OR_NULL(buf)) {
+ MALI_DEBUG_PRINT_ERROR(("Failed to get dma buf!\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ if (size != buf->size) {
+ MALI_DEBUG_PRINT_ERROR(("The secure mem size not match to the dma buf size!\n"));
+ goto failed_alloc_mem;
+ }
+
+ secure_mem->buf = buf;
+ secure_mem->attachment = dma_buf_attach(secure_mem->buf, &mali_platform_device->dev);
+ if (NULL == secure_mem->attachment) {
+ MALI_DEBUG_PRINT_ERROR(("Failed to get dma buf attachment!\n"));
+ goto failed_dma_attach;
+ }
+
+ secure_mem->sgt = dma_buf_map_attachment(secure_mem->attachment, DMA_BIDIRECTIONAL);
+ if (IS_ERR_OR_NULL(secure_mem->sgt)) {
+ MALI_DEBUG_PRINT_ERROR(("Failed to map dma buf attachment\n"));
+ goto failed_dma_map;
+ }
+
+ secure_mem->count = size / MALI_MMU_PAGE_SIZE;
+
+ return _MALI_OSK_ERR_OK;
+
+failed_dma_map:
+ dma_buf_detach(secure_mem->buf, secure_mem->attachment);
+failed_dma_attach:
+failed_alloc_mem:
+ dma_buf_put(buf);
+ return _MALI_OSK_ERR_FAULT;
+}
+
+_mali_osk_errcode_t mali_mem_secure_mali_map(mali_mem_secure *secure_mem, struct mali_session_data *session, u32 vaddr, u32 props)
+{
+ struct mali_page_directory *pagedir;
+ struct scatterlist *sg;
+ u32 virt = vaddr;
+ u32 prop = props;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(secure_mem);
+ MALI_DEBUG_ASSERT_POINTER(secure_mem->sgt);
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ pagedir = session->page_directory;
+
+ for_each_sg(secure_mem->sgt->sgl, sg, secure_mem->sgt->nents, i) {
+ u32 size = sg_dma_len(sg);
+ dma_addr_t phys = sg_dma_address(sg);
+
+ /* sg must be page aligned. */
+ MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
+ MALI_DEBUG_ASSERT(0 == (phys & ~(uintptr_t)0xFFFFFFFF));
+
+ mali_mmu_pagedir_update(pagedir, virt, phys, size, prop);
+
+ MALI_DEBUG_PRINT(3, ("The secure mem physical address: 0x%x gpu virtual address: 0x%x! \n", phys, virt));
+ virt += size;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_mem_secure_mali_unmap(mali_mem_allocation *alloc)
+{
+ struct mali_session_data *session;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ session = alloc->session;
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ mali_session_memory_lock(session);
+ mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
+ alloc->flags);
+ mali_session_memory_unlock(session);
+}
+
+
+int mali_mem_secure_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma)
+{
+
+ int ret = 0;
+ struct scatterlist *sg;
+ mali_mem_secure *secure_mem = &mem_bkend->secure_mem;
+ unsigned long addr = vma->vm_start;
+ int i;
+
+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_SECURE);
+
+ for_each_sg(secure_mem->sgt->sgl, sg, secure_mem->sgt->nents, i) {
+ phys_addr_t phys;
+ dma_addr_t dev_addr;
+ u32 size, j;
+ dev_addr = sg_dma_address(sg);
+#if defined(CONFIG_ARM64) ||LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
+ phys = dma_to_phys(&mali_platform_device->dev, dev_addr);
+#else
+ phys = page_to_phys(pfn_to_page(dma_to_pfn(&mali_platform_device->dev, dev_addr)));
+#endif
+ size = sg_dma_len(sg);
+ MALI_DEBUG_ASSERT(0 == size % _MALI_OSK_MALI_PAGE_SIZE);
+
+ for (j = 0; j < size / _MALI_OSK_MALI_PAGE_SIZE; j++) {
+ ret = vm_insert_pfn(vma, addr, PFN_DOWN(phys));
+
+ if (unlikely(0 != ret)) {
+ return -EFAULT;
+ }
+ addr += _MALI_OSK_MALI_PAGE_SIZE;
+ phys += _MALI_OSK_MALI_PAGE_SIZE;
+
+ MALI_DEBUG_PRINT(3, ("The secure mem physical address: 0x%x , cpu virtual address: 0x%x! \n", phys, addr));
+ }
+ }
+ return ret;
+}
+
+u32 mali_mem_secure_release(mali_mem_backend *mem_bkend)
+{
+ struct mali_mem_secure *mem;
+ mali_mem_allocation *alloc = mem_bkend->mali_allocation;
+ u32 free_pages_nr = 0;
+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_SECURE);
+
+ mem = &mem_bkend->secure_mem;
+ MALI_DEBUG_ASSERT_POINTER(mem->attachment);
+ MALI_DEBUG_ASSERT_POINTER(mem->buf);
+ MALI_DEBUG_ASSERT_POINTER(mem->sgt);
+ /* Unmap the memory from the mali virtual address space. */
+ mali_mem_secure_mali_unmap(alloc);
+ mutex_lock(&mem_bkend->mutex);
+ dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
+ dma_buf_detach(mem->buf, mem->attachment);
+ dma_buf_put(mem->buf);
+ mutex_unlock(&mem_bkend->mutex);
+
+ free_pages_nr = mem->count;
+
+ return free_pages_nr;
+}
+
+
--- /dev/null
+/*
+ * Copyright (C) 2010, 2013, 2015 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_MEMORY_SECURE_H__
+#define __MALI_MEMORY_SECURE_H__
+
+#include "mali_session.h"
+#include "mali_memory.h"
+#include <linux/spinlock.h>
+
+#include "mali_memory_types.h"
+
+_mali_osk_errcode_t mali_mem_secure_attach_dma_buf(mali_mem_secure *secure_mem, u32 size, int mem_fd);
+
+_mali_osk_errcode_t mali_mem_secure_mali_map(mali_mem_secure *secure_mem, struct mali_session_data *session, u32 vaddr, u32 props);
+
+void mali_mem_secure_mali_unmap(mali_mem_allocation *alloc);
+
+int mali_mem_secure_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma);
+
+u32 mali_mem_secure_release(mali_mem_backend *mem_bkend);
+
+#endif /* __MALI_MEMORY_SECURE_H__ */
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*\r
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
MALI_MEM_UMP,
MALI_MEM_BLOCK,
MALI_MEM_COW,
+ MALI_MEM_SECURE,
MALI_MEM_TYPE_MAX,
} mali_mem_type;
u32 count;
} mali_mem_swap;
+typedef struct mali_mem_secure {
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ struct dma_buf *buf;
+ struct dma_buf_attachment *attachment;
+ struct sg_table *sgt;
+#endif
+ u32 count;
+} mali_mem_secure;
+
#define MALI_MEM_BACKEND_FLAG_COWED (0x1) /* COW has happen on this backend */
#define MALI_MEM_BACKEND_FLAG_COW_CPU_NO_WRITE (0x2) /* This is an COW backend, mapped as not allowed cpu to write */
#define MALI_MEM_BACKEND_FLAG_SWAP_COWED (0x4) /* Mark the given backend is cowed from swappable memory. */
mali_mem_block_mem block_mem; /**< MALI_MEM_BLOCK */
mali_mem_cow cow_mem;
mali_mem_swap swap_mem;
+ mali_mem_secure secure_mem;
};
mali_mem_allocation *mali_allocation;
struct mutex mutex;
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2016 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.
#include "mali_memory_os_alloc.h"
#if defined(CONFIG_DMA_SHARED_BUFFER)
#include "mali_memory_dma_buf.h"
+#include "mali_memory_secure.h"
#endif
#if defined(CONFIG_MALI400_UMP)
#include "mali_memory_ump.h"
mali_mem_unbind_ump_buf(mem_bkend);
atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
#else
- MALI_DEBUG_PRINT(2, ("UMP not supported\n"));
+ MALI_DEBUG_PRINT(1, ("UMP not supported\n"));
#endif
break;
case MALI_MEM_DMA_BUF:
mali_mem_unbind_dma_buf(mem_bkend);
atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
#else
- MALI_DEBUG_PRINT(2, ("DMA not supported\n"));
+ MALI_DEBUG_PRINT(1, ("DMA not supported\n"));
#endif
break;
case MALI_MEM_EXTERNAL:
atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
atomic_sub(free_pages_nr, &session->mali_mem_array[mem_bkend->type]);
break;
+ case MALI_MEM_SECURE:
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ free_pages_nr = mali_mem_secure_release(mem_bkend);
+ atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
+#else
+ MALI_DEBUG_PRINT(1, ("DMA not supported for mali secure memory\n"));
+#endif
+ break;
default:
MALI_DEBUG_PRINT(1, ("mem type %d is not in the mali_mem_type enum.\n", mem_bkend->type));
break;
/*\r
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*\r
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2016 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.
/*\r
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
/*\r
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
#include "mali_osk.h" /* kernel side OS functions */
#include "mali_kernel_linux.h"
+static mali_bool mali_secure_mode_enabled = MALI_FALSE;
+static mali_bool mali_secure_mode_supported = MALI_FALSE;
+
+/* Function that init the mali gpu secure mode */
+void (*mali_secure_mode_deinit)(void) = NULL;
+/* Function that enable the mali gpu secure mode */
+int (*mali_secure_mode_enable)(void) = NULL;
+/* Function that disable the mali gpu secure mode */
+int (*mali_secure_mode_disable)(void) = NULL;
#ifdef CONFIG_MALI_DT
return MALI_FALSE;
}
+
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_init(void)
+{
+ _mali_osk_device_data data = { 0, };
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
+ if ((NULL != data.secure_mode_init) && (NULL != data.secure_mode_deinit)
+ && (NULL != data.secure_mode_enable) && (NULL != data.secure_mode_disable)) {
+ int err = data.secure_mode_init();
+ if (err) {
+ MALI_DEBUG_PRINT(1, ("Failed to init gpu secure mode.\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mali_secure_mode_deinit = data.secure_mode_deinit;
+ mali_secure_mode_enable = data.secure_mode_enable;
+ mali_secure_mode_disable = data.secure_mode_disable;
+
+ mali_secure_mode_supported = MALI_TRUE;
+ mali_secure_mode_enabled = MALI_FALSE;
+ return _MALI_OSK_ERR_OK;
+ }
+ }
+ MALI_DEBUG_PRINT(3, ("GPU secure mode not supported.\n"));
+ return _MALI_OSK_ERR_UNSUPPORTED;
+
+}
+
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_deinit(void)
+{
+ if (NULL != mali_secure_mode_deinit) {
+ mali_secure_mode_deinit();
+ mali_secure_mode_enabled = MALI_FALSE;
+ mali_secure_mode_supported = MALI_FALSE;
+ return _MALI_OSK_ERR_OK;
+ }
+ MALI_DEBUG_PRINT(3, ("GPU secure mode not supported.\n"));
+ return _MALI_OSK_ERR_UNSUPPORTED;
+
+}
+
+
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_enable(void)
+{
+ /* the mali executor lock must be held before enter this function. */
+
+ MALI_DEBUG_ASSERT(MALI_FALSE == mali_secure_mode_enabled);
+
+ if (NULL != mali_secure_mode_enable) {
+ if (mali_secure_mode_enable()) {
+ MALI_DEBUG_PRINT(1, ("Failed to enable gpu secure mode.\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_secure_mode_enabled = MALI_TRUE;
+ return _MALI_OSK_ERR_OK;
+ }
+ MALI_DEBUG_PRINT(1, ("GPU secure mode not supported.\n"));
+ return _MALI_OSK_ERR_UNSUPPORTED;
+}
+
+_mali_osk_errcode_t _mali_osk_gpu_secure_mode_disable(void)
+{
+ /* the mali executor lock must be held before enter this function. */
+
+ MALI_DEBUG_ASSERT(MALI_TRUE == mali_secure_mode_enabled);
+
+ if (NULL != mali_secure_mode_disable) {
+ if (mali_secure_mode_disable()) {
+ MALI_DEBUG_PRINT(1, ("Failed to disable gpu secure mode.\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_secure_mode_enabled = MALI_FALSE;
+
+ return _MALI_OSK_ERR_OK;
+
+ }
+ MALI_DEBUG_PRINT(1, ("GPU secure mode not supported.\n"));
+ return _MALI_OSK_ERR_UNSUPPORTED;
+
+}
+
+mali_bool _mali_osk_gpu_secure_mode_is_enabled(void)
+{
+ return mali_secure_mode_enabled;
+}
+
+mali_bool _mali_osk_gpu_secure_mode_is_supported(void)
+{
+ return mali_secure_mode_supported;
+}
+
+
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
return res;
}
-void _mali_osk_ctxprintf(_mali_osk_print_ctx *print_ctx, const char *fmt, ...)
-{
- va_list args;
- char buf[512];
-
- va_start(args, fmt);
- vscnprintf(buf, 512, fmt, args);
- seq_printf(print_ctx, buf);
- va_end(args);
-}
-
void _mali_osk_abort(void)
{
/* make a simple fault by dereferencing a NULL pointer */
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
u8 byte_value = ~0;
while ((byte_value & 0x80) != 0) {
- if ((*pos) >= packet_size);
- return -1;
+ if ((*pos) >= packet_size)
+ return -1;
byte_value = buf[*pos];
*pos += 1;
int_value |= (u32)(byte_value & 0x7f) << shift;
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/**
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
/*
- * Copyright (C) 2012, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012, 2016 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.
/*
- * Copyright (C) 2012-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
/*
- * Copyright (C) 2012, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
kargs.ctx = (uintptr_t)session_data;
-
+
/* Sanity check about the size */
if (kargs.control_packet_size > PAGE_SIZE || kargs.response_packet_size > PAGE_SIZE)
return -EINVAL;
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
/*
- * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2016 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.
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2016 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.
#include "arm_core_scaling.h"
#include "mali_executor.h"
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+#include <linux/devfreq_cooling.h>
+#include <linux/thermal.h>
+#endif
static int mali_core_scaling_enable = 0;
static void mali_write_phys(u32 phys_addr, u32 value);
#endif
+#if defined(CONFIG_ARCH_VEXPRESS) && defined(CONFIG_ARM64)
+
+#define SECURE_MODE_CONTROL_HANDLER 0x6F02006C
+void *secure_mode_mapped_addr = NULL;
+/**
+ * Enable/Disable Mali secure mode.
+ * @Return value:
+ * 0: success
+ * non-0: failure.
+ */
+
+static int mali_secure_mode_enable_juno(void)
+{
+ u32 phys_offset = SECURE_MODE_CONTROL_HANDLER & 0x00001FFF;
+ MALI_DEBUG_ASSERT(NULL != secure_mode_mapped_addr);
+
+ iowrite32(1, ((u8 *)secure_mode_mapped_addr) + phys_offset);
+
+ if (1 == (u32)ioread32(((u8 *)secure_mode_mapped_addr) + phys_offset)) {
+ MALI_DEBUG_PRINT(3, ("Mali enables secured mode successfully! \n"));
+ return 0;
+ }
+
+ MALI_PRINT_ERROR(("Failed to enable Mali secured mode !!! \n"));
+
+ return -1;
+
+}
+
+static int mali_secure_mode_disable_juno(void)
+{
+ u32 phys_offset = SECURE_MODE_CONTROL_HANDLER & 0x00001FFF;
+ MALI_DEBUG_ASSERT(NULL != secure_mode_mapped_addr);
+
+ iowrite32(0, ((u8 *)secure_mode_mapped_addr) + phys_offset);
+
+ if (0 == (u32)ioread32(((u8 *)secure_mode_mapped_addr) + phys_offset)) {
+ MALI_DEBUG_PRINT(3, ("Mali disable secured mode successfully! \n"));
+ return 0;
+ }
+
+ MALI_PRINT_ERROR(("Failed to disable mali secured mode !!! \n"));
+ return -1;
+}
+
+static int mali_secure_mode_init_juno(void)
+{
+ u32 phys_addr_page = SECURE_MODE_CONTROL_HANDLER & 0xFFFFE000;
+ u32 phys_offset = SECURE_MODE_CONTROL_HANDLER & 0x00001FFF;
+ u32 map_size = phys_offset + sizeof(u32);
+
+ MALI_DEBUG_ASSERT(NULL == secure_mode_mapped_addr);
+
+ secure_mode_mapped_addr = ioremap_nocache(phys_addr_page, map_size);
+ if (NULL != secure_mode_mapped_addr) {
+ return mali_secure_mode_disable_juno();
+ }
+ MALI_DEBUG_PRINT(2, ("Failed to ioremap for Mali secured mode! \n"));
+ return -1;
+}
+
+static void mali_secure_mode_deinit_juno(void)
+{
+ if (NULL != secure_mode_mapped_addr) {
+ mali_secure_mode_disable_juno();
+ iounmap(secure_mode_mapped_addr);
+ secure_mode_mapped_addr = NULL;
+ }
+}
+#endif
+
#ifndef CONFIG_MALI_DT
static void mali_platform_device_release(struct device *device);
#endif
#endif
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+
+#define FALLBACK_STATIC_TEMPERATURE 55000
+
+static struct thermal_zone_device *gpu_tz;
+
+/* Calculate gpu static power example for reference */
+static unsigned long arm_model_static_power(unsigned long voltage)
+{
+ int temperature, temp;
+ int temp_squared, temp_cubed, temp_scaling_factor;
+ const unsigned long coefficient = (410UL << 20) / (729000000UL >> 10);
+ const unsigned long voltage_cubed = (voltage * voltage * voltage) >> 10;
+ unsigned long static_power;
+
+ if (gpu_tz) {
+ int ret;
+
+ ret = gpu_tz->ops->get_temp(gpu_tz, &temperature);
+ if (ret) {
+ MALI_DEBUG_PRINT(2, ("Error reading temperature for gpu thermal zone: %d\n", ret));
+ temperature = FALLBACK_STATIC_TEMPERATURE;
+ }
+ } else {
+ temperature = FALLBACK_STATIC_TEMPERATURE;
+ }
+
+ /* Calculate the temperature scaling factor. To be applied to the
+ * voltage scaled power.
+ */
+ temp = temperature / 1000;
+ temp_squared = temp * temp;
+ temp_cubed = temp_squared * temp;
+ temp_scaling_factor =
+ (2 * temp_cubed)
+ - (80 * temp_squared)
+ + (4700 * temp)
+ + 32000;
+
+ static_power = (((coefficient * voltage_cubed) >> 20)
+ * temp_scaling_factor)
+ / 1000000;
+
+ return static_power;
+}
+
+/* Calculate gpu dynamic power example for reference */
+static unsigned long arm_model_dynamic_power(unsigned long freq,
+ unsigned long voltage)
+{
+ /* The inputs: freq (f) is in Hz, and voltage (v) in mV.
+ * The coefficient (c) is in mW/(MHz mV mV).
+ *
+ * This function calculates the dynamic power after this formula:
+ * Pdyn (mW) = c (mW/(MHz*mV*mV)) * v (mV) * v (mV) * f (MHz)
+ */
+ const unsigned long v2 = (voltage * voltage) / 1000; /* m*(V*V) */
+ const unsigned long f_mhz = freq / 1000000; /* MHz */
+ const unsigned long coefficient = 3600; /* mW/(MHz*mV*mV) */
+ unsigned long dynamic_power;
+
+ dynamic_power = (coefficient * v2 * f_mhz) / 1000000; /* mW */
+
+ return dynamic_power;
+}
+
+struct devfreq_cooling_power arm_cooling_ops = {
+ .get_static_power = arm_model_static_power,
+ .get_dynamic_power = arm_model_dynamic_power,
+};
+#endif
+
static struct mali_gpu_device_data mali_gpu_data = {
#ifndef CONFIG_MALI_DT
.pmu_switch_delay = 0xFF, /* do not have to be this high on FPGA, but it is good for testing to have a delay */
- .max_job_runtime = 60000, /* 60 seconds */
#if defined(CONFIG_ARCH_VEXPRESS)
.shared_mem_size = 256 * 1024 * 1024, /* 256MB */
#endif
#endif
+ .max_job_runtime = 60000, /* 60 seconds */
#if defined(CONFIG_ARCH_REALVIEW)
.dedicated_mem_start = 0x80000000, /* Physical start address (use 0xD0000000 for old indirect setup) */
.get_clock_info = NULL,
.get_freq = NULL,
.set_freq = NULL,
+#if defined(CONFIG_ARCH_VEXPRESS) && defined(CONFIG_ARM64)
+ .secure_mode_init = mali_secure_mode_init_juno,
+ .secure_mode_deinit = mali_secure_mode_deinit_juno,
+ .secure_mode_enable = mali_secure_mode_enable_juno,
+ .secure_mode_disable = mali_secure_mode_disable_juno,
+#else
+ .secure_mode_init = NULL,
+ .secure_mode_deinit = NULL,
+ .secure_mode_enable = NULL,
+ .secure_mode_disable = NULL,
+#endif
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+ .gpu_cooling_ops = &arm_cooling_ops,
+#endif
};
#ifndef CONFIG_MALI_DT
MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
mali_core_scaling_term();
+#ifdef CONFIG_PM_RUNTIME
+ pm_runtime_disable(&(mali_gpu_device.dev));
+#endif
platform_device_unregister(&mali_gpu_device);
platform_device_put(&mali_gpu_device);
mali_core_scaling_init(num_pp_cores);
}
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_DEVFREQ_THERMAL)
+ /* Get thermal zone */
+ gpu_tz = thermal_zone_get_zone_by_name("soc_thermal");
+ if (IS_ERR(gpu_tz)) {
+ MALI_DEBUG_PRINT(2, ("Error getting gpu thermal zone (%ld), not yet ready?\n",
+ PTR_ERR(gpu_tz)));
+ gpu_tz = NULL;
+
+ err = -EPROBE_DEFER;
+ }
+#endif
+
return err;
}
MALI_DEBUG_PRINT(4, ("mali_platform_device_deinit() called\n"));
mali_core_scaling_term();
+#ifdef CONFIG_PM_RUNTIME
+ pm_runtime_disable(&(device->dev));
+#endif
#if defined(CONFIG_ARCH_REALVIEW)
mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */
/*
- * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 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.
/*
- * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2016 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.
--- /dev/null
+/*
+ * Copyright (C) 2010, 2012-2016 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 juno_opp.c
+ * Example: Set up opp table
+ * Using ARM64 juno specific SCPI_PROTOCOL get frequence inform
+ * Customer need implement your own platform releated logic
+ */
+#ifdef CONFIG_ARCH_VEXPRESS
+#ifdef CONFIG_MALI_DEVFREQ
+#ifdef CONFIG_ARM64
+#ifdef CONFIG_ARM_SCPI_PROTOCOL
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/scpi_protocol.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
+#include <linux/pm_opp.h>
+#else /* Linux >= 3.13 */
+/* In 3.13 the OPP include header file, types, and functions were all
+ * renamed. Use the old filename for the include, and define the new names to
+ * the old, when an old kernel is detected.
+ */
+#include <linux/opp.h>
+#define dev_pm_opp_add opp_add
+#define dev_pm_opp_remove opp_remove
+#endif /* Linux >= 3.13 */
+
+#include "mali_kernel_common.h"
+
+static int init_juno_opps_from_scpi(struct device *dev)
+{
+ struct scpi_dvfs_info *sinfo;
+ struct scpi_ops *sops;
+
+ int i;
+
+ sops = get_scpi_ops();
+ if (NULL == sops) {
+ MALI_DEBUG_PRINT(2, ("Mali didn't get any scpi ops \n"));
+ return -1;
+ }
+
+ /* Hard coded for Juno. 2 is GPU domain */
+ sinfo = sops->dvfs_get_info(2);
+ if (IS_ERR_OR_NULL(sinfo))
+ return PTR_ERR(sinfo);
+
+ for (i = 0; i < sinfo->count; i++) {
+ struct scpi_opp *e = &sinfo->opps[i];
+
+ MALI_DEBUG_PRINT(2, ("Mali OPP from SCPI: %u Hz @ %u mV\n", e->freq, e->m_volt));
+
+ dev_pm_opp_add(dev, e->freq, e->m_volt * 1000);
+ }
+
+ return 0;
+}
+
+int setup_opps(void)
+{
+ struct device_node *np;
+ struct platform_device *pdev;
+ int err;
+
+ np = of_find_node_by_name(NULL, "gpu");
+ if (!np) {
+ pr_err("Failed to find DT entry for Mali\n");
+ return -EFAULT;
+ }
+
+ pdev = of_find_device_by_node(np);
+ if (!pdev) {
+ pr_err("Failed to find device for Mali\n");
+ of_node_put(np);
+ return -EFAULT;
+ }
+
+ err = init_juno_opps_from_scpi(&pdev->dev);
+
+ of_node_put(np);
+
+ return err;
+}
+
+int term_opps(struct device *dev)
+{
+ struct scpi_dvfs_info *sinfo;
+ struct scpi_ops *sops;
+
+ int i;
+
+ sops = get_scpi_ops();
+ if (NULL == sops) {
+ MALI_DEBUG_PRINT(2, ("Mali didn't get any scpi ops \n"));
+ return -1;
+ }
+
+ /* Hard coded for Juno. 2 is GPU domain */
+ sinfo = sops->dvfs_get_info(2);
+ if (IS_ERR_OR_NULL(sinfo))
+ return PTR_ERR(sinfo);
+
+ for (i = 0; i < sinfo->count; i++) {
+ struct scpi_opp *e = &sinfo->opps[i];
+
+ MALI_DEBUG_PRINT(2, ("Mali Remove OPP: %u Hz \n", e->freq));
+
+ dev_pm_opp_remove(dev, e->freq);
+ }
+
+ return 0;
+
+}
+#endif
+#endif
+#endif
+#endif
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2016 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.
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2016 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.
/*
- * Copyright (C) 2010-2011, 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
ccflags-y += -DSVN_REV=$(SVN_REV)
ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\"
-ccflags-y += -I$(src) -I$(src)/common -I$(src)/linux -I$(src)/../mali/common -I$(src)/../mali/linux -I$(src)/../../ump/include/ump
+ccflags-y += -I$(src) -I$(src)/common -I$(src)/linux -I$(src)/../mali/common -I$(src)/../mali/linux -I$(src)/include -I$(src)/../../ump/include/ump
ccflags-y += -DMALI_STATE_TRACKING=0
ccflags-y += -DMALI_ENABLE_CPU_CYCLES=0
ccflags-$(CONFIG_UMP_DEBUG) += -DDEBUG
linux/ump_osk_atomics.o \
linux/ump_osk_low_level_mem.o \
linux/ump_osk_misc.o \
- linux/ump_kernel_random_mapping.o \
- $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
- $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
- $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
- $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
- $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
+ linux/ump_kernel_random_mapping.o
+
+ifneq ($(CONFIG_MALI400),y)
+ump-y += $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
+endif
obj-$(CONFIG_UMP) := ump.o
#
-# Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
+# Copyright (C) 2010-2012, 2014, 2016 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.
#
-# Copyright (C) 2010-2011, 2013, 2015 ARM Limited. All rights reserved.
+# Copyright (C) 2010-2011, 2013, 2016 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.
/*
- * Copyright (C) 2010, 2012, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012, 2014, 2016 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.
/*
- * Copyright (C) 2010-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2013, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
_mali_osk_errcode_t ump_kernel_constructor(void);
void ump_kernel_destructor(void);
-int map_errcode(_mali_osk_errcode_t err);
+int ump_map_errcode(_mali_osk_errcode_t err);
/**
* variables from user space cannot be dereferenced from kernel space; tagging them
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
#include "mali_osk.h"
#include <linux/rbtree.h>
+#ifdef CONFIG_DMA_SHARED_BUFFER
+#include <linux/dma-buf.h>
+#endif
typedef enum {
UMP_USED_BY_CPU = 0,
int is_cached;
ump_hw_usage hw_device;
ump_lock_usage lock_usage;
+#ifdef CONFIG_DMA_SHARED_BUFFER
+ struct dma_buf_attachment *import_attach;
+ struct sg_table *sgt;
+#endif
} ump_dd_mem;
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
_UMP_IOC_SWITCH_HW_USAGE,
_UMP_IOC_LOCK,
_UMP_IOC_UNLOCK,
+ _UMP_IOC_DMABUF_IMPORT,
} _ump_uk_functions;
typedef enum
u32 secure_id; /**< [in] secure_id that identifies the ump buffer */
} _ump_uk_unlock_s;
+typedef struct _ump_uk_dmabuf_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [in] dmabuf_fd that identifies the dmabuf buffer */
+ size_t size; /**< [in] size of the buffer */
+ u32 secure_id; /**< [out] secure_id that identifies the ump buffer */
+} _ump_uk_dmabuf_s;
+
#ifdef __cplusplus
}
#endif
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010, 2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013, 2016 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.
/*
- * Copyright (C) 2010-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2013, 2016 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.
#define UMP_IOC_LOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_LOCK, _ump_uk_lock_s)
#define UMP_IOC_UNLOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_UNLOCK, _ump_uk_unlock_s)
+#define UMP_IOC_DMABUF_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_DMABUF_IMPORT, _ump_uk_dmabuf_s)
#ifdef __cplusplus
}
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/* The global variable containing the global device data */
static struct ump_device ump_device;
-
+struct device *ump_global_mdev = NULL;
/* Forward declare static functions */
static int ump_file_open(struct inode *inode, struct file *filp);
err = ump_kernel_constructor();
if (_MALI_OSK_ERR_OK != err) {
MSG_ERR(("UMP device driver init failed\n"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
MSG(("UMP device driver %s loaded\n", SVN_REV_STRING));
if (IS_ERR(ump_device.ump_class)) {
err = PTR_ERR(ump_device.ump_class);
} else {
- struct device *mdev;
- mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name);
- if (!IS_ERR(mdev)) {
+ ump_global_mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name);
+ if (!IS_ERR(ump_global_mdev)) {
return 0;
}
- err = PTR_ERR(mdev);
+ err = PTR_ERR(ump_global_mdev);
}
cdev_del(&ump_device.cdev);
#else
err = _ump_ukk_open((void **) &session_data);
if (_MALI_OSK_ERR_OK != err) {
MSG_ERR(("Ump failed to open a new session\n"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
filp->private_data = (void *)session_data;
err = _ump_ukk_close((void **) &filp->private_data);
if (_MALI_OSK_ERR_OK != err) {
- return map_errcode(err);
+ return ump_map_errcode(err);
}
return 0; /* success */
err = ump_unlock_wrapper((u32 __user *)argument, session_data);
break;
+ case UMP_IOC_DMABUF_IMPORT:
+ #ifdef CONFIG_DMA_SHARED_BUFFER
+ err = ump_dmabuf_import_wrapper((u32 __user *)argument, session_data);
+ #else
+ err = -EFAULT;
+ DBG_MSG(1, ("User space use dmabuf API, but kernel don't support DMA BUF\n"));
+ #endif
+ break;
+
default:
DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg));
err = -EFAULT;
return err;
}
-int map_errcode(_mali_osk_errcode_t err)
+int ump_map_errcode(_mali_osk_errcode_t err)
{
switch (err) {
case _MALI_OSK_ERR_OK :
err = _ump_ukk_map_mem(&args);
if (_MALI_OSK_ERR_OK != err) {
MSG_ERR(("_ump_ukk_map_mem() failed in function ump_file_mmap()"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
return 0; /* success */
/*
- * Copyright (C) 2010-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2013, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2014, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2014, 2016 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.
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
if (0 == new_ref) {
DBG_MSG(3, ("Final release of memory. ID: %u\n", mem->secure_id));
+#ifdef CONFIG_DMA_SHARED_BUFFER
+ if (mem->import_attach) {
+ struct dma_buf_attachment *attach = mem->import_attach;
+ struct dma_buf *dma_buf;
+
+ if (mem->sgt)
+ dma_buf_unmap_attachment(attach, mem->sgt,
+ DMA_BIDIRECTIONAL);
+
+ dma_buf = attach->dmabuf;
+ dma_buf_detach(attach->dmabuf, attach);
+ dma_buf_put(dma_buf);
+
+ }
+#endif
ump_random_mapping_remove_internal(device.secure_id_map, mem->secure_id);
mem->release_func(mem->ctx, mem);
/*
- * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010, 2014-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2014, 2016 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.
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
#include "ump_uk_types.h"
#include "ump_ukk.h"
#include "ump_kernel_common.h"
+#include <linux/scatterlist.h>
+#include "ump_kernel_interface_ref_drv.h"
+#include "mali_osk_list.h"
+
+extern struct device *ump_global_mdev;
/*
* IOCTL operation; Allocate UMP memory
err = _ump_ukk_allocate(&user_interaction);
if (_MALI_OSK_ERR_OK != err) {
DBG_MSG(1, ("_ump_ukk_allocate() failed in ump_ioctl_allocate()\n"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
user_interaction.ctx = NULL;
return 0; /* success */
}
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+static ump_dd_handle get_ump_handle_from_dmabuf(struct ump_session_data *session_data,
+ struct dma_buf *dmabuf)
+{
+ ump_session_memory_list_element *session_mem, *tmp;
+ struct dma_buf_attachment *attach;
+ ump_dd_handle ump_handle;
+
+ DEBUG_ASSERT_POINTER(session_data);
+
+ _mali_osk_mutex_wait(session_data->lock);
+
+ _MALI_OSK_LIST_FOREACHENTRY(session_mem, tmp,
+ &session_data->list_head_session_memory_list,
+ ump_session_memory_list_element, list) {
+ if (session_mem->mem->import_attach) {
+ attach = session_mem->mem->import_attach;
+ if (attach->dmabuf == dmabuf) {
+ _mali_osk_mutex_signal(session_data->lock);
+ ump_handle = (ump_dd_handle)session_mem->mem;
+ ump_random_mapping_get(device.secure_id_map, ump_dd_secure_id_get(ump_handle));
+ return ump_handle;
+ }
+ }
+ }
+
+ _mali_osk_mutex_signal(session_data->lock);
+
+ return NULL;
+}
+
+int ump_dmabuf_import_wrapper(u32 __user *argument,
+ struct ump_session_data *session_data)
+{
+ ump_session_memory_list_element *session = NULL;
+ _ump_uk_dmabuf_s ump_dmabuf;
+ ump_dd_handle ump_handle;
+ ump_dd_physical_block *blocks = NULL;
+ struct dma_buf_attachment *attach = NULL;
+ struct dma_buf *dma_buf;
+ struct sg_table *sgt = NULL;
+ struct scatterlist *sgl;
+ unsigned int i = 0;
+ int ret = 0;
+
+ /* Sanity check input parameters */
+ if (!argument || !session_data) {
+ MSG_ERR(("NULL parameter.\n"));
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&ump_dmabuf, argument,
+ sizeof(_ump_uk_dmabuf_s))) {
+ MSG_ERR(("copy_from_user() failed.\n"));
+ return -EFAULT;
+ }
+
+ dma_buf = dma_buf_get(ump_dmabuf.fd);
+ if (IS_ERR(dma_buf))
+ return PTR_ERR(dma_buf);
+
+ /*
+ * if already imported then increase a refcount to the ump descriptor
+ * and call dma_buf_put() and then go to found to return previous
+ * ump secure id.
+ */
+ ump_handle = get_ump_handle_from_dmabuf(session_data, dma_buf);
+ if (ump_handle) {
+ dma_buf_put(dma_buf);
+ goto found;
+ }
+
+ attach = dma_buf_attach(dma_buf, ump_global_mdev);
+ if (IS_ERR(attach)) {
+ ret = PTR_ERR(attach);
+ goto err_dma_buf_put;
+ }
+
+ sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sgt)) {
+ ret = PTR_ERR(sgt);
+ goto err_dma_buf_detach;
+ }
+
+ blocks = (ump_dd_physical_block *)_mali_osk_malloc(sizeof(ump_dd_physical_block) * sgt->nents);
+ if (!blocks) {
+ DBG_MSG(1, ("Failed to allocate blocks.\n"));
+ ret = -EFAULT;
+ goto err_dma_buf_unmap;
+ }
+ for_each_sg(sgt->sgl, sgl, sgt->nents, i) {
+ blocks[i].addr = sg_phys(sgl);
+ blocks[i].size = sg_dma_len(sgl);
+ }
+
+ /*
+ * Initialize the session memory list element, and add it
+ * to the session object
+ */
+ session = _mali_osk_calloc(1, sizeof(*session));
+ if (!session) {
+ DBG_MSG(1, ("Failed to allocate session.\n"));
+ ret = -EFAULT;
+ goto err_free_block;
+ }
+
+ ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, i);
+ if (UMP_DD_HANDLE_INVALID == ump_handle) {
+ DBG_MSG(1, ("Failed to create ump handle.\n"));
+ ret = -EFAULT;
+ goto err_free_session;
+ }
+
+ session->mem = (ump_dd_mem *)ump_handle;
+ session->mem->import_attach = attach;
+ session->mem->sgt = sgt;
+
+ _mali_osk_mutex_wait(session_data->lock);
+ _mali_osk_list_add(&(session->list),
+ &(session_data->list_head_session_memory_list));
+ _mali_osk_mutex_signal(session_data->lock);
+
+ _mali_osk_free(blocks);
+
+found:
+ ump_dmabuf.ctx = (void *)session_data;
+ ump_dmabuf.secure_id = ump_dd_secure_id_get(ump_handle);
+ ump_dmabuf.size = ump_dd_size_get(ump_handle);
+
+ if (copy_to_user(argument, &ump_dmabuf,
+ sizeof(_ump_uk_dmabuf_s))) {
+ MSG_ERR(("copy_to_user() failed.\n"));
+ ret = -EFAULT;
+ goto err_release_ump_handle;
+ }
+
+ return ret;
+
+err_release_ump_handle:
+ ump_dd_reference_release(ump_handle);
+err_free_session:
+ _mali_osk_free(session);
+err_free_block:
+ _mali_osk_free(blocks);
+err_dma_buf_unmap:
+ dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+err_dma_buf_detach:
+ dma_buf_detach(dma_buf, attach);
+err_dma_buf_put:
+ dma_buf_put(dma_buf);
+ return ret;
+}
+#endif
/*
- * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2014, 2016 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.
int ump_allocate_wrapper(u32 __user *argument, struct ump_session_data *session_data);
-
+#ifdef CONFIG_DMA_SHARED_BUFFER
+int ump_dmabuf_import_wrapper(u32 __user *argument, struct ump_session_data *session_data);
+#endif
#ifdef __cplusplus
}
/*
- * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2014, 2016 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.
err = _ump_uku_get_api_version(&version_info);
if (_MALI_OSK_ERR_OK != err) {
MSG_ERR(("_ump_uku_get_api_version() failed in ump_ioctl_get_api_version()\n"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
version_info.ctx = NULL;
err = _ump_ukk_release(&release_args);
if (_MALI_OSK_ERR_OK != err) {
MSG_ERR(("_ump_ukk_release() failed in ump_ioctl_release()\n"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
err = _ump_ukk_size_get(&user_interaction);
if (_MALI_OSK_ERR_OK != err) {
MSG_ERR(("_ump_ukk_size_get() failed in ump_ioctl_size_get()\n"));
- return map_errcode(err);
+ return ump_map_errcode(err);
}
user_interaction.ctx = NULL;
/*
- * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2014, 2016 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.
#
-# Copyright (C) 2012, 2015 ARM Limited. All rights reserved.
+# Copyright (C) 2012, 2016 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.
/*
- * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2016 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.
/*
- * Copyright (C) 2012-2013, 2015 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 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.