summaryrefslogtreecommitdiff
path: root/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common')
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c23
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h117
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c163
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c137
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c83
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h12
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c4
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c361
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h9
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c59
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c17
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h7
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c240
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h46
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c266
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h124
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h4
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h117
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h183
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h14
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h10
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c191
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h45
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c350
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h87
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h16
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c1
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h2
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c17
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h4
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c12
-rw-r--r--drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h31
40 files changed, 2011 insertions, 757 deletions
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c
index fc80a20c813..5416ca9ea4d 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.c
@@ -49,6 +49,7 @@ static void block_allocator_release(void * ctx, void * handle);
static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block);
static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block );
static void block_allocator_destroy(mali_physical_memory_allocator * allocator);
+static u32 block_allocator_stat(mali_physical_memory_allocator * allocator);
mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name)
{
@@ -97,6 +98,7 @@ mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u
allocator->allocate = block_allocator_allocate;
allocator->allocate_page_table_block = block_allocator_allocate_page_table_block;
allocator->destroy = block_allocator_destroy;
+ allocator->stat = block_allocator_stat;
allocator->ctx = info;
allocator->name = name;
@@ -275,7 +277,8 @@ static void block_allocator_release(void * ctx, void * handle)
_mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_free( allocation );}
+ _mali_osk_free( allocation );
+}
static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
@@ -368,3 +371,21 @@ static void block_allocator_release_page_table_block( mali_page_table_block *pag
_mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
}
+static u32 block_allocator_stat(mali_physical_memory_allocator * allocator)
+{
+ block_allocator * info;
+ block_info *block;
+ u32 free_blocks = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(allocator);
+
+ info = (block_allocator*)allocator->ctx;
+ block = info->first_free;
+
+ while(block)
+ {
+ free_blocks++;
+ block = block->next;
+ }
+ return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE;
+}
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h
index c3b5761e23a..d3f0f9be60a 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_block_allocator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h
new file mode 100644
index 00000000000..dee50a359a1
--- /dev/null
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_cinstr_profiling_events_m200.h
@@ -0,0 +1,117 @@
+/**
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms of
+ * such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _CINSTR_PROFILING_EVENTS_M200_H_
+#define _CINSTR_PROFILING_EVENTS_M200_H_
+
+/*
+ * The event ID is a 32 bit value consisting of different fields
+ * reserved, 4 bits, for future use
+ * event type, 4 bits, cinstr_profiling_event_type_t
+ * event channel, 8 bits, the source of the event.
+ * event data, 16 bit field, data depending on event type
+ */
+
+/**
+ * Specifies what kind of event this is
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_TYPE_SINGLE = 0 << 24,
+ MALI_PROFILING_EVENT_TYPE_START = 1 << 24,
+ MALI_PROFILING_EVENT_TYPE_STOP = 2 << 24,
+ MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24,
+ MALI_PROFILING_EVENT_TYPE_RESUME = 4 << 24,
+} cinstr_profiling_event_type_t;
+
+
+/**
+ * Secifies the channel/source of the event
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE = 0 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_GP0 = 1 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP0 = 5 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP1 = 6 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP2 = 7 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP3 = 8 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP4 = 9 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP5 = 10 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP6 = 11 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP7 = 12 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_GPU = 21 << 16,
+} cinstr_profiling_event_channel_t;
+
+
+#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16)
+#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16)
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME = 1,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH = 2,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS = 3,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4
+} cinstr_profiling_event_reason_single_sw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1,
+} cinstr_profiling_event_reason_start_stop_sw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT= 27,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC= 28,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33,
+} cinstr_profiling_event_reason_suspend_resume_sw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx)
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT = 1,
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH = 2,
+} cinstr_profiling_event_reason_single_hw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
+} cinstr_profiling_event_reason_single_gpu_t;
+
+#endif /*_CINSTR_PROFILING_EVENTS_M200_H_*/
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c
index e91abe120cb..dd357dec3b9 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_GP2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
@@ -15,8 +15,8 @@
#include "mali_kernel_rendercore.h"
#include "mali_osk.h"
#include "mali_osk_list.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
+#if MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
#endif
#if defined(USING_MALI400_L2_CACHE)
#include "mali_kernel_l2_cache.h"
@@ -80,7 +80,7 @@ typedef struct maligp_job
u32 perf_counter_l2_val1;
#endif
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if MALI_TIMELINE_PROFILING_ENABLED
u32 pid;
u32 tid;
#endif
@@ -102,7 +102,7 @@ static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resou
static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
#endif
#if MALI_STATE_TRACKING
-void maligp_subsystem_dump_state(void);
+u32 maligp_subsystem_dump_state(char *buf, u32 size);
#endif
/* Internal support functions */
@@ -583,8 +583,9 @@ static void maligp_initialize_registers_mgmt(mali_core_renderunit *core )
MALI_DEBUG_PRINT(6, ("Mali GP: maligp_initialize_registers_mgmt: %s\n", core->description)) ;
for(i=0 ; i< (sizeof(default_mgmt_regs)/sizeof(*default_mgmt_regs)) ; ++i)
{
- mali_core_renderunit_register_write(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value);
+ mali_core_renderunit_register_write_relaxed(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value);
}
+ _mali_osk_write_mem_barrier();
}
@@ -627,17 +628,43 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_
&(jobgp->user_input.frame_registers[0]),
sizeof(jobgp->user_input.frame_registers)/sizeof(jobgp->user_input.frame_registers[0]));
+#if MALI_TIMELINE_PROFILING_ENABLED
+ /*
+ * If the hardware counters are not turned on, ask the external profiler
+ * if they should be.
+ */
+ if (jobgp->user_input.perf_counter_flag == 0)
+ {
+ mali_bool src0_enabled = _mali_osk_profiling_query_hw_counter(COUNTER_VP_C0,
+ &(jobgp->user_input.perf_counter_src0));
+ mali_bool src1_enabled = _mali_osk_profiling_query_hw_counter(COUNTER_VP_C1,
+ &(jobgp->user_input.perf_counter_src1));
+
+ if (src0_enabled == MALI_TRUE)
+ {
+ jobgp->user_input.perf_counter_flag |=
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE;
+ }
+
+ if (src1_enabled == MALI_TRUE)
+ {
+ jobgp->user_input.perf_counter_flag |=
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE;
+ }
+ }
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
+
/* This selects which performance counters we are reading */
if ( 0 != jobgp->user_input.perf_counter_flag )
{
if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
{
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC,
jobgp->user_input.perf_counter_src0);
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE,
MALIGP2_REG_VAL_PERF_CNT_ENABLE);
@@ -645,12 +672,12 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_
if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
{
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC,
jobgp->user_input.perf_counter_src1);
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
MALIGP2_REG_VAL_PERF_CNT_ENABLE);
@@ -689,13 +716,13 @@ static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_
jobgp->have_extended_progress_checking = 1;
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC,
MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED
);
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
MALIGP2_REG_VAL_PERF_CNT_ENABLE);
@@ -704,14 +731,20 @@ 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,
MALIGP2_REG_ADDR_MGMT_CMD,
startcmd);
+ _mali_osk_write_mem_barrier();
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0);
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ jobgp->user_input.frame_builder_id, jobgp->user_input.flush_id, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0);
#endif
MALI_SUCCESS;
@@ -729,12 +762,16 @@ static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core)
irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
- MALI_DEBUG_PRINT(5, ("Mali GP: IRQ: %04x\n", irq_readout)) ;
if ( MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout )
{
/* Mask out all IRQs from this core until IRQ is handled */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK , MALIGP2_REG_VAL_IRQ_MASK_NONE);
+ mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
+#endif
+
/* We do need to handle this in a bottom half, return 1 */
return 1;
}
@@ -792,15 +829,17 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
if ( 0 != jobgp->is_stalled_waiting_for_more_memory )
{
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
/* Readback the performance counters */
if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
{
jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ /* Report the hardware counter values to the external profiler */
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, jobgp->perf_counter0);
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, jobgp->perf_counter1);
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
}
#if defined(USING_MALI400_L2_CACHE)
@@ -832,16 +871,19 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
}
#endif
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
+#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 ? */
else if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
{
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
#ifdef DEBUG
MALI_DEBUG_PRINT(4, ("Mali GP: Registers On job end:\n"));
maligp_print_regs(4, core);
@@ -859,6 +901,12 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
{
jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ /* Report the hardware counter values to the external profiler */
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, jobgp->perf_counter0);
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, jobgp->perf_counter1);
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
}
#if defined(USING_MALI400_L2_CACHE)
@@ -891,8 +939,25 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
#endif
}
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number),
+ jobgp->perf_counter0, jobgp->perf_counter1,
+ jobgp->user_input.perf_counter_src0 | (jobgp->user_input.perf_counter_src1 << 8)
+#if defined(USING_MALI400_L2_CACHE)
+ | (jobgp->user_input.perf_counter_l2_src0 << 16) | (jobgp->user_input.perf_counter_l2_src1 << 24),
+ jobgp->perf_counter_l2_val0,
+ jobgp->perf_counter_l2_val1
+#else
+ ,0, 0
+#endif
+ );
+#endif
+
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 ? */
@@ -910,8 +975,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
{
/* no progress detected, killed by the watchdog */
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
#endif
MALI_DEBUG_PRINT(1, ("Mali GP: SW-Timeout. Regs:\n"));
@@ -922,6 +987,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 */
@@ -932,8 +1002,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
_mali_osk_notification_t *notific;
_mali_uk_gp_job_suspended_s * suspended_job;
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
#endif
session = job->session;
@@ -1013,8 +1083,8 @@ static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
/* Else there must be some error */
else
{
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
#endif
MALI_DEBUG_PRINT(1, ("Mali GP: Core crashed? *IRQ: 0x%x Status: 0x%x\n", irq_readout, core_status ));
@@ -1022,6 +1092,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;
}
}
@@ -1032,7 +1105,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;
@@ -1071,7 +1144,7 @@ static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_co
jobgp->is_stalled_waiting_for_more_memory = 0;
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if MALI_TIMELINE_PROFILING_ENABLED
jobgp->pid = _mali_osk_get_pid();
jobgp->tid = _mali_osk_get_tid();
#endif
@@ -1154,6 +1227,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);
}
@@ -1197,12 +1280,13 @@ static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_se
mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]);
+ mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]);
+ mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]);
mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
+ _mali_osk_write_mem_barrier();
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0);
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0);
#endif
MALI_DEBUG_PRINT(4, ("GP resumed with new heap\n"));
@@ -1281,6 +1365,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;
@@ -1411,8 +1498,8 @@ _mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only )
#endif
#if MALI_STATE_TRACKING
-void maligp_subsystem_dump_state(void)
+u32 maligp_subsystem_dump_state(char *buf, u32 size)
{
- mali_core_renderunit_dump_state(&subsystem_maligp);
+ return mali_core_renderunit_dump_state(&subsystem_maligp, buf, size);
}
#endif
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c
index 0ac49379bea..d861b2288d3 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
@@ -15,8 +15,8 @@
#include "mali_kernel_core.h"
#include "regs/mali_200_regs.h"
#include "mali_kernel_rendercore.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
+#if MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
#endif
#ifdef USING_MALI400_L2_CACHE
#include "mali_kernel_l2_cache.h"
@@ -71,8 +71,8 @@ typedef struct mali200_job
u32 perf_counter_l2_val1_raw;
#endif
-#if MALI_TIMELINE_PROFILING_ENABLED
- u32 pid;
+#if MALI_TIMELINE_PROFILING_ENABLED
+ u32 pid;
u32 tid;
#endif
} mali200_job;
@@ -94,7 +94,7 @@ static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * reso
static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
#endif
#if MALI_STATE_TRACKING
-void mali200_subsystem_dump_state(void);
+u32 mali200_subsystem_dump_state(char *buf, u32 size);
#endif
/* Internal support functions */
@@ -572,17 +572,49 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali
&(job200->user_input.wb2_registers[0]),
MALI200_NUM_REGS_WBx);
+#if MALI_TIMELINE_PROFILING_ENABLED
+ /*
+ * If the hardware counters are not turned on, ask the external profiler
+ * if they should be.
+ */
+ if (job200->user_input.perf_counter_flag == 0)
+ {
+ /*
+ * Work out the correct counter offset to use. Each fragment processor
+ * has two hardware counters.
+ */
+ u32 counter0_offset = MALI_PROFILING_PP_CORE_COUNTER0_OFFSET(core->core_number);
+ u32 counter1_offset = MALI_PROFILING_PP_CORE_COUNTER1_OFFSET(core->core_number);
+
+ mali_bool src0_enabled = _mali_osk_profiling_query_hw_counter(counter0_offset,
+ &(job200->user_input.perf_counter_src0));
+ mali_bool src1_enabled = _mali_osk_profiling_query_hw_counter(counter1_offset,
+ &(job200->user_input.perf_counter_src1));
+
+ if (src0_enabled == MALI_TRUE)
+ {
+ job200->user_input.perf_counter_flag |=
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE;
+ }
+
+ if (src1_enabled == MALI_TRUE)
+ {
+ job200->user_input.perf_counter_flag |=
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE;
+ }
+ }
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
/* This selects which performance counters we are reading */
if ( 0 != job200->user_input.perf_counter_flag )
{
if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
{
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE,
MALI200_REG_VAL_PERF_CNT_ENABLE);
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC,
job200->user_input.perf_counter_src0);
@@ -591,11 +623,11 @@ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali
if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
{
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
MALI200_REG_VAL_PERF_CNT_ENABLE);
- mali_core_renderunit_register_write(
+ mali_core_renderunit_register_write_relaxed(
core,
MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC,
job200->user_input.perf_counter_src1);
@@ -630,16 +662,21 @@ 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,
MALI200_REG_ADDR_MGMT_CTRL_MGMT,
MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
+ _mali_osk_write_mem_barrier();
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job200->user_input.frame_builder_id, job200->user_input.flush_id, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid, 0, 0, 0);
#endif
MALI_SUCCESS;
@@ -653,13 +690,17 @@ static u32 subsystem_mali200_irq_handler_upper_half(mali_core_renderunit * core)
return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */
}
- MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_irq_handler_upper_half: %s\n", core->description)) ;
irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS);
if ( MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout )
{
/* Mask out all IRQs from this core until IRQ is handled */
mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
+#endif
+
return 1;
}
return 0;
@@ -710,16 +751,24 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES);
#endif
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
-#endif
-
if (0 != job200->user_input.perf_counter_flag )
{
if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
{
+#if MALI_TIMELINE_PROFILING_ENABLED
+ /* Work out the counter offsets for the core number */
+ u32 counter0_offset = MALI_PROFILING_PP_CORE_COUNTER0_OFFSET(core->core_number);
+ u32 counter1_offset = MALI_PROFILING_PP_CORE_COUNTER1_OFFSET(core->core_number);
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
+
job200->perf_counter0 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
job200->perf_counter1 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ /* Report the counter values */
+ _mali_osk_profiling_report_hw_counter(counter0_offset, job200->perf_counter0);
+ _mali_osk_profiling_report_hw_counter(counter1_offset, job200->perf_counter1);
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
}
#if defined(USING_MALI400_L2_CACHE)
@@ -757,6 +806,23 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
}
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number),
+ job200->perf_counter0, job200->perf_counter1,
+ job200->user_input.perf_counter_src0 | (job200->user_input.perf_counter_src1 << 8)
+#if defined(USING_MALI400_L2_CACHE)
+ | (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24),
+ job200->perf_counter_l2_val0, job200->perf_counter_l2_val1
+#else
+ , 0, 0
+#endif
+ );
+#endif
+
+
+#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,12 +831,17 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
((CORE_HANG_CHECK_TIMEOUT == core->state) && (current_tile_addr == job200->last_tile_list_addr))
)
{
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
#endif
/* 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? */
@@ -796,8 +867,8 @@ static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit
}
else
{
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
#endif
MALI_DEBUG_PRINT(1, ("Mali PP: Job: 0x%08x CRASH? Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n",
@@ -814,6 +885,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 */
}
}
@@ -824,7 +898,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;
@@ -872,7 +946,7 @@ static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_c
job_priority_set(job, job200->user_input.priority);
job_watchdog_set(job, job200->user_input.watchdog_msecs );
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if MALI_TIMELINE_PROFILING_ENABLED
job200->pid = _mali_osk_get_pid();
job200->tid = _mali_osk_get_tid();
#endif
@@ -954,6 +1028,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);
}
@@ -1026,6 +1110,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;
@@ -1180,8 +1267,8 @@ _mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_
#endif
#if MALI_STATE_TRACKING
-void mali200_subsystem_dump_state(void)
+u32 mali200_subsystem_dump_state(char *buf, u32 size)
{
- mali_core_renderunit_dump_state(&subsystem_mali200);
+ return mali_core_renderunit_dump_state(&subsystem_mali200, buf, size);
}
#endif
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h
index 08516c56a9f..1a9459bff2b 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c
index a40808bd2d8..f8ca4030fd8 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.c
@@ -52,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
@@ -105,15 +106,15 @@ static struct mali_kernel_subsystem mali_subsystem_core =
static struct mali_kernel_subsystem * subsystems[] =
{
- /* always initialize the hw subsystems first */
- /* always included */
- &mali_subsystem_memory,
#if USING_MALI_PMM
/* The PMM must be initialized before any cores - including L2 cache */
&mali_subsystem_pmm,
#endif
+ /* always included */
+ &mali_subsystem_memory,
+
/* The rendercore subsystem must be initialized before any subsystem based on the
* rendercores is started e.g. mali_subsystem_mali200 and mali_subsystem_gp2 */
&mali_subsystem_rendercore,
@@ -154,7 +155,7 @@ _mali_osk_errcode_t mali_kernel_constructor( void )
{
_mali_osk_errcode_t err;
- err = mali_platform_init(NULL);
+ err = mali_platform_init();
if (_MALI_OSK_ERR_OK != err) goto error1;
err = _mali_osk_init();
@@ -177,7 +178,7 @@ error3:
_mali_osk_term();
error2:
MALI_PRINT(("Mali device driver init failed\n"));
- if (_MALI_OSK_ERR_OK != mali_platform_deinit(NULL))
+ if (_MALI_OSK_ERR_OK != mali_platform_deinit())
{
MALI_PRINT(("Failed to deinit platform\n"));
}
@@ -191,10 +192,13 @@ void mali_kernel_destructor( void )
{
MALI_DEBUG_PRINT(2, ("\n"));
MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
+#if USING_MALI_PMM
+ malipmm_force_powerup();
+#endif
terminate_subsystems(); /* subsystems are responsible for their registered resources */
_mali_osk_term();
- if (_MALI_OSK_ERR_OK != mali_platform_deinit(NULL))
+ if (_MALI_OSK_ERR_OK != mali_platform_deinit())
{
MALI_PRINT(("Failed to deinit platform\n"));
}
@@ -304,6 +308,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)
@@ -341,6 +348,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)
{
@@ -406,25 +437,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);
@@ -873,20 +886,26 @@ _mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_boo
#endif
-
#if MALI_STATE_TRACKING
-void _mali_kernel_core_dump_state(void)
+u32 _mali_kernel_core_dump_state(char* buf, u32 size)
{
- int i;
+ int i, n;
+ char *original_buf = buf;
for (i = 0; i < SUBSYSTEMS_COUNT; ++i)
- {
+ {
if (NULL != subsystems[i]->dump_state)
{
- subsystems[i]->dump_state();
+ n = subsystems[i]->dump_state(buf, size);
+ size -= n;
+ buf += n;
}
- }
+ }
#if USING_MALI_PMM
- mali_pmm_dump_os_thread_state();
+ 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/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h
index 3819ecc5e1c..ced6b8fb118 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_core.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/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/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c
index 45c280edd6a..8b2a97d1545 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h
index f626aa59455..745be9235e7 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c
index fded5c93ab9..3c4c68d74bd 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c
@@ -495,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;
@@ -502,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/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c
index 8277fd1e1c6..60f5ebd77ec 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c
@@ -24,6 +24,8 @@
#include "mali_osk_indir_mmap.h"
#endif
+#error Support for non-MMU builds is no longer supported and is planned for removal.
+
/**
* Minimum memory allocation size
*/
@@ -55,7 +57,7 @@ typedef struct mali_memory_bank
_mali_osk_list_t list; /* links multiple banks together */
_mali_osk_lock_t *lock;
u32 base_addr; /* Mali seen address of bank */
- u32 cpu_usage_adjust; /* Adjustmen factor for what the CPU sees */
+ u32 cpu_usage_adjust; /* Adjustment factor for what the CPU sees */
u32 size; /* the effective size */
u32 real_size; /* the real size of the bank, as given by to the subsystem */
int min_order;
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c
index 7a48e27ede7..46eaea8eea5 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c
@@ -18,6 +18,7 @@
#include "mali_kernel_mem_os.h"
#include "mali_kernel_session_manager.h"
#include "mali_kernel_core.h"
+#include "mali_kernel_rendercore.h"
#if defined USING_MALI400_L2_CACHE
#include "mali_kernel_l2_cache.h"
@@ -205,6 +206,7 @@ typedef struct mali_kernel_memory_mmu
memory_session * active_session; /**< Active session, NULL if no session is active */
u32 usage_count; /**< Number of nested activations of the active session */
_mali_osk_list_t callbacks; /**< Callback registered for MMU idle notification */
+ void *core;
int in_page_fault_handler;
@@ -329,10 +331,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 +378,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);
@@ -533,7 +562,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);
@@ -544,6 +573,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);
}
@@ -630,8 +660,9 @@ static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_da
for (i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
{
/* mark each page table as not present */
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, sizeof(u32) * i, 0);
+ _mali_osk_mem_iowrite32_relaxed(session_data->page_directory_mapped, sizeof(u32) * i, 0);
}
+ _mali_osk_write_mem_barrier();
/* page_table_mapped[] is already set to NULL by _mali_osk_calloc call */
@@ -813,8 +844,9 @@ static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data)
for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
{
- _mali_osk_mem_iowrite32( mapping, i * sizeof(u32), data);
+ _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data);
}
+ _mali_osk_mem_barrier();
MALI_SUCCESS;
}
@@ -887,7 +919,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"));
@@ -992,7 +1024,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 */
@@ -1021,7 +1053,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"));
@@ -1157,6 +1189,7 @@ static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(v
{
mali_kernel_memory_mmu * mmu;
u32 int_stat;
+ mali_core_renderunit *core;
if (mali_benchmark) MALI_SUCCESS;
@@ -1164,15 +1197,19 @@ static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(v
MALI_DEBUG_ASSERT_POINTER(mmu);
+ core = (mali_core_renderunit *)mmu->core;
+ if(core && (CORE_OFF == core->state))
+ {
+ MALI_SUCCESS;
+ }
+
/* check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS);
if (0 == int_stat)
{
- MALI_DEBUG_PRINT(5, ("Ignoring shared interrupt\n"));
MALI_ERROR(_MALI_OSK_ERR_FAULT); /* no bits set, we are sharing the IRQ line and someone else caused the interrupt */
}
- MALI_DEBUG_PRINT(1, ("mali_kernel_memory_mmu_interrupt_handler_upper_half\n"));
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0);
@@ -1180,13 +1217,10 @@ static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(v
if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
{
- MALI_PRINT(("Page fault on %s\n", mmu->description));
-
_mali_osk_irq_schedulework(mmu->irq);
}
if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
{
- MALI_PRINT(("Bus read error on %s\n", mmu->description));
/* clear interrupt flag */
mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
/* reenable it */
@@ -1219,6 +1253,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);
@@ -1239,16 +1276,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);
@@ -1258,6 +1302,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;
@@ -1273,10 +1412,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);
}
@@ -1302,6 +1441,7 @@ static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data)
{
mali_kernel_memory_mmu * mmu;
u32 raw, fault_address, status;
+ mali_core_renderunit *core;
if (NULL == data)
{
@@ -1310,11 +1450,19 @@ static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data)
}
mmu = (mali_kernel_memory_mmu*)data;
-
MALI_DEBUG_PRINT(4, ("Locking subsystems\n"));
/* lock all subsystems */
_mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP0_LOCK_SUBSYSTEM, (u32)mmu);
+ /* Pointer to core holding this MMU */
+ core = (mali_core_renderunit *)mmu->core;
+
+ if(CORE_OFF == core->state)
+ {
+ _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
+ return;
+ }
+
raw = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_RAWSTAT);
status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
@@ -1404,7 +1552,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)
{
@@ -1575,6 +1722,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;
@@ -1594,14 +1742,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"));
@@ -1629,7 +1782,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;
@@ -1768,7 +1927,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;
@@ -1781,13 +1940,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"));
@@ -1815,7 +1979,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;
@@ -1870,6 +2040,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)
@@ -1941,7 +2113,14 @@ _mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *ma
_mali_osk_set_nonatomic_bit(0, alloc->usage_map);
- _mali_osk_list_add(&alloc->list, &page_table_cache.partial);
+ if (alloc->num_pages > 1)
+ {
+ _mali_osk_list_add(&alloc->list, &page_table_cache.partial);
+ }
+ else
+ {
+ _mali_osk_list_add(&alloc->list, &page_table_cache.full);
+ }
_mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
*table_page = alloc->pages.phys_base; /* return the first page */
@@ -2001,8 +2180,21 @@ void mali_mmu_release_table_page(u32 pa)
_mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
- /* transfer to partial list */
- _mali_osk_list_move(&alloc->list, &page_table_cache.partial);
+
+ if (0 == alloc->usage_count)
+ {
+ /* empty, release whole page alloc */
+ _mali_osk_list_del(&alloc->list);
+ alloc->pages.release(&alloc->pages);
+ _mali_osk_free(alloc->usage_map);
+ _mali_osk_free(alloc);
+ }
+ else
+ {
+ /* transfer to partial list */
+ _mali_osk_list_move(&alloc->list, &page_table_cache.partial);
+ }
+
_mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa));
return;
@@ -2014,6 +2206,17 @@ void mali_mmu_release_table_page(u32 pa)
_mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
}
+void mali_memory_core_mmu_owner(void *core, void *mmu_ptr)
+{
+ mali_kernel_memory_mmu *mmu;
+
+ MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ mmu = (mali_kernel_memory_mmu *)mmu_ptr;
+ mmu->core = core;
+}
+
void* mali_memory_core_mmu_lookup(u32 id)
{
mali_kernel_memory_mmu * mmu, * temp_mmu;
@@ -2030,24 +2233,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)
@@ -2517,8 +2706,9 @@ static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * des
for ( ; mali_address < mali_address_end; mali_address += MALI_MMU_PAGE_SIZE, current_phys_addr += MALI_MMU_PAGE_SIZE)
{
MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]);
- _mali_osk_mem_iowrite32(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
+ _mali_osk_mem_iowrite32_relaxed(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
}
+ _mali_osk_write_mem_barrier();
#if defined USING_MALI400_L2_CACHE
if (1 == has_active_mmus)
@@ -2574,7 +2764,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))
{
@@ -2587,12 +2777,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);
}
@@ -2618,7 +2805,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;
@@ -2641,24 +2828,34 @@ 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;
-
+ u32 status;
+ status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
+ if ( MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE == (status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) {
+ MALI_DEBUG_PRINT(2, ("Stopped stall attempt for mmu with id %d since it is in page fault mode.\n", mmu->id));
+ continue;
+ }
_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 */
@@ -2671,10 +2868,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 */
@@ -2682,6 +2881,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);
@@ -2695,20 +2895,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 */
@@ -2922,3 +3136,8 @@ _mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args )
MALI_IGNORE( args );
return _MALI_OSK_ERR_FAULT;
}
+
+u32 _mali_ukk_report_memory_usage(void)
+{
+ return mali_allocation_engine_memory_usage(physical_memory_allocators);
+}
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h
index a199fd66b5a..98610803978 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h
@@ -21,6 +21,15 @@
void* mali_memory_core_mmu_lookup(u32 id);
/**
+ * Set the core pointer of MMU to core owner of MMU
+ *
+ * @param core Core holding this MMU
+ * @param mmu_ptr The MMU whose core pointer needs set to core holding the MMU
+ *
+ */
+void mali_memory_core_mmu_owner(void *core, void *mmu_ptr);
+
+/**
* Activate a user session with its address space on the given MMU.
* If the session can't be activated due to that the MMU is busy and
* a callback pointer is given, the callback will be called once the MMU becomes idle.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c
index 845de935ec9..65958576c7a 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c
@@ -44,6 +44,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate_page_table_b
static void os_allocator_release(void * ctx, void * handle);
static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block );
static void os_allocator_destroy(mali_physical_memory_allocator * allocator);
+static u32 os_allocator_stat(mali_physical_memory_allocator * allocator);
mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name)
{
@@ -70,6 +71,7 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3
allocator->allocate = os_allocator_allocate;
allocator->allocate_page_table_block = os_allocator_allocate_page_table_block;
allocator->destroy = os_allocator_destroy;
+ allocator->stat = os_allocator_stat;
allocator->ctx = info;
allocator->name = name;
@@ -83,6 +85,13 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3
return NULL;
}
+static u32 os_allocator_stat(mali_physical_memory_allocator * allocator)
+{
+ os_allocator * info;
+ info = (os_allocator*)allocator->ctx;
+ return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE;
+}
+
static void os_allocator_destroy(mali_physical_memory_allocator * allocator)
{
os_allocator * info;
@@ -158,6 +167,9 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m
*offset += _MALI_OSK_CPU_PAGE_SIZE;
}
+ if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB Configured maximum OS memory usage: %d kB\n",
+ (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
+
/* Loop termination; decide on result */
if (pages_allocated)
{
@@ -167,7 +179,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m
/* 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.
*/
_mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE );
allocation->num_pages = pages_allocated;
@@ -231,10 +243,9 @@ static void os_allocator_release(void * ctx, void * handle)
static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
{
- const int allocation_order = 6; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */
- void *virt;
- const u32 pages_to_allocate = 1 << allocation_order;
- const u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
+ int allocation_order = 6; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */
+ void *virt = NULL;
+ u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
os_allocator * info;
u32 cpu_phys_base;
@@ -245,22 +256,48 @@ static mali_physical_memory_allocation_result os_allocator_allocate_page_table_b
/* Ensure we don't allocate more than we're supposed to from the ctx */
if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- if ( (info->num_pages_allocated + pages_to_allocate > info->num_pages_max) && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) )
+ /* if the number of pages to be requested lead to exceeding the memory
+ * limit in info->num_pages_max, reduce the size that is to be requested. */
+ while ( (info->num_pages_allocated + (1 << allocation_order) > info->num_pages_max)
+ && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) )
{
- /* return OOM */
- _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
- return MALI_MEM_ALLOC_NONE;
+ if ( allocation_order > 0 ) {
+ --allocation_order;
+ } else {
+ /* return OOM */
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+ return MALI_MEM_ALLOC_NONE;
+ }
}
- virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size );
+ /* try to allocate 2^(allocation_order) pages, if that fails, try
+ * allocation_order-1 to allocation_order 0 (inclusive) */
+ while ( allocation_order >= 0 )
+ {
+ size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
+ virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size );
+
+ if (NULL != virt) break;
+
+ --allocation_order;
+ }
if ( NULL == virt )
{
+ MALI_DEBUG_PRINT(1, ("Failed to allocate consistent memory. Is CONSISTENT_DMA_SIZE set too low?\n"));
/* return OOM */
_mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
return MALI_MEM_ALLOC_NONE;
}
+ MALI_DEBUG_PRINT(5, ("os_allocator_allocate_page_table_block: Allocation of order %i succeeded\n",
+ allocation_order));
+
+ /* we now know the size of the allocation since we know for what
+ * allocation_order the allocation succeeded */
+ size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
+
+
block->release = os_allocator_page_table_block_release;
block->ctx = ctx;
block->handle = (void*)allocation_order;
@@ -268,7 +305,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate_page_table_b
block->phys_base = cpu_phys_base - info->cpu_usage_adjust;
block->mapping = virt;
- info->num_pages_allocated += pages_to_allocate;
+ info->num_pages_allocated += (1 << allocation_order);
_mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h
index ff49f8a816a..0946169f79d 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c
index 3b4ace05f01..f6860c78a0b 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c
@@ -123,7 +123,7 @@ _mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engin
}
}
- MALI_DEBUG_PRINT(3, ("Non-fatal OOM, have to cleanup, stopped at offset %d for size %d\n", offset, descriptor->size));
+ MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024));
/* allocation failure, start cleanup */
/* loop over any potential partial allocations */
@@ -346,3 +346,18 @@ void mali_allocation_engine_report_allocators( mali_physical_memory_allocator *
}
}
+
+u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator)
+{
+ u32 sum = 0;
+ while(NULL != allocator)
+ {
+ /* Only count allocators that have set up a stat function. */
+ if(allocator->stat)
+ sum += allocator->stat(allocator);
+
+ allocator = allocator->next;
+ }
+
+ return sum;
+}
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h
index 80a2b4bb3a7..1ef7a089e95 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h
@@ -47,7 +47,7 @@ typedef enum
/**
* Supplying this 'magic' physical address requests that the OS allocate the
- * physical address at page commit time, rather than commiting a specific page
+ * physical address at page commit time, rather than committing a specific page
*/
#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1))
@@ -78,6 +78,7 @@ typedef struct mali_physical_memory_allocator
mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */
void (*destroy)(struct mali_physical_memory_allocator * allocator);
+ u32 (*stat)(struct mali_physical_memory_allocator * allocator);
void * ctx;
const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */
u32 alloc_order; /**< Order in which the allocations should happen */
@@ -96,7 +97,7 @@ typedef struct mali_kernel_mem_address_manager
* @param[in] off Offset from the start of range
* @param[in,out] phys_addr A pointer to the physical address of the start of the
* physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC
- * is used, this requests the function must allocate the physical page
+ * is used, this requests the function to allocate the physical page
* itself, and return it through the pointer provided.
* @param[in] size Length in bytes of the physical block
* @return _MALI_OSK_ERR_OK on success.
@@ -142,4 +143,6 @@ int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_pag
void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider);
+u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator);
+
#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c
deleted file mode 100644
index 07bb894b1b4..00000000000
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_ukk.h"
-#include "mali_timestamp.h"
-
-#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576
-
-typedef struct mali_profiling_entry
-{
- u64 timestamp;
- u32 event_id;
- u32 data[5];
-} mali_profiling_entry;
-
-
-typedef enum mali_profiling_state
-{
- MALI_PROFILING_STATE_UNINITIALIZED,
- MALI_PROFILING_STATE_IDLE,
- MALI_PROFILING_STATE_RUNNING,
- MALI_PROFILING_STATE_RETURN,
-} mali_profiling_state;
-
-
-static _mali_osk_lock_t *lock = NULL;
-static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
-static mali_profiling_entry* profile_entries = NULL;
-static u32 profile_entry_count = 0;
-static _mali_osk_atomic_t profile_insert_index;
-static _mali_osk_atomic_t profile_entries_written;
-
-
-_mali_osk_errcode_t _mali_profiling_init(void)
-{
- profile_entries = NULL;
- profile_entry_count = 0;
- _mali_osk_atomic_init(&profile_insert_index, 0);
- _mali_osk_atomic_init(&profile_entries_written, 0);
-
- lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 );
- if (NULL == lock)
- {
- return _MALI_OSK_ERR_FAULT;
- }
-
- prof_state = MALI_PROFILING_STATE_IDLE;
-
- return _MALI_OSK_ERR_OK;
-}
-
-void _mali_profiling_term(void)
-{
- prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
-
- /* wait for all elements to be completely inserted into array */
- while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written))
- {
- /* do nothing */;
- }
-
- if (NULL != profile_entries)
- {
- _mali_osk_free(profile_entries);
- profile_entries = NULL;
- }
-
- if (NULL != lock)
- {
- _mali_osk_lock_term(lock);
- lock = NULL;
- }
-}
-
-inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
-{
- u32 cur_index = _mali_osk_atomic_inc_return(&profile_insert_index) - 1;
-
- if (prof_state != MALI_PROFILING_STATE_RUNNING || cur_index >= profile_entry_count)
- {
- /*
- * Not in recording mode, or buffer is full
- * Decrement index again, and early out
- */
- _mali_osk_atomic_dec(&profile_insert_index);
- return _MALI_OSK_ERR_FAULT;
- }
-
- profile_entries[cur_index].timestamp = _mali_timestamp_get();
- profile_entries[cur_index].event_id = event_id;
- profile_entries[cur_index].data[0] = data0;
- profile_entries[cur_index].data[1] = data1;
- profile_entries[cur_index].data[2] = data2;
- profile_entries[cur_index].data[3] = data3;
- profile_entries[cur_index].data[4] = data4;
-
- _mali_osk_atomic_inc(&profile_entries_written);
-
- return _MALI_OSK_ERR_OK;
-}
-
-
-_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
-{
- _mali_osk_errcode_t ret;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_IDLE)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- if (args->limit > MALI_PROFILING_MAX_BUFFER_ENTRIES)
- {
- args->limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
- }
-
- profile_entries = _mali_osk_malloc(args->limit * sizeof(mali_profiling_entry));
- profile_entry_count = args->limit;
- if (NULL == profile_entries)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_NOMEM;
- }
-
- ret = _mali_timestamp_reset();
-
- if (ret == _MALI_OSK_ERR_OK)
- {
- prof_state = MALI_PROFILING_STATE_RUNNING;
- }
- else
- {
- _mali_osk_free(profile_entries);
- profile_entries = NULL;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return ret;
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args)
-{
- /* Always add process and thread identificator in the first two data elements for events from user space */
- return _mali_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]);
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_RUNNING)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- /* go into return state (user to retreive events), no more events will be added after this */
- prof_state = MALI_PROFILING_STATE_RETURN;
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
-
- /* wait for all elements to be completely inserted into array */
- while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written))
- {
- /* do nothing */;
- }
-
- args->count = _mali_osk_atomic_read(&profile_insert_index);
-
- return _MALI_OSK_ERR_OK;
-}
-
-
-_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args)
-{
- u32 index = args->index;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_RETURN)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- if (index >= _mali_osk_atomic_read(&profile_entries_written))
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_FAULT;
- }
-
- args->timestamp = profile_entries[index].timestamp;
- args->event_id = profile_entries[index].event_id;
- args->data[0] = profile_entries[index].data[0];
- args->data[1] = profile_entries[index].data[1];
- args->data[2] = profile_entries[index].data[2];
- args->data[3] = profile_entries[index].data[3];
- args->data[4] = profile_entries[index].data[4];
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_RETURN)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- prof_state = MALI_PROFILING_STATE_IDLE;
- profile_entry_count = 0;
- _mali_osk_atomic_init(&profile_insert_index, 0);
- _mali_osk_atomic_init(&profile_entries_written, 0);
- if (NULL != profile_entries)
- {
- _mali_osk_free(profile_entries);
- profile_entries = NULL;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_OK;
-}
-
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h
deleted file mode 100644
index 5d3aa6eb841..00000000000
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_profiling.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __MALI_KERNEL_PROFILING_H__
-#define __MALI_KERNEL_PROFILING_H__
-
-#if MALI_TIMELINE_PROFILING_ENABLED
-
-#include <../../../include/cinstr/mali_cinstr_profiling_events_m200.h>
-
-/**
- * Initialize the profiling module.
- * @return _MALI_OSK_ERR_OK on success, otherwise failure.
- */
-_mali_osk_errcode_t _mali_profiling_init(void);
-
-/*
- * Terminate the profiling module.
- */
-void _mali_profiling_term(void);
-
-/**
- * Add an profiling event
- *
- * @param event_id The event identificator.
- * @param data0 - First data parameter, depending on event_id specified.
- * @param data1 - Second data parameter, depending on event_id specified.
- * @param data2 - Third data parameter, depending on event_id specified.
- * @param data3 - Fourth data parameter, depending on event_id specified.
- * @param data4 - Fifth data parameter, depending on event_id specified.
- * @return _MALI_OSK_ERR_OK on success, otherwise failure.
- */
-_mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
-
-#endif /* MALI_TIMELINE_PROFILING_ENABLED */
-
-#endif /* __MALI_KERNEL_PROFILING_H__ */
-
-
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c
index 1db8f3ad5ab..f06b17bcb31 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
@@ -11,7 +11,6 @@
#include "mali_kernel_common.h"
#include "mali_kernel_core.h"
#include "mali_osk.h"
-#include "mali_kernel_pp.h"
#include "mali_kernel_subsystem.h"
#include "mali_kernel_rendercore.h"
#include "mali_osk_list.h"
@@ -19,7 +18,7 @@
#include "mali_kernel_utilization.h"
#endif
#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
+#include "mali_osk_profiling.h"
#endif
#if USING_MMU
#include "mali_kernel_mem_mmu.h"
@@ -42,6 +41,10 @@
int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
+#if MALI_TIMELINE_PROFILING_ENABLED
+int mali_boot_profiling = 0;
+#endif
+
/* Subsystem entrypoints: */
static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id);
static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id);
@@ -157,7 +160,7 @@ static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_id
#endif
#if MALI_TIMELINE_PROFILING_ENABLED
- if (_mali_profiling_init() != _MALI_OSK_ERR_OK)
+ if (_mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE) != _MALI_OSK_ERR_OK)
{
/* No biggie if we wheren't able to initialize the profiling */
MALI_PRINT_ERROR(("Rendercore: Failed to initialize profiling, feature will be unavailable\n")) ;
@@ -187,7 +190,7 @@ static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id)
MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex );
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_term();
+ _mali_osk_profiling_term();
#endif
#if MALI_GPU_UTILIZATION
@@ -258,104 +261,6 @@ static void rendercore_subsystem_broadcast_notification(mali_core_notification_m
* Functions inherited by the subsystems that extend the ''rendercore''.
*/
-u32 mali_core_renderunit_register_read(mali_core_renderunit *core, u32 relative_address)
-{
- u32 read_val;
-
- #if USING_MALI_PMM
- if( core->state == CORE_OFF )
- {
- MALI_PRINT_ERROR(("Core is OFF during read: Core:%s Addr:0x%04X\n",
- core->description,relative_address));
- return 0xDEADBEEF;
- }
- #endif
-
- MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
-
- if (mali_benchmark) return 0;
-
- if (relative_address >= core->size)
- {
- MALI_PRINT_ERROR(("Trying to read from illegal register: 0x%04x in core: %s\n",
- relative_address, core->description));
- return 0xDEADBEEF;
- }
-
- read_val = _mali_osk_mem_ioread32(core->registers_mapped, relative_address);
-
- MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read: Core:%s Addr:0x%04X Val:0x%08x\n",
- core->description,relative_address, read_val));
-
- return read_val;
-}
-
-void mali_core_renderunit_register_read_array(mali_core_renderunit *core,
- u32 relative_address,
- u32 * result_array,
- u32 nr_of_regs
- )
-{
- /* NOTE Do not use burst reads against the registers */
-
- u32 i;
-
- for(i=0; i<nr_of_regs; ++i)
- {
- result_array[i] = mali_core_renderunit_register_read(core, relative_address + i*4);
- }
-
- MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read_array: Core:%s Addr:0x%04X Nr_regs: %u\n",
- core->description,relative_address, nr_of_regs));
-}
-
-void mali_core_renderunit_register_write(mali_core_renderunit *core, u32 relative_address, u32 new_val)
-{
- #if USING_MALI_PMM
- if( core->state == CORE_OFF )
- {
- MALI_PRINT_ERROR(("Core is OFF during write: Core:%s Addr:0x%04X Val:0x%08x\n",
- core->description,relative_address, new_val));
- return;
- }
- #endif
-
- MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
-
- if (mali_benchmark) return;
-
- if (relative_address >= core->size)
- {
- MALI_PRINT_ERROR(("Trying to write to illegal register: 0x%04x in core: %s",
- relative_address, core->description));
- return;
- }
-
- MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write: Core:%s Addr:0x%04X Val:0x%08x\n",
- core->description,relative_address, new_val));
-
- _mali_osk_mem_iowrite32(core->registers_mapped, relative_address, new_val);
-}
-
-
-void mali_core_renderunit_register_write_array(mali_core_renderunit *core,
- u32 relative_address,
- u32 * source_array,
- u32 nr_of_regs)
-{
-
- u32 i;
- MALI_DEBUG_PRINT(6, ("Core: renderunit_register_write_array: Core:%s Addr:0x%04X Nr_regs: %u\n",
- core->description,relative_address, nr_of_regs));
-
- /* Do not use burst writes against the registers */
-
- for( i = 0; i< nr_of_regs; i++)
- {
- mali_core_renderunit_register_write(core, relative_address + i*4, source_array[i]);
- }
-}
-
void mali_core_renderunit_timeout_function_hang_detection(void *arg)
{
mali_bool action = MALI_FALSE;
@@ -364,8 +269,8 @@ void mali_core_renderunit_timeout_function_hang_detection(void *arg)
core = (mali_core_renderunit *) arg;
if( !core ) return;
- /* if NOT idle OR has TIMED_OUT */
- if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state)) )
+ /* if NOT idle OR NOT powered off OR has TIMED_OUT */
+ if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state) || (CORE_OFF == core->state)) )
{
core->state = CORE_HANG_CHECK_TIMEOUT;
action = MALI_TRUE;
@@ -615,6 +520,7 @@ void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys)
core = mali_core_renderunit_get_mali_core_nr(subsys,i);
if ( NULL==core ) break;
core->mmu = mali_memory_core_mmu_lookup(core->mmu_id);
+ mali_memory_core_mmu_owner(core,core->mmu);
MALI_DEBUG_PRINT(2, ("Attach mmu: 0x%x to core: %s in subsystem: %s\n", core->mmu, core->description, subsys->name));
}
@@ -871,11 +777,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)
@@ -1067,15 +973,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 );
@@ -1098,6 +996,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 */
@@ -1398,6 +1305,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) ) ;
@@ -1440,7 +1354,6 @@ void mali_core_session_close(mali_core_session * session)
core = _MALI_OSK_LIST_ENTRY(session->renderunits_working_head.next, mali_core_renderunit, list);
MALI_DEBUG_PRINT(3, ("Core: session_close: Core was working: %s\n", core->description )) ;
mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_SHUTDOWN );
- break;
}
_MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head); /* Not necessary - we will _mali_osk_free session*/
@@ -1749,6 +1662,11 @@ static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data)
core = (mali_core_renderunit * )data;
+ if(core && (CORE_OFF == core->state))
+ {
+ MALI_SUCCESS;
+ }
+
if ( (NULL == core) ||
(NULL == core->subsystem) ||
(NULL == core->subsystem->irq_handler_upper_half) )
@@ -1785,7 +1703,7 @@ static void mali_core_irq_handler_bottom_half ( void *data )
MALI_CHECK_SUBSYSTEM(subsystem);
MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
- if ( CORE_IDLE == core->state ) goto end_function;
+ if ( CORE_IDLE == core->state || CORE_OFF == core->state ) goto end_function;
MALI_DEBUG_PRINT(5, ("IRQ: handling irq from core %s\n", core->description )) ;
@@ -1856,7 +1774,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *s
{
/* Couldn't find the core */
MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 5, ("Core: Failed to find core to power down\n") );
+ MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power down\n") );
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
else if ( core->state != CORE_IDLE )
@@ -1896,7 +1814,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub
{
/* Couldn't find the core */
MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 5, ("Core: Failed to find core to power up\n") );
+ MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power up\n") );
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
else if( core->state != CORE_OFF )
@@ -1904,7 +1822,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub
/* This will usually happen because we are trying to cancel a pending power down */
core->pend_power_down = MALI_FALSE;
MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 5, ("Core: No powered off core to power up (cancelled power down?)\n") );
+ MALI_DEBUG_PRINT( 1, ("Core: No powered off core to power up (cancelled power down?)\n") );
MALI_ERROR(_MALI_OSK_ERR_BUSY);
}
@@ -1945,88 +1863,126 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub
#endif /* USING_MALI_PMM */
#if MALI_STATE_TRACKING
-void mali_core_renderunit_dump_state(mali_core_subsystem* subsystem)
+u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size)
{
- u32 i;
+ 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 );
- MALI_PRINT(("Subsystem;\n"));
- MALI_PRINT((" Name: %s\n", subsystem->name));
+ 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++)
{
- MALI_PRINT((" Core: #%u\n", subsystem->mali_core_array[i]->core_number));
- MALI_PRINT((" Description: %s\n", subsystem->mali_core_array[i]->description));
+ 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:
- MALI_PRINT((" State: CORE_IDLE\n"));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_IDLE\n");
break;
case CORE_WORKING:
- MALI_PRINT((" State: CORE_WORKING\n"));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WORKING\n");
break;
case CORE_WATCHDOG_TIMEOUT:
- MALI_PRINT((" State: CORE_WATCHDOG_TIMEOUT\n"));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WATCHDOG_TIMEOUT\n");
break;
case CORE_POLL:
- MALI_PRINT((" State: CORE_POLL\n"));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_POLL\n");
break;
case CORE_HANG_CHECK_TIMEOUT:
- MALI_PRINT((" State: CORE_HANG_CHECK_TIMEOUT\n"));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_HANG_CHECK_TIMEOUT\n");
break;
case CORE_OFF:
- MALI_PRINT((" State: CORE_OFF\n"));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_OFF\n");
break;
default:
- MALI_PRINT((" State: Unknown (0x%X)\n", subsystem->mali_core_array[i]->state));
+ len += _mali_osk_snprintf(buf + len, size - len, " State: Unknown (0x%X)\n",
+ subsystem->mali_core_array[i]->state);
break;
}
- MALI_PRINT((" Current job: 0x%x\n", (u32)(subsystem->mali_core_array[i]->current_job)));
- MALI_PRINT((" Core version: 0x%x\n", subsystem->mali_core_array[i]->core_version));
+ 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
- MALI_PRINT((" PMM id: 0x%x\n", subsystem->mali_core_array[i]->pmm_id));
- MALI_PRINT((" Power down requested: %s\n", subsystem->mali_core_array[i]->pend_power_down ? "TRUE" : "FALSE"));
+ 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
}
- MALI_PRINT((" Cores on idle list:\n"));
+ 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)
{
- MALI_PRINT((" Core #%u\n", core->core_number));
+ len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number);
}
- MALI_PRINT((" Cores on off list:\n"));
+ 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)
{
- MALI_PRINT((" Core #%u\n", core->core_number));
+ len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number);
}
- MALI_PRINT((" Connected sessions:\n"));
+ 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)
{
- MALI_PRINT((" Session 0x%X:\n", (u32)session));
- MALI_PRINT((" Waiting job: 0x%X\n", (u32)session->job_waiting_to_run));
- MALI_PRINT((" Notification queue: %s\n", _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY"));
- }
-
- MALI_PRINT((" Waiting sessions sum all priorities: %u\n", subsystem->awaiting_sessions_sum_all_priorities));
+ 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++)
{
- MALI_PRINT((" 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, " 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)
{
- MALI_PRINT((" Session 0x%X:\n", (u32)session));
- MALI_PRINT((" Waiting job: 0x%X\n", (u32)session->job_waiting_to_run));
- MALI_PRINT((" Notification queue: %s\n", _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY"));
+ 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/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h
index 94bce94d4e1..c4a13796ba9 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_rendercore.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/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;
/*
@@ -309,11 +317,117 @@ typedef struct register_array_user
if ( rendercores_global_mutex_owner != _mali_osk_get_tid() ) MALI_PRINT_ERROR(("Owner mismatch"));\
} while (0)
+MALI_STATIC_INLINE _mali_osk_errcode_t mali_core_renderunit_register_rw_check(mali_core_renderunit *core,
+ u32 relative_address)
+{
+#if USING_MALI_PMM
+ if( core->state == CORE_OFF )
+ {
+ MALI_PRINT_ERROR(("Core is OFF during access: Core: %s Addr: 0x%04X\n",
+ core->description,relative_address));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+#endif
+
+ MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
+
+ if (mali_benchmark) MALI_ERROR(_MALI_OSK_ERR_FAULT);
+
+ MALI_DEBUG_CODE(if (relative_address >= core->size)
+ {
+ MALI_PRINT_ERROR(("Trying to access illegal register: 0x%04x in core: %s",
+ relative_address, core->description));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ })
+
+ MALI_SUCCESS;
+}
-u32 mali_core_renderunit_register_read(struct mali_core_renderunit *core, u32 relative_address);
-void mali_core_renderunit_register_read_array(struct mali_core_renderunit *core, u32 relative_address, u32 * result_array, u32 nr_of_regs);
-void mali_core_renderunit_register_write(struct mali_core_renderunit *core, u32 relative_address, u32 new_val);
-void mali_core_renderunit_register_write_array(struct mali_core_renderunit *core, u32 relative_address, u32 * write_array, u32 nr_of_regs);
+
+MALI_STATIC_INLINE u32 mali_core_renderunit_register_read(struct mali_core_renderunit *core, u32 relative_address)
+{
+ u32 read_val;
+
+ if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address))
+ return 0xDEADBEEF;
+
+ read_val = _mali_osk_mem_ioread32(core->registers_mapped, relative_address);
+
+ MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read: Core:%s Addr:0x%04X Val:0x%08x\n",
+ core->description,relative_address, read_val));
+
+ return read_val;
+}
+
+MALI_STATIC_INLINE void mali_core_renderunit_register_read_array(struct mali_core_renderunit *core,
+ u32 relative_address,
+ u32 * result_array,
+ u32 nr_of_regs)
+{
+ /* NOTE Do not use burst reads against the registers */
+ u32 i;
+
+ MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read_array: Core:%s Addr:0x%04X Nr_regs: %u\n",
+ core->description,relative_address, nr_of_regs));
+
+ for(i=0; i<nr_of_regs; ++i)
+ {
+ result_array[i] = mali_core_renderunit_register_read(core, relative_address + i*4);
+ }
+}
+
+/*
+ * Write to a core register, and bypass implied memory barriers.
+ *
+ * On some systems, _mali_osk_mem_iowrite32() implies a memory barrier. This
+ * can be a performance problem when doing many writes in sequence.
+ *
+ * When using this function, ensure proper barriers are put in palce. Most
+ * likely a _mali_osk_mem_barrier() is needed after all related writes are
+ * completed.
+ *
+ */
+MALI_STATIC_INLINE void mali_core_renderunit_register_write_relaxed(mali_core_renderunit *core,
+ u32 relative_address,
+ u32 new_val)
+{
+ if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address))
+ return;
+
+ MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write_relaxed: Core:%s Addr:0x%04X Val:0x%08x\n",
+ core->description,relative_address, new_val));
+
+ _mali_osk_mem_iowrite32_relaxed(core->registers_mapped, relative_address, new_val);
+}
+
+MALI_STATIC_INLINE void mali_core_renderunit_register_write(struct mali_core_renderunit *core,
+ u32 relative_address,
+ u32 new_val)
+{
+ MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write: Core:%s Addr:0x%04X Val:0x%08x\n",
+ core->description,relative_address, new_val));
+
+ if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address))
+ return;
+
+ _mali_osk_mem_iowrite32(core->registers_mapped, relative_address, new_val);
+}
+
+MALI_STATIC_INLINE void mali_core_renderunit_register_write_array(struct mali_core_renderunit *core,
+ u32 relative_address,
+ u32 * write_array,
+ u32 nr_of_regs)
+{
+ u32 i;
+ MALI_DEBUG_PRINT(6, ("Core: renderunit_register_write_array: Core:%s Addr:0x%04X Nr_regs: %u\n",
+ core->description,relative_address, nr_of_regs));
+
+ /* Do not use burst writes against the registers */
+ for( i = 0; i< nr_of_regs; i++)
+ {
+ mali_core_renderunit_register_write_relaxed(core, relative_address + i*4, write_array[i]);
+ }
+}
_mali_osk_errcode_t mali_core_renderunit_init(struct mali_core_renderunit * core);
void mali_core_renderunit_term(struct mali_core_renderunit * core);
@@ -349,7 +463,7 @@ _mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *sub
#endif
#if MALI_STATE_TRACKING
-void mali_core_renderunit_dump_state(mali_core_subsystem* subsystem);
+u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size);
#endif
#endif /* __MALI_RENDERCORE_H__ */
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h
index ce290d0c1c9..8cc41d7f937 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_session_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h
index e8c6530668c..9efba566bd9 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_kernel_subsystem.h
@@ -74,7 +74,7 @@ typedef struct mali_kernel_subsystem
#if MALI_STATE_TRACKING
/** Dump the current state of the subsystem */
- void (*dump_state)(void);
+ u32 (*dump_state)(char *buf, u32 size);
#endif
} mali_kernel_subsystem;
@@ -100,7 +100,7 @@ void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_messag
/**
* Tell all subsystems to dump their current state
*/
-void _mali_kernel_core_dump_state(void);
+u32 _mali_kernel_core_dump_state(char *buf, u32 size);
#endif
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h
index c35d90577a3..35737e68cb3 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
@@ -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 */
@@ -785,6 +795,10 @@ void _mali_osk_atomic_term( _mali_osk_atomic_t *atom );
* Returns a buffer capable of containing at least \a n elements of \a size
* bytes each. The buffer is initialized to zero.
*
+ * If there is a need for a bigger block of memory (16KB or bigger), then
+ * consider to use _mali_osk_vmalloc() instead, as this function might
+ * map down to a OS function with size limitations.
+ *
* The buffer is suitably aligned for storage and subsequent access of every
* type that the compiler supports. Therefore, the pointer to the start of the
* buffer may be cast into any pointer type, and be subsequently accessed from
@@ -807,6 +821,10 @@ void *_mali_osk_calloc( u32 n, u32 size );
* Returns a buffer capable of containing at least \a size bytes. The
* contents of the buffer are undefined.
*
+ * If there is a need for a bigger block of memory (16KB or bigger), then
+ * consider to use _mali_osk_vmalloc() instead, as this function might
+ * map down to a OS function with size limitations.
+ *
* The buffer is suitably aligned for storage and subsequent access of every
* type that the compiler supports. Therefore, the pointer to the start of the
* buffer may be cast into any pointer type, and be subsequently accessed from
@@ -840,6 +858,46 @@ void *_mali_osk_malloc( u32 size );
*/
void _mali_osk_free( void *ptr );
+/** @brief Allocate memory.
+ *
+ * Returns a buffer capable of containing at least \a size bytes. The
+ * contents of the buffer are undefined.
+ *
+ * This function is potentially slower than _mali_osk_malloc() and _mali_osk_calloc(),
+ * but do support bigger sizes.
+ *
+ * The buffer is suitably aligned for storage and subsequent access of every
+ * type that the compiler supports. Therefore, the pointer to the start of the
+ * buffer may be cast into any pointer type, and be subsequently accessed from
+ * such a pointer, without loss of information.
+ *
+ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
+ * Failure to do so will cause a memory leak.
+ *
+ * @note Most toolchains supply memory allocation functions that meet the
+ * compiler's alignment requirements.
+ *
+ * Remember to free memory using _mali_osk_free().
+ * @param size Number of bytes to allocate
+ * @return On success, the buffer allocated. NULL on failure.
+ */
+void *_mali_osk_valloc( u32 size );
+
+/** @brief Free memory.
+ *
+ * Reclaims the buffer pointed to by the parameter \a ptr for the system.
+ * All memory returned from _mali_osk_valloc() must be freed before the
+ * application exits. Otherwise a memory leak will occur.
+ *
+ * Memory must be freed once. It is an error to free the same non-NULL pointer
+ * more than once.
+ *
+ * It is legal to free the NULL pointer.
+ *
+ * @param ptr Pointer to buffer to free
+ */
+void _mali_osk_vfree( void *ptr );
+
/** @brief Copies memory.
*
* Copies the \a len bytes from the buffer pointed by the parameter \a src
@@ -871,7 +929,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 +937,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 );
@@ -971,12 +1029,18 @@ void _mali_osk_lock_term( _mali_osk_lock_t *lock );
/** @brief Issue a memory barrier
*
- * This defines an arbitrary memory barrier operation, which affects memory
- * mapped by _mali_osk_mem_mapregion. It will not be needed for memory
- * mapped through _mali_osk_mem_mapioregion.
+ * This defines an arbitrary memory barrier operation, which forces an ordering constraint
+ * on memory read and write operations.
*/
void _mali_osk_mem_barrier( void );
+/** @brief Issue a write memory barrier
+ *
+ * This defines an write memory barrier operation which forces an ordering constraint
+ * on memory write operations.
+ */
+void _mali_osk_write_mem_barrier( void );
+
/** @brief Map a physically contiguous region into kernel space
*
* This is primarily used for mapping in registers from resources, and Mali-MMU
@@ -1120,7 +1184,21 @@ void _mali_osk_mem_unreqregion( u32 phys, u32 size );
u32 _mali_osk_mem_ioread32( volatile mali_io_address mapping, u32 offset );
/** @brief Write to a location currently mapped in through
- * _mali_osk_mem_mapioregion
+ * _mali_osk_mem_mapioregion without memory barriers
+ *
+ * This write a 32-bit word to a 32-bit aligned location without using memory barrier.
+ * It is a programming error to provide unaligned locations, or to write to memory that is not
+ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
+ * _mali_osk_mem_allocioregion().
+ *
+ * @param mapping Mali IO address to write to
+ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
+ * @param val the 32-bit word to write.
+ */
+void _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val );
+
+/** @brief Write to a location currently mapped in through
+ * _mali_osk_mem_mapioregion with write memory barrier
*
* This write a 32-bit word to a 32-bit aligned location. It is a programming
* error to provide unaligned locations, or to write to memory that is not
@@ -1147,7 +1225,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 );
@@ -1522,7 +1600,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 );
@@ -1559,6 +1637,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.
@@ -1594,8 +1684,13 @@ u32 _mali_osk_get_pid(void);
*/
u32 _mali_osk_get_tid(void);
-/** @} */ /* end group _mali_osk_miscellaneous */
+/** @brief Return a handle to the current task.
+ *
+ * @return An OS-specific handle to the current task.
+ */
+void * _mali_osk_get_task(void);
+/** @} */ /* end group _mali_osk_miscellaneous */
/** @} */ /* end group osuapi */
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h
index 28026ba1e6d..f262f7dad37 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_bitops.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h
new file mode 100644
index 00000000000..a291bd1965b
--- /dev/null
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_osk_profiling.h
@@ -0,0 +1,183 @@
+/**
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms of
+ * such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_OSK_PROFILING_H__
+#define __MALI_OSK_PROFILING_H__
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#include "mali_linux_trace.h"
+#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */
+
+#include "mali_cinstr_profiling_events_m200.h"
+
+#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576
+
+#define MALI_PROFILING_PP_CORE_COUNTER0_OFFSET(core_number) (((core_number) * 2) + COUNTER_FP0_C0)
+#define MALI_PROFILING_PP_CORE_COUNTER1_OFFSET(core_number) (((core_number) * 2) + COUNTER_FP0_C1)
+
+/** @defgroup _mali_osk_profiling External profiling connectivity
+ * @{ */
+
+/**
+ * Initialize the profiling module.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start);
+
+/*
+ * Terminate the profiling module.
+ */
+void _mali_osk_profiling_term(void);
+
+/**
+ * Start recording profiling data
+ *
+ * The specified limit will determine how large the capture buffer is.
+ * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver.
+ *
+ * @param limit The desired maximum number of events to record on input, the actual maximum on output.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
+
+/**
+ * Add an profiling event
+ *
+ * @param event_id The event identificator.
+ * @param data0 First data parameter, depending on event_id specified.
+ * @param data1 Second data parameter, depending on event_id specified.
+ * @param data2 Third data parameter, depending on event_id specified.
+ * @param data3 Fourth data parameter, depending on event_id specified.
+ * @param data4 Fifth data parameter, depending on event_id specified.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+/*
+ * On platforms where we are using Linux tracepoints and we aren't forcing
+ * internal profiling we can call through to the tracepoint directly and
+ * avoid the overhead of the function call.
+ */
+#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) \
+ trace_mali_timeline_event((event_id), (data0), (data1), (u32)_mali_osk_get_task(), (data3), (data4))
+#else
+void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
+#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */
+
+/**
+ * Report a hardware counter event.
+ *
+ * @param counter_id The ID of the counter.
+ * @param value The value of the counter.
+ */
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+/*
+ * On platforms where we are using Linux tracepoints and we aren't forcing
+ * internal profiling we can call through to the tracepoint directly and
+ * avoid the overhead of the function call.
+ */
+#define _mali_osk_profiling_report_hw_counter trace_mali_hw_counter
+#else
+void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value);
+#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */
+
+/**
+ * Query a hardware counter. Given a counter ID, check which event the
+ * counter should report and update the given pointer with that event
+ * number before returning MALI_TRUE. If the counter has been disabled
+ * by the profiling tool, returns MALI_FALSE and does not update the
+ * pointer.
+ *
+ * MALI_FALSE is also returned if the counter is not a valid hardware
+ * counter ID. In this case the event value is not updated.
+ *
+ * @param counter_id The counter ID.
+ * @param event_id A pointer to a u32 value that will be updated with
+ * the event ID that should be counted, should the counter have been
+ * enabled by the profiling tool.
+ *
+ * @return MALI_TRUE if the counter should be enabled, MALI_FALSE otherwise.
+ */
+mali_bool _mali_osk_profiling_query_hw_counter(u32 counter_id, u32 *event_id);
+
+/**
+ * Stop recording profiling data
+ *
+ * @param count Returns the number of recorded events.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count);
+
+/**
+ * Retrieves the number of events that can be retrieved
+ *
+ * @return The number of recorded events that can be retrieved.
+ */
+u32 _mali_osk_profiling_get_count(void);
+
+/**
+ * Retrieve an event
+ *
+ * @param index Event index (start with 0 and continue until this function fails to retrieve all events)
+ * @param timestamp The timestamp for the retrieved event will be stored here.
+ * @param event_id The event ID for the retrieved event will be stored here.
+ * @param data The 5 data values for the retrieved event will be stored here.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
+
+/**
+ * Clear the recorded buffer.
+ *
+ * This is needed in order to start another recording.
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_clear(void);
+
+/**
+ * Checks if a recording of profiling data is in progress
+ *
+ * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not
+ */
+mali_bool _mali_osk_profiling_is_recording(void);
+
+/**
+ * Checks if profiling data is available for retrival
+ *
+ * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not
+ */
+mali_bool _mali_osk_profiling_have_recording(void);
+
+/**
+ * Enable or disable profiling events as default for new sessions (applications)
+ *
+ * @param enable MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE
+ */
+void _mali_osk_profiling_set_default_enable_state(mali_bool enable);
+
+/**
+ * Get current default enable state for new sessions (applications)
+ *
+ * @return MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE
+ */
+mali_bool _mali_osk_profiling_get_default_enable_state(void);
+
+/** @} */ /* end group _mali_osk_profiling */
+
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
+
+#endif /* __MALI_OSK_PROFILING_H__ */
+
+
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h
index 9a1583658c9..433de1fc537 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_uk_types.h
@@ -121,6 +121,7 @@ typedef enum
_MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */
_MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */
_MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */
+ _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */
#if USING_MALI_PMM
/** Power Management Module Functions */
@@ -461,6 +462,8 @@ typedef struct
u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */
u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */
u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */
+ u32 frame_builder_id; /**< [in] id of the originating frame builder */
+ u32 flush_id; /**< [in] flush id within the originating frame builder */
} _mali_uk_gp_start_job_s;
#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */
@@ -574,6 +577,8 @@ typedef struct
u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */
u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */
u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */
+ u32 frame_builder_id; /**< [in] id of the originating frame builder */
+ u32 flush_id; /**< [in] flush id within the originating frame builder */
} _mali_uk_pp_start_job_s;
/** @} */ /* end group _mali_uk_ppstartjob_s */
@@ -733,7 +738,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 8
+#define _MALI_API_VERSION 9
#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
/**
@@ -1019,6 +1024,11 @@ typedef struct
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
} _mali_uk_profiling_clear_s;
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 enable_events; /**< [out] 1 if user space process should generate events, 0 if not */
+} _mali_uk_profiling_get_config_s;
/** @} */ /* end group _mali_uk_gp */
@@ -1102,7 +1112,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 */
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h
index d066046901d..c70dccc3c20 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/mali_ukk.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/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);
@@ -680,6 +680,13 @@ _mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s
*/
_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args);
+/** @brief Get the profiling config applicable for calling process.
+ *
+ * @param args see _mali_uk_profiling_get_config_s in "mali_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args);
+
+
/** @} */ /* end group _mali_uk_profiling */
#endif
@@ -702,6 +709,7 @@ _mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *
/** @} */ /* end group uddapi */
+u32 _mali_ukk_report_memory_usage(void);
#ifdef __cplusplus
}
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
index eeb29589ddc..1b17a9ffe95 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.c
@@ -23,6 +23,7 @@
#include "mali_pmm_system.h"
#include "mali_pmm_state.h"
#include "mali_pmm_policy.h"
+#include "mali_pmm_pmu.h"
#include "mali_platform.h"
/* Internal PMM subsystem state */
@@ -64,7 +65,7 @@ _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
- void malipmm_subsystem_dump_state( void );
+u32 malipmm_subsystem_dump_state( char *buf, u32 size );
#endif
@@ -295,7 +296,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[] = {
@@ -307,19 +308,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",
@@ -335,6 +323,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;
@@ -480,11 +497,11 @@ _mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource)
/* Set up assumes all values are initialized to NULL or MALI_FALSE, so
* we can exit halfway through set up and perform clean up
*/
-#if !MALI_PMM_NO_PMU
- if( mali_platform_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup;
- pmm_state->pmu_initialized = MALI_TRUE;
-#endif
+#if USING_MALI_PMU
+ if( mali_pmm_pmu_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup;
+ pmm_state->pmu_initialized = MALI_TRUE;
+#endif
pmm_state->queue = _mali_osk_notification_queue_init();
if( !pmm_state->queue ) goto pmm_fail_cleanup;
@@ -518,12 +535,18 @@ pmm_fail_cleanup:
MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") );
if( pmm_state )
{
- _mali_osk_resource_type_t t = PMU;
if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock );
if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq );
if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue );
if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue );
- if( pmm_state->pmu_initialized ) ( mali_platform_deinit(&t) );
+#if USING_MALI_PMU
+ if( pmm_state->pmu_initialized )
+ {
+ _mali_osk_resource_type_t t = PMU;
+ mali_pmm_pmu_deinit(&t);
+ }
+#endif /* USING_MALI_PMU */
+
_mali_osk_free(pmm_state);
pmm_state = NULL;
}
@@ -547,6 +570,23 @@ _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;
+ MALI_PMM_UNLOCK(pmm);
+
+ /* flush PMM workqueue */
+ _mali_osk_flush_workqueue( pmm->irq );
+
+ if (pmm->cores_powered == 0)
+ {
+ malipmm_powerup(pmm->cores_registered);
+ }
+}
+
void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
{
/* Check this is the right system */
@@ -555,7 +595,6 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
if( pmm_state )
{
- _mali_osk_resource_type_t t = PMU;
#if PMM_OS_TEST
power_test_end();
#endif
@@ -569,11 +608,20 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
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 );
_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);
+ if (pmm_state->cores_registered) malipmm_powerdown(pmm_state->cores_registered,MALI_POWER_MODE_LIGHT_SLEEP);
+#if USING_MALI_PMU
+ if( pmm_state->pmu_initialized )
+ {
+ _mali_osk_resource_type_t t = PMU;
+ mali_pmm_pmu_deinit(&t);
+ }
+#endif /* USING_MALI_PMU */
+
_mali_osk_atomic_term( &(pmm_state->messages_queued) );
MALI_PMM_LOCK_TERM(pmm_state);
_mali_osk_free(pmm_state);
@@ -583,6 +631,47 @@ void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") );
}
+_mali_osk_errcode_t malipmm_powerup( u32 cores )
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+ _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
+
+ /* If all the cores are powered down, power up the MALI */
+ if (pmm->cores_powered == 0)
+ {
+ mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+ /* Initiate the power up */
+ _mali_osk_pmm_dev_activate();
+#endif
+ }
+
+#if USING_MALI_PMU
+ err = mali_pmm_pmu_powerup( cores );
+#endif
+ return err;
+}
+
+_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode )
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+ _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
+#if USING_MALI_PMU
+ err = mali_pmm_pmu_powerdown( cores );
+#endif
+
+ /* If all cores are powered down, power off the MALI */
+ if (pmm->cores_powered == 0)
+ {
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+ /* Initiate the power down */
+ _mali_osk_pmm_dev_idle();
+#endif
+ mali_platform_power_mode_change(power_mode);
+ }
+ return err;
+}
+
_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
{
_mali_osk_errcode_t err;
@@ -614,7 +703,7 @@ _mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
#if !MALI_PMM_NO_PMU
/* Make sure the core is powered up */
- err = mali_platform_powerup( core );
+ err = malipmm_powerup( core );
#else
err = _MALI_OSK_ERR_OK;
#endif
@@ -668,18 +757,7 @@ 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);
pmm->cores_powered &= (~core);
pmm->cores_pend_down &= (~core);
@@ -740,7 +818,7 @@ void malipmm_irq_bhandler(void *data)
#endif
MALI_PMM_LOCK(pmm);
-#ifdef MALI_STATE_TRACKING
+#if MALI_STATE_TRACKING
pmm->mali_pmm_lock_acquired = 1;
#endif /* MALI_STATE_TRACKING */
@@ -825,10 +903,10 @@ static void pmm_event_process( void )
return;
}
else
- {
+ {
#if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->messages_received++;
- #endif
+ #endif
}
}
else
@@ -843,7 +921,7 @@ static void pmm_event_process( void )
{
#if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
pmm->imessages_received++;
- #endif
+ #endif
}
MALI_DEBUG_ASSERT_POINTER( msg );
@@ -893,29 +971,36 @@ static void pmm_event_process( void )
}
#if MALI_STATE_TRACKING
-void malipmm_subsystem_dump_state(void)
-{
- malipmm_state_dump();
-}
-#endif
-
-#if (defined(DEBUG) || MALI_STATE_TRACKING)
-void malipmm_state_dump()
+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(("Locks::\nPMM_LOCK_STATUS=%ld",pmm->mali_pmm_lock_acquired));
- MALI_PRINT(("PMM state:\nPrevious_status=%d\nstatus=%d\nCurrent_event=%d\npolicy=%d\ncheck_policy=%d\nstate=%d\n", pmm->mali_last_pmm_status,pmm->status, pmm->mali_new_event_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/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h
index fe7a046cb47..6157746da0c 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm.h
@@ -18,6 +18,7 @@
/* For mali_pmm_message_data and MALI_PMM_EVENT_UK_* defines */
#include "mali_uk_types.h"
+#include "mali_platform.h"
#ifdef __cplusplus
extern "C"
@@ -40,7 +41,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 +53,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
@@ -95,6 +96,7 @@ typedef enum mali_pmm_core_id_tag
MALI_PMM_CORE_PP_ALL = 0x0000003C /**< Mali 200 pixel processors 0-3 */
} mali_pmm_core_id;
+
/* @brief PMM bitmask of mali_pmm_core_ids
*/
typedef u32 mali_pmm_core_mask;
@@ -137,6 +139,23 @@ 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 power up MALI
+ *
+ * @param cores core mask to power up the cores
+ *
+ * @return error code if MALI fails to power up
+ */
+_mali_osk_errcode_t malipmm_powerup( u32 cores );
+
+/** @brief Function to power down MALI
+ *
+ * @param cores core mask to power down the cores
+ * @param The power mode to which MALI transitions
+ *
+ * @return error code if MALI fails to power down
+ */
+_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode );
+
/** @brief Function to report to the OS when the power down has finished
*
* @param data The event message data that initiated the power down
@@ -149,7 +168,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
*/
@@ -164,6 +183,12 @@ 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 report the OS that device is idle
*
* @note inform the OS that device is idle
@@ -176,6 +201,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
@@ -305,15 +336,9 @@ void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool receive
/** @brief Dumps the current state of OS PMM thread
*/
#if MALI_STATE_TRACKING
-void mali_pmm_dump_os_thread_state( void );
+u32 mali_pmm_dump_os_thread_state( char *buf, u32 size );
#endif /* MALI_STATE_TRACKING */
-#if (defined(DEBUG) || MALI_STATE_TRACKING)
-/** @brief Dumps the current state of the PMM
- */
-void malipmm_state_dump( void );
-#endif
-
/** @} */ /* end group pmmapi */
#ifdef __cplusplus
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c
new file mode 100644
index 00000000000..da8957724e8
--- /dev/null
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c
@@ -0,0 +1,350 @@
+/*
+ * 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_pmm_pmu.c
+ * Mali driver functions for Mali 400 PMU hardware
+ */
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_platform.h"
+
+#if USING_MALI_PMU
+#if USING_MALI_PMM
+
+#include "mali_pmm.h"
+
+/* Internal test on/off */
+#define PMU_TEST 0
+
+#if MALI_POWER_MGMT_TEST_SUITE
+#include "mali_platform_pmu_internal_testing.h"
+#endif /* MALI_POWER_MGMT_TEST_SUITE */
+
+/** @brief PMU hardware info
+ */
+typedef struct platform_pmu
+{
+ u32 reg_base_addr; /**< PMU registers base address */
+ u32 reg_size; /**< PMU registers size */
+ const char *name; /**< PMU name */
+ u32 irq_num; /**< PMU irq number */
+
+ mali_io_address reg_mapped; /**< IO-mapped pointer to registers */
+} platform_pmu_t;
+
+static platform_pmu_t *pmu_info = NULL;
+
+/** @brief Register layout for hardware PMU
+ */
+typedef enum {
+ PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */
+ PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */
+ PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */
+ PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */
+ PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */
+ PMU_REG_ADDR_MGMT_INT_STAT = 0x14, /*< Interrupt status register */
+ PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */
+ PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Software delay register */
+ PMU_REG_ADDR_MGMT_MASTER_PWR_UP = 0x24, /*< Master power up register */
+ PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */
+} pmu_reg_addr_mgmt_addr;
+
+/* Internal functions */
+static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address);
+static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val);
+static mali_pmm_core_mask pmu_translate_cores_to_pmu(mali_pmm_core_mask cores);
+#if PMU_TEST
+static void pmm_pmu_dump_regs( platform_pmu_t *pmu );
+static pmm_pmu_test( platform_pmu_t *pmu, u32 cores );
+#endif
+
+_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource)
+{
+
+ if( resource->type == PMU )
+ {
+ if( (resource->base == 0) ||
+ (resource->description == NULL) )
+ {
+ /* NOTE: We currently don't care about any other resource settings */
+ MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n"));
+ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ }
+ pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info));
+ MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM );
+
+ /* All values get 0 as default */
+ _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info));
+
+ pmu_info->reg_base_addr = resource->base;
+ pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE;
+ pmu_info->name = resource->description;
+ pmu_info->irq_num = resource->irq;
+
+ if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) )
+ {
+ MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n",
+ pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name));
+ goto cleanup;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n",
+ pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name));
+ }
+
+ pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name );
+
+ if( 0 == pmu_info->reg_mapped )
+ {
+ MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name));
+ _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size );
+ goto cleanup;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n",
+ (u32) pmu_info->reg_mapped,
+ ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1,
+ pmu_info->name));
+ }
+
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name));
+
+#if PMU_TEST
+ pmu_test(pmu_info, (MALI_PMM_CORE_GP));
+ pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0));
+#endif
+
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) );
+ }
+ else
+ {
+ /* Didn't expect a different resource */
+ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ }
+
+ MALI_SUCCESS;
+
+cleanup:
+ _mali_osk_free(pmu_info);
+ pmu_info = NULL;
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+}
+
+_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type)
+{
+ if (*type == PMU)
+ {
+ if( pmu_info )
+ {
+ _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped);
+ _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size);
+ _mali_osk_free(pmu_info);
+ pmu_info = NULL;
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") );
+ }
+ }
+ else
+ {
+ /* Didn't expect a different resource */
+ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ }
+
+ MALI_SUCCESS;
+
+}
+
+_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores)
+{
+ u32 stat;
+ u32 timeout;
+ u32 cores_pmu;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu_info);
+ MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power down (0x%x)\n", cores) );
+
+ cores_pmu = pmu_translate_cores_to_pmu(cores);
+ pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_DOWN, cores_pmu );
+
+ /* Wait for cores to be powered down */
+ timeout = 10; /* 10ms */
+ do
+ {
+ /* Get status of sleeping cores */
+ stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS );
+ stat &= cores_pmu;
+ if( stat == cores_pmu ) break; /* All cores we wanted are now asleep */
+ _mali_osk_time_ubusydelay(1000); /* 1ms */
+ timeout--;
+ } while( timeout > 0 );
+
+ if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT);
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores)
+{
+ u32 cores_pmu;
+ u32 stat;
+ u32 timeout;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu_info);
+ MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */
+ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) );
+
+ /* Don't use interrupts - just poll status */
+ pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 );
+ cores_pmu = pmu_translate_cores_to_pmu(cores);
+ pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu );
+
+ timeout = 10; /* 10ms */
+ do
+ {
+ /* Get status of sleeping cores */
+ stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS );
+ stat &= cores_pmu;
+ if( stat == 0 ) break; /* All cores we wanted are now awake */
+ _mali_osk_time_ubusydelay(1000); /* 1ms */
+ timeout--;
+ } while( timeout > 0 );
+
+ if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT);
+
+ MALI_SUCCESS;
+}
+
+
+/***** INTERNAL *****/
+
+/** @brief Internal PMU function to translate the cores bit mask
+ * into something the hardware PMU understands
+ *
+ * @param cores PMM cores bitmask
+ * @return PMU hardware cores bitmask
+ */
+static u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores)
+{
+ /* For Mali 400 PMU the cores mask is already the same as what
+ * the hardware PMU expects.
+ * For other hardware, some translation can be done here, by
+ * translating the MALI_PMM_CORE_* bits into specific hardware
+ * bits
+ */
+ return cores;
+}
+
+/** @brief Internal PMU function to read a PMU register
+ *
+ * @param pmu handle that identifies the PMU hardware
+ * @param relative_address relative PMU hardware address to read from
+ * @return 32-bit value that was read from the address
+ */
+static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address)
+{
+ u32 read_val;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
+ MALI_DEBUG_ASSERT(relative_address < pmu->reg_size);
+
+ read_val = _mali_osk_mem_ioread32(pmu->reg_mapped, relative_address);
+
+ MALI_DEBUG_PRINT( 5, ("PMU: reg_read: %s Addr:0x%04X Val:0x%08x\n",
+ pmu->name, relative_address, read_val));
+
+ return read_val;
+}
+
+/** @brief Internal PMU function to write to a PMU register
+ *
+ * @param pmu handle that identifies the PMU hardware
+ * @param relative_address relative PMU hardware address to write to
+ * @param new_val new 32-bit value to write into the address
+ */
+static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val)
+{
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
+ MALI_DEBUG_ASSERT(relative_address < pmu->reg_size);
+
+ MALI_DEBUG_PRINT( 5, ("PMU: reg_write: %s Addr:0x%04X Val:0x%08x\n",
+ pmu->name, relative_address, new_val));
+
+ _mali_osk_mem_iowrite32(pmu->reg_mapped, relative_address, new_val);
+}
+
+#if PMU_TEST
+
+/***** TEST *****/
+
+static void pmu_dump_regs( platform_pmu_t *pmu )
+{
+ u32 addr;
+ for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 )
+ {
+ MALI_PRINT( ("PMU_REG: 0x%08x: 0x%04x\n", (addr + pmu->reg_base_addr), pmu_reg_read( pmu, addr ) ) );
+ }
+}
+
+/* This function is an internal test for the PMU without any Mali h/w interaction */
+static void pmu_test( platform_pmu_t *pmu, u32 cores )
+{
+ u32 stat;
+ u32 timeout;
+
+ MALI_PRINT( ("PMU_TEST: Start\n") );
+
+ pmu_dump_regs( pmu );
+
+ MALI_PRINT( ("PMU_TEST: Power down cores: 0x%x\n", cores) );
+ _mali_pmm_pmu_power_down( pmu, cores, MALI_TRUE );
+
+ stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS );
+ MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == cores ? "SUCCESS" : "FAIL" ) );
+
+ pmu_dump_regs( pmu );
+
+ MALI_PRINT( ("PMU_TEST: Power up cores: 0x%x\n", cores) );
+ _mali_pmm_pmu_power_up( pmu, cores, MALI_FALSE );
+
+ MALI_PRINT( ("PMU_TEST: Waiting for power up...\n") );
+ timeout = 1000; /* 1 sec */
+ while( !_mali_pmm_pmu_irq_power_up(pmu) && timeout > 0 )
+ {
+ _mali_osk_time_ubusydelay(1000); /* 1ms */
+ timeout--;
+ }
+
+ MALI_PRINT( ("PMU_TEST: Waited %dms for interrupt\n", (1000-timeout)) );
+ stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS );
+ MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == 0 ? "SUCCESS" : "FAIL" ) );
+
+ _mali_pmm_pmu_irq_power_up_clear(pmu);
+
+ pmu_dump_regs( pmu );
+
+ MALI_PRINT( ("PMU_TEST: Finish\n") );
+}
+#endif /* PMU_TEST */
+
+#if MALI_POWER_MGMT_TEST_SUITE
+
+u32 pmu_get_power_up_down_info(void)
+{
+ return pmu_reg_read(pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS);
+}
+
+#endif /* MALI_POWER_MGMT_TEST_SUITE */
+#endif /* USING_MALI_PMM */
+#endif /* USING_MALI_PMU */
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h
new file mode 100644
index 00000000000..112074b2010
--- /dev/null
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h
@@ -0,0 +1,87 @@
+/*
+ * 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_platform.h
+ * Platform specific Mali driver functions
+ */
+
+#include "mali_osk.h"
+
+#if !USING_MALI_PMM
+/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */
+#define MALI_PLATFORM_SYSTEM 0
+#endif
+
+#if USING_MALI_PMM
+#if USING_MALI_PMU
+#include "mali_pmm.h"
+
+/** @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
+ * system PMU
+ *
+ * @param resource This is NULL when called on first driver start up, else it will
+ * be a pointer to a PMU resource
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmm_pmu_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
+ *
+ * @param type This is NULL when called on driver exit, else it will
+ * be a pointer to a PMU resource type (not the full resource)
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmm_pmu_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.
+ *
+ * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will
+ * be a mask of cores to power down based on the mali_pmm_core_id enum
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmm_pmu_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.
+ *
+ * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will
+ * be a mask of cores to power down based on the mali_pmm_core_id enum
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores);
+
+#if MALI_POWER_MGMT_TEST_SUITE
+#if USING_MALI_PMM
+#if USING_MALI_PMU
+/** @brief function to get status of individual cores
+ *
+ * This function is used by power management test suite to get the status of powered up/down the number
+ * of cores
+ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
+ */
+u32 pmu_get_power_up_down_info(void);
+#endif
+#endif
+#endif
+#endif
+#endif
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h
index 83cb7f29a92..739c4c4ef17 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/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/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c
index 643bb04553b..a4b893b21e6 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c
@@ -21,7 +21,6 @@
#include "mali_pmm.h"
#include "mali_pmm_system.h"
#include "mali_pmm_state.h"
-#include "mali_pmm_policy.h"
#include "mali_pmm_policy_alwayson.h"
_mali_osk_errcode_t pmm_policy_init_always_on(void)
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h
index a158b09f610..da13224d955 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c
index 8450bd722f4..7f339718354 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c
@@ -231,7 +231,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
if( cores_subset != 0 )
{
/* There are some cores that need powering down */
- if( !pmm_invoke_power_down( pmm ) )
+ if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) )
{
/* We need to wait until they are idle */
@@ -242,6 +242,11 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
break;
}
}
+ else
+ {
+ mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
+
+ }
/* Set waiting status */
pmm->status = MALI_PMM_STATUS_OS_WAITING;
/* All cores now down - respond to OS power event */
@@ -280,7 +285,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
/* Check if we can really power down, if not then we are not
* really in-active
*/
- if( !pmm_invoke_power_down( pmm ) )
+ if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_LIGHT_SLEEP ) )
{
pmm_power_down_cancel( pmm );
}
@@ -322,12 +327,16 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
pmm->status = MALI_PMM_STATUS_OS_WAITING;
if ( pmm->cores_powered != 0 )
{
- if ( pmm_invoke_power_down( pmm ) )
+ if ( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) )
{
_mali_osk_pmm_power_down_done( 0 );
break;
}
}
+ else
+ {
+ mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
+ }
_mali_osk_pmm_power_down_done( 0 );
break;
default:
@@ -384,7 +393,7 @@ _mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *
}
/* Now check if we can power down */
- if( pmm_invoke_power_down( pmm ) )
+ if( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) )
{
if( pmm->status == MALI_PMM_STATUS_OS_POWER_DOWN )
{
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h
index 455234b80bc..f1e7c2d9a82 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/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/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c
index a0ac1c7790c..2e05555cf29 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c
@@ -199,6 +199,7 @@ mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mal
}
else
{
+ MALI_DEBUG_PRINT(1,("The error in PMM is ...%x...%x",err,*ppowered));
MALI_DEBUG_ASSERT( err == _MALI_OSK_ERR_BUSY ||
(err == _MALI_OSK_ERR_FAULT &&
(*ppowered & cores_list[n]) == 0) );
@@ -297,7 +298,7 @@ mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm )
return ( pmm->cores_pend_down == pmm->cores_ack_down ? MALI_TRUE : MALI_FALSE );
}
-mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm )
+mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode )
{
_mali_osk_errcode_t err;
MALI_DEBUG_ASSERT_POINTER(pmm);
@@ -315,8 +316,9 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm )
}
else
{
+ pmm->cores_powered &= ~(pmm->cores_pend_down);
#if !MALI_PMM_NO_PMU
- err = mali_platform_powerdown( pmm->cores_pend_down );
+ err = malipmm_powerdown( pmm->cores_pend_down, power_mode);
#else
err = _MALI_OSK_ERR_OK;
#endif
@@ -327,7 +329,6 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm )
mali_pmm_core_mask old_power = pmm->cores_powered;
#endif
/* Remove powered down cores from idle and powered list */
- pmm->cores_powered &= ~(pmm->cores_pend_down);
pmm->cores_idle &= ~(pmm->cores_pend_down);
/* Reset pending/acknowledged status */
pmm->cores_pend_down = 0;
@@ -338,6 +339,7 @@ mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm )
}
else
{
+ pmm->cores_powered |= pmm->cores_pend_down;
MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power down cores - (0x%x) %s",
pmm->cores_pend_down, pmm_trace_get_core_name(pmm->cores_pend_down)) );
pmm->fatal_power_err = MALI_TRUE;
@@ -429,7 +431,7 @@ mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm )
{
#if !MALI_PMM_NO_PMU
/* Power up must now be done */
- err = mali_platform_powerup( pmm->cores_pend_up );
+ err = malipmm_powerup( pmm->cores_pend_up );
#else
err = _MALI_OSK_ERR_OK;
#endif
@@ -537,7 +539,7 @@ void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm )
int n;
volatile mali_pmm_core_mask *pregistered = &(pmm->cores_registered);
#if !MALI_PMM_NO_PMU
- err = mali_platform_powerup( pmm->cores_registered );
+ err = malipmm_powerup( pmm->cores_registered );
#endif
if( err != _MALI_OSK_ERR_OK )
{
diff --git a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h
index 3c8c31f066d..849fe8b8048 100644
--- a/drivers/gpu/mali/mali400ko/driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h
+++ b/drivers/gpu/mali/mali400ko/driver/src/devicedrv/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 */
@@ -96,12 +95,12 @@ typedef struct _mali_pmm_internal_state
mali_bool fatal_power_err; /**< PMM has had a fatal power error? */
u32 is_dvfs_active; /**< PMM DVFS activity */
-#if (defined(DEBUG) || MALI_STATE_TRACKING)
- u32 mali_last_pmm_status;
- u32 mali_new_event_status;
- u32 mali_pmm_lock_acquired;
+#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 */
@@ -133,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 );
@@ -153,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 );
@@ -177,13 +176,13 @@ 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
* @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE
*/
-mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm );
+mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode );
/** @brief Check if all the pending cores to power up have done so
*
@@ -230,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
@@ -253,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