summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChunsang Jeong <chunsang.jeong@linaro.org>2011-08-13 23:11:20 +0900
committerTushar Behera <tushar.behera@linaro.org>2012-12-13 14:53:55 +0530
commitf2d2017e4c3b4cb288ecee5eacab5979769ba1eb (patch)
tree60c54631ef44a0237bddc3c0438d73b91b11529f
parent60bca1f6e10139cec94063740bb6f115b16c8995 (diff)
downloadlinux-topics-f2d2017e4c3b4cb288ecee5eacab5979769ba1eb.tar.gz
Update with r2p2-03release at 17th, Jul from malideveloper.com
Signed-off-by: Chunsang Jeong <chunsang.jeong@linaro.org>
-rw-r--r--drivers/gpu/arm/mali/Kconfig16
-rwxr-xr-xdrivers/gpu/arm/mali/Makefile16
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_GP2.c45
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_MALI200.c45
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_core.c79
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_core.h12
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_l2_cache.c13
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_mem_buddy.c3
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_mem_mmu.c284
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_rendercore.c170
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_rendercore.h15
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_subsystem.h13
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_kernel_utilization.c24
-rw-r--r--drivers/gpu/arm/mali/common/mali_kernel_vsync.c29
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_osk.h43
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_osk_list.h2
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_uk_types.h42
-rwxr-xr-xdrivers/gpu/arm/mali/common/mali_ukk.h17
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm.c187
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm.h33
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm_policy.h16
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.c18
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.h4
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm_state.c33
-rwxr-xr-xdrivers/gpu/arm/mali/common/pmm/mali_pmm_state.h29
-rw-r--r--drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h2
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_device_pause_resume.c18
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_kernel_ioctl.h2
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_kernel_linux.c137
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_kernel_linux.h14
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_kernel_pm.c149
-rw-r--r--drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c137
-rw-r--r--drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h30
-rw-r--r--drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c72
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_linux_pm.h8
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h4
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_osk_irq.c15
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_osk_locks.c34
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c276
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_osk_mali.c7
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_osk_misc.c12
-rw-r--r--[-rwxr-xr-x]drivers/gpu/arm/mali/linux/mali_osk_notification.c32
-rw-r--r--[-rwxr-xr-x]drivers/gpu/arm/mali/linux/mali_osk_pm.c18
-rw-r--r--[-rwxr-xr-x]drivers/gpu/arm/mali/linux/mali_osk_timers.c1
-rw-r--r--[-rwxr-xr-x]drivers/gpu/arm/mali/linux/mali_ukk_core.c2
-rw-r--r--drivers/gpu/arm/mali/linux/mali_ukk_gp.c2
-rw-r--r--drivers/gpu/arm/mali/linux/mali_ukk_vsync.c41
-rwxr-xr-xdrivers/gpu/arm/mali/linux/mali_ukk_wrappers.h2
-rw-r--r--[-rwxr-xr-x]drivers/gpu/arm/mali/platform/mali_platform.h18
-rwxr-xr-xdrivers/gpu/arm/mali/timestamp-arm11-cc/mali_timestamp.h2
-rwxr-xr-xdrivers/gpu/arm/mali/timestamp-default/mali_timestamp.h2
-rw-r--r--drivers/gpu/arm/ump/Kconfig2
-rwxr-xr-xdrivers/gpu/arm/ump/Makefile2
-rwxr-xr-xdrivers/gpu/arm/ump/common/ump_kernel_api.c45
-rwxr-xr-xdrivers/gpu/arm/ump/common/ump_kernel_common.c6
-rwxr-xr-xdrivers/gpu/arm/ump/common/ump_osk.h2
-rw-r--r--drivers/gpu/arm/ump/linux/license/gpl/ump_kernel_license.h2
-rwxr-xr-xdrivers/gpu/arm/ump/linux/ump_kernel_memory_backend_dedicated.c1
-rwxr-xr-xdrivers/gpu/arm/ump/linux/ump_kernel_memory_backend_os.c5
-rwxr-xr-xdrivers/gpu/arm/ump/linux/ump_osk_low_level_mem.c111
-rwxr-xr-xdrivers/gpu/arm/ump/linux/ump_ukk_wrappers.c4
61 files changed, 1718 insertions, 687 deletions
diff --git a/drivers/gpu/arm/mali/Kconfig b/drivers/gpu/arm/mali/Kconfig
index dd9cb7ce977..e17f277ff68 100644
--- a/drivers/gpu/arm/mali/Kconfig
+++ b/drivers/gpu/arm/mali/Kconfig
@@ -18,24 +18,10 @@ config USING_UMP
---help---
Using UMP for Mali memory.
-config ONLY_ZBT
- bool "Only ZBT"
- depends on MALI400MP
- default "0"
- ---help---
- Only ZBT, add here more
-
-config USING_ZBT
- bool "Using ZBT"
- depends on MALI400MP
- default "1"
- ---help---
- This support ZBT add here more
-
config USING_OS_MEMORY
bool "Using OS memory"
depends on MALI400MP
- default "0"
+ default "1"
---help---
This enables for Mali to use OS memory.
diff --git a/drivers/gpu/arm/mali/Makefile b/drivers/gpu/arm/mali/Makefile
index 84817064db0..1f955dd7219 100755
--- a/drivers/gpu/arm/mali/Makefile
+++ b/drivers/gpu/arm/mali/Makefile
@@ -31,10 +31,6 @@ ifeq ($(CONFIG_USING_MMU),y)
USING_MMU=1
endif
-ifeq ($(CONFIG_ONLY_ZBT),y)
-ONLY_ZBT =1
-endif
-
ifeq ($(CONFIG_USING_OS_MEMORY),y)
USING_OS_MEMORY=1
endif
@@ -63,13 +59,12 @@ endif
ARCH ?= arm
USING_MMU ?= 1
USING_UMP ?= 0
-ONLY_ZBT ?= 0
-USING_ZBT ?= 1
USING_OS_MEMORY ?= 0
USING_PMM ?= 0
USING_GPU_UTILIZATION ?= 0
USING_MALI_RUN_TIME_PM ?= 0
USING_MALI_PMM_TESTSUITE ?= 0
+OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6
USING_PROFILING ?= 0
TIMESTAMP ?= default
TARGET_PLATFORM ?= default
@@ -83,16 +78,18 @@ endif
submodule_enabled = $(shell gcc $(DEFINES) -E $(MALICONFIGDIR)/config.h | grep type | grep -c $(2))
# Set up our defines, which will be passed to gcc
-DEFINES += -DUSING_ZBT=$(USING_ZBT)
DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY)
DEFINES += -DUSING_MMU=$(USING_MMU)
DEFINES += -DUSING_UMP=$(USING_UMP)
-DEFINES += -DONLY_ZBT=$(ONLY_ZBT)
DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP
DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING)
DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE)
DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(USING_MALI_RUN_TIME_PM)
+# MALI_STATE_TRACKING is only supported on Linux kernels from version 2.6.32.
+DEFINES += -DMALI_STATE_TRACKING=1
+DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
+
ifneq ($(call submodule_enabled, $M, PMU),0)
MALI_PLATFORM_FILE = platform/mali400-pmu/mali_platform.o
else
@@ -168,6 +165,9 @@ mali-y := \
$(OSKOS)/mali_osk_indir_mmap.o \
common/mali_kernel_rendercore.o \
common/mali_kernel_descriptor_mapping.o \
+ common/mali_kernel_vsync.o \
+ linux/mali_ukk_vsync.o \
+ linux/mali_kernel_sysfs.o \
$(MALI_PLATFORM_FILE) \
$(OSKFILES) \
$(UKKFILES)
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_GP2.c b/drivers/gpu/arm/mali/common/mali_kernel_GP2.c
index d6ce174abb5..552b57efcb4 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_GP2.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_GP2.c
@@ -101,6 +101,9 @@ static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resou
#if USING_MMU
static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
#endif
+#if MALI_STATE_TRACKING
+u32 maligp_subsystem_dump_state(char *buf, u32 size);
+#endif
/* Internal support functions */
static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core );
@@ -156,6 +159,9 @@ struct mali_kernel_subsystem mali_subsystem_gp2=
#else
NULL,
#endif
+#if MALI_STATE_TRACKING
+ maligp_subsystem_dump_state, /* dump_state */
+#endif
} ;
static mali_core_subsystem subsystem_maligp ;
@@ -698,6 +704,9 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_
subsystem_flush_mapped_mem_cache();
MALI_DEBUG_PRINT(4, ("Mali GP: STARTING GP WITH CMD: 0x%x\n", startcmd));
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_started);
+#endif
/* This is the command that starts the Core */
mali_core_renderunit_register_write(core,
@@ -827,6 +836,9 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
#endif
MALI_DEBUG_PRINT(2, ("Mali GP: Job aborted - userspace would not provide more heap memory.\n"));
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/
}
/* finished ? */
@@ -887,6 +899,9 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
return JOB_STATUS_END_SUCCESS; /* core idle */
}
/* sw watchdog timeout handling or time to do hang checking ? */
@@ -916,6 +931,11 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
#ifdef DEBUG
maligp_print_regs(2, core);
#endif
+
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
+
return JOB_STATUS_END_HANG;
}
/* if hang timeout checking was enabled and we detected progress, will be fall down to this check */
@@ -1016,6 +1036,9 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
MALI_DEBUG_PRINT(1, ("Mali GP: Registers Before reset:\n"));
maligp_print_regs(1, core);
#endif
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
return JOB_STATUS_END_UNKNOWN_ERR;
}
}
@@ -1026,7 +1049,7 @@ to a created mali_core_job object with the data given from userspace */
static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument)
{
maligp_job *jobgp;
- mali_core_job *job;
+ mali_core_job *job = NULL;
mali_core_job *previous_replaced_job;
_mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
_mali_uk_gp_start_job_s * user_ptr_job_input;
@@ -1148,6 +1171,16 @@ function_exit:
{
_mali_osk_free(jobgp);
}
+#if MALI_STATE_TRACKING
+ if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status)
+ {
+ if(job)
+ {
+ job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received);
+ }
+ }
+#endif
+
MALI_ERROR(err);
}
@@ -1275,6 +1308,9 @@ static void subsystem_maligp_return_job_to_user( mali_core_job * job, mali_subsy
job_out->perf_counter_l2_val1 = jobgp->perf_counter_l2_val1;
#endif
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&session->jobs_returned);
+#endif
_mali_osk_notification_queue_send( session->notification_queue, jobgp->notification_obj);
jobgp->notification_obj = NULL;
@@ -1403,3 +1439,10 @@ _mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only )
}
#endif
+
+#if MALI_STATE_TRACKING
+u32 maligp_subsystem_dump_state(char *buf, u32 size)
+{
+ return mali_core_renderunit_dump_state(&subsystem_maligp, buf, size);
+}
+#endif
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_MALI200.c b/drivers/gpu/arm/mali/common/mali_kernel_MALI200.c
index c1eb8fed32d..75e6af78978 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_MALI200.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_MALI200.c
@@ -93,6 +93,9 @@ static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * reso
#if USING_MMU
static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
#endif
+#if MALI_STATE_TRACKING
+u32 mali200_subsystem_dump_state(char *buf, u32 size);
+#endif
/* Internal support functions */
static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core );
@@ -135,7 +138,10 @@ struct mali_kernel_subsystem mali_subsystem_mali200=
#if USING_MMU
mali200_subsystem_broadcast_notification, /* broadcast_notification */
#else
- NULL
+ NULL,
+#endif
+#if MALI_STATE_TRACKING
+ mali200_subsystem_dump_state, /* dump_state */
#endif
} ;
@@ -626,6 +632,10 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali
subsystem_flush_mapped_mem_cache();
_mali_osk_mem_barrier();
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_started);
+#endif
+
/* This is the command that starts the Core */
mali_core_renderunit_register_write(
core,
@@ -751,6 +761,9 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
}
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
return JOB_STATUS_END_SUCCESS; /* reschedule */
}
/* Overall SW watchdog timeout or (time to do hang checking and progress detected)? */
@@ -765,6 +778,11 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
/* no progress detected, killed by the watchdog */
MALI_DEBUG_PRINT(2, ("M200: SW-Timeout Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x.\n", irq_readout ,current_tile_addr ,core_status) );
/* In this case will the system outside cleanup and reset the core */
+
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
+
return JOB_STATUS_END_HANG;
}
/* HW watchdog triggered or an existing hang check passed? */
@@ -808,6 +826,9 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
(void)bus_error;
}
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&job->session->jobs_ended);
+#endif
return JOB_STATUS_END_UNKNOWN_ERR; /* reschedule */
}
}
@@ -818,7 +839,7 @@ to a created mali_core_job object with the data given from userspace */
static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument)
{
mali200_job *job200;
- mali_core_job *job;
+ mali_core_job *job = NULL;
mali_core_job *previous_replaced_job;
_mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
_mali_uk_pp_start_job_s * user_ptr_job_input;
@@ -948,6 +969,16 @@ function_exit:
{
_mali_osk_free(job200);
}
+#if MALI_STATE_TRACKING
+ if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status)
+ {
+ if(job)
+ {
+ job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received);
+ }
+ }
+#endif
+
MALI_ERROR(err);
}
@@ -1020,6 +1051,9 @@ static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subs
job_out->perf_counter_l2_val1_raw = job200->perf_counter_l2_val1_raw;
#endif
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_inc(&session->jobs_returned);
+#endif
_mali_osk_notification_queue_send( session->notification_queue, job200->notification_obj);
job200->notification_obj = NULL;
@@ -1172,3 +1206,10 @@ _mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_
}
#endif
+
+#if MALI_STATE_TRACKING
+u32 mali200_subsystem_dump_state(char *buf, u32 size)
+{
+ return mali_core_renderunit_dump_state(&subsystem_mali200, buf, size);
+}
+#endif
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_core.c b/drivers/gpu/arm/mali/common/mali_kernel_core.c
index f3603cc7d0c..d4d0f5013fb 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_core.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_core.c
@@ -21,6 +21,9 @@
#if defined USING_MALI400_L2_CACHE
#include "mali_kernel_l2_cache.h"
#endif
+#if USING_MALI_PMM
+#include "mali_pmm.h"
+#endif /* USING_MALI_PMM */
/* platform specific set up */
#include "mali_platform.h"
@@ -49,6 +52,7 @@ static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_sys
static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
static _mali_osk_errcode_t build_system_info(void);
+static void cleanup_system_info(_mali_system_info *cleanup);
/**
* @brief handler for MEM_VALIDATION resources
@@ -95,6 +99,9 @@ static struct mali_kernel_subsystem mali_subsystem_core =
mali_kernel_subsystem_core_session_begin, /* session_begin */
NULL, /* session_end */
NULL, /* broadcast_notification */
+#if MALI_STATE_TRACKING
+ NULL, /* dump_state */
+#endif
};
static struct mali_kernel_subsystem * subsystems[] =
@@ -298,6 +305,9 @@ static void terminate_subsystems(void)
if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i);
}
if (system_info_lock) _mali_osk_lock_term( system_info_lock );
+
+ /* Free _mali_system_info struct */
+ cleanup_system_info(system_info);
}
void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data)
@@ -335,6 +345,30 @@ static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier
_mali_osk_resources_term(&arch_configuration, num_resources);
}
+static void cleanup_system_info(_mali_system_info *cleanup)
+{
+ _mali_core_info * current_core;
+ _mali_mem_info * current_mem;
+
+ /* delete all the core info structs */
+ while (NULL != cleanup->core_info)
+ {
+ current_core = cleanup->core_info;
+ cleanup->core_info = cleanup->core_info->next;
+ _mali_osk_free(current_core);
+ }
+
+ /* delete all the mem info struct */
+ while (NULL != cleanup->mem_info)
+ {
+ current_mem = cleanup->mem_info;
+ cleanup->mem_info = cleanup->mem_info->next;
+ _mali_osk_free(current_mem);
+ }
+
+ /* delete the system info struct itself */
+ _mali_osk_free(cleanup);
+}
static _mali_osk_errcode_t build_system_info(void)
{
@@ -400,25 +434,7 @@ error_exit:
if (NULL == cleanup) MALI_ERROR((_mali_osk_errcode_t)err); /* no cleanup needed, return what err contains */
/* cleanup */
-
- /* delete all the core info structs */
- while (NULL != cleanup->core_info)
- {
- current_core = cleanup->core_info;
- cleanup->core_info = cleanup->core_info->next;
- _mali_osk_free(current_core);
- }
-
- /* delete all the mem info struct */
- while (NULL != cleanup->mem_info)
- {
- current_mem = cleanup->mem_info;
- cleanup->mem_info = cleanup->mem_info->next;
- _mali_osk_free(current_mem);
- }
-
- /* delete the system info struct itself */
- _mali_osk_free(cleanup);
+ cleanup_system_info(cleanup);
/* return whatever err is, we could end up here in both the error and success cases */
MALI_ERROR((_mali_osk_errcode_t)err);
@@ -865,3 +881,28 @@ _mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_boo
}
#endif
+
+
+#if MALI_STATE_TRACKING
+u32 _mali_kernel_core_dump_state(char* buf, u32 size)
+{
+ int i, n;
+ char *original_buf = buf;
+ for (i = 0; i < SUBSYSTEMS_COUNT; ++i)
+ {
+ if (NULL != subsystems[i]->dump_state)
+ {
+ n = subsystems[i]->dump_state(buf, size);
+ size -= n;
+ buf += n;
+ }
+ }
+#if USING_MALI_PMM
+ n = mali_pmm_dump_os_thread_state(buf, size);
+ size -= n;
+ buf += n;
+#endif
+ /* Return number of bytes written to buf */
+ return (u32)(buf - original_buf);
+}
+#endif
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_core.h b/drivers/gpu/arm/mali/common/mali_kernel_core.h
index 3819ecc5e1c..ced6b8fb118 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_core.h
+++ b/drivers/gpu/arm/mali/common/mali_kernel_core.h
@@ -88,9 +88,9 @@ _mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u3
* @brief Signal a power up on a Mali core.
*
* This function flags a core as powered up.
- * For PP and GP cores it calls functions that move the core from a power off
+ * For PP and GP cores it calls functions that move the core from a power off
* queue into the idle queue ready to run jobs. It also tries to schedule any
- * pending jobs to run on it.
+ * pending jobs to run on it.
*
* This function will fail if the core is not powered off - either running or
* already idle.
@@ -100,7 +100,7 @@ _mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u3
*
* @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a
* suitable _mali_osk_errcode_t error.
- */
+ */
_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only );
/**
@@ -108,9 +108,9 @@ _mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool
*
* This function flags a core as powered down.
* For PP and GP cores it calls functions that move the core from an idle
- * queue into the power off queue.
+ * queue into the power off queue.
*
- * This function will fail if the core is not idle - either running or
+ * This function will fail if the core is not idle - either running or
* already powered down.
*
* @param core The PMM core id to power up.
@@ -119,7 +119,7 @@ _mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool
*
* @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a
* suitable _mali_osk_errcode_t error.
- */
+ */
_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only );
#endif
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_l2_cache.c b/drivers/gpu/arm/mali/common/mali_kernel_l2_cache.c
index af307c6ec0b..3c4c68d74bd 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_l2_cache.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_l2_cache.c
@@ -33,6 +33,7 @@ typedef enum mali_l2_cache_register {
/*unused = 0x0003 */
MALI400_L2_CACHE_REGISTER_COMMAND = 0x0004, /**< Misc cache commands, e.g. clear */
MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0005,
+ MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0006, /**< Limit of outstanding read requests */
MALI400_L2_CACHE_REGISTER_ENABLE = 0x0007, /**< Enable misc cache features */
MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0008,
MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0009,
@@ -87,6 +88,10 @@ typedef struct mali_kernel_l2_cache_core
} mali_kernel_l2_cache_core;
+#define MALI400_L2_MAX_READS_DEFAULT 0x1C
+
+int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT;
+
/**
* Mali L2 cache subsystem startup function
@@ -154,6 +159,9 @@ struct mali_kernel_subsystem mali_subsystem_l2_cache =
NULL, /**< session_begin */
NULL, /**< session_end */
NULL, /**< broadcast_notification */
+#if MALI_STATE_TRACKING
+ NULL, /**< dump_state */
+#endif
};
@@ -193,6 +201,7 @@ static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id)
_MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list )
{
/* reset to defaults */
+ mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT);
mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT);
/* remove from the list of cacges on the system */
@@ -327,11 +336,11 @@ void mali_kernel_l2_cache_do_enable(void)
{
mali_kernel_l2_cache_core * cache, *temp_cache;
-
/* loop over all L2 cache units and enable them*/
_MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
{
mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);
+ mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads);
}
}
@@ -486,6 +495,7 @@ void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32
MALI_DEBUG_PRINT(5, ("L2 cache counters get: SRC0=%u, VAL0=%u, SRC1=%u, VAL1=%u\n", cur_src0, cur_val0, cur_src1, cur_val1));
+ /* Only update the counter source once, with the value from the first L2 cache unit. */
if (first_time)
{
*src0 = cur_src0;
@@ -493,6 +503,7 @@ void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32
first_time = 0;
}
+ /* Bail out if the L2 cache units have different counters set. */
if (*src0 == cur_src0 && *src1 == cur_src1)
{
*val0 += cur_val0;
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_mem_buddy.c b/drivers/gpu/arm/mali/common/mali_kernel_mem_buddy.c
index 2f0e0ffafea..8277fd1e1c6 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_mem_buddy.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_mem_buddy.c
@@ -389,6 +389,9 @@ struct mali_kernel_subsystem mali_subsystem_memory =
mali_memory_core_session_begin, /* session_begin */
mali_memory_core_session_end, /* session_end */
NULL, /* broadcast_notification */
+#if MALI_STATE_TRACKING
+ NULL, /* dump_state */
+#endif
};
/* Initialized when this subsystem is initialized. This is determined by the
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_mem_mmu.c b/drivers/gpu/arm/mali/common/mali_kernel_mem_mmu.c
index f43ca21cdf1..0476986ffd2 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_mem_mmu.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_mem_mmu.c
@@ -329,10 +329,13 @@ static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resourc
* also call this directly (depending on compilation options), having locked
* the descriptor.
*
+ * This function will fail if it is unable to put the MMU in stall mode (which
+ * might be the case if a page fault is also being processed).
+ *
* @param args see _mali_uk_mem_munmap_s in "mali_uk_types.h"
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
*/
-static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args );
+static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args );
/**
* The MMU interrupt handler
@@ -373,6 +376,30 @@ static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_regist
*/
static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val);
+/**
+ * Issues the reset command to the MMU and waits for HW to be ready again
+ * @param mmu The MMU to reset
+ */
+static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu);
+
+/**
+ * Issues the enable paging command to the MMU and waits for HW to complete the request
+ * @param mmu The MMU to enable paging for
+ */
+static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu);
+
+/**
+ * Issues the enable stall command to the MMU and waits for HW to complete the request
+ * @param mmu The MMU to enable paging for
+ * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out)
+ */
+static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu);
+
+/**
+ * Issues the disable stall command to the MMU and waits for HW to complete the request
+ * @param mmu The MMU to enable paging for
+ */
+static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu);
#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
static void ump_memory_release(void * ctx, void * handle);
@@ -463,7 +490,10 @@ struct mali_kernel_subsystem mali_subsystem_memory =
mali_memory_core_system_info_fill, /* system_info_fill */
mali_memory_core_session_begin, /* session_begin */
mali_memory_core_session_end, /* session_end */
- NULL /* broadcast_notification */
+ NULL, /* broadcast_notification */
+#if MALI_STATE_TRACKING
+ NULL, /* dump_state */
+#endif
};
static mali_kernel_mem_address_manager mali_address_manager =
@@ -530,7 +560,7 @@ static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id)
_MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
{
/* reset to defaults */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
+ mali_mmu_raw_reset(mmu);
/* unregister the irq */
_mali_osk_irq_term(mmu->irq);
@@ -541,6 +571,7 @@ static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id)
/* release resources */
_mali_osk_mem_unmapioregion(mmu->base, mmu->mapping_size, mmu->mapped_registers);
_mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size);
+ _mali_osk_lock_term(mmu->lock);
_mali_osk_free(mmu);
}
@@ -884,7 +915,7 @@ static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_
_MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
{
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
+ mali_mmu_enable_paging(mmu);
}
MALI_DEBUG_PRINT(4, ("MMUs activated\n"));
@@ -989,7 +1020,7 @@ static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t *
/* setup MMU interrupt mask */
/* set all values to known defaults */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
+ mali_mmu_raw_reset(mmu);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
/* setup MMU page directory pointer */
/* The mali_page_directory pointer is guaranteed to be 4kb aligned because we've used get_zeroed_page to accquire it */
@@ -1018,7 +1049,7 @@ static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t *
}
/* set to a known state */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
+ mali_mmu_raw_reset(mmu);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
MALI_DEBUG_PRINT(2, ("MMU registered\n"));
@@ -1216,6 +1247,9 @@ static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu)
/* no new request will come from any of the connected cores from now
* we must now flush the playback buffer for any requests queued already
*/
+
+ _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
+
MALI_DEBUG_PRINT(4, ("Switching to the special page fault flush page directory\n"));
/* don't use the mali_mmu_activate_address_space function here as we can't stall the MMU */
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_page_fault_flush_page_directory);
@@ -1236,16 +1270,23 @@ static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu)
MALI_DEBUG_PRINT_IF(1, i == replay_buffer_max_number_of_checks, ("MMU: %s: Failed to flush replay buffer on page fault\n", mmu->description));
MALI_DEBUG_PRINT(1, ("Replay playback took %ld usec\n", i * replay_buffer_check_interval));
}
+
+ _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
+
#endif
/* notify all subsystems that the core should be reset once the bus is actually stopped */
MALI_DEBUG_PRINT(4,("Sending job abort command to subsystems\n"));
_mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, (u32)mmu);
+ _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
+
/* reprogram the MMU */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
+ mali_mmu_raw_reset(mmu);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
+ mali_mmu_enable_paging(mmu);
+
+ _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
/* release the extra address space reference, will schedule */
mali_memory_core_mmu_release_address_space_reference(mmu);
@@ -1255,6 +1296,101 @@ static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu)
MALI_DEBUG_PRINT(4, ("Page fault handling complete\n"));
}
+static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 1;
+
+ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
+ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
+
+ if (!mali_benchmark)
+ {
+ int i;
+ for (i = 0; i < max_loop_count; ++i)
+ {
+ if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_DTE_ADDR) == 0)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Reset request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
+ }
+}
+
+static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 1;
+
+ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
+
+ if (!mali_benchmark)
+ {
+ int i;
+ for (i = 0; i < max_loop_count; ++i)
+ {
+ if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable paging request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
+ }
+}
+
+static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 999;
+ int i;
+
+ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
+
+ if (!mali_benchmark)
+ {
+ for (i = 0; i < max_loop_count; ++i)
+ {
+ if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
+ if (max_loop_count == i)
+ {
+ return MALI_FALSE;
+ }
+ }
+
+ return MALI_TRUE;
+}
+
+static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 1;
+ int i;
+
+ mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
+
+ if (!mali_benchmark)
+ {
+ for (i = 0; i < max_loop_count; ++i)
+ {
+ if ((mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Disable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
+ }
+}
+
void mali_kernel_mmu_reset(void * input_mmu)
{
mali_kernel_memory_mmu * mmu;
@@ -1270,10 +1406,10 @@ void mali_kernel_mmu_reset(void * input_mmu)
return;
}
_mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
+ mali_mmu_raw_reset(mmu);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
+ mali_mmu_enable_paging(mmu);
_mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
}
@@ -1401,7 +1537,6 @@ static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_regi
_mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val);
}
-
#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
{
@@ -1572,6 +1707,7 @@ _mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args )
descriptor->mali_address = args->mali_address;
descriptor->mali_addr_mapping_info = (void*)session_data;
descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
+ descriptor->lock = session_data->lock;
if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
{
descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
@@ -1591,14 +1727,19 @@ _mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args )
external_memory_allocator.name = "UMP Memory";
external_memory_allocator.next = NULL;
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
{
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
ump_dd_reference_release(ump_mem);
_mali_osk_free(descriptor);
MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
args->cookie = md;
MALI_DEBUG_PRINT(5,("Returning from UMP attach\n"));
@@ -1626,7 +1767,13 @@ _mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args
}
mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
+
+ _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
+
mali_allocation_engine_release_memory(memory_engine, descriptor);
+
+ _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW );
+
_mali_osk_free(descriptor);
MALI_SUCCESS;
@@ -1765,7 +1912,7 @@ _mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *arg
descriptor->mali_address = args->mali_address;
descriptor->mali_addr_mapping_info = (void*)session_data;
descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
- descriptor->lock = NULL;
+ descriptor->lock = session_data->lock;
if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
{
descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
@@ -1778,13 +1925,18 @@ _mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *arg
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
{
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
_mali_osk_free(descriptor);
MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
args->cookie = md;
MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n"));
@@ -1812,7 +1964,13 @@ _mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s
}
mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
+
+ _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
+
mali_allocation_engine_release_memory(memory_engine, descriptor);
+
+ _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW );
+
_mali_osk_free(descriptor);
MALI_SUCCESS;
@@ -1867,6 +2025,8 @@ void mali_mmu_page_table_cache_destroy(void)
_mali_osk_free(alloc->usage_map);
_mali_osk_free(alloc);
}
+
+ _mali_osk_lock_term(page_table_cache.lock);
}
_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping)
@@ -2027,24 +2187,10 @@ void* mali_memory_core_mmu_lookup(u32 id)
void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory)
{
- const int delay_in_usecs = 10;
- const int max_loop_count = 10;
- int i;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
-
- if (!mali_benchmark) {
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) break;
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Stall request failed, swapping anyway\n"));
- }
-
+ mali_mmu_enable_stall(mmu); /* this might fail, but changing the DTE address and ZAP should work anyway... */
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, page_directory);
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
+ mali_mmu_disable_stall(mmu);
}
_mali_osk_errcode_t mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument)
@@ -2571,7 +2717,7 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
descriptor->lock = session_data->lock;
_mali_osk_list_init( &descriptor->list );
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head))
{
@@ -2584,12 +2730,9 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
_mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
- if (!mali_benchmark) {
- while ( (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0) _mali_osk_time_ubusydelay(1);
- }
+ mali_mmu_enable_stall(mmu); /* this might fail, but ZAP should work anyway... */
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
+ mali_mmu_disable_stall(mmu);
_mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
}
@@ -2615,7 +2758,7 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
}
}
-static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
+static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
{
memory_session * session_data;
mali_kernel_memory_mmu * mmu, * temp_mmu;
@@ -2638,24 +2781,28 @@ static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
*/
_MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
{
- const int max_loop_count = 100;
- const int sleep_duration = 1; /* must be below 1000 */
- int i;
-
_mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
-
- if (!mali_benchmark)
+ /*
+ * If we're unable to stall, then make sure we tell our caller that,
+ * the caller should then release the session lock for a while,
+ * then this function again.
+ * This function will fail if we're in page fault mode, and to get
+ * out of page fault mode, the page fault handler must be able to
+ * take the session lock.
+ */
+ if (!mali_mmu_enable_stall(mmu))
{
- for ( i = 0; i < max_loop_count; i++)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) break;
- _mali_osk_time_ubusydelay(sleep_duration);
- }
-
- MALI_DEBUG_PRINT_IF(3, max_loop_count == i, ("Stall failed, trying zap anyway\n"));
+ _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_BUSY;
}
+
+ _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
+ {
+ _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
}
/* This function also removes the memory from the session's memory list */
@@ -2668,10 +2815,12 @@ static void _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
_MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
{
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
+ mali_mmu_disable_stall(mmu);
_mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
}
+
+ return _MALI_OSK_ERR_OK;
}
/* Handler for unmapping memory for MMU builds */
@@ -2679,6 +2828,7 @@ _mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
{
mali_memory_allocation * descriptor;
_mali_osk_lock_t *descriptor_lock;
+ _mali_osk_errcode_t err;
descriptor = (mali_memory_allocation *)args->cookie;
MALI_DEBUG_ASSERT_POINTER(descriptor);
@@ -2692,20 +2842,34 @@ _mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
descriptor_lock = descriptor->lock; /* should point to the session data lock... */
- if (descriptor_lock)
+ err = _MALI_OSK_ERR_BUSY;
+ while (err == _MALI_OSK_ERR_BUSY)
{
- _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
- }
- /* Noninterruptable spinlock type, so must always have locked. Checking should've been done in OSK function. */
+ if (descriptor_lock)
+ {
+ _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
+ }
- _mali_ukk_mem_munmap_internal( args );
- /* descriptor is no longer valid - it may've been freed */
+ err = _mali_ukk_mem_munmap_internal( args );
- if (descriptor_lock)
- {
- _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
+ if (descriptor_lock)
+ {
+ _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
+ }
+
+ if (err == _MALI_OSK_ERR_BUSY)
+ {
+ /*
+ * Reason for this;
+ * We where unable to stall the MMU, probably because we are in page fault handling.
+ * Sleep for a while with the session lock released, then try again.
+ * Abnormal termination of programs with running Mali jobs is a normal reason for this.
+ */
+ _mali_osk_time_ubusydelay(10);
+ }
}
- return _MALI_OSK_ERR_OK;
+
+ return err;
}
/* Is called when the rendercore wants the mmu to give an interrupt */
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_rendercore.c b/drivers/gpu/arm/mali/common/mali_kernel_rendercore.c
index e3027cc4f26..5ff681b32d3 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_rendercore.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_rendercore.c
@@ -94,14 +94,18 @@ struct mali_kernel_subsystem mali_subsystem_rendercore=
NULL, /* session_begin */
NULL, /* session_end */
#if USING_MMU
- rendercore_subsystem_broadcast_notification /* broadcast_notification */
+ rendercore_subsystem_broadcast_notification, /* broadcast_notification */
#else
- NULL
+ NULL,
+#endif
+#if MALI_STATE_TRACKING
+ NULL, /* dump_state */
#endif
} ;
static _mali_osk_lock_t *rendercores_global_mutex = NULL;
static u32 rendercores_global_mutex_is_held = 0;
+static u32 rendercores_global_mutex_owner = 0;
/** The 'dummy' rendercore subsystem to allow global subsystem mutex to be
* locked for all subsystems that extend the ''rendercore'' */
@@ -544,6 +548,7 @@ static void mali_core_renderunit_irq_handler_remove(mali_core_renderunit *core)
mali_core_renderunit * mali_core_renderunit_get_mali_core_nr(mali_core_subsystem *subsys, u32 mali_core_nr)
{
mali_core_renderunit * core;
+ MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
if (subsys->number_of_cores <= mali_core_nr)
{
MALI_PRINT_ERROR(("Trying to get illegal mali_core_nr: 0x%x for %s", mali_core_nr, subsys->name));
@@ -603,6 +608,8 @@ void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys)
u32 i;
mali_core_renderunit * core;
+ MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
+
for(i=0 ; i < subsys->number_of_cores ; ++i)
{
core = mali_core_renderunit_get_mali_core_nr(subsys,i);
@@ -610,6 +617,8 @@ void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys)
core->mmu = mali_memory_core_mmu_lookup(core->mmu_id);
MALI_DEBUG_PRINT(2, ("Attach mmu: 0x%x to core: %s in subsystem: %s\n", core->mmu, core->description, subsys->name));
}
+
+ MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
}
#endif
@@ -862,11 +871,11 @@ _mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_sess
if ( NULL != number_of_cores )
{
*number_of_cores = subsystem->number_of_cores;
- }
- MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ;
+ MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ;
+ }
- MALI_SUCCESS;
+ MALI_SUCCESS;
}
_mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data)
@@ -1058,15 +1067,7 @@ static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core)
oldstatus = core->state;
- if( core->pend_power_down )
- {
- core->state = CORE_OFF ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head );
- /* Done the move from the active queues, so the pending power down can be done */
- core->pend_power_down = MALI_FALSE;
- malipmm_core_power_down_okay( core->pmm_id );
- }
- else
+ if ( !core->pend_power_down )
{
core->state = CORE_IDLE ;
_mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head );
@@ -1089,6 +1090,15 @@ static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core)
#endif /* USING_MMU */
}
+ if( core->pend_power_down )
+ {
+ core->state = CORE_OFF ;
+ _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head );
+
+ /* Done the move from the active queues, so the pending power down can be done */
+ core->pend_power_down = MALI_FALSE;
+ malipmm_core_power_down_okay( core->pmm_id );
+ }
#else /* !USING_MALI_PMM */
@@ -1389,6 +1399,13 @@ void mali_core_session_begin(mali_core_session * session)
MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
_mali_osk_list_add(&session->all_sessions_list, &session->subsystem->all_sessions_head);
+
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_init(&session->jobs_received, 0);
+ _mali_osk_atomic_init(&session->jobs_returned, 0);
+ session->pid = _mali_osk_get_pid();
+#endif
+
MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
MALI_DEBUG_PRINT(5, ("Core: session_begin: for %s DONE\n", session->subsystem->name) ) ;
@@ -1934,3 +1951,128 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub
}
#endif /* USING_MALI_PMM */
+
+#if MALI_STATE_TRACKING
+u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size)
+{
+ u32 i, len = 0;
+ mali_core_renderunit *core;
+ mali_core_renderunit *tmp_core;
+
+ mali_core_session* session;
+ mali_core_session* tmp_session;
+
+ if (0 >= size)
+ {
+ return 0;
+ }
+
+ MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
+
+ len += _mali_osk_snprintf(buf + len, size - len, "Subsystem:\n");
+ len += _mali_osk_snprintf(buf + len, size - len, " Name: %s\n", subsystem->name);
+
+ for (i = 0; i < subsystem->number_of_cores; i++)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len, " Core: #%u\n",
+ subsystem->mali_core_array[i]->core_number);
+ len += _mali_osk_snprintf(buf + len, size - len, " Description: %s\n",
+ subsystem->mali_core_array[i]->description);
+ switch(subsystem->mali_core_array[i]->state)
+ {
+ case CORE_IDLE:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_IDLE\n");
+ break;
+ case CORE_WORKING:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WORKING\n");
+ break;
+ case CORE_WATCHDOG_TIMEOUT:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WATCHDOG_TIMEOUT\n");
+ break;
+ case CORE_POLL:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_POLL\n");
+ break;
+ case CORE_HANG_CHECK_TIMEOUT:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_HANG_CHECK_TIMEOUT\n");
+ break;
+ case CORE_OFF:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_OFF\n");
+ break;
+ default:
+ len += _mali_osk_snprintf(buf + len, size - len, " State: Unknown (0x%X)\n",
+ subsystem->mali_core_array[i]->state);
+ break;
+ }
+ len += _mali_osk_snprintf(buf + len, size - len, " Current job: 0x%X\n",
+ (u32)(subsystem->mali_core_array[i]->current_job));
+ if (subsystem->mali_core_array[i]->current_job)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len, " Current job session: 0x%X\n",
+ subsystem->mali_core_array[i]->current_job->session);
+ len += _mali_osk_snprintf(buf + len, size - len, " Current job number: %d\n",
+ subsystem->mali_core_array[i]->current_job->job_nr);
+ len += _mali_osk_snprintf(buf + len, size - len, " Current job render_time jiffies: %d\n",
+ _mali_osk_time_tickcount()-subsystem->mali_core_array[i]->current_job->start_time_jiffies);
+ }
+ len += _mali_osk_snprintf(buf + len, size - len, " Core version: 0x%X\n",
+ subsystem->mali_core_array[i]->core_version);
+#if USING_MALI_PMM
+ len += _mali_osk_snprintf(buf + len, size - len, " PMM id: 0x%X\n",
+ subsystem->mali_core_array[i]->pmm_id);
+ len += _mali_osk_snprintf(buf + len, size - len, " Power down requested: %s\n",
+ subsystem->mali_core_array[i]->pend_power_down ? "TRUE" : "FALSE");
+#endif
+ }
+
+ len += _mali_osk_snprintf(buf + len, size - len, " Cores on idle list:\n");
+ _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_idle_head, mali_core_renderunit, list)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number);
+ }
+
+ len += _mali_osk_snprintf(buf + len, size - len, " Cores on off list:\n");
+ _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_off_head, mali_core_renderunit, list)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number);
+ }
+
+ len += _mali_osk_snprintf(buf + len, size - len, " Connected sessions:\n");
+ _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->all_sessions_head, mali_core_session, all_sessions_list)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len,
+ " Session 0x%X:\n", (u32)session);
+ len += _mali_osk_snprintf(buf + len, size - len,
+ " Waiting job: 0x%X\n", (u32)session->job_waiting_to_run);
+ len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n",
+ _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY");
+ len += _mali_osk_snprintf(buf + len, size - len,
+ " Jobs received:%4d\n", _mali_osk_atomic_read(&session->jobs_received));
+ len += _mali_osk_snprintf(buf + len, size - len,
+ " Jobs started :%4d\n", _mali_osk_atomic_read(&session->jobs_started));
+ len += _mali_osk_snprintf(buf + len, size - len,
+ " Jobs ended :%4d\n", _mali_osk_atomic_read(&session->jobs_ended));
+ len += _mali_osk_snprintf(buf + len, size - len,
+ " Jobs returned:%4d\n", _mali_osk_atomic_read(&session->jobs_returned));
+ len += _mali_osk_snprintf(buf + len, size - len, " PID: %d\n", session->pid);
+ }
+
+ len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions sum all priorities: %u\n",
+ subsystem->awaiting_sessions_sum_all_priorities);
+ for (i = 0; i < PRIORITY_LEVELS; i++)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions with priority %u:\n", i);
+ _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->awaiting_sessions_head[i],
+ mali_core_session, awaiting_sessions_list)
+ {
+ len += _mali_osk_snprintf(buf + len, size - len, " Session 0x%X:\n", (u32)session);
+ len += _mali_osk_snprintf(buf + len, size - len, " Waiting job: 0x%X\n",
+ (u32)session->job_waiting_to_run);
+ len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n",
+ _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY");
+ }
+ }
+
+ MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem );
+ return len;
+}
+#endif
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_rendercore.h b/drivers/gpu/arm/mali/common/mali_kernel_rendercore.h
index 80d7dd82cea..b72d467a0c3 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_rendercore.h
+++ b/drivers/gpu/arm/mali/common/mali_kernel_rendercore.h
@@ -188,6 +188,13 @@ typedef struct mali_core_session
struct mali_session_data * mmu_session; /* The session associated with the MMU page tables for this core */
#endif
u32 magic_nr;
+#if MALI_STATE_TRACKING
+ _mali_osk_atomic_t jobs_received;
+ _mali_osk_atomic_t jobs_started;
+ _mali_osk_atomic_t jobs_ended;
+ _mali_osk_atomic_t jobs_returned;
+ u32 pid;
+#endif
} mali_core_session;
@@ -204,6 +211,7 @@ typedef struct mali_core_job
u32 start_time_jiffies;
unsigned long watchdog_jiffies;
u32 abort_id;
+ u32 job_nr;
} mali_core_job;
/*
@@ -287,12 +295,14 @@ typedef struct register_array_user
MALI_DEBUG_PRINT(5, ("MUTEX: GRABBED %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
rendercores_global_mutex_is_held = 1; \
+ rendercores_global_mutex_owner = _mali_osk_get_tid(); \
} while (0) ;
#define MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys) \
do { \
MALI_DEBUG_PRINT(5, ("MUTEX: RELEASE %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
rendercores_global_mutex_is_held = 0; \
+ rendercores_global_mutex_owner = 0; \
if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
_mali_osk_lock_signal( rendercores_global_mutex, _MALI_OSK_LOCKMODE_RW); \
MALI_DEBUG_PRINT(5, ("MUTEX: RELEASED %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
@@ -304,6 +314,7 @@ typedef struct register_array_user
do { \
if ( 0 == rendercores_global_mutex_is_held ) MALI_PRINT_ERROR(("ASSERT MUTEX SHOULD BE GRABBED"));\
if ( SUBSYSTEM_MAGIC_NR != input_pointer->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
+ if ( rendercores_global_mutex_owner != _mali_osk_get_tid() ) MALI_PRINT_ERROR(("Owner mismatch"));\
} while (0)
@@ -345,4 +356,8 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *s
_mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool queue_only);
#endif
+#if MALI_STATE_TRACKING
+u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size);
+#endif
+
#endif /* __MALI_RENDERCORE_H__ */
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_subsystem.h b/drivers/gpu/arm/mali/common/mali_kernel_subsystem.h
index ba757abef0a..9efba566bd9 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_subsystem.h
+++ b/drivers/gpu/arm/mali/common/mali_kernel_subsystem.h
@@ -71,6 +71,11 @@ typedef struct mali_kernel_subsystem
/* Used by subsystems to send messages to each other. This is the receiving end */
void (*broadcast_notification)(mali_core_notification_message message, u32 data);
+
+#if MALI_STATE_TRACKING
+ /** Dump the current state of the subsystem */
+ u32 (*dump_state)(char *buf, u32 size);
+#endif
} mali_kernel_subsystem;
/* functions used by the subsystems to interact with the core */
@@ -91,4 +96,12 @@ _mali_osk_errcode_t _mali_kernel_core_register_resource_handler(_mali_osk_resour
*/
void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data);
+#if MALI_STATE_TRACKING
+/**
+ * Tell all subsystems to dump their current state
+ */
+u32 _mali_kernel_core_dump_state(char *buf, u32 size);
+#endif
+
+
#endif /* __MALI_KERNEL_SUBSYSTEM_H__ */
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_utilization.c b/drivers/gpu/arm/mali/common/mali_kernel_utilization.c
index 1ba122a9856..a8acd8c2cce 100755
--- a/drivers/gpu/arm/mali/common/mali_kernel_utilization.c
+++ b/drivers/gpu/arm/mali/common/mali_kernel_utilization.c
@@ -29,7 +29,7 @@ static mali_bool timer_running = MALI_FALSE;
static void calculate_gpu_utilization(void* arg)
{
- u64 time_now = _mali_osk_time_get_ns();
+ u64 time_now;
u64 time_period;
u32 leading_zeroes;
u32 shift_val;
@@ -39,7 +39,7 @@ static void calculate_gpu_utilization(void* arg)
_mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
- if (accumulated_work_time == 0)
+ if (accumulated_work_time == 0 && work_start_time == 0)
{
/* Don't reschedule timer, this will be started if new work arrives */
timer_running = MALI_FALSE;
@@ -52,6 +52,7 @@ static void calculate_gpu_utilization(void* arg)
return;
}
+ time_now = _mali_osk_time_get_ns();
time_period = time_now - period_start_time;
/* If we are currently busy, update working period up to now */
@@ -129,20 +130,15 @@ _mali_osk_errcode_t mali_utilization_init(void)
return _MALI_OSK_ERR_OK;
}
-
-
-
void mali_utilization_suspend(void)
{
- if (NULL != utilization_timer)
- {
- _mali_osk_timer_del(utilization_timer);
- timer_running = MALI_FALSE;
- }
+ if (NULL != utilization_timer)
+ {
+ _mali_osk_timer_del(utilization_timer);
+ timer_running = MALI_FALSE;
+ }
}
-
-
void mali_utilization_term(void)
{
if (NULL != utilization_timer)
@@ -198,9 +194,11 @@ void mali_utilization_core_end(void)
/*
* No more cores are working, so accumulate the time we was busy.
*/
- u64 time_now = _mali_osk_time_get_ns();
+ u64 time_now;
+
_mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ time_now = _mali_osk_time_get_ns();
accumulated_work_time += (time_now - work_start_time);
work_start_time = 0;
diff --git a/drivers/gpu/arm/mali/common/mali_kernel_vsync.c b/drivers/gpu/arm/mali/common/mali_kernel_vsync.c
new file mode 100644
index 00000000000..8dfa3a393ba
--- /dev/null
+++ b/drivers/gpu/arm/mali/common/mali_kernel_vsync.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+/*#include "mali_timestamp.h"
+*/
+
+_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args)
+{
+ _mali_uk_vsync_event event = (_mali_uk_vsync_event)args->event;
+ MALI_IGNORE(event); /* event is not used for release code, and that is OK */
+/* u64 ts = _mali_timestamp_get();
+ */
+
+ MALI_DEBUG_PRINT(4, ("Received VSYNC event: %d\n", event));
+
+ MALI_SUCCESS;
+}
+
diff --git a/drivers/gpu/arm/mali/common/mali_osk.h b/drivers/gpu/arm/mali/common/mali_osk.h
index a287a6af7dc..77a96dcfb50 100755
--- a/drivers/gpu/arm/mali/common/mali_osk.h
+++ b/drivers/gpu/arm/mali/common/mali_osk.h
@@ -54,7 +54,7 @@ extern "C"
/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE
*/
typedef unsigned long mali_bool;
-
+
#ifndef MALI_TRUE
#define MALI_TRUE ((mali_bool)1)
#endif
@@ -700,6 +700,16 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq );
* resource whose IRQ handling is to be terminated.
*/
void _mali_osk_irq_term( _mali_osk_irq_t *irq );
+
+/** @brief flushing workqueue.
+ *
+ * This will flush the workqueue.
+ *
+ * @param irq a pointer to the _mali_osk_irq_t object corresponding to the
+ * resource whose IRQ handling is to be terminated.
+ */
+void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq );
+
/** @} */ /* end group _mali_osk_irq */
@@ -871,7 +881,7 @@ void *_mali_osk_memset( void *s, u32 c, u32 n );
/** @brief Checks the amount of memory allocated
*
- * Checks that not more than \a max_allocated bytes are allocated.
+ * Checks that not more than \a max_allocated bytes are allocated.
*
* Some OS bring up an interactive out of memory dialogue when the
* system runs out of memory. This can stall non-interactive
@@ -879,7 +889,7 @@ void *_mali_osk_memset( void *s, u32 c, u32 n );
* not trigger the OOM dialogue by keeping allocations
* within a certain limit.
*
- * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE
+ * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE
* when at least \a max_allocated bytes are in use.
*/
mali_bool _mali_osk_mem_check_allocated( u32 max_allocated );
@@ -1147,7 +1157,7 @@ void _mali_osk_cache_flushall( void );
*
* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory.
* They zero the memory through a cached mapping, then flush the inner caches but not the outer caches.
- * This is required for MALI to have the correct view of the memory.
+ * This is required for MALI to have the correct view of the memory.
*/
void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size );
@@ -1303,6 +1313,17 @@ void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue );
*/
void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object );
+#if MALI_STATE_TRACKING
+/** @brief Receive a notification from a queue
+ *
+ * Check if a notification queue is empty.
+ *
+ * @param queue The queue to check.
+ * @return MALI_TRUE if queue is empty, otherwise MALI_FALSE.
+ */
+mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue );
+#endif
+
/** @brief Receive a notification from a queue
*
* Receives a single notification from the given queue.
@@ -1511,7 +1532,7 @@ u32 _mali_osk_time_tickcount( void );
void _mali_osk_time_ubusydelay( u32 usecs );
/** @brief Return time in nano seconds, since any given reference.
- *
+ *
* @return Time in nano seconds
*/
u64 _mali_osk_time_get_ns( void );
@@ -1548,6 +1569,18 @@ u32 _mali_osk_clz( u32 val );
*/
void _mali_osk_dbgmsg( const char *fmt, ... );
+/** @brief Print fmt into buf.
+ *
+ * The interpretation of \a fmt is the same as the \c format parameter in
+ * _mali_osu_vsnprintf().
+ *
+ * @param buf a pointer to the result buffer
+ * @param size the total number of bytes allowed to write to \a buf
+ * @param fmt a _mali_osu_vsnprintf() style format string
+ * @param ... a variable-number of parameters suitable for \a fmt
+ */
+u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... );
+
/** @brief Abnormal process abort.
*
* Terminates the caller-process if this function is called.
diff --git a/drivers/gpu/arm/mali/common/mali_osk_list.h b/drivers/gpu/arm/mali/common/mali_osk_list.h
index bfa6cdbe88a..a8d15f2a107 100755
--- a/drivers/gpu/arm/mali/common/mali_osk_list.h
+++ b/drivers/gpu/arm/mali/common/mali_osk_list.h
@@ -126,7 +126,7 @@ MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list )
* An empty list is one that contains a single element that points to itself.
*
* @param list the list to check.
- * @return non-zero if the list it empty, and zero otherwise.
+ * @return non-zero if the list is empty, and zero otherwise.
*/
MALI_STATIC_INLINE int _mali_osk_list_empty( _mali_osk_list_t *list )
{
diff --git a/drivers/gpu/arm/mali/common/mali_uk_types.h b/drivers/gpu/arm/mali/common/mali_uk_types.h
index 6af29f39b44..dc40b2bad2d 100755
--- a/drivers/gpu/arm/mali/common/mali_uk_types.h
+++ b/drivers/gpu/arm/mali/common/mali_uk_types.h
@@ -55,6 +55,7 @@ typedef enum
_MALI_UK_GP_SUBSYSTEM, /**< Vertex Processor Group of U/K calls */
_MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */
_MALI_UK_PMM_SUBSYSTEM, /**< Power Management Module Group of U/K calls */
+ _MALI_UK_VSYNC_SUBSYSTEM, /**< VSYNC Group of U/K calls */
} _mali_uk_subsystem_t;
/** Within a function group each function has its unique sequence number
@@ -125,6 +126,10 @@ typedef enum
/** Power Management Module Functions */
_MALI_UK_PMM_EVENT_MESSAGE = 0, /**< Raise an event message */
#endif
+
+ /** VSYNC reporting fuctions */
+ _MALI_UK_VSYNC_EVENT_REPORT = 0, /**< _mali_ukk_vsync_event_report() */
+
} _mali_uk_functions;
/** @brief Get the size necessary for system info
@@ -613,7 +618,6 @@ typedef enum
{
/** core notifications */
- _MALI_NOTIFICATION_CORE_TIMEOUT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x10,
_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20,
_MALI_NOTIFICATION_APPLICATION_QUIT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40,
@@ -647,13 +651,6 @@ typedef enum
*
* Interpreting the data union member depends on the notification type:
*
- * - type == _MALI_NOTIFICATION_CORE_TIMEOUT
- * - A notification timeout has occurred, since the code.timeout member was
- * exceeded.
- * - In this case, the value of the data union member is undefined.
- * - This is used so that the client can check other user-space state.
- * The client may repeat the call to _mali_ukk_wait_for_notification() to
- * continue reception of notifications.
* - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS
* - The kernel side is shutting down. No further
* _mali_uk_wait_for_notification() calls should be made.
@@ -736,7 +733,7 @@ typedef struct
* The 16bit integer is stored twice in a 32bit integer
* For example, for version 1 the value would be 0x00010001
*/
-#define _MALI_API_VERSION 7
+#define _MALI_API_VERSION 8
#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
/**
@@ -1105,7 +1102,7 @@ typedef u32 mali_pmm_message_data;
/** @brief Arguments to _mali_ukk_pmm_event_message()
*/
-typedef struct
+typedef struct
{
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
u32 id; /**< [in] event id */
@@ -1115,6 +1112,31 @@ typedef struct
/** @} */ /* end group _mali_uk_pmm */
#endif /* USING_MALI_PMM */
+/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module
+ * @{ */
+
+/** @brief VSYNC events
+ *
+ * These events are reported when DDK starts to wait for vsync and when the
+ * vsync has occured and the DDK can continue on the next frame.
+ */
+typedef enum _mali_uk_vsync_event
+{
+ _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0,
+ _MALI_UK_VSYNC_EVENT_END_WAIT
+} _mali_uk_vsync_event;
+
+/** @brief Arguments to _mali_ukk_vsync_event()
+ *
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_uk_vsync_event event; /**< [in] VSYNCH event type */
+} _mali_uk_vsync_event_report_s;
+
+/** @} */ /* end group _mali_uk_vsync */
+
/** @} */ /* end group u_k_api */
/** @} */ /* end group uddapi */
diff --git a/drivers/gpu/arm/mali/common/mali_ukk.h b/drivers/gpu/arm/mali/common/mali_ukk.h
index 981a1f07c53..ccd9ac80cd5 100755
--- a/drivers/gpu/arm/mali/common/mali_ukk.h
+++ b/drivers/gpu/arm/mali/common/mali_ukk.h
@@ -663,7 +663,7 @@ _mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args);
_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args);
/** @brief Stop recording profiling events.
- *
+ *
* @param args see _mali_uk_profiling_stop_s in "mali_uk_types.h"
*/
_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args);
@@ -683,6 +683,21 @@ _mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args);
/** @} */ /* end group _mali_uk_profiling */
#endif
+/** @addtogroup _mali_uk_vsync U/K VSYNC reporting module
+ * @{ */
+
+/** @brief Report events related to vsync.
+ *
+ * @note Events should be reported when starting to wait for vsync and when the
+ * waiting is finished. This information can then be used in kernel space to
+ * complement the GPU utilization metric.
+ *
+ * @param args see _mali_uk_vsync_event_report_s in "mali_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args);
+
+/** @} */ /* end group _mali_uk_vsync */
+
/** @} */ /* end group u_k_api */
/** @} */ /* end group uddapi */
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm.c b/drivers/gpu/arm/mali/common/pmm/mali_pmm.c
index 39a5a6e21d5..dd8f5e3a284 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm.c
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm.c
@@ -30,10 +30,7 @@ static _mali_pmm_internal_state_t *pmm_state = NULL;
/* Mali kernel subsystem id */
static mali_kernel_subsystem_identifier mali_subsystem_pmm_id = -1;
-/* lock for SMP */
-#ifdef CONFIG_SMP
-_mali_osk_lock_t *mali_pmm_lock;
-#endif /* CONFIG_SMP */
+static u32 pmm_cores_registered_mask = 0;
#define GET_PMM_STATE_PTR (pmm_state)
@@ -68,6 +65,10 @@ _mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifi
*/
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id );
+#if MALI_STATE_TRACKING
+u32 malipmm_subsystem_dump_state( char *buf, u32 size );
+#endif
+
/* This will be one of the subsystems in the array of subsystems:
static struct mali_kernel_subsystem * subsystems[];
@@ -82,7 +83,10 @@ struct mali_kernel_subsystem mali_subsystem_pmm=
NULL,
NULL,
NULL,
-} ;
+#if MALI_STATE_TRACKING
+ malipmm_subsystem_dump_state, /* dump_state */
+#endif
+};
#if PMM_OS_TEST
@@ -192,7 +196,7 @@ void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args )
{
/* Internal PMM message */
_mali_osk_notification_queue_send( pmm->iqueue, msg );
- #if MALI_PMM_TRACE
+ #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->imessages_sent++;
#endif
}
@@ -200,7 +204,7 @@ void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args )
{
/* Real event */
_mali_osk_notification_queue_send( pmm->queue, msg );
- #if MALI_PMM_TRACE
+ #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->messages_sent++;
#endif
}
@@ -293,7 +297,7 @@ _mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy )
MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
}
-#if MALI_PMM_TRACE
+#if ( MALI_PMM_TRACE || MALI_STATE_TRACKING )
/* Event names - order must match mali_pmm_event_id enum */
static char *pmm_trace_events[] = {
@@ -305,19 +309,6 @@ static char *pmm_trace_events[] = {
"TIMEOUT",
};
-/* UK event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events_uk[] = {
- "UKS",
- "UK_EXAMPLE",
-};
-
-/* Internal event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events_internal[] = {
- "INTERNALS",
- "INTERNAL_POWER_UP_ACK",
- "INTERNAL_POWER_DOWN_ACK",
-};
-
/* State names - order must match mali_pmm_state enum */
static char *pmm_trace_state[] = {
"UNAVAILABLE",
@@ -333,6 +324,35 @@ static char *pmm_trace_policy[] = {
"JOB CONTROL",
};
+/* Status names - order must match mali_pmm_status enum */
+static char *pmm_trace_status[] = {
+ "MALI_PMM_STATUS_IDLE", /**< PMM is waiting next event */
+ "MALI_PMM_STATUS_POLICY_POWER_DOWN", /**< Policy initiated power down */
+ "MALI_PMM_STATUS_POLICY_POWER_UP", /**< Policy initiated power down */
+ "MALI_PMM_STATUS_OS_WAITING", /**< PMM is waiting for OS power up */
+ "MALI_PMM_STATUS_OS_POWER_DOWN", /**< OS initiated power down */
+ "MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS",
+ "MALI_PMM_STATUS_DVFS_PAUSE", /**< PMM DVFS Status Pause */
+ "MALI_PMM_STATUS_OS_POWER_UP", /**< OS initiated power up */
+ "MALI_PMM_STATUS_OFF", /**< PMM is not active */
+};
+
+#endif /* MALI_PMM_TRACE || MALI_STATE_TRACKING */
+#if MALI_PMM_TRACE
+
+/* UK event names - order must match mali_pmm_event_id enum */
+static char *pmm_trace_events_uk[] = {
+ "UKS",
+ "UK_EXAMPLE",
+};
+
+/* Internal event names - order must match mali_pmm_event_id enum */
+static char *pmm_trace_events_internal[] = {
+ "INTERNALS",
+ "INTERNAL_POWER_UP_ACK",
+ "INTERNAL_POWER_DOWN_ACK",
+};
+
void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate )
{
const char *dname;
@@ -499,10 +519,6 @@ _mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource)
"PMM handler" );
if( !pmm_state->irq ) goto pmm_fail_cleanup;
-#ifdef CONFIG_SMP
- mali_pmm_lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0);
- if( !mali_pmm_lock ) goto pmm_fail_cleanup;
-#endif /* CONFIG_SMP */
pmm_state->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 75);
if( !pmm_state->lock ) goto pmm_fail_cleanup;
@@ -549,6 +565,29 @@ _mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifi
return pmm_policy_init( pmm );
}
+void malipmm_force_powerup( void )
+{
+ _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
+ MALI_DEBUG_ASSERT_POINTER(pmm);
+ MALI_PMM_LOCK(pmm);
+ pmm->status = MALI_PMM_STATUS_OFF;
+ pmm_cores_registered_mask = pmm->cores_registered;
+ MALI_PMM_UNLOCK(pmm);
+
+ /* flush PMM workqueue */
+ _mali_osk_flush_workqueue( pmm->irq );
+
+ if (pmm->cores_powered == 0)
+ {
+ mali_platform_powerup(pmm_cores_registered_mask);
+ }
+}
+
+void malipmm_force_powerdown( void )
+{
+ mali_platform_powerdown(pmm_cores_registered_mask);
+}
+
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
{
/* Check this is the right system */
@@ -563,14 +602,17 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
#endif
/* Get the lock so we can shutdown */
MALI_PMM_LOCK(pmm_state);
+#if MALI_STATE_TRACKING
+ pmm_state->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
pmm_state->status = MALI_PMM_STATUS_OFF;
+#if MALI_STATE_TRACKING
+ pmm_state->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
MALI_PMM_UNLOCK(pmm_state);
+ _mali_osk_pmm_ospmm_cleanup();
pmm_policy_term(pmm_state);
_mali_osk_irq_term( pmm_state->irq );
-#ifdef CONFIG_SMP
- _mali_osk_lock_term(mali_pmm_lock);
-#endif /* CONFIG_SMP */
-
_mali_osk_notification_queue_term( pmm_state->queue );
_mali_osk_notification_queue_term( pmm_state->iqueue );
if( pmm_state->pmu_initialized ) mali_platform_deinit(&t);
@@ -602,6 +644,11 @@ _mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
+
+
/* Check if the core is registered more than once in PMM */
MALI_DEBUG_ASSERT( (pmm->cores_registered & core) == 0 );
@@ -634,6 +681,10 @@ _mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
err, core, pmm_trace_get_core_name(core)) );
}
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
return err;
@@ -645,6 +696,10 @@ void malipmm_core_unregister( mali_pmm_core_id core )
MALI_DEBUG_ASSERT_POINTER(pmm);
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
+
/* Check if the core is registered in PMM */
MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, core );
@@ -655,16 +710,6 @@ void malipmm_core_unregister( mali_pmm_core_id core )
#if MALI_PMM_TRACE
mali_pmm_core_mask old_power = pmm->cores_powered;
#endif
-
-#if !MALI_PMM_NO_PMU
- /* Turn off the core */
- if( mali_platform_powerdown( core ) != _MALI_OSK_ERR_OK )
- {
- MALI_PRINT_ERROR( ("PMM: Error powering down unregistered core: (0x%x) %s\n",
- core, pmm_trace_get_core_name(core)) );
- }
-#endif
-
/* Remove the core from the system */
pmm->cores_registered &= (~core);
pmm->cores_idle &= (~core);
@@ -681,6 +726,10 @@ void malipmm_core_unregister( mali_pmm_core_id core )
#endif
}
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
}
void malipmm_core_power_down_okay( mali_pmm_core_id core )
@@ -722,18 +771,20 @@ void malipmm_irq_bhandler(void *data)
if( power_test_check() ) return;
#endif
-#ifdef CONFIG_SMP
- _mali_osk_lock_wait( mali_pmm_lock, _MALI_OSK_LOCKMODE_RW );
-#endif /* CONFIG_SMP */
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
/* Quick out when we are shutting down */
if( pmm->status == MALI_PMM_STATUS_OFF )
{
+
+ #if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+ #endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
-#ifdef CONFIG_SMP
- _mali_osk_lock_signal( mali_pmm_lock, _MALI_OSK_LOCKMODE_RW );
-#endif /* CONFIG_SMP */
return;
}
@@ -761,10 +812,11 @@ void malipmm_irq_bhandler(void *data)
}
}
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
-#ifdef CONFIG_SMP
- _mali_osk_lock_signal(mali_pmm_lock, _MALI_OSK_LOCKMODE_RW );
-#endif /* CONFIG_SMP */
}
static void pmm_event_process( void )
@@ -805,10 +857,10 @@ static void pmm_event_process( void )
return;
}
else
- {
- #if MALI_PMM_TRACE
+ {
+ #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->messages_received++;
- #endif
+ #endif
}
}
else
@@ -821,9 +873,9 @@ static void pmm_event_process( void )
}
else
{
- #if MALI_PMM_TRACE
+ #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->imessages_received++;
- #endif
+ #endif
}
MALI_DEBUG_ASSERT_POINTER( msg );
@@ -872,22 +924,37 @@ static void pmm_event_process( void )
}
}
-#ifdef DEBUG
-void malipmm_state_dump()
+#if MALI_STATE_TRACKING
+u32 malipmm_subsystem_dump_state(char *buf, u32 size)
{
+ int len = 0;
_mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
if( !pmm )
{
- MALI_PRINT(("PMM: Null state\n"));
+ len += _mali_osk_snprintf(buf + len, size + len, "PMM: Null state\n");
}
else
{
- MALI_PRINT(("PMM state:\nstatus=%d\npolicy=%d\ncheck_policy=%d\nstate=%d\n", pmm->status, pmm->policy, pmm->check_policy, pmm->state));
- MALI_PRINT(("PMM cores:\ncores_registered=%d\ncores_powered=%d\ncores_idle=%d\ncores_pend_down=%d\ncores_pend_up=%d\ncores_ack_down=%d\ncores_ack_up=%d\n", pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down, pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up));
- MALI_PRINT(("PMM misc:\npmu_init=%d\nmessages_queued=%d\nwaiting=%d\nno_events=%d\nmissed=%d\nfatal_power_err=%d\n", pmm->pmu_initialized, _mali_osk_atomic_read( &(pmm->messages_queued) ), pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err));
+ len += _mali_osk_snprintf(buf+len, size+len, "Locks:\n PMM lock acquired: %s\n",
+ pmm->mali_pmm_lock_acquired ? "true" : "false");
+ len += _mali_osk_snprintf(buf+len, size+len,
+ "PMM state:\n Previous status: %s\n Status: %s\n Current event: %s\n Policy: %s\n Check policy: %s\n State: %s\n",
+ pmm_trace_status[pmm->mali_last_pmm_status], pmm_trace_status[pmm->status],
+ pmm_trace_events[pmm->mali_new_event_status], pmm_trace_policy[pmm->policy],
+ pmm->check_policy ? "true" : "false", pmm_trace_state[pmm->state]);
+ len += _mali_osk_snprintf(buf+len, size+len,
+ "PMM cores:\n Cores registered: %d\n Cores powered: %d\n Cores idle: %d\n"
+ " Cores pending down: %d\n Cores pending up: %d\n Cores ack down: %d\n Cores ack up: %d\n",
+ pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down,
+ pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up);
+ len += _mali_osk_snprintf(buf+len, size+len, "PMM misc:\n PMU init: %s\n Messages queued: %d\n"
+ " Waiting: %d\n No events: %d\n Missed events: %d\n Fatal power error: %s\n",
+ pmm->pmu_initialized ? "true" : "false", _mali_osk_atomic_read(&(pmm->messages_queued)),
+ pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err ? "true" : "false");
}
+ return len;
}
-#endif
+#endif /* MALI_STATE_TRACKING */
#endif /* USING_MALI_PMM */
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm.h b/drivers/gpu/arm/mali/common/pmm/mali_pmm.h
index 74a61b1cd45..7b45fd36eea 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm.h
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm.h
@@ -40,7 +40,7 @@ extern "C"
/** @brief Compile option to switch between always on or job control PMM policy */
#define MALI_PMM_ALWAYS_ON 0
-/** @brief Overrides hardware PMU and uses software simulation instead
+/** @brief Overrides hardware PMU and uses software simulation instead
* @note This even stops intialization of PMU and cores being powered on at start up
*/
#define MALI_PMM_NO_PMU 0
@@ -52,7 +52,7 @@ extern "C"
/** @brief power management event message identifiers.
*/
-/* These must match up with the pmm_trace_events & pmm_trace_events_internal
+/* These must match up with the pmm_trace_events & pmm_trace_events_internal
* arrays
*/
typedef enum mali_pmm_event_id
@@ -137,7 +137,6 @@ typedef enum mali_pmm_policy_tag
MALI_PMM_POLICY_RUNTIME_JOB_CONTROL = 3 /**< Run time power management control policy */
} mali_pmm_policy;
-
/** @brief Function to report to the OS when the power down has finished
*
* @param data The event message data that initiated the power down
@@ -150,7 +149,7 @@ void _mali_osk_pmm_power_down_done(mali_pmm_message_data data);
*/
void _mali_osk_pmm_power_up_done(mali_pmm_message_data data);
-/** @brief Function to report that DVFS operation done
+/** @brief Function to report that DVFS operation done
*
* @param data The event message data
*/
@@ -165,6 +164,18 @@ void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id event_id);
#endif
+/** @brief Function to power up MALI
+ *
+ * @note powers up the MALI during MALI device driver is unloaded
+ */
+void malipmm_force_powerup( void );
+
+/** @brief Function to power down MALI
+ *
+ * @note powers down the MALI during MALI device driver is unloaded
+ */
+void malipmm_force_powerdown( void );
+
/** @brief Function to report the OS that device is idle
*
* @note inform the OS that device is idle
@@ -177,6 +188,12 @@ _mali_osk_errcode_t _mali_osk_pmm_dev_idle( void );
*/
void _mali_osk_pmm_dev_activate( void );
+/** @brief Function to report OS PMM for cleanup
+ *
+ * @note Function to report OS PMM for cleanup
+ */
+void _mali_osk_pmm_ospmm_cleanup( void );
+
/** @brief Queries the current state of the PMM software
*
* @note the state of the PMM can change after this call has returned
@@ -303,11 +320,11 @@ void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool receive
#endif /* MALI_PMM_TRACE */
-#ifdef DEBUG
-/** @brief Dumps the current state of the PMM
+/** @brief Dumps the current state of OS PMM thread
*/
-void malipmm_state_dump(void);
-#endif
+#if MALI_STATE_TRACKING
+u32 mali_pmm_dump_os_thread_state( char *buf, u32 size );
+#endif /* MALI_STATE_TRACKING */
/** @} */ /* end group pmmapi */
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy.h b/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy.h
index 83cb7f29a92..739c4c4ef17 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy.h
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy.h
@@ -46,7 +46,7 @@ typedef struct _pmm_policy_timer
/** @brief Policy timer initialization
*
* This will create a timer for use in policies, but won't start it
- *
+ *
* @param pptimer An empty timer structure to be initialized
* @param timeout Timeout in ticks for the timer
* @param id Event id that will be raised on timeout
@@ -59,7 +59,7 @@ _mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 tim
*
* This will clean up a timer that was previously used in policies, it
* will also stop it if started
- *
+ *
* @param pptimer An initialized timer structure to be terminated
*/
void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer );
@@ -67,10 +67,10 @@ void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer );
/** @brief Policy timer start
*
* This will start a previously created timer for use in policies
- * When the timer expires after the initialized timeout it will raise
+ * When the timer expires after the initialized timeout it will raise
* a PMM event of the event id given on initialization
* As data for the event it will pass the start time of the timer
- *
+ *
* @param pptimer A previously initialized policy timer
* @return MALI_TRUE if the timer was started, MALI_FALSE if it is already started
*/
@@ -79,7 +79,7 @@ mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer );
/** @brief Policy timer stop
*
* This will stop a previously created timer for use in policies
- *
+ *
* @param pptimer A previously started policy timer
* @return MALI_TRUE if the timer was stopped, MALI_FALSE if it is already stopped
*/
@@ -88,7 +88,7 @@ mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer );
/** @brief Policy timer stop
*
* This raise an event for an expired timer
- *
+ *
* @param pptimer An expired policy timer
* @return MALI_TRUE if an event was raised, else MALI_FALSE
*/
@@ -97,7 +97,7 @@ mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer );
/** @brief Policy timer valid checker
*
* This will check that a timer was started after a given time
- *
+ *
* @param timer_start Time the timer was started
* @param other_start Time when another event or action occurred
* @return MALI_TRUE if the timer was started after the other time, else MALI_FALSE
@@ -106,7 +106,7 @@ mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start );
/** @brief Common policy initialization
- *
+ *
* This will initialize the current policy
*
* @note Any previously initialized policy should be terminated first
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.c b/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.c
index 192647d6306..8450bd722f4 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.c
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.c
@@ -173,6 +173,10 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
/* Mainly the data is the cores */
cores = pmm_cores_from_event_data( pmm, event );
+#if MALI_STATE_TRACKING
+ pmm->mali_last_pmm_status = pmm->status;
+#endif /* MALI_STATE_TRACKING */
+
switch( pmm->status )
{
/**************** IDLE ****************/
@@ -217,7 +221,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
}
}
pmm->status = MALI_PMM_STATUS_DVFS_PAUSE;
- _mali_osk_pmm_dvfs_operation_done( 0 );
+ _mali_osk_pmm_dvfs_operation_done(0);
break;
case MALI_PMM_EVENT_OS_POWER_DOWN:
@@ -300,7 +304,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
{
case MALI_PMM_EVENT_DVFS_RESUME:
- if ( pmm->cores_powered !=0)
+ if ( pmm->cores_powered != 0 )
{
pmm->cores_ack_down =0;
pmm_power_down_cancel( pmm );
@@ -316,9 +320,9 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
case MALI_PMM_EVENT_OS_POWER_DOWN:
/* Set waiting status */
pmm->status = MALI_PMM_STATUS_OS_WAITING;
- if ( pmm->cores_powered != 0)
+ if ( pmm->cores_powered != 0 )
{
- if( pmm_invoke_power_down( pmm ) )
+ if ( pmm_invoke_power_down( pmm ) )
{
_mali_osk_pmm_power_down_done( 0 );
break;
@@ -373,7 +377,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
if( pmm_power_down_okay( pmm ) )
{
pmm->is_dvfs_active = 0;
- pmm->status = MALI_PMM_STATUS_DVFS_PAUSE;
+ pmm->status = MALI_PMM_STATUS_DVFS_PAUSE;
_mali_osk_pmm_dvfs_operation_done( pmm_retrieve_os_event_data( pmm ) );
}
break;
@@ -436,6 +440,10 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
/* Update the PMM state */
pmm_update_system_state( pmm );
+#if MALI_STATE_TRACKING
+ pmm->mali_new_event_status = event->id;
+#endif /* MALI_STATE_TRACKING */
+
MALIPMM_DEBUG_PRINT( ("PMM: Job control policy process end - status=%d and event=%d\n", pmm->status,event->id) );
MALI_SUCCESS;
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.h b/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.h
index 455234b80bc..f1e7c2d9a82 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.h
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm_policy_jobcontrol.h
@@ -27,10 +27,10 @@ extern "C"
* @{
*/
-/** @brief The jobcontrol policy inactivity latency timeout (in ticks)
+/** @brief The jobcontrol policy inactivity latency timeout (in ticks)
* before the hardware is switched off
*
- * @note Setting this low whilst tracing or producing debug output can
+ * @note Setting this low whilst tracing or producing debug output can
* cause alot of timeouts to fire which can affect the PMM behaviour
*/
#define MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT 50
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.c b/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.c
index 69193a25459..a0ac1c7790c 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.c
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.c
@@ -167,6 +167,10 @@ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mal
* as the core is unregistered before we tell it to power
* down, but it does not matter as we are terminating
*/
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
/* Signal the core to power down
* If it is busy (not idle) it will set a pending power down flag
@@ -177,6 +181,11 @@ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mal
err = mali_core_signal_power_down( cores_list[n], immediate_only );
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
+
+
/* Re-read cores_subset in case it has changed */
cores_subset = (*ppowered & cores);
@@ -244,12 +253,19 @@ void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm )
* as the core is unregistered before we tell it to power
* up, but it does not matter as we are terminating
*/
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
/* As we are cancelling - only move the cores back to the queue -
* no reset needed
*/
err = mali_core_signal_power_up( cores_list[n], MALI_TRUE );
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
/* Update pending list with the current registered cores */
pd &= (*pregistered);
@@ -374,10 +390,19 @@ mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm )
* as the core is unregistered before we tell it to power
* up, but it does not matter as we are terminating
*/
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
err = mali_core_signal_power_up( cores_list[n], MALI_FALSE );
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
+
+
if( err != _MALI_OSK_ERR_OK )
{
MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_FAULT &&
@@ -527,10 +552,18 @@ void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm )
{
if( (cores_list[n] & (*pregistered)) != 0 )
{
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 0;
+#endif /* MALI_STATE_TRACKING */
+
MALI_PMM_UNLOCK(pmm);
/* Core is now active - so try putting it in the idle queue */
err = mali_core_signal_power_up( cores_list[n], MALI_FALSE );
MALI_PMM_LOCK(pmm);
+#if MALI_STATE_TRACKING
+ pmm->mali_pmm_lock_acquired = 1;
+#endif /* MALI_STATE_TRACKING */
+
/* We either succeeded, or we were not off anyway, or we have
* just be deregistered
*/
diff --git a/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.h b/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.h
index f019fb67b77..c2fb32171c4 100755
--- a/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.h
+++ b/drivers/gpu/arm/mali/common/pmm/mali_pmm_state.h
@@ -55,8 +55,7 @@ typedef enum mali_pmm_status_tag
MALI_PMM_STATUS_POLICY_POWER_DOWN, /**< Policy initiated power down */
MALI_PMM_STATUS_POLICY_POWER_UP, /**< Policy initiated power down */
MALI_PMM_STATUS_OS_WAITING, /**< PMM is waiting for OS power up */
- MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */
- MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS,
+ MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */
MALI_PMM_STATUS_DVFS_PAUSE, /**< PMM DVFS Status Pause */
MALI_PMM_STATUS_OS_POWER_UP, /**< OS initiated power up */
MALI_PMM_STATUS_OFF, /**< PMM is not active */
@@ -95,8 +94,14 @@ typedef struct _mali_pmm_internal_state
u32 missed; /**< PMM missed events due to OOM */
mali_bool fatal_power_err; /**< PMM has had a fatal power error? */
u32 is_dvfs_active; /**< PMM DVFS activity */
-
-#if MALI_PMM_TRACE
+
+#if MALI_STATE_TRACKING
+ mali_pmm_status mali_last_pmm_status; /**< The previous PMM status */
+ mali_pmm_event_id mali_new_event_status;/**< The type of the last PMM event */
+ mali_bool mali_pmm_lock_acquired; /**< Is the PMM lock held somewhere or not */
+#endif
+
+#if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
u32 messages_sent; /**< Total event messages sent */
u32 messages_received; /**< Total event messages received */
u32 imessages_sent; /**< Total event internal messages sent */
@@ -127,11 +132,11 @@ mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, m
/** @brief Sort out which cores need to be powered up from the given core mask
*
- * All cores that can be powered up will be put into a pending state
+ * All cores that can be powered up will be put into a pending state
*
* @param pmm internal PMM state
* @param cores mask of cores to check if they need to be powered up
- * @return mask of cores that need to be powered up, this can be 0 if all cores
+ * @return mask of cores that need to be powered up, this can be 0 if all cores
* are powered up already
*/
mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
@@ -147,7 +152,7 @@ mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_
* @param cores mask of cores to check if they need to be powered down
* @param immediate_only MALI_TRUE means that only cores that can power down now will
* be put into a pending state
- * @return mask of cores that need to be powered down, this can be 0 if all cores
+ * @return mask of cores that need to be powered down, this can be 0 if all cores
* are powered down already
*/
mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only );
@@ -171,7 +176,7 @@ mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm );
/** @brief Try to make all the pending cores power down
*
- * If all the pending cores have acknowledged they can power down, this will call the
+ * If all the pending cores have acknowledged they can power down, this will call the
* PMU power down function to turn them off
*
* @param pmm internal PMM state
@@ -224,7 +229,7 @@ mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm
/** @brief Set the cores that have acknowledged a pending power down
*
- * Updates which cores have acknowledged the pending power down and are now ready
+ * Updates which cores have acknowledged the pending power down and are now ready
* to be turned off
*
* @param pmm internal PMM state
@@ -247,15 +252,15 @@ mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_p
/** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues
*
- * This will try and make all the cores powered up and reset the PMM state
- * to its initial state after core registration - all cores powered but not
+ * This will try and make all the cores powered up and reset the PMM state
+ * to its initial state after core registration - all cores powered but not
* pending or active.
* All events in the event queues will be thrown away.
*
* @note: Any pending power down will be cancelled including the OS calling for power down
*/
void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm );
-
+
/** @brief Save the OS specific data for an OS power up/down event
*
* @param pmm internal PMM state
diff --git a/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h b/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h
index e9e5e55a082..2220b3b35ef 100644
--- a/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h
+++ b/drivers/gpu/arm/mali/linux/license/gpl/mali_kernel_license.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c
index 1c1bf306688..7a69ae95011 100755
--- a/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c
+++ b/drivers/gpu/arm/mali/linux/mali_device_pause_resume.c
@@ -31,13 +31,8 @@ int mali_dev_pause()
{
int err = 0;
_mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS)
- || (mali_device_state == _MALI_DEVICE_SUSPEND)
-#ifdef CONFIG_HAS_EARLYSUSPEND
- || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB))
-#else
- )
-#endif
+ if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND)
+ || (mali_device_state == _MALI_DEVICE_SUSPEND) )
{
err = -EPERM;
}
@@ -56,13 +51,8 @@ int mali_dev_resume()
{
int err = 0;
_mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS)
- || (mali_device_state == _MALI_DEVICE_SUSPEND)
-#ifdef CONFIG_HAS_EARLYSUSPEND
- || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB))
-#else
- )
-#endif
+ if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME)
+ || (mali_device_state == _MALI_DEVICE_SUSPEND) )
{
err = -EPERM;
}
diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h
index 87d94db7886..30a6fa041db 100755
--- a/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h
+++ b/drivers/gpu/arm/mali/linux/mali_kernel_ioctl.h
@@ -37,6 +37,7 @@ extern "C"
#define MALI_IOC_PP_BASE (_MALI_UK_PP_SUBSYSTEM + MALI_IOC_BASE)
#define MALI_IOC_GP_BASE (_MALI_UK_GP_SUBSYSTEM + MALI_IOC_BASE)
#define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE)
+#define MALI_IOC_VSYNC_BASE (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE)
#define MALI_IOC_GET_SYSTEM_INFO_SIZE _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO_SIZE, _mali_uk_get_system_info_s *)
#define MALI_IOC_GET_SYSTEM_INFO _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO, _mali_uk_get_system_info_s *)
@@ -67,6 +68,7 @@ extern "C"
#define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *)
#define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *)
#define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *)
+#define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *)
#ifdef __cplusplus
}
diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c
index 70d9bfd5b83..382be6802b2 100755
--- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.c
+++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.c
@@ -16,7 +16,6 @@
#include <linux/fs.h> /* file system operations */
#include <linux/cdev.h> /* character device definitions */
#include <linux/mm.h> /* memory mananger definitions */
-#include <asm/uaccess.h> /* user space access */
#include <linux/device.h>
/* the mali kernel subsystem types */
@@ -24,7 +23,6 @@
/* A memory subsystem always exists, so no need to conditionally include it */
#include "mali_kernel_common.h"
-#include "mali_kernel_mem.h"
#include "mali_kernel_session_manager.h"
#include "mali_kernel_core.h"
@@ -35,6 +33,8 @@
#include "mali_ukk_wrappers.h"
#include "mali_kernel_pm.h"
+#include "mali_kernel_sysfs.h"
+
/* */
#include "mali_kernel_license.h"
@@ -60,19 +60,18 @@ extern int mali_max_job_runtime;
module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what");
-struct mali_dev
-{
- struct cdev cdev;
-#if MALI_LICENSE_IS_GPL
- struct class * mali_class;
+#if defined(USING_MALI400_L2_CACHE)
+extern int mali_l2_max_reads;
+module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache");
#endif
-};
static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
/* the mali device */
static struct mali_dev device;
+
static int mali_open(struct inode *inode, struct file *filp);
static int mali_release(struct inode *inode, struct file *filp);
#ifdef HAVE_UNLOCKED_IOCTL
@@ -104,47 +103,40 @@ int mali_driver_init(void)
#if USING_MALI_PMM
#if MALI_LICENSE_IS_GPL
#ifdef CONFIG_PM
- err = _mali_dev_platform_register();
- if (err)
- {
- return err;
- }
+ err = _mali_dev_platform_register();
+ if (err)
+ {
+ return err;
+ }
#endif
#endif
#endif
- err = mali_kernel_constructor();
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_PRINT(("Failed to initialize driver (error %d)\n", err));
- return -EFAULT;
- }
+ err = mali_kernel_constructor();
+ if (_MALI_OSK_ERR_OK != err)
+ {
+#if USING_MALI_PMM
+#if MALI_LICENSE_IS_GPL
+#ifdef CONFIG_PM
+ _mali_dev_platform_unregister();
+#endif
+#endif
+#endif
+ MALI_PRINT(("Failed to initialize driver (error %d)\n", err));
+ return -EFAULT;
+ }
return 0;
}
void mali_driver_exit(void)
{
-
#if USING_MALI_PMM
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-
- _mali_osk_pmm_dev_activate();
-#endif
+ malipmm_force_powerup();
#endif
-#endif
-#endif
- mali_kernel_destructor();
+ mali_kernel_destructor();
#if USING_MALI_PMM
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- _mali_osk_pmm_dev_idle();
-#endif
-#endif
-#endif
+ malipmm_force_powerdown();
#endif
#if USING_MALI_PMM
@@ -174,45 +166,39 @@ int initialize_kernel_device(void)
err = register_chrdev_region(dev, 1/*count*/, mali_dev_name);
}
- if (0 == err)
+ if (err)
{
- memset(&device, 0, sizeof(device));
+ goto init_chrdev_err;
+ }
- /* initialize our char dev data */
- cdev_init(&device.cdev, &mali_fops);
- device.cdev.owner = THIS_MODULE;
- device.cdev.ops = &mali_fops;
+ memset(&device, 0, sizeof(device));
- /* register char dev with the kernel */
- err = cdev_add(&device.cdev, dev, 1/*count*/);
+ /* initialize our char dev data */
+ cdev_init(&device.cdev, &mali_fops);
+ device.cdev.owner = THIS_MODULE;
+ device.cdev.ops = &mali_fops;
- if (0 == err)
- {
-#if MALI_LICENSE_IS_GPL
- device.mali_class = class_create(THIS_MODULE, mali_dev_name);
- if (IS_ERR(device.mali_class))
- {
- err = PTR_ERR(device.mali_class);
- }
- else
- {
- struct device * mdev;
- mdev = device_create(device.mali_class, NULL, dev, NULL, mali_dev_name);
- if (!IS_ERR(mdev))
- {
- return 0;
- }
-
- err = PTR_ERR(mdev);
- }
- cdev_del(&device.cdev);
-#else
- return 0;
-#endif
- }
- unregister_chrdev_region(dev, 1/*count*/);
+ /* register char dev with the kernel */
+ err = cdev_add(&device.cdev, dev, 1/*count*/);
+ if (err)
+ {
+ goto init_cdev_err;
}
+ err = mali_sysfs_register(&device, dev, mali_dev_name);
+ if (err)
+ {
+ goto init_sysfs_err;
+ }
+
+ /* Success! */
+ return 0;
+
+init_sysfs_err:
+ cdev_del(&device.cdev);
+init_cdev_err:
+ unregister_chrdev_region(dev, 1/*count*/);
+init_chrdev_err:
return err;
}
@@ -220,11 +206,9 @@ int initialize_kernel_device(void)
void terminate_kernel_device(void)
{
dev_t dev = MKDEV(mali_major, 0);
+
+ mali_sysfs_unregister(&device, dev, mali_dev_name);
-#if MALI_LICENSE_IS_GPL
- device_destroy(device.mali_class, dev);
- class_destroy(device.mali_class);
-#endif
/* unregister char device */
cdev_del(&device.cdev);
/* free major */
@@ -427,7 +411,7 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case MALI_IOC_MEM_ATTACH_UMP:
case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */
- MALI_DEBUG_PRINT(2, ("UMP not supported\n", cmd, arg));
+ MALI_DEBUG_PRINT(2, ("UMP not supported\n"));
err = -ENOTTY;
break;
#endif
@@ -468,6 +452,10 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg);
break;
+ case MALI_IOC_VSYNC_EVENT_REPORT:
+ err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg);
+ break;
+
default:
MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg));
err = -ENOTTY;
@@ -476,6 +464,7 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return err;
}
+
module_init(mali_driver_init);
module_exit(mali_driver_exit);
diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h
index 785eaca4889..485c27e1ecb 100755
--- a/drivers/gpu/arm/mali/linux/mali_kernel_linux.h
+++ b/drivers/gpu/arm/mali/linux/mali_kernel_linux.h
@@ -16,9 +16,23 @@ extern "C"
{
#endif
+#include <linux/cdev.h> /* character device definitions */
+#include "mali_kernel_license.h"
+
+struct mali_dev
+{
+ struct cdev cdev;
+#if MALI_LICENSE_IS_GPL
+ struct class * mali_class;
+#endif
+};
+
_mali_osk_errcode_t initialize_kernel_device(void);
void terminate_kernel_device(void);
+void mali_osk_low_level_mem_init(void);
+void mali_osk_low_level_mem_term(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c
index e6c78c2f6e7..3969466f39e 100755
--- a/drivers/gpu/arm/mali/linux/mali_kernel_pm.c
+++ b/drivers/gpu/arm/mali/linux/mali_kernel_pm.c
@@ -15,9 +15,6 @@
#if USING_MALI_PMM
#include <linux/sched.h>
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#ifdef CONFIG_PM_RUNTIME
#include <linux/pm_runtime.h>
@@ -51,6 +48,8 @@ unsigned int pwr_mgmt_status_reg = 0;
#endif /* CONFIG_PM */
#endif /* MALI_POWER_MGMT_TEST_SUITE */
+static int is_os_pmm_thread_waiting = 0;
+
/* kernel should be configured with power management support */
#ifdef CONFIG_PM
@@ -70,10 +69,6 @@ unsigned int pwr_mgmt_status_reg = 0;
static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = {
[_MALI_DEVICE_SUSPEND] = "suspend",
[_MALI_DEVICE_RESUME] = "resume",
-#ifdef CONFIG_HAS_EARLYSUSPEND
- [_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB] = "early_suspend_level_disable_framebuffer",
- [_MALI_DEVICE_LATERESUME] = "late_resume",
-#endif /* CONFIG_HAS_EARLYSUSPEND */
[_MALI_DVFS_PAUSE_EVENT] = "dvfs_pause",
[_MALI_DVFS_RESUME_EVENT] = "dvfs_resume",
};
@@ -86,13 +81,11 @@ extern void set_mali_parent_power_domain(struct platform_device* dev);
#ifdef CONFIG_PM_RUNTIME
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#ifndef CONFIG_HAS_EARLYSUSPEND
static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy);
static struct notifier_block mali_pwr_notif_block = {
.notifier_call = mali_pwr_suspend_notifier
};
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
#endif /* CONFIG_PM_RUNTIME */
@@ -143,12 +136,6 @@ static int mali_device_runtime_resume(struct device *dev);
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
#endif /* CONFIG_PM_RUNTIME */
-/* Early suspend functions */
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mali_pm_early_suspend(struct early_suspend *mali_dev);
-static void mali_pm_late_resume(struct early_suspend *mali_dev);
-#endif /* CONFIG_HAS_EARLYSUSPEND */
-
/* OS suspend and resume callbacks */
#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
#ifndef CONFIG_PM_RUNTIME
@@ -231,15 +218,6 @@ static struct platform_driver mali_plat_driver = {
},
};
-#ifdef CONFIG_HAS_EARLYSUSPEND
-/* Early suspend hooks */
-static struct early_suspend mali_dev_early_suspend = {
- .suspend = mali_pm_early_suspend,
- .resume = mali_pm_late_resume,
- .level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
-};
-#endif /* CONFIG_HAS_EARLYSUSPEND */
-
/* Mali GPU platform device */
struct platform_device mali_gpu_device = {
.name = "mali_dev",
@@ -308,7 +286,9 @@ int mali_device_suspend(unsigned int event_id, struct task_struct **pwr_mgmt_thr
*pwr_mgmt_thread = current;
MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being suspended\n" ));
_mali_ukk_pmm_event_message(&event);
+ is_os_pmm_thread_waiting = 1;
err = mali_wait_for_power_management_policy_event();
+ is_os_pmm_thread_waiting = 0;
return err;
}
@@ -322,17 +302,11 @@ static int mali_pm_suspend(struct device *dev)
#if MALI_GPU_UTILIZATION
mali_utilization_suspend();
#endif /* MALI_GPU_UTILIZATION */
- if ((mali_device_state == _MALI_DEVICE_SUSPEND)
-#ifdef CONFIG_HAS_EARLYSUSPEND
- || mali_device_state == (_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB))
-#else
- )
-#endif /* CONFIG_HAS_EARLYSUSPEND */
+ if ((mali_device_state == _MALI_DEVICE_SUSPEND))
{
_mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
return err;
}
- mali_device_state = _MALI_DEVICE_SUSPEND_IN_PROGRESS;
err = mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread);
mali_device_state = _MALI_DEVICE_SUSPEND;
_mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
@@ -356,7 +330,6 @@ static int mali_pm_os_suspend(struct device *dev)
#ifdef CONFIG_PM_RUNTIME
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#ifndef CONFIG_HAS_EARLYSUSPEND
static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy)
{
int err = 0;
@@ -374,7 +347,6 @@ static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long eve
}
return 0;
}
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
#endif /* CONFIG_PM_RUNTIME */
@@ -391,7 +363,9 @@ int mali_device_resume(unsigned int event_id, struct task_struct **pwr_mgmt_thre
MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being resumed\n" ));
_mali_ukk_pmm_event_message(&event);
MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power up event is scheduled\n" ));
+ is_os_pmm_thread_waiting = 1;
err = mali_wait_for_power_management_policy_event();
+ is_os_pmm_thread_waiting = 0;
return err;
}
@@ -463,69 +437,6 @@ static int mali_device_runtime_resume(struct device *dev)
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
#endif /* CONFIG_PM_RUNTIME */
-#ifdef CONFIG_HAS_EARLYSUSPEND
-
-/* This function is called from android framework.
- */
-static void mali_pm_early_suspend(struct early_suspend *mali_dev)
-{
- switch(mali_dev->level)
- {
- /* Screen should be turned off but framebuffer will be accessible */
- case EARLY_SUSPEND_LEVEL_BLANK_SCREEN:
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Screen is off\n" ));
- break;
-
- case EARLY_SUSPEND_LEVEL_STOP_DRAWING:
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Suspend level stop drawing\n" ));
- break;
-
- /* Turn off the framebuffer. In our case No Mali GPU operation */
- case EARLY_SUSPEND_LEVEL_DISABLE_FB:
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Suspend level Disable framebuffer\n" ));
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-#if MALI_GPU_UTILIZATION
- mali_utilization_suspend();
-#endif /* MALI_GPU_UTILIZATION */
- if ((mali_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB))
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return;
- }
- mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread);
- mali_device_state = _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB;
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- break;
-
- default:
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Invalid Suspend Mode\n" ));
- break;
- }
-}
-
-/* This function is invoked from android framework when mali device needs to be
- * resumed.
- */
-static void mali_pm_late_resume(struct early_suspend *mali_dev)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if (mali_device_state == _MALI_DEVICE_RESUME)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return;
- }
- if (mali_device_state == _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB)
- {
- mali_device_resume(MALI_PMM_EVENT_OS_POWER_UP, &pm_thread);
- mali_dvfs_device_state = _MALI_DEVICE_RESUME;
- mali_device_state = _MALI_DEVICE_RESUME;
- }
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
-
-}
-
-#endif /* CONFIG_HAS_EARLYSUSPEND */
-
#ifdef CONFIG_PM_DEBUG
/** This function is used for debugging purposes when the user want to see
@@ -557,9 +468,6 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char
static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int err = 0;
-#ifdef CONFIG_HAS_EARLYSUSPEND
- struct early_suspend mali_dev;
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#if MALI_POWER_MGMT_TEST_SUITE
int test_flag_dvfs = 0;
@@ -597,19 +505,6 @@ static ssize_t store_file(struct device *dev, struct device_attribute *attr, con
MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" ));
err = mali_pm_resume(NULL);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
- else if (!strncmp(buf,mali_states[_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB],strlen(mali_states[_MALI_DEVICE_EARLYSUSPEND_DISABLE_FB])))
- {
- mali_dev.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Android early suspend operation is scheduled\n" ));
- mali_pm_early_suspend(&mali_dev);
- }
- else if (!strncmp(buf,mali_states[_MALI_DEVICE_LATERESUME],strlen(mali_states[_MALI_DEVICE_LATERESUME])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" ));
- mali_pm_late_resume(NULL);
- }
-#endif /* CONFIG_HAS_EARLYSUSPEND */
else if (!strncmp(buf,mali_states[_MALI_DVFS_PAUSE_EVENT],strlen(mali_states[_MALI_DVFS_PAUSE_EVENT])))
{
MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Pause Power operation is scheduled\n" ));
@@ -694,7 +589,6 @@ int _mali_dev_platform_register(void)
#endif
#ifdef CONFIG_PM_RUNTIME
-#ifndef CONFIG_HAS_EARLYSUSPEND
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
err = register_pm_notifier(&mali_pwr_notif_block);
if (err)
@@ -702,28 +596,19 @@ int _mali_dev_platform_register(void)
return err;
}
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#endif /* CONFIG_PM_RUNTIME */
err = platform_device_register(&mali_gpu_device);
lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0);
if (!err)
{
err = platform_driver_register(&mali_plat_driver);
- if (!err)
- {
-#ifdef CONFIG_HAS_EARLYSUSPEND
- register_early_suspend(&mali_dev_early_suspend);
-#endif /* CONFIG_HAS_EARLYSUSPEND */
- }
- else
+ if (err)
{
_mali_osk_lock_term(lock);
#ifdef CONFIG_PM_RUNTIME
-#ifndef CONFIG_HAS_EARLYSUSPEND
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
unregister_pm_notifier(&mali_pwr_notif_block);
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#endif /* CONFIG_PM_RUNTIME */
platform_device_unregister(&mali_gpu_device);
}
@@ -737,22 +622,28 @@ void _mali_dev_platform_unregister(void)
{
_mali_osk_lock_term(lock);
-#ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&mali_dev_early_suspend);
-#endif /* CONFIG_HAS_EARLYSUSPEND */
-
#ifdef CONFIG_PM_RUNTIME
-#ifndef CONFIG_HAS_EARLYSUSPEND
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
unregister_pm_notifier(&mali_pwr_notif_block);
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_HAS_EARLYSUSPEND */
#endif /* CONFIG_PM_RUNTIME */
platform_driver_unregister(&mali_plat_driver);
platform_device_unregister(&mali_gpu_device);
}
+int mali_get_ospmm_thread_state(void)
+{
+ return is_os_pmm_thread_waiting;
+}
+
#endif /* MALI_LICENSE_IS_GPL */
#endif /* CONFIG_PM */
+
+#if MALI_STATE_TRACKING
+u32 mali_pmm_dump_os_thread_state( char *buf, u32 size )
+{
+ return snprintf(buf, size, "OSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false");
+}
+#endif /* MALI_STATE_TRACKING */
#endif /* USING_MALI_PMM */
diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c
new file mode 100644
index 00000000000..62c7fba8791
--- /dev/null
+++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.c
@@ -0,0 +1,137 @@
+/**
+ * Copyright (C) 2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+/**
+ * @file mali_kernel_sysfs.c
+ * Implementation of some sysfs data exports
+ */
+#include <linux/fs.h> /* file system operations */
+#include <linux/device.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+
+/* the mali kernel subsystem types */
+#include "mali_kernel_subsystem.h"
+
+#include "mali_kernel_linux.h"
+#include "mali_kernel_sysfs.h"
+
+#include "mali_kernel_license.h"
+
+#if MALI_LICENSE_IS_GPL
+static struct dentry *mali_debugfs_dir;
+#endif
+
+
+#if MALI_STATE_TRACKING
+static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
+{
+ u32 len = 0;
+ u32 size;
+ char *buf;
+
+ size = seq_get_buf(seq_file, &buf);
+
+ if(!size)
+ {
+ return -ENOMEM;
+ }
+
+ /* Create the internal state dump. */
+ len = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING);
+ len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE);
+
+ len += _mali_kernel_core_dump_state(buf + len, size - len);
+
+ seq_commit(seq_file, len);
+
+ return 0;
+}
+
+static int mali_seq_internal_state_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mali_seq_internal_state_show, NULL);
+}
+
+static const struct file_operations mali_seq_internal_state_fops = {
+ .owner = THIS_MODULE,
+ .open = mali_seq_internal_state_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif /* MALI_STATE_TRACKING */
+
+int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
+{
+ int err = 0;
+#if MALI_LICENSE_IS_GPL
+ struct device * mdev;
+
+ device->mali_class = class_create(THIS_MODULE, mali_dev_name);
+ if (IS_ERR(device->mali_class))
+ {
+ err = PTR_ERR(device->mali_class);
+ goto init_class_err;
+ }
+ mdev = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name);
+ if (IS_ERR(mdev))
+ {
+ err = PTR_ERR(mdev);
+ goto init_mdev_err;
+ }
+
+ mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL);
+ if(ERR_PTR(-ENODEV) == mali_debugfs_dir) {
+ /* Debugfs not supported. */
+ mali_debugfs_dir = NULL;
+ } else {
+ if(NULL != mali_debugfs_dir)
+ {
+ /* Debugfs directory created successfully; create files now */
+#if MALI_STATE_TRACKING
+ debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops);
+#endif
+ }
+ }
+#endif /* MALI_LICENSE_IS_GPL */
+
+ /* Success! */
+ return 0;
+
+ /* Error handling */
+#if MALI_LICENSE_IS_GPL
+ if(NULL != mali_debugfs_dir)
+ {
+ debugfs_remove_recursive(mali_debugfs_dir);
+ }
+ device_destroy(device->mali_class, dev);
+init_mdev_err:
+ class_destroy(device->mali_class);
+init_class_err:
+#endif
+ return err;
+}
+
+int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
+{
+#if MALI_LICENSE_IS_GPL
+ if(NULL != mali_debugfs_dir)
+ {
+ debugfs_remove_recursive(mali_debugfs_dir);
+ }
+ device_destroy(device->mali_class, dev);
+ class_destroy(device->mali_class);
+#endif
+
+ return 0;
+}
+
diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h
new file mode 100644
index 00000000000..d79a8862269
--- /dev/null
+++ b/drivers/gpu/arm/mali/linux/mali_kernel_sysfs.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_SYSFS_H__
+#define __MALI_KERNEL_SYSFS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MALI_PROC_DIR "driver/mali"
+
+int mali_sysfs_register(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name);
+
+int mali_sysfs_unregister(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_KERNEL_LINUX_H__ */
diff --git a/drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c b/drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c
new file mode 100644
index 00000000000..3d60d18e005
--- /dev/null
+++ b/drivers/gpu/arm/mali/linux/mali_linux_dvfs_pause_resume.c
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_linux_dvfs_pause_resume.c
+ * Implementation of the Mali pause/resume functionality
+ */
+#if USING_MALI_PMM
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_platform.h"
+#include "mali_linux_pm.h"
+#include "mali_linux_dvfs_pause_resume.h"
+#include "mali_pmm.h"
+#include "mali_kernel_license.h"
+#ifdef CONFIG_PM
+#if MALI_LICENSE_IS_GPL
+
+/* Mali Pause Resume APIs */
+int mali_dev_dvfs_pause()
+{
+ int err = 0;
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+ if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS)
+ || (mali_device_state == _MALI_DEVICE_SUSPEND))
+ {
+ err = -EPERM;
+ }
+ if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err))
+ {
+ mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread);
+ mali_dvfs_device_state = _MALI_DEVICE_SUSPEND;
+ }
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return err;
+}
+
+EXPORT_SYMBOL(mali_dev_dvfs_pause);
+
+int mali_dev_dvfs_resume()
+{
+ int err = 0;
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+ if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) || (mali_device_state == _MALI_DEVICE_SUSPEND_IN_PROGRESS)
+ || (mali_device_state == _MALI_DEVICE_SUSPEND))
+ {
+ err = -EPERM;
+ }
+ if (!err)
+ {
+ mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread);
+ mali_dvfs_device_state = _MALI_DEVICE_RESUME;
+ }
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return err;
+}
+
+EXPORT_SYMBOL(mali_dev_dvfs_resume);
+
+#endif /* MALI_LICENSE_IS_GPL */
+#endif /* CONFIG_PM */
+#endif /* USING_MALI_PMM */
diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm.h b/drivers/gpu/arm/mali/linux/mali_linux_pm.h
index 614d5e1deee..d401697f2f4 100755
--- a/drivers/gpu/arm/mali/linux/mali_linux_pm.h
+++ b/drivers/gpu/arm/mali/linux/mali_linux_pm.h
@@ -20,18 +20,13 @@ typedef enum
{
_MALI_DEVICE_SUSPEND, /* Suspend */
_MALI_DEVICE_RESUME, /* Resume */
-#ifdef CONFIG_HAS_EARLYSUSPEND
- _MALI_DEVICE_EARLYSUSPEND_DISABLE_FB, /* Early suspend */
- _MALI_DEVICE_LATERESUME, /* Late resume */
-#endif /* CONFIG_HAS_EARLYSUSPEND */
- _MALI_DEVICE_SUSPEND_IN_PROGRESS, /* Suspend in progress */
_MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */
} _mali_device_power_states;
/* Number of DVFS events */
typedef enum
{
- _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES-1, /* DVFS Pause event */
+ _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES, /* DVFS Pause event */
_MALI_DVFS_RESUME_EVENT, /* DVFS Resume event */
_MALI_MAX_DEBUG_OPERATIONS,
} _mali_device_dvfs_events;
@@ -51,6 +46,7 @@ extern struct task_struct *pm_thread;
int mali_device_suspend(u32 event_id, struct task_struct **pwr_mgmt_thread);
int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread);
+int mali_get_ospmm_thread_state(void);
#endif /* CONFIG_PM */
#endif /* USING_MALI_PMM */
diff --git a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h
index d6a920827c9..c80b0b0a5e3 100755
--- a/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h
+++ b/drivers/gpu/arm/mali/linux/mali_linux_pm_testsuite.h
@@ -13,7 +13,6 @@
#if USING_MALI_PMM
#if MALI_POWER_MGMT_TEST_SUITE
#ifdef CONFIG_PM
-#define MALI_PMM_INTERNAL_TESTING 1
typedef enum
{
@@ -28,10 +27,7 @@ extern unsigned int mali_timeout_event_recording_on;
extern unsigned int mali_job_scheduling_events_recording_on;
extern unsigned int pwr_mgmt_status_reg;
extern unsigned int is_mali_pmm_testsuite_enabled;
-
-#if MALI_PMM_INTERNAL_TESTING
extern unsigned int is_mali_pmu_present;
-#endif /* MALI_PMM_INTERNAL_TESTING */
#endif /* CONFIG_PM */
#endif /* MALI_POWER_MGMT_TEST_SUITE */
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_irq.c b/drivers/gpu/arm/mali/linux/mali_osk_irq.c
index 73ab8182815..b667961a0ac 100755
--- a/drivers/gpu/arm/mali/linux/mali_osk_irq.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_irq.c
@@ -136,7 +136,7 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl
#if MALI_LICENSE_IS_GPL
if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum )
{
- pmm_wq = create_workqueue("mali-pmm-wq");
+ pmm_wq = create_singlethread_workqueue("mali-pmm-wq");
}
#endif
@@ -149,7 +149,7 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq )
#if MALI_LICENSE_IS_GPL
if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
{
- queue_work(pmm_wq,&irq_object->work_queue_irq_handle);
+ queue_work( pmm_wq,&irq_object->work_queue_irq_handle );
}
else
{
@@ -160,6 +160,17 @@ void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq )
#endif
}
+void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq )
+{
+#if MALI_LICENSE_IS_GPL
+ mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
+ if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
+ {
+ flush_workqueue(pmm_wq);
+ }
+#endif
+}
+
void _mali_osk_irq_term( _mali_osk_irq_t *irq )
{
mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_locks.c b/drivers/gpu/arm/mali/linux/mali_osk_locks.c
index 79010fcdc5a..139dc5e3de3 100755
--- a/drivers/gpu/arm/mali/linux/mali_osk_locks.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_locks.c
@@ -29,12 +29,6 @@
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
-#define LOCK_INIT(x) sema_init(x,1)
-#else
-#define LOCK_INIT(x) init_MUTEX(x)
-#endif
-
/* These are all the locks we implement: */
typedef enum
{
@@ -67,7 +61,6 @@ struct _mali_osk_lock_t_struct
MALI_DEBUG_CODE(
/** original flags for debug checking */
_mali_osk_lock_flags_t orig_flags;
- _mali_osk_lock_mode_t locked_as;
); /* MALI_DEBUG_CODE */
};
@@ -82,10 +75,10 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
| _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
| _MALI_OSK_LOCKFLAG_READERWRITER
| _MALI_OSK_LOCKFLAG_ORDERED
- | _MALI_OSK_LOCKFLAG_ONELOCK)) );
+ | _MALI_OSK_LOCKFLAG_ONELOCK )) );
/* Spinlocks are always non-interruptable */
MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE))
- || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK) );
+ || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK));
/* Parameter initial SBZ - for future expansion */
MALI_DEBUG_ASSERT( 0 == initial );
@@ -130,13 +123,12 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
}
/* Initially unlocked */
- LOCK_INIT( &lock->obj.sema );
+ sema_init( &lock->obj.sema, 1 );
}
MALI_DEBUG_CODE(
/* Debug tracking of flags */
lock->orig_flags = flags;
- lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF;
); /* MALI_DEBUG_CODE */
return lock;
@@ -196,17 +188,6 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
break;
}
- /* DEBUG tracking of previously locked state - occurs after lock obtained */
- MALI_DEBUG_CODE(
- if ( _MALI_OSK_ERR_OK == err )
- {
- /* Assert that this is not currently locked */
- MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_UNDEF == lock->locked_as );
-
- lock->locked_as = mode;
- }
- ); /* MALI_DEBUG_CODE */
-
return err;
}
@@ -224,12 +205,6 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
|| (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) );
- /* For DEBUG only, assert that we previously locked this, and in the same way (RW/RO) */
- MALI_DEBUG_ASSERT( mode == lock->locked_as );
-
- /* DEBUG tracking of previously locked state - occurs before lock released */
- MALI_DEBUG_CODE( lock->locked_as = _MALI_OSK_LOCKMODE_UNDEF );
-
switch ( lock->type )
{
case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN:
@@ -269,9 +244,6 @@ void _mali_osk_lock_term( _mali_osk_lock_t *lock )
/* Parameter validation */
MALI_DEBUG_ASSERT_POINTER( lock );
- /* For DEBUG only, assert that this is not currently locked */
- MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_UNDEF == lock->locked_as );
-
/* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */
kfree(lock);
}
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c
index 730ee814e38..40373427d44 100755
--- a/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_low_level_mem.c
@@ -21,7 +21,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
-#include <asm/cacheflush.h>
#include "mali_osk.h"
#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */
@@ -38,6 +37,7 @@ static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma,
static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address);
#endif
+
typedef struct mali_vma_usage_tracker
{
int references;
@@ -50,9 +50,9 @@ typedef struct mali_vma_usage_tracker
*/
struct AllocationList
{
- struct AllocationList *next;
- u32 offset;
- u32 physaddr;
+ struct AllocationList *next;
+ u32 offset;
+ u32 physaddr;
};
typedef struct AllocationList AllocationList;
@@ -63,11 +63,28 @@ typedef struct AllocationList AllocationList;
struct MappingInfo
{
struct vm_area_struct *vma;
- struct AllocationList *list;
+ struct AllocationList *list;
};
typedef struct MappingInfo MappingInfo;
+
+static u32 _kernel_page_allocate(void);
+static void _kernel_page_release(u32 physical_address);
+static AllocationList * _allocation_list_item_get(void);
+static void _allocation_list_item_release(AllocationList * item);
+
+
+/* Variable declarations */
+spinlock_t allocation_list_spinlock;
+static AllocationList * pre_allocated_memory = (AllocationList*) NULL ;
+static int pre_allocated_memory_size_current = 0;
+#ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB
+ static int pre_allocated_memory_size_max = MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB * 1024 * 1024;
+#else
+ static int pre_allocated_memory_size_max = 6 * 1024 * 1024; /* 6 MiB */
+#endif
+
static struct vm_operations_struct mali_kernel_vm_ops =
{
.open = mali_kernel_memory_vma_open,
@@ -80,6 +97,108 @@ static struct vm_operations_struct mali_kernel_vm_ops =
};
+void mali_osk_low_level_mem_init(void)
+{
+ spin_lock_init( &allocation_list_spinlock );
+ pre_allocated_memory = (AllocationList*) NULL ;
+}
+
+void mali_osk_low_level_mem_term(void)
+{
+ while ( NULL != pre_allocated_memory )
+ {
+ AllocationList *item;
+ item = pre_allocated_memory;
+ pre_allocated_memory = item->next;
+ _kernel_page_release(item->physaddr);
+ _mali_osk_free( item );
+ }
+ pre_allocated_memory_size_current = 0;
+}
+
+static u32 _kernel_page_allocate(void)
+{
+ struct page *new_page;
+ u32 linux_phys_addr;
+
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
+
+ if ( NULL == new_page )
+ {
+ return 0;
+ }
+
+ /* Ensure page is flushed from CPU caches. */
+ linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
+
+ return linux_phys_addr;
+}
+
+static void _kernel_page_release(u32 physical_address)
+{
+ struct page *unmap_page;
+
+ #if 1
+ dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ #endif
+
+ unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT );
+ MALI_DEBUG_ASSERT_POINTER( unmap_page );
+ __free_page( unmap_page );
+}
+
+static AllocationList * _allocation_list_item_get(void)
+{
+ AllocationList *item = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&allocation_list_spinlock,flags);
+ if ( pre_allocated_memory )
+ {
+ item = pre_allocated_memory;
+ pre_allocated_memory = pre_allocated_memory->next;
+ pre_allocated_memory_size_current -= PAGE_SIZE;
+
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+ return item;
+ }
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+
+ item = _mali_osk_malloc( sizeof(AllocationList) );
+ if ( NULL == item)
+ {
+ return NULL;
+ }
+
+ item->physaddr = _kernel_page_allocate();
+ if ( 0 == item->physaddr )
+ {
+ /* Non-fatal error condition, out of memory. Upper levels will handle this. */
+ _mali_osk_free( item );
+ return NULL;
+ }
+ return item;
+}
+
+static void _allocation_list_item_release(AllocationList * item)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&allocation_list_spinlock,flags);
+ if ( pre_allocated_memory_size_current < pre_allocated_memory_size_max)
+ {
+ item->next = pre_allocated_memory;
+ pre_allocated_memory = item;
+ pre_allocated_memory_size_current += PAGE_SIZE;
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+ return;
+ }
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+
+ _kernel_page_release(item->physaddr);
+ _mali_osk_free( item );
+}
+
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
#else
@@ -108,7 +227,7 @@ static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_st
static void mali_kernel_memory_vma_open(struct vm_area_struct * vma)
{
mali_vma_usage_tracker * vma_usage_tracker;
- MALI_DEBUG_PRINT(2, ("Open called on vma %p\n", vma));
+ MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma));
vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data;
vma_usage_tracker->references++;
@@ -154,17 +273,17 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma)
void _mali_osk_mem_barrier( void )
{
- mb();
+ mb();
}
mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description )
{
- return (mali_io_address)ioremap_nocache(phys, size);
+ return (mali_io_address)ioremap_nocache(phys, size);
}
void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt )
{
- iounmap((void*)virt);
+ iounmap((void*)virt);
}
mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size )
@@ -204,27 +323,27 @@ void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt )
_mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description )
{
- return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK);
+ return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK);
}
void inline _mali_osk_mem_unreqregion( u32 phys, u32 size )
{
- release_mem_region(phys, size);
+ release_mem_region(phys, size);
}
u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset )
{
- return ioread32(((u8*)addr) + offset);
+ return ioread32(((u8*)addr) + offset);
}
void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val )
{
- iowrite32(val, ((u8*)addr) + offset);
+ iowrite32(val, ((u8*)addr) + offset);
}
void _mali_osk_cache_flushall( void )
{
- /** @note Cached memory is not currently supported in this implementation */
+ /** @note Cached memory is not currently supported in this implementation */
}
void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size )
@@ -274,6 +393,7 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descr
*/
vma->vm_flags |= VM_IO;
vma->vm_flags |= VM_RESERVED;
+ vma->vm_flags |= VM_DONTCOPY;
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */
@@ -334,14 +454,14 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri
MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK));
- if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS;
+ if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS;
- if (size > (descriptor->size - offset))
- {
- MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n",
- *phys_addr, size, descriptor->mapping, offset));
- return _MALI_OSK_ERR_FAULT;
- }
+ if (size > (descriptor->size - offset))
+ {
+ MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n",
+ *phys_addr, size, descriptor->mapping, offset));
+ return _MALI_OSK_ERR_FAULT;
+ }
mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
@@ -351,57 +471,35 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri
if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
- MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", phys_addr, (long unsigned int)(descriptor->mapping + offset), size));
+ MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", *phys_addr, (long unsigned int)(descriptor->mapping + offset), size));
if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr )
{
_mali_osk_errcode_t ret;
+ AllocationList *alloc_item;
u32 linux_phys_frame_num;
- u32 linux_phys_addr;
- AllocationList *allocItem;
- struct page *new_page;
- allocItem = _mali_osk_malloc( sizeof(AllocationList) );
- if ( NULL == allocItem )
- {
- /* Out of memory. Try another allocator */
- return _MALI_OSK_ERR_NOMEM;
- }
+ alloc_item = _allocation_list_item_get();
- {
- new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD);
-
- if ( NULL == new_page )
- {
- /* Non-fatal error condition, out of memory. Upper levels will handle this. */
- _mali_osk_free( allocItem );
- return _MALI_OSK_ERR_NOMEM;
- }
-
- /* Ensure page is flushed from CPU caches. */
- linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
-
- linux_phys_frame_num = linux_phys_addr >> PAGE_SHIFT;
- }
+ linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT;
ret = ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, linux_phys_frame_num, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;
if ( ret != _MALI_OSK_ERR_OK)
{
- dma_unmap_page(NULL, linux_phys_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
- __free_page( new_page );
- _mali_osk_free( allocItem );
+ _allocation_list_item_release(alloc_item);
return ret;
}
- /* Put our allocItem into the list of allocations on success */
- allocItem->next = mappingInfo->list;
- allocItem->offset = offset;
- allocItem->physaddr = linux_phys_addr;
- mappingInfo->list = allocItem;
+ /* Put our alloc_item into the list of allocations on success */
+ alloc_item->next = mappingInfo->list;
+ alloc_item->offset = offset;
+
+ /*alloc_item->physaddr = linux_phys_addr;*/
+ mappingInfo->list = alloc_item;
/* Write out new physical address on success */
- *phys_addr = linux_phys_addr;
+ *phys_addr = alloc_item->physaddr;
return ret;
}
@@ -427,56 +525,50 @@ void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 off
MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) );
- if (NULL == descriptor->mapping) return;
+ if (NULL == descriptor->mapping) return;
- if (size > (descriptor->size - offset))
- {
- MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n",
+ if (size > (descriptor->size - offset))
+ {
+ MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n",
size, descriptor->mapping, offset));
- return;
- }
+ return;
+ }
mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
MALI_DEBUG_ASSERT_POINTER( mappingInfo );
if ( 0 != (flags & _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR) )
{
- /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and
- * so needs to be unmapped
- */
- while (size)
+ /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and
+ * so needs to be unmapped
+ */
+ while (size)
{
- /* First find the allocation in the list of allocations */
- AllocationList *alloc = mappingInfo->list;
- AllocationList **prev = &(mappingInfo->list);
- while (NULL != alloc && alloc->offset != offset)
- {
- prev = &(alloc->next);
- alloc = alloc->next;
- }
- if (alloc == NULL) {
- MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n"));
- size -= _MALI_OSK_CPU_PAGE_SIZE;
- offset += _MALI_OSK_CPU_PAGE_SIZE;
- continue;
- }
-
+ /* First find the allocation in the list of allocations */
+ AllocationList *alloc = mappingInfo->list;
+ AllocationList **prev = &(mappingInfo->list);
+ while (NULL != alloc && alloc->offset != offset)
{
- struct page *unmap_page;
- unmap_page = pfn_to_page( alloc->physaddr >> PAGE_SHIFT );
- MALI_DEBUG_ASSERT_POINTER( unmap_page );
- dma_unmap_page(NULL, alloc->physaddr, PAGE_SIZE, DMA_BIDIRECTIONAL);
- __free_page( unmap_page );
+ prev = &(alloc->next);
+ alloc = alloc->next;
}
+ if (alloc == NULL) {
+ MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n"));
+ size -= _MALI_OSK_CPU_PAGE_SIZE;
+ offset += _MALI_OSK_CPU_PAGE_SIZE;
+ continue;
+ }
+
+ _kernel_page_release(alloc->physaddr);
- /* Remove the allocation from the list */
- *prev = alloc->next;
- _mali_osk_free( alloc );
+ /* Remove the allocation from the list */
+ *prev = alloc->next;
+ _mali_osk_free( alloc );
- /* Move onto the next allocation */
- size -= _MALI_OSK_CPU_PAGE_SIZE;
- offset += _MALI_OSK_CPU_PAGE_SIZE;
- }
+ /* Move onto the next allocation */
+ size -= _MALI_OSK_CPU_PAGE_SIZE;
+ offset += _MALI_OSK_CPU_PAGE_SIZE;
+ }
}
/* Linux does the right thing as part of munmap to remove the mapping */
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_mali.c b/drivers/gpu/arm/mali/linux/mali_osk_mali.c
index d6c4b41ebc0..5b84549ef86 100755
--- a/drivers/gpu/arm/mali/linux/mali_osk_mali.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_mali.c
@@ -18,21 +18,24 @@
#include "mali_kernel_common.h" /* MALI_xxx macros */
#include "mali_osk.h" /* kernel side OS functions */
#include "mali_uk_types.h"
-#include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() */
+#include "mali_kernel_linux.h" /* exports initialize/terminate_kernel_device() definition of mali_osk_low_level_mem_init() and term */
#include <mach/irqs.h>
-#include <mach/mali/config.h> /* contains the configuration of the arch we are compiling for */
+#include <mach/mali/config.h> /* contains the configuration of the arch we are compiling for */
/* is called from mali_kernel_constructor in common code */
_mali_osk_errcode_t _mali_osk_init( void )
{
if (0 != initialize_kernel_device()) MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ mali_osk_low_level_mem_init();
+
MALI_SUCCESS;
}
/* is called from mali_kernel_deconstructor in common code */
void _mali_osk_term( void )
{
+ mali_osk_low_level_mem_term();
terminate_kernel_device();
}
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_misc.c b/drivers/gpu/arm/mali/linux/mali_osk_misc.c
index 3afd2da736c..12f4299ee9b 100755
--- a/drivers/gpu/arm/mali/linux/mali_osk_misc.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_misc.c
@@ -27,6 +27,18 @@ void _mali_osk_dbgmsg( const char *fmt, ... )
va_end(args);
}
+u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... )
+{
+ int res;
+ va_list args;
+ va_start(args, fmt);
+
+ res = vsnprintf(buf, (size_t)size, fmt, args);
+
+ va_end(args);
+ return res;
+}
+
void _mali_osk_abort(void)
{
/* make a simple fault by dereferencing a NULL pointer */
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_notification.c b/drivers/gpu/arm/mali/linux/mali_osk_notification.c
index 6eb277f3724..539f9ab68b0 100755..100644
--- a/drivers/gpu/arm/mali/linux/mali_osk_notification.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_notification.c
@@ -20,7 +20,6 @@
#include <linux/version.h>
#include <linux/sched.h>
-#include <linux/mm.h>
#include <linux/slab.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#include <linux/semaphore.h>
@@ -28,12 +27,6 @@
#include <asm/semaphore.h>
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
-#define LOCK_INIT(x) sema_init(x,1)
-#else
-#define LOCK_INIT(x) init_MUTEX(x)
-#endif
-
/**
* Declaration of the notification queue object type
* Contains a linked list of notification pending delivery to user space.
@@ -60,7 +53,7 @@ _mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL);
if (NULL == result) return NULL;
- LOCK_INIT(&result->mutex);
+ sema_init(&result->mutex, 1);
init_waitqueue_head(&result->receive_queue);
INIT_LIST_HEAD(&result->head);
@@ -72,7 +65,7 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
/* OPT Recycling of notification objects */
_mali_osk_notification_wrapper_t *notification;
- notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t), GFP_KERNEL );
+ notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, GFP_KERNEL );
if (NULL == notification)
{
MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n"));
@@ -82,21 +75,13 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
/* Init the list */
INIT_LIST_HEAD(&notification->list);
- /* allocate memory for the buffer requested */
if (0 != size)
{
- notification->data.result_buffer = kmalloc( size, GFP_KERNEL );
- if ( NULL == notification->data.result_buffer )
- {
- /* failed to buffer, cleanup */
- MALI_DEBUG_PRINT(1, ("Failed to allocate memory for notification object buffer of size %d\n", size));
- kfree(notification);
- return NULL;
- }
+ notification->data.result_buffer = ((u8*)notification) + sizeof(_mali_osk_notification_wrapper_t);
}
else
{
- notification->data.result_buffer = 0;
+ notification->data.result_buffer = NULL;
}
/* set up the non-allocating fields */
@@ -116,8 +101,6 @@ void _mali_osk_notification_delete( _mali_osk_notification_t *object )
/* Remove from the list */
list_del(&notification->list);
- /* Free the buffer */
- kfree(notification->data.result_buffer);
/* Free the container */
kfree(notification);
}
@@ -159,6 +142,13 @@ static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *qu
return ret;
}
+#if MALI_STATE_TRACKING
+mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue )
+{
+ return _mali_notification_queue_is_empty(queue) ? MALI_TRUE : MALI_FALSE;
+}
+#endif
+
_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
{
_mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND;
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_pm.c b/drivers/gpu/arm/mali/linux/mali_osk_pm.c
index f1363167292..f9c9e5ce2e8 100755..100644
--- a/drivers/gpu/arm/mali/linux/mali_osk_pm.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_pm.c
@@ -33,11 +33,13 @@
#include "mali_linux_pm.h"
#include "mali_linux_pm_testsuite.h"
+#if MALI_LICENSE_IS_GPL
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
#ifdef CONFIG_PM_RUNTIME
static int is_runtime =0;
#endif /* CONFIG_PM_RUNTIME */
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
+#endif /* MALI_LICENSE_IS_GPL */
#if MALI_POWER_MGMT_TEST_SUITE
@@ -118,12 +120,10 @@ void _mali_osk_pmm_power_down_done(mali_pmm_message_data data)
#ifdef CONFIG_PM
is_wake_up_needed = 1;
#if MALI_POWER_MGMT_TEST_SUITE
-#if MALI_PMM_INTERNAL_TESTING
if (is_mali_pmu_present == 0)
{
pwr_mgmt_status_reg = _mali_pmm_cores_list();
}
-#endif /* MALI_PMM_INTERNAL_TESTING */
#endif /* MALI_POWER_MGMT_TEST_SUITE */
wake_up_process(pm_thread);
MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power down Done\n" ));
@@ -182,6 +182,20 @@ void _mali_osk_pmm_dev_activate(void)
#endif /* MALI_LICENSE_IS_GPL */
}
+void _mali_osk_pmm_ospmm_cleanup( void )
+{
+#if MALI_LICENSE_IS_GPL
+#ifdef CONFIG_PM
+ int thread_state;
+ thread_state = mali_get_ospmm_thread_state();
+ if (thread_state)
+ {
+ _mali_osk_pmm_dvfs_operation_done(0);
+ }
+#endif /* CONFIG_PM */
+#endif /* MALI_LICENSE_IS_GPL */
+}
+
void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data)
{
#if MALI_LICENSE_IS_GPL
diff --git a/drivers/gpu/arm/mali/linux/mali_osk_timers.c b/drivers/gpu/arm/mali/linux/mali_osk_timers.c
index 1cffce37461..3dfba76bcb3 100755..100644
--- a/drivers/gpu/arm/mali/linux/mali_osk_timers.c
+++ b/drivers/gpu/arm/mali/linux/mali_osk_timers.c
@@ -51,7 +51,6 @@ void _mali_osk_timer_del( _mali_osk_timer_t *tim )
del_timer_sync(&(tim->timer));
}
-
void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data )
{
MALI_DEBUG_ASSERT_POINTER(tim);
diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_core.c b/drivers/gpu/arm/mali/linux/mali_ukk_core.c
index a10d1ba8a5e..0f745492613 100755..100644
--- a/drivers/gpu/arm/mali/linux/mali_ukk_core.c
+++ b/drivers/gpu/arm/mali/linux/mali_ukk_core.c
@@ -105,7 +105,7 @@ int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_
err = _mali_ukk_wait_for_notification(&kargs);
if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
- if( !(_MALI_NOTIFICATION_CORE_TIMEOUT == kargs.type || _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS == kargs.type ) )
+ if(_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS != kargs.type)
{
kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_wait_for_notification_s))) return -EFAULT;
diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_gp.c b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c
index 58ff1de5108..a6f355fd459 100644
--- a/drivers/gpu/arm/mali/linux/mali_ukk_gp.c
+++ b/drivers/gpu/arm/mali/linux/mali_ukk_gp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c b/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c
new file mode 100644
index 00000000000..965ee411535
--- /dev/null
+++ b/drivers/gpu/arm/mali/linux/mali_ukk_vsync.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_session_manager.h"
+#include "mali_ukk_wrappers.h"
+
+
+int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs)
+{
+ _mali_uk_vsync_event_report_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_vsync_event_report_s)))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_vsync_event_report(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
diff --git a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h
index 0bc6b87e69c..54e3f656b37 100755
--- a/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h
+++ b/drivers/gpu/arm/mali/linux/mali_ukk_wrappers.h
@@ -59,6 +59,8 @@ int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_prof
int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs);
int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs);
+int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs);
+
int map_errcode( _mali_osk_errcode_t err );
#ifdef __cplusplus
diff --git a/drivers/gpu/arm/mali/platform/mali_platform.h b/drivers/gpu/arm/mali/platform/mali_platform.h
index 96812562127..b381070235e 100755..100644
--- a/drivers/gpu/arm/mali/platform/mali_platform.h
+++ b/drivers/gpu/arm/mali/platform/mali_platform.h
@@ -24,10 +24,14 @@
#define MALI_PLATFORM_SYSTEM 0
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** @brief Platform specific setup and initialisation of MALI
- *
+ *
* This is called from the entrypoint of the driver to initialize the platform
- * When using PMM, it is also called from the PMM start up to initialise the
+ * When using PMM, it is also called from the PMM start up to initialise the
* system PMU
*
* @param resource This is NULL when called on first driver start up, else it will
@@ -37,7 +41,7 @@
_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource);
/** @brief Platform specific deinitialisation of MALI
- *
+ *
* This is called on the exit of the driver to terminate the platform
* When using PMM, it is also called from the PMM termination code to clean up the
* system PMU
@@ -49,7 +53,7 @@ _mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource);
_mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type);
/** @brief Platform specific powerdown sequence of MALI
- *
+ *
* Called as part of platform init if there is no PMM support, else the
* PMM will call it.
*
@@ -60,7 +64,7 @@ _mali_osk_errcode_t mali_platform_deinit(_mali_osk_resource_type_t *type);
_mali_osk_errcode_t mali_platform_powerdown(u32 cores);
/** @brief Platform specific powerup sequence of MALI
- *
+ *
* Called as part of platform deinit if there is no PMM support, else the
* PMM will call it.
*
@@ -90,3 +94,7 @@ void mali_gpu_utilization_handler(u32 utilization);
u32 pmu_get_power_up_down_info(void);
#endif
#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/drivers/gpu/arm/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/gpu/arm/mali/timestamp-arm11-cc/mali_timestamp.h
index 96b709bc166..3279daede45 100755
--- a/drivers/gpu/arm/mali/timestamp-arm11-cc/mali_timestamp.h
+++ b/drivers/gpu/arm/mali/timestamp-arm11-cc/mali_timestamp.h
@@ -11,7 +11,7 @@
#ifndef __MALI_TIMESTAMP_H__
#define __MALI_TIMESTAMP_H__
-#include "mali_osk.h"
+#include "mali_osk.h"
MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void)
{
diff --git a/drivers/gpu/arm/mali/timestamp-default/mali_timestamp.h b/drivers/gpu/arm/mali/timestamp-default/mali_timestamp.h
index 11031d675ca..94b842a1008 100755
--- a/drivers/gpu/arm/mali/timestamp-default/mali_timestamp.h
+++ b/drivers/gpu/arm/mali/timestamp-default/mali_timestamp.h
@@ -11,7 +11,7 @@
#ifndef __MALI_TIMESTAMP_H__
#define __MALI_TIMESTAMP_H__
-#include "mali_osk.h"
+#include "mali_osk.h"
MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void)
{
diff --git a/drivers/gpu/arm/ump/Kconfig b/drivers/gpu/arm/ump/Kconfig
index db7b45b03de..62f1cec9311 100644
--- a/drivers/gpu/arm/ump/Kconfig
+++ b/drivers/gpu/arm/ump/Kconfig
@@ -1,6 +1,6 @@
config UMP
bool "Enable UMP(Unified Memory Provider)"
- default y
+ default n
---help---
This enables UMP memory provider
diff --git a/drivers/gpu/arm/ump/Makefile b/drivers/gpu/arm/ump/Makefile
index 7e2501d8087..9c1b214b998 100755
--- a/drivers/gpu/arm/ump/Makefile
+++ b/drivers/gpu/arm/ump/Makefile
@@ -22,7 +22,7 @@ UDD_FILE_PREFIX := drivers/gpu/arm/ump/
ifeq (($CONFIG_UMP_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
-
+EXTRA_CFLAGS += -DMALI_STATE_TRACKING=0
USING_MEMORY_TYPE ?=0 # 0: dedicated memory 1: OS memory
EXTRA_CFLAGS += -I$(UDD_FILE_PREFIX) -I$(UDD_FILE_PREFIX)/common -I$(UDD_FILE_PREFIX)/linux -I$(UDD_FILE_PREFIX)/../mali/common -I$(UDD_FILE_PREFIX)/../mali/linux -I$(UDD_FILE_PREFIX)/include
diff --git a/drivers/gpu/arm/ump/common/ump_kernel_api.c b/drivers/gpu/arm/ump/common/ump_kernel_api.c
index 719370c3de7..329a3ac115c 100755
--- a/drivers/gpu/arm/ump/common/ump_kernel_api.c
+++ b/drivers/gpu/arm/ump/common/ump_kernel_api.c
@@ -296,15 +296,21 @@ _mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction )
void _ump_ukk_msync( _ump_uk_msync_s *args )
{
ump_dd_mem * mem = NULL;
+ void *virtual = NULL;
+ u32 size = 0;
+ u32 offset = 0;
_mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
- _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
- if (NULL==mem)
+ if (NULL == mem)
{
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id));
return;
}
+ /* Ensure the memory doesn't dissapear when we are flushing it. */
+ ump_dd_reference_add(mem);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
/* Returns the cache settings back to Userspace */
args->is_cached=mem->is_cached;
@@ -313,17 +319,44 @@ void _ump_ukk_msync( _ump_uk_msync_s *args )
if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op )
{
DBG_MSG(3, ("_ump_ukk_msync READOUT ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached));
- return;
+ goto msync_release_and_return;
}
/* Nothing to do if the memory is not caches */
if ( 0==mem->is_cached )
{
DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op));
- return ;
+ goto msync_release_and_return;
+ }
+ DBG_MSG(3, ("_ump_ukk_msync FLUSHING ID: %u Enabled: %d OP: %d Address: 0x%08x Mapping: 0x%08x\n",
+ (ump_secure_id)args->secure_id, mem->is_cached, args->op, args->address, args->mapping));
+
+ if ( args->address )
+ {
+ virtual = ((u32)args->address);
+ offset = (u32)((args->address) - (args->mapping));
+ } else {
+ /* Flush entire mapping when no address is specified. */
+ virtual = args->mapping;
+ }
+ if ( args->size )
+ {
+ size = args->size;
+ } else {
+ /* Flush entire mapping when no size is specified. */
+ size = mem->size_bytes - offset;
+ }
+
+ if ( (offset + size) > mem->size_bytes )
+ {
+ DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes));
+ goto msync_release_and_return;
}
- DBG_MSG(3, ("_ump_ukk_msync FLUSHING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op));
/* The actual cache flush - Implemented for each OS*/
- _ump_osk_msync( mem , args->op);
+ _ump_osk_msync( mem, virtual, offset, size, args->op);
+
+msync_release_and_return:
+ ump_dd_reference_release(mem);
+ return;
}
diff --git a/drivers/gpu/arm/ump/common/ump_kernel_common.c b/drivers/gpu/arm/ump/common/ump_kernel_common.c
index 5575a5e3b1b..b99c3e7c7d2 100755
--- a/drivers/gpu/arm/ump/common/ump_kernel_common.c
+++ b/drivers/gpu/arm/ump/common/ump_kernel_common.c
@@ -280,12 +280,6 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
args->is_cached = 1;
DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id));
}
- else if ( args->is_cached)
- {
- mem->is_cached = 1;
- descriptor->is_cached = 1;
- DBG_MSG(3, ("Warning mapping UMP secure_id: %d. As cached, while it was allocated uncached.\n", args->secure_id));
- }
else
{
descriptor->is_cached = 0;
diff --git a/drivers/gpu/arm/ump/common/ump_osk.h b/drivers/gpu/arm/ump/common/ump_osk.h
index 73284f02b47..3e2be49b80d 100755
--- a/drivers/gpu/arm/ump/common/ump_osk.h
+++ b/drivers/gpu/arm/ump/common/ump_osk.h
@@ -39,7 +39,7 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript
void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor );
-void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op );
+void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op );
#ifdef __cplusplus
}
diff --git a/drivers/gpu/arm/ump/linux/license/gpl/ump_kernel_license.h b/drivers/gpu/arm/ump/linux/license/gpl/ump_kernel_license.h
index 17b930d2c57..a5f4b529f0d 100644
--- a/drivers/gpu/arm/ump/linux/license/gpl/ump_kernel_license.h
+++ b/drivers/gpu/arm/ump/linux/license/gpl/ump_kernel_license.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_dedicated.c
index e53ed444977..91440296459 100755
--- a/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_dedicated.c
+++ b/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_dedicated.c
@@ -222,6 +222,7 @@ static int block_allocator_allocate(void* ctx, ump_dd_mem * mem)
mem->backend_info = last_allocated;
up(&allocator->mutex);
+ mem->is_cached=0;
return 1;
}
diff --git a/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_os.c b/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_os.c
index 09f303f78f9..938cf496440 100755
--- a/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_os.c
+++ b/drivers/gpu/arm/ump/linux/ump_kernel_memory_backend_os.c
@@ -142,10 +142,11 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
if (is_cached)
{
- new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN );
+ /* Only allocate lowmem pages when using cached memory. */
+ new_page = alloc_page(GFP_USER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN);
} else
{
- new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD);
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
}
if (NULL == new_page)
{
diff --git a/drivers/gpu/arm/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/arm/ump/linux/ump_osk_low_level_mem.c
index 7a1c5e97886..3a3a6f78fcc 100755
--- a/drivers/gpu/arm/ump/linux/ump_osk_low_level_mem.c
+++ b/drivers/gpu/arm/ump/linux/ump_osk_low_level_mem.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <asm/memory.h>
+#include <asm/uaccess.h> /* to verify pointers from user space */
#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
@@ -206,38 +207,92 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript
}
-void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op )
+void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op )
{
int i;
- DBG_MSG(3, ("Flushing nr of blocks: %u. First: paddr: 0x%08x vaddr: 0x%08x size:%dB\n", mem->nr_blocks, mem->block_array[0].addr, phys_to_virt(mem->block_array[0].addr), mem->block_array[0].size));
+ const void *start_v, *end_v;
- /* TODO: Use args->size and args->address to select a subrange of this allocation to flush */
- for (i=0 ; i<mem->nr_blocks; i++)
+ DBG_MSG(3, ("Flushing nr of blocks: %u, size: %u. First: paddr: 0x%08x vaddr: 0x%08x offset: 0x%08x size:%uB\n",
+ mem->nr_blocks, mem->size_bytes, mem->block_array[0].addr, virt, offset, size));
+
+ /* Flush L1 using virtual address, the entire range in one go.
+ * Only flush if user space process has a valid write mapping on given address. */
+ if(access_ok(VERIFY_WRITE, virt, size))
+ {
+ start_v = (void *)virt;
+ end_v = (void *)(start_v + size - 1);
+ /* There is no dmac_clean_range, so the L1 is always flushed,
+ * also for UMP_MSYNC_CLEAN. */
+ dmac_flush_range(start_v, end_v);
+ }
+ else
{
- /* TODO: Find out which flush method is best of 1)Dma OR 2)Normal flush functions */
- /* TODO: Use args->op to select the flushing method: CLEAN_AND_INVALIDATE or CLEAN */
- /*#define USING_DMA_FLUSH*/
- #ifdef USING_DMA_FLUSH
- DEBUG_ASSERT( (PAGE_SIZE==mem->block_array[i].size));
- dma_map_page(NULL, pfn_to_page(mem->block_array[i].addr >> PAGE_SHIFT), 0, PAGE_SIZE, DMA_BIDIRECTIONAL );
- /*dma_unmap_page(NULL, mem->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL);*/
- #else
- /* Normal style flush */
- ump_dd_physical_block *block;
- u32 start_p, end_p;
- const void *start_v, *end_v;
- block = &mem->block_array[i];
-
- start_p = (u32)block->addr;
- start_v = phys_to_virt( start_p ) ;
-
- end_p = start_p + block->size-1;
- end_v = phys_to_virt( end_p ) ;
-
- dmac_flush_range(start_v, end_v);
- outer_flush_range(start_p, end_p);
- #endif
+ DBG_MSG(1, ("Attempt to flush %d@%x as part of ID %u rejected: there is no valid mapping.\n",
+ size, virt, mem->secure_id));
+ return;
}
- return ;
+ /* Flush L2 using physical addresses, block for block. */
+ for (i=0 ; i < mem->nr_blocks; i++)
+ {
+ u32 start_p, end_p;
+ ump_dd_physical_block *block;
+ block = &mem->block_array[i];
+
+ if(offset >= block->size)
+ {
+ offset -= block->size;
+ continue;
+ }
+
+ if(offset)
+ {
+ start_p = (u32)block->addr + offset;
+ /* We'll zero the offset later, after using it to calculate end_p. */
+ }
+ else
+ {
+ start_p = (u32)block->addr;
+ }
+
+ if(size < block->size - offset)
+ {
+ end_p = start_p + size - 1;
+ size = 0;
+ }
+ else
+ {
+ if(offset)
+ {
+ end_p = start_p + (block->size - offset - 1);
+ size -= block->size - offset;
+ offset = 0;
+ }
+ else
+ {
+ end_p = start_p + block->size - 1;
+ size -= block->size;
+ }
+ }
+
+ switch(op)
+ {
+ case _UMP_UK_MSYNC_CLEAN:
+ outer_clean_range(start_p, end_p);
+ break;
+ case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE:
+ outer_flush_range(start_p, end_p);
+ break;
+ default:
+ break;
+ }
+
+ if(0 == size)
+ {
+ /* Nothing left to flush. */
+ break;
+ }
+ }
+
+ return;
}
diff --git a/drivers/gpu/arm/ump/linux/ump_ukk_wrappers.c b/drivers/gpu/arm/ump/linux/ump_ukk_wrappers.c
index d14b631246c..d986e9f51d6 100755
--- a/drivers/gpu/arm/ump/linux/ump_ukk_wrappers.c
+++ b/drivers/gpu/arm/ump/linux/ump_ukk_wrappers.c
@@ -138,9 +138,9 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi
}
/*
- * IOCTL operation; Return size for specified UMP memory.
+ * IOCTL operation; Do cache maintenance on specified UMP memory.
*/
- int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data)
{
_ump_uk_msync_s user_interaction;