aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/mali/common
diff options
context:
space:
mode:
authorJustin <justin.a.rogers@gmail.com>2013-03-25 18:06:02 -0500
committercodeworkx <codeworkx@cyanogenmod.org>2013-03-26 10:53:49 +0000
commit88234890ea8fd8f60101c0b9690f1ea756cc3c5b (patch)
tree8693cc089c9608442a871037d2a576f4dd104660 /drivers/media/video/samsung/mali/common
parentcba07183cc76b06a5ef2b20eef70d203dc5bcd5d (diff)
downloadkernel_samsung_smdk4412-88234890ea8fd8f60101c0b9690f1ea756cc3c5b.zip
kernel_samsung_smdk4412-88234890ea8fd8f60101c0b9690f1ea756cc3c5b.tar.gz
kernel_samsung_smdk4412-88234890ea8fd8f60101c0b9690f1ea756cc3c5b.tar.bz2
smdk4412: mali: merge with r3p1 driver from note8
Change-Id: I75db69081b986ec326fe347f73aa3655648e6b81
Diffstat (limited to 'drivers/media/video/samsung/mali/common')
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp.c45
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_job.c18
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_job.h38
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_scheduler.c18
-rw-r--r--drivers/media/video/samsung/mali/common/mali_group.h2
-rw-r--r--drivers/media/video/samsung/mali/common/mali_hw_core.h33
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_common.h10
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_core.c6
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_core.h1
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c6
-rw-r--r--drivers/media/video/samsung/mali/common/mali_osk.h11
-rw-r--r--drivers/media/video/samsung/mali/common/mali_osk_profiling.h22
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp.c121
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_job.c59
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_job.h103
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.c248
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.h1
-rw-r--r--drivers/media/video/samsung/mali/common/mali_ukk.h10
18 files changed, 345 insertions, 407 deletions
diff --git a/drivers/media/video/samsung/mali/common/mali_gp.c b/drivers/media/video/samsung/mali/common/mali_gp.c
index 2110471..1624e46 100644
--- a/drivers/media/video/samsung/mali/common/mali_gp.c
+++ b/drivers/media/video/samsung/mali/common/mali_gp.c
@@ -361,8 +361,8 @@ void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
#if MALI_TIMELINE_PROFILING_ENABLED
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
- mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job), 0, 0, 0);
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), mali_gp_job_get_pid(job), mali_gp_job_get_tid(job), 0, 0, 0);
+ job->frame_builder_id, job->flush_id, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), job->pid, job->tid, 0, 0, 0);
#endif
core->running_job = job;
@@ -480,7 +480,9 @@ static void mali_gp_bottom_half(void *data)
u32 irq_errors;
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0), 0, 0);
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0);
+#endif
#endif
mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */
@@ -489,9 +491,6 @@ static void mali_gp_bottom_half(void *data)
{
MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
mali_group_unlock(core->group);
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
@@ -506,9 +505,6 @@ static void mali_gp_bottom_half(void *data)
mali_gp_post_process_job(core, MALI_FALSE);
MALI_DEBUG_PRINT(4, ("Mali GP: Job completed, calling group handler\n"));
mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_COMPLETED); /* Will release group lock */
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
}
@@ -523,9 +519,6 @@ static void mali_gp_bottom_half(void *data)
mali_gp_post_process_job(core, MALI_FALSE);
MALI_PRINT_ERROR(("Mali GP: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, core->hw_core.description));
mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_FAILED); /* Will release group lock */
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
@@ -537,9 +530,6 @@ static void mali_gp_bottom_half(void *data)
mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_TIMED_OUT);
}
core->core_timed_out = MALI_FALSE;
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
@@ -556,30 +546,25 @@ static void mali_gp_bottom_half(void *data)
mali_gp_post_process_job(core, MALI_TRUE);
MALI_DEBUG_PRINT(3, ("Mali GP: PLBU needs more heap memory\n"));
mali_group_bottom_half(core->group, GROUP_EVENT_GP_OOM); /* Will release group lock */
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
else if (irq_readout & MALIGP2_REG_VAL_IRQ_HANG)
{
- /* we mask hang interrupts, so this should never happen... */
- MALI_DEBUG_ASSERT( 0 );
+ /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_HANG);
}
- /* The only way to get here is if we only got one of two needed END_CMD_LST
- * interrupts. Disable the interrupt that has been received and continue to
- * run. */
- mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK,
- MALIGP2_REG_VAL_IRQ_MASK_USED &
- ((irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST)
- ? ~MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST
- : ~MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST
- ));
+ /*
+ * The only way to get here is if we got a HANG interrupt, which we ignore, or only one of two needed END_CMD_LST interrupts.
+ * Re-enable interrupts and let core continue to run.
+ */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
mali_group_unlock(core->group);
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0);
+#endif
#endif
}
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.c b/drivers/media/video/samsung/mali/common/mali_gp_job.c
index 2e445d6..abe1d93 100644
--- a/drivers/media/video/samsung/mali/common/mali_gp_job.c
+++ b/drivers/media/video/samsung/mali/common/mali_gp_job.c
@@ -13,27 +13,29 @@
#include "mali_osk_list.h"
#include "mali_uk_types.h"
-struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id)
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id)
{
struct mali_gp_job *job;
job = _mali_osk_malloc(sizeof(struct mali_gp_job));
if (NULL != job)
{
- if (0 != copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_gp_start_job_s)))
- {
- _mali_osk_free(job);
- return NULL;
- }
-
_mali_osk_list_init(&job->list);
job->session = session;
job->id = id;
- job->heap_current_addr = job->uargs.frame_registers[4];
+ job->user_id = args->user_job_ptr;
+ _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers));
+ job->heap_current_addr = args->frame_registers[4];
+ job->perf_counter_flag = args->perf_counter_flag;
+ job->perf_counter_src0 = args->perf_counter_src0;
+ job->perf_counter_src1 = args->perf_counter_src1;
job->perf_counter_value0 = 0;
job->perf_counter_value1 = 0;
+
job->pid = _mali_osk_get_pid();
job->tid = _mali_osk_get_tid();
+ job->frame_builder_id = args->frame_builder_id;
+ job->flush_id = args->flush_id;
return job;
}
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.h b/drivers/media/video/samsung/mali/common/mali_gp_job.h
index 7b45552..9c29f1c 100644
--- a/drivers/media/video/samsung/mali/common/mali_gp_job.h
+++ b/drivers/media/video/samsung/mali/common/mali_gp_job.h
@@ -25,16 +25,22 @@ struct mali_gp_job
{
_mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */
struct mali_session_data *session; /**< Session which submitted this job */
- _mali_uk_gp_start_job_s uargs; /**< Arguments from user space */
u32 id; /**< identifier for this job in kernel space (sequential numbering) */
+ u32 user_id; /**< identifier for the job in user space */
+ u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< core specific registers associated with this job, see ARM DDI0415A */
u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */
+ u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
+ u32 perf_counter_src0; /**< source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
+ u32 perf_counter_src1; /**< source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
u32 perf_counter_value0; /**< Value of performance counter 0 (to be returned to user space) */
u32 perf_counter_value1; /**< Value of performance counter 1 (to be returned to user space) */
u32 pid; /**< Process ID of submitting process */
u32 tid; /**< Thread ID of submitting thread */
+ u32 frame_builder_id; /**< id of the originating frame builder */
+ u32 flush_id; /**< flush id within the originating frame builder */
};
-struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id);
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id);
void mali_gp_job_delete(struct mali_gp_job *job);
MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
@@ -44,32 +50,22 @@ MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job)
{
- return job->uargs.user_job_ptr;
+ return job->user_id;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
{
- return job->uargs.frame_builder_id;
+ return job->frame_builder_id;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
{
- return job->uargs.flush_id;
-}
-
-MALI_STATIC_INLINE u32 mali_gp_job_get_pid(struct mali_gp_job *job)
-{
- return job->pid;
-}
-
-MALI_STATIC_INLINE u32 mali_gp_job_get_tid(struct mali_gp_job *job)
-{
- return job->tid;
+ return job->flush_id;
}
MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job)
{
- return job->uargs.frame_registers;
+ return job->frame_registers;
}
MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job)
@@ -79,12 +75,12 @@ MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali
MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job)
{
- return (job->uargs.frame_registers[0] != job->uargs.frame_registers[1]) ? MALI_TRUE : MALI_FALSE;
+ return (job->frame_registers[0] != job->frame_registers[1]) ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job)
{
- return (job->uargs.frame_registers[2] != job->uargs.frame_registers[3]) ? MALI_TRUE : MALI_FALSE;
+ return (job->frame_registers[2] != job->frame_registers[3]) ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job)
@@ -99,17 +95,17 @@ MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *jo
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job)
{
- return job->uargs.perf_counter_flag;
+ return job->perf_counter_flag;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
{
- return job->uargs.perf_counter_src0;
+ return job->perf_counter_src0;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
{
- return job->uargs.perf_counter_src1;
+ return job->perf_counter_src1;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job)
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
index 52fa15b..f06d899 100644
--- a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
+++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
@@ -274,17 +274,25 @@ void mali_gp_scheduler_resume(void)
mali_gp_scheduler_unlock();
}
-_mali_osk_errcode_t _mali_ukk_gp_start_job(void *ctx, _mali_uk_gp_start_job_s *uargs)
+_mali_osk_errcode_t _mali_ukk_gp_start_job(_mali_uk_gp_start_job_s *args)
{
struct mali_session_data *session;
struct mali_gp_job *job;
- MALI_DEBUG_ASSERT_POINTER(uargs);
- MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ if (NULL == args->ctx)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
- session = (struct mali_session_data*)ctx;
+ session = (struct mali_session_data*)args->ctx;
+ if (NULL == session)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
- job = mali_gp_job_create(session, uargs, mali_scheduler_get_new_id());
+ job = mali_gp_job_create(session, args, mali_scheduler_get_new_id());
if (NULL == job)
{
return _MALI_OSK_ERR_NOMEM;
diff --git a/drivers/media/video/samsung/mali/common/mali_group.h b/drivers/media/video/samsung/mali/common/mali_group.h
index 1561d6b..3533d13 100644
--- a/drivers/media/video/samsung/mali/common/mali_group.h
+++ b/drivers/media/video/samsung/mali/common/mali_group.h
@@ -102,7 +102,7 @@ _mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mal
*/
_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job);
-/** @brief Resume GP job that suspended waiting for more heap memory
+/** @brief Resume GP job that suspended waiting for more heap memory
*/
void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr);
/** @brief Abort GP job
diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.h b/drivers/media/video/samsung/mali/common/mali_hw_core.h
index b62e843..c797804 100644
--- a/drivers/media/video/samsung/mali/common/mali_hw_core.h
+++ b/drivers/media/video/samsung/mali/common/mali_hw_core.h
@@ -48,20 +48,6 @@ MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core
_mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
}
-/* Conditionally write a register.
- * The register will only be written if the new value is different from the old_value.
- * If the new value is different, the old value will also be updated */
-MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 new_val, const u32 old_val)
-{
- MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n",
- core->description, relative_address, new_val));
- if(old_val != new_val)
- {
- _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
- }
-}
-
-
MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val)
{
MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n",
@@ -82,23 +68,4 @@ MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw
}
}
-/* Conditionally write a set of registers.
- * The register will only be written if the new value is different from the old_value.
- * If the new value is different, the old value will also be updated */
-MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs, const u32* old_array)
-{
- u32 i;
- MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of 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++)
- {
- if(old_array[i] != write_array[i])
- {
- mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
- }
- }
-}
-
#endif /* __MALI_HW_CORE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_common.h b/drivers/media/video/samsung/mali/common/mali_kernel_common.h
index a33660b..b354f92 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_common.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_common.h
@@ -18,6 +18,16 @@
#endif
#endif
+/* Macro for generating a kernel panic.
+ * Turned on off by compile-time Makefile settings
+ */
+#if defined(USING_KERNEL_PANIC)
+#include <linux/kernel.h>
+ #define MALI_PANIC(fmt, args...) panic( fmt, ## args );
+#else
+ #define MALI_PANIC(fmt, args...)
+#endif
+
/* The file include several useful macros for error checking, debugging and printing.
* - MALI_PRINTF(...) Do not use this function: Will be included in Release builds.
* - MALI_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=MALI_DEBUG_LEVEL.
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.c b/drivers/media/video/samsung/mali/common/mali_kernel_core.c
index f31c505..45e86d2 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_core.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.c
@@ -35,10 +35,6 @@
#if MALI_TIMELINE_PROFILING_ENABLED
#include "mali_osk_profiling.h"
#endif
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
-#include "mali_profiling_internal.h"
-#endif
-
/** Pointer to table of resource definitions available to the Mali driver.
* _mali_osk_resources_init() sets up the pointer to this table.
@@ -58,10 +54,12 @@ static u32 global_gpu_minor_version = 0;
static u32 first_pp_offset = 0;
+#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */
#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
/* timer related */
int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
+int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset)
{
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.h b/drivers/media/video/samsung/mali/common/mali_kernel_core.h
index 0ac967e..d424c48 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_core.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.h
@@ -13,6 +13,7 @@
#include "mali_osk.h"
+extern int mali_hang_check_interval;
extern int mali_max_job_runtime;
typedef enum
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
index 2830ff8..243595d 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
@@ -132,7 +132,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m
allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER;
MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*)));
- while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max) && _mali_osk_mem_check_allocated(os_mem_max_usage))
+ while (left > 0)
{
err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE);
if ( _MALI_OSK_ERR_OK != err)
@@ -243,7 +243,11 @@ 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)
{
+#ifdef CONFIG_CPU_EXYNOS4210
int allocation_order = 6; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */
+#else
+ int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 11 */
+#endif
void *virt = NULL;
u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
os_allocator * info;
diff --git a/drivers/media/video/samsung/mali/common/mali_osk.h b/drivers/media/video/samsung/mali/common/mali_osk.h
index c478057..e32d15d 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk.h
+++ b/drivers/media/video/samsung/mali/common/mali_osk.h
@@ -1422,6 +1422,17 @@ void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue );
*/
void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object );
+#if MALI_STATE_TRACKING
+/** @brief Receive a notification from a queue
+ *
+ * Check if a notification queue is empty.
+ *
+ * @param queue The queue to check.
+ * @return MALI_TRUE if queue is empty, otherwise MALI_FALSE.
+ */
+mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue );
+#endif
+
/** @brief Receive a notification from a queue
*
* Receives a single notification from the given queue.
diff --git a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h
index bf1cf8c..fd9a8fb 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h
+++ b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h
@@ -11,9 +11,12 @@
#ifndef __MALI_OSK_PROFILING_H__
#define __MALI_OSK_PROFILING_H__
-#if MALI_TIMELINE_PROFILING_ENABLED && defined (CONFIG_TRACEPOINTS)
+#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_profiling_events.h"
#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576
@@ -56,8 +59,13 @@ _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
* @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
/* Call Linux tracepoint directly */
#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) trace_mali_timeline_event((event_id), (data0), (data1), (data2), (data3), (data4))
+#else
+/* Internal profiling is handled like a plain function call */
+void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
+#endif
/**
* Report a hardware counter event.
@@ -66,8 +74,13 @@ _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
* @param value The value of the counter.
*/
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
/* Call Linux tracepoint directly */
#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value)
+#else
+/* Internal profiling is handled like a plain function call */
+void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value);
+#endif
/**
* Report SW counters
@@ -127,12 +140,7 @@ mali_bool _mali_osk_profiling_have_recording(void);
/** @} */ /* end group _mali_osk_profiling */
-#else
- /* Dummy add_event, for when profiling is disabled. */
-
-#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4)
-
-#endif /* MALI_TIMELINE_PROFILING_ENABLED && defined(CONFIG_TRACEPOINTS*/
+#endif /* MALI_TIMELINE_PROFILING_ENABLED */
#endif /* __MALI_OSK_PROFILING_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pp.c b/drivers/media/video/samsung/mali/common/mali_pp.c
index b525063..5549f82 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp.c
+++ b/drivers/media/video/samsung/mali/common/mali_pp.c
@@ -12,7 +12,6 @@
#include "mali_hw_core.h"
#include "mali_group.h"
#include "mali_osk.h"
-#include "mali_pp_scheduler.h"
#include "regs/mali_200_regs.h"
#include "mali_kernel_common.h"
#include "mali_kernel_core.h"
@@ -195,55 +194,6 @@ _mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
return _MALI_OSK_ERR_OK;
}
-/* Frame register reset values.
- * Taken from the Mali400 TRM, 3.6. Pixel processor control register summary */
-static const u32 mali_frame_registers_reset_values[_MALI_PP_MAX_FRAME_REGISTERS] =
-{
- 0x0, /* Renderer List Address Register */
- 0x0, /* Renderer State Word Base Address Register */
- 0x0, /* Renderer Vertex Base Register */
- 0x2, /* Feature Enable Register */
- 0x0, /* Z Clear Value Register */
- 0x0, /* Stencil Clear Value Register */
- 0x0, /* ABGR Clear Value 0 Register */
- 0x0, /* ABGR Clear Value 1 Register */
- 0x0, /* ABGR Clear Value 2 Register */
- 0x0, /* ABGR Clear Value 3 Register */
- 0x0, /* Bounding Box Left Right Register */
- 0x0, /* Bounding Box Bottom Register */
- 0x0, /* FS Stack Address Register */
- 0x0, /* FS Stack Size and Initial Value Register */
- 0x0, /* Reserved */
- 0x0, /* Reserved */
- 0x0, /* Origin Offset X Register */
- 0x0, /* Origin Offset Y Register */
- 0x75, /* Subpixel Specifier Register */
- 0x0, /* Tiebreak mode Register */
- 0x0, /* Polygon List Format Register */
- 0x0, /* Scaling Register */
- 0x0 /* Tilebuffer configuration Register */
-};
-
-/* WBx register reset values */
-static const u32 mali_wb_registers_reset_values[_MALI_PP_MAX_WB_REGISTERS] =
-{
- 0x0, /* WBx Source Select Register */
- 0x0, /* WBx Target Address Register */
- 0x0, /* WBx Target Pixel Format Register */
- 0x0, /* WBx Target AA Format Register */
- 0x0, /* WBx Target Layout */
- 0x0, /* WBx Target Scanline Length */
- 0x0, /* WBx Target Flags Register */
- 0x0, /* WBx MRT Enable Register */
- 0x0, /* WBx MRT Offset Register */
- 0x0, /* WBx Global Test Enable Register */
- 0x0, /* WBx Global Test Reference Value Register */
- 0x0 /* WBx Global Test Compare Function Register */
-};
-
-/* Performance Counter 0 Enable Register reset value */
-static const u32 mali_perf_cnt_enable_reset_value = 0;
-
_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
{
/* Bus must be stopped before calling this function */
@@ -256,7 +206,7 @@ _mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
MALI_ASSERT_GROUP_LOCKED(core->group);
- mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
+ mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
/* Set register to a bogus value. The register will be used to detect when reset is complete */
mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
@@ -297,11 +247,10 @@ _mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
MALI_ASSERT_GROUP_LOCKED(core->group);
- mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
+ mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
-
#if defined(USING_MALI200)
/* On Mali-200, stop the bus, then do a hard reset of the core */
@@ -370,10 +319,7 @@ void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 s
MALI_DEBUG_ASSERT_POINTER(core);
MALI_ASSERT_GROUP_LOCKED(core->group);
- mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, frame_registers, MALI200_NUM_REGS_FRAME, mali_frame_registers_reset_values);
-
- _mali_osk_mem_barrier();
-
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, frame_registers, MALI200_NUM_REGS_FRAME);
if (0 != sub_job)
{
/*
@@ -382,34 +328,22 @@ void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 s
* but we need to patch these for all other sub jobs
*/
mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job));
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK/4]);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job));
}
if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
{
- mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, MALI200_NUM_REGS_WBx, mali_wb_registers_reset_values);
- }
- else
- {
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, 0, mali_wb_registers_reset_values[0] );
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, MALI200_NUM_REGS_WBx);
}
if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
{
- mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, MALI200_NUM_REGS_WBx, mali_wb_registers_reset_values);
- }
- else
- {
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, 0, mali_wb_registers_reset_values[0] );
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, MALI200_NUM_REGS_WBx);
}
if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
{
- mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, MALI200_NUM_REGS_WBx, mali_wb_registers_reset_values);
- }
- else
- {
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, 0, mali_wb_registers_reset_values[0] );
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, MALI200_NUM_REGS_WBx);
}
/* This selects which performance counters we are reading */
@@ -418,14 +352,13 @@ void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 s
/* global_config has enabled HW counters, this will override anything specified by user space */
if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
{
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
-
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
}
if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
{
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
}
}
else
@@ -437,15 +370,15 @@ void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 s
if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
{
core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job);
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
}
if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
{
core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
- mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
}
}
}
@@ -466,8 +399,8 @@ void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 s
core->timeout_job_id = mali_pp_job_get_id(job);
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job->frame_builder_id, job->flush_id, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), job->pid, job->tid, 0, 0, 0);
#endif
core->running_job = job;
@@ -565,7 +498,9 @@ static void mali_pp_bottom_half(void *data)
u32 irq_errors;
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
+#endif
#endif
mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */
@@ -574,9 +509,6 @@ static void mali_pp_bottom_half(void *data)
{
MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
mali_group_unlock(core->group);
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
@@ -589,9 +521,6 @@ static void mali_pp_bottom_half(void *data)
mali_pp_post_process_job(core);
MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED); /* Will release group lock */
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
@@ -606,9 +535,6 @@ static void mali_pp_bottom_half(void *data)
MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n",
irq_readout, core->hw_core.description));
mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED); /* Will release group lock */
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
@@ -625,9 +551,6 @@ static void mali_pp_bottom_half(void *data)
mali_group_unlock(core->group);
}
core->core_timed_out = MALI_FALSE;
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
-#endif
return;
}
else if (irq_readout & MALI200_REG_VAL_IRQ_HANG)
@@ -644,7 +567,9 @@ static void mali_pp_bottom_half(void *data)
mali_group_unlock(core->group);
#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
+#endif
#endif
}
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.c b/drivers/media/video/samsung/mali/common/mali_pp_job.c
index 3c23637..47b8a0a 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp_job.c
+++ b/drivers/media/video/samsung/mali/common/mali_pp_job.c
@@ -14,41 +14,65 @@
#include "mali_kernel_common.h"
#include "mali_uk_types.h"
-struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id)
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id)
{
struct mali_pp_job *job;
+ if (args->num_cores > _MALI_PP_MAX_SUB_JOBS)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
+ return NULL;
+ }
+
job = _mali_osk_malloc(sizeof(struct mali_pp_job));
if (NULL != job)
{
u32 i;
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ job->id = id;
+ job->user_id = args->user_job_ptr;
+ job->barrier = args->flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE;
+ job->active_barrier = job->barrier;
+ job->no_notification = args->flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE;
+ _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers));
+ _mali_osk_memcpy(job->frame_registers_addr_frame, args->frame_registers_addr_frame, sizeof(job->frame_registers_addr_frame));
+ _mali_osk_memcpy(job->frame_registers_addr_stack, args->frame_registers_addr_stack, sizeof(job->frame_registers_addr_stack));
- if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_pp_start_job_s)))
+ /* Only copy write back registers for the units that are enabled */
+ job->wb0_registers[0] = 0;
+ job->wb1_registers[0] = 0;
+ job->wb2_registers[0] = 0;
+ if (args->wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
{
- _mali_osk_free(job);
- return NULL;
+ _mali_osk_memcpy(job->wb0_registers, args->wb0_registers, sizeof(job->wb0_registers));
}
-
- if (job->uargs.num_cores > _MALI_PP_MAX_SUB_JOBS)
+ if (args->wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
+ {
+ _mali_osk_memcpy(job->wb1_registers, args->wb1_registers, sizeof(job->wb1_registers));
+ }
+ if (args->wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
{
- MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
- _mali_osk_free(job);
- return NULL;
+ _mali_osk_memcpy(job->wb2_registers, args->wb2_registers, sizeof(job->wb2_registers));
}
- _mali_osk_list_init(&job->list);
- job->session = session;
- job->id = id;
- for (i = 0; i < job->uargs.num_cores; i++)
+ job->perf_counter_flag = args->perf_counter_flag;
+ job->perf_counter_src0 = args->perf_counter_src0;
+ job->perf_counter_src1 = args->perf_counter_src1;
+ for (i = 0; i < args->num_cores; i++)
{
job->perf_counter_value0[i] = 0;
job->perf_counter_value1[i] = 0;
}
+ job->sub_job_count = args->num_cores;
job->sub_jobs_started = 0;
job->sub_jobs_completed = 0;
job->sub_job_errors = 0;
+
job->pid = _mali_osk_get_pid();
job->tid = _mali_osk_get_tid();
+ job->frame_builder_id = args->frame_builder_id;
+ job->flush_id = args->flush_id;
return job;
}
@@ -60,3 +84,12 @@ void mali_pp_job_delete(struct mali_pp_job *job)
{
_mali_osk_free(job);
}
+
+_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
+{
+ if ((0 == job->frame_registers[0]) || (0 == job->frame_registers[1]))
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.h b/drivers/media/video/samsung/mali/common/mali_pp_job.h
index 7e25504..4399c1d 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp_job.h
+++ b/drivers/media/video/samsung/mali/common/mali_pp_job.h
@@ -27,28 +27,40 @@ struct mali_pp_job
{
_mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */
struct mali_session_data *session; /**< Session which submitted this job */
- _mali_uk_pp_start_job_s uargs; /**< Arguments from user space */
u32 id; /**< identifier for this job in kernel space (sequencial numbering) */
+ u32 user_id; /**< identifier for the job in user space */
+ u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< core specific registers associated with this job, see ARM DDI0415A */
+ u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_FRAME registers for sub job 1-7 */
+ u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_STACK registers for sub job 1-7 */
+ u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 0 registers */
+ u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 1 registers */
+ u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 2 registers */
+ u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
+ u32 perf_counter_src0; /**< Source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
+ u32 perf_counter_src1; /**< Source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 0 (to be returned to user space), one for each sub job */
- u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
+ u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
+ u32 sub_job_count; /**< Total number of sub-jobs in this superjob */
u32 sub_jobs_started; /**< Total number of sub-jobs started (always started in ascending order) */
u32 sub_jobs_completed; /**< Number of completed sub-jobs in this superjob */
u32 sub_job_errors; /**< Bitfield with errors (errors for each single sub-job is or'ed together) */
u32 pid; /**< Process ID of submitting process */
u32 tid; /**< Thread ID of submitting thread */
+ u32 frame_builder_id; /**< id of the originating frame builder */
+ u32 flush_id; /**< flush id within the originating frame builder */
+ mali_bool barrier; /**< [in] MALI_TRUE means wait for all my previous jobs to complete before scheduling this one */
+ mali_bool active_barrier; /**< [in] Changes from MALI_TRUE to MALI_FALSE when barrier has been resolved */
+ mali_bool no_notification; /**< [in] MALI_TRUE means do not notify user space when this job has completed */
};
-struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id);
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id);
void mali_pp_job_delete(struct mali_pp_job *job);
-MALI_STATIC_INLINE _mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
-{
- if ((0 == job->uargs.frame_registers[0]) || (0 == job->uargs.frame_registers[1]))
- {
- return _MALI_OSK_ERR_FAULT;
- }
- return _MALI_OSK_ERR_OK;
-}
+_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job);
+
+/******************************************************
+ * simple utility functions for dealing with pp jobs:
+ *****************************************************/
MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
{
@@ -57,43 +69,33 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job)
{
- return job->uargs.user_job_ptr;
+ return job->user_id;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job)
{
- return job->uargs.frame_builder_id;
+ return job->frame_builder_id;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job)
{
- return job->uargs.flush_id;
-}
-
-MALI_STATIC_INLINE u32 mali_pp_job_get_pid(struct mali_pp_job *job)
-{
- return job->pid;
-}
-
-MALI_STATIC_INLINE u32 mali_pp_job_get_tid(struct mali_pp_job *job)
-{
- return job->tid;
+ return job->flush_id;
}
MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job)
{
- return job->uargs.frame_registers;
+ return job->frame_registers;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job)
{
if (sub_job == 0)
{
- return job->uargs.frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
+ return job->frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
}
else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
{
- return job->uargs.frame_registers_addr_frame[sub_job - 1];
+ return job->frame_registers_addr_frame[sub_job - 1];
}
return 0;
@@ -103,11 +105,11 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 s
{
if (sub_job == 0)
{
- return job->uargs.frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
+ return job->frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
}
else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
{
- return job->uargs.frame_registers_addr_stack[sub_job - 1];
+ return job->frame_registers_addr_stack[sub_job - 1];
}
return 0;
@@ -115,32 +117,32 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 s
MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job)
{
- return job->uargs.wb0_registers;
+ return job->wb0_registers;
}
MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job)
{
- return job->uargs.wb1_registers;
+ return job->wb1_registers;
}
MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job)
{
- return job->uargs.wb2_registers;
+ return job->wb2_registers;
}
MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job)
{
- job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+ job->wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
}
MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job)
{
- job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+ job->wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
}
MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job)
{
- job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+ job->wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
}
MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job)
@@ -150,7 +152,7 @@ MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali
MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job)
{
- return (job->sub_jobs_started < job->uargs.num_cores) ? MALI_TRUE : MALI_FALSE;
+ return (job->sub_jobs_started < job->sub_job_count) ? MALI_TRUE : MALI_FALSE;
}
/* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job.
@@ -158,7 +160,7 @@ MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_j
MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(struct mali_pp_job *job)
{
/* All can not be started, since then it would not be in the job queue */
- MALI_DEBUG_ASSERT( job->sub_jobs_started != job->uargs.num_cores );
+ MALI_DEBUG_ASSERT( job->sub_jobs_started != job->sub_job_count );
/* If at least one job is started */
if ( (job->sub_jobs_started > 0) )
@@ -166,7 +168,7 @@ MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_
/* If at least one job is currently being rendered, and thus assigned to a group and core */
if (job->sub_jobs_started > job->sub_jobs_completed )
{
- u32 jobs_remaining = job->uargs.num_cores - job->sub_jobs_started;
+ u32 jobs_remaining = job->sub_job_count - job->sub_jobs_started;
job->sub_jobs_started += jobs_remaining;
job->sub_jobs_completed += jobs_remaining;
job->sub_job_errors += jobs_remaining;
@@ -180,7 +182,7 @@ MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_
MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job)
{
- return (job->uargs.num_cores == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE;
+ return (job->sub_job_count == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job)
@@ -190,7 +192,7 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_jo
MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job)
{
- return job->uargs.num_cores;
+ return job->sub_job_count;
}
MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job)
@@ -200,15 +202,6 @@ MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job
job->sub_jobs_started++;
}
-MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_not_stated(struct mali_pp_job *job, u32 sub_job)
-{
- /* This is only safe on Mali-200. */
-#if !defined(USING_MALI200)
- MALI_DEBUG_ASSERT(0);
-#endif
- job->sub_jobs_started--;
-}
-
MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success)
{
job->sub_jobs_completed++;
@@ -229,32 +222,32 @@ MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job)
MALI_STATIC_INLINE mali_bool mali_pp_job_has_active_barrier(struct mali_pp_job *job)
{
- return job->uargs.flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE;
+ return job->active_barrier;
}
MALI_STATIC_INLINE void mali_pp_job_barrier_enforced(struct mali_pp_job *job)
{
- job->uargs.flags &= ~_MALI_PP_JOB_FLAG_BARRIER;
+ job->active_barrier = MALI_FALSE;
}
MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(struct mali_pp_job *job)
{
- return job->uargs.flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE;
+ return job->no_notification;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
{
- return job->uargs.perf_counter_flag;
+ return job->perf_counter_flag;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job)
{
- return job->uargs.perf_counter_src0;
+ return job->perf_counter_src0;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job)
{
- return job->uargs.perf_counter_src1;
+ return job->perf_counter_src1;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job)
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
index eedf661..a944055 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
+++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
@@ -17,8 +17,6 @@
#include "mali_pp_job.h"
#include "mali_group.h"
#include "mali_cluster.h"
-#include "mali_osk_profiling.h"
-
/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
#define MALI_MAX_NUMBER_OF_PP_GROUPS 8
@@ -41,14 +39,10 @@ struct mali_pp_slot
*/
enum mali_pp_slot_state state;
struct mali_session_data *session;
- struct mali_pp_job *job;
- u32 subjob;
};
static u32 pp_version = 0;
static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */
-static u32 job_queue_depth;
-
static struct mali_pp_slot slots[MALI_MAX_NUMBER_OF_PP_GROUPS];
static u32 num_slots = 0;
static u32 num_slots_idle = 0;
@@ -67,7 +61,7 @@ _mali_osk_errcode_t mali_pp_scheduler_initialize(void)
_MALI_OSK_INIT_LIST_HEAD(&job_queue);
- pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
if (NULL == pp_scheduler_lock)
{
return _MALI_OSK_ERR_NOMEM;
@@ -160,7 +154,7 @@ static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_
for (i = 0; i < num_slots; i++)
{
if (MALI_PP_SLOT_STATE_WORKING == slots[i].state)
- {
+ {
if (slots[i].session == session)
{
return MALI_TRUE;
@@ -171,123 +165,131 @@ static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_
return MALI_FALSE;
}
-static mali_bool slots_available(void)
-{
- return num_slots_idle > 0;
-}
-
static void mali_pp_scheduler_schedule(void)
{
+ u32 i;
struct mali_pp_job *job;
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
+ struct mali_session_data * session;
+#endif
+
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
- if (0 < pause_count || 0 == num_slots_idle || 0 == job_queue_depth)
+ if (0 < pause_count || 0 == num_slots_idle || _mali_osk_list_empty(&job_queue))
{
MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
pause_count, num_slots_idle));
return; /* Nothing to do, so early out */
}
- while(slots_available() && 0 < job_queue_depth)
+
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP
+ if ( num_slots_idle < num_slots )
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started, since only %d/%d cores are available\n", num_slots_idle,num_slots));
+ return;
+ }
+#endif
+
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
+ /* Finding initial session for the PP cores */
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
+ session = job->session;
+ if ( num_slots != num_slots_idle )
+ {
+ for (i = 0; (i < num_slots) ; i++)
+ {
+ if ( slots[i].state == MALI_PP_SLOT_STATE_IDLE )
+ {
+ continue;
+ }
+ session = mali_group_get_session(slots[i].group);
+ break;
+ }
+ }
+#endif
+
+ for (i = 0; (i < num_slots) && (0 < num_slots_idle); i++)
{
- u32 i, slot_count;
- struct mali_pp_slot *reserved_slots[num_slots];
- struct mali_session_data *session;
+ u32 sub_job;
- mali_pp_scheduler_lock();
- /* Get job */
- if (_mali_osk_list_empty(&job_queue) || !slots_available())
+ if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */
{
- mali_pp_scheduler_unlock();
break; /* No more jobs to schedule, so early out */
}
+
+ if (MALI_PP_SLOT_STATE_IDLE != slots[i].state)
+ {
+ continue;
+ }
+
job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job)); /* All jobs on the job_queue should have unstarted sub jobs */
- session = mali_pp_job_get_session(job);
if (MALI_TRUE == mali_pp_job_has_active_barrier(job))
{
if (MALI_TRUE == mali_pp_scheduler_session_has_running_jobs(mali_pp_job_get_session(job)))
{
- /* There is already a running job from this
- * session, so we need to enforce the barrier */
- mali_pp_scheduler_unlock();
+ /* There is already a running job from this session, so we need to enforce the barrier */
return;
}
else
{
- /* Barrier is now enforced, update job object
- * so we don't delay execution of sub-jobs */
+ /* Barrier is now enforced, update job object so we don't delay execution of sub-jobs */
mali_pp_job_barrier_enforced(job);
}
}
- /* Reserve slots */
- for (i = 0, slot_count = 0; i < num_slots; i++)
+ #if MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED
+ if ( (0==job->sub_jobs_started) && (num_slots_idle < num_slots) && (job->sub_job_count > num_slots_idle))
{
- struct mali_pp_slot *slot = &slots[i];
-
- if (MALI_PP_SLOT_STATE_IDLE != slot->state) continue;
-
- slot->state = MALI_PP_SLOT_STATE_WORKING;
- slot->session = session;
- slot->job = job;
- slot->subjob = mali_pp_job_get_first_unstarted_sub_job(job);
- mali_pp_job_mark_sub_job_started(job, slot->subjob);
- --job_queue_depth;
-
- --num_slots_idle;
- reserved_slots[slot_count++] = slot;
-
- if (!mali_pp_job_has_unstarted_sub_jobs(job))
- {
- _mali_osk_list_del(&job->list);
- break;
- }
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job with %d subjobs not started, since only %d/%d cores are available\n", job->sub_job_count, num_slots_idle,num_slots));
+ return;
}
+ #endif
- MALI_DEBUG_ASSERT(0 < slot_count);
+ #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
+ if ( job->session != session )
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started since existing job is from another application\n"));
+ return;
+ }
+ #endif
- mali_pp_scheduler_unlock();
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
- /* Start (sub)job(s) on core(s) */
- for(i = 0; i < slot_count; i++)
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Starting job %u (0x%08X) part %u/%u\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job)));
+ if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slots[i].group, job, sub_job))
{
- struct mali_pp_slot *slot = reserved_slots[i];
- struct mali_pp_job *job;
- u32 subjob;
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job)));
- MALI_DEBUG_ASSERT_POINTER(slot);
- MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slot->state);
- MALI_DEBUG_ASSERT_POINTER(slot->job);
+ /* Mark this sub job as started */
+ mali_pp_job_mark_sub_job_started(job, sub_job);
- job = slot->job;
- subjob = slot->subjob;
+ /* Mark slot as busy */
+ slots[i].state = MALI_PP_SLOT_STATE_WORKING;
+ slots[i].session = mali_pp_job_get_session(job);
+ num_slots_idle--;
- if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slot->group, slot->job, slot->subjob))
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n",
- mali_pp_job_get_id(job), job, subjob + 1,
- mali_pp_job_get_sub_job_count(job)));
- }
- else
+ if (!mali_pp_job_has_unstarted_sub_jobs(job))
{
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n"));
- /* This can only happen on Mali-200 */
-#if !defined(USING_MALI200)
- MALI_DEBUG_ASSERT(0);
+ /*
+ * All sub jobs have now started for this job, remove this job from the job queue.
+ * The job will now only be referred to by the slots which are running it.
+ * The last slot to complete will make sure it is returned to user space.
+ */
+ _mali_osk_list_del(&job->list);
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP
+ MALI_DEBUG_PRINT(6, ("Mali PP scheduler: Skip scheduling more jobs when MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP is set.\n"));
+ return;
#endif
- mali_pp_scheduler_lock();
- /* Put job back on queue */
- mali_pp_job_mark_sub_job_not_stated(job, subjob);
- _mali_osk_list_add(&job->list, &job_queue);
- /* Set slot idle */
- slot->state = MALI_PP_SLOT_STATE_IDLE;
- slot->session = NULL;
- slot->job = NULL;
- slot->subjob = 0;
- mali_pp_scheduler_unlock();
}
}
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n"));
+ return;
+ }
}
}
@@ -333,42 +335,35 @@ static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job)
void mali_pp_scheduler_do_schedule(void)
{
+ mali_pp_scheduler_lock();
+
mali_pp_scheduler_schedule();
+
+ mali_pp_scheduler_unlock();
}
void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
{
u32 i;
- struct mali_pp_slot *slot = NULL;
mali_bool job_is_done;
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n",
- mali_pp_job_get_id(job),
- job, sub_job + 1,
- mali_pp_job_get_sub_job_count(job),
- success ? "success" : "failure"));
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job), success ? "success" : "failure"));
mali_pp_scheduler_lock();
- mali_pp_job_mark_sub_job_completed(job, success);
-
/* Find slot which was running this job */
for (i = 0; i < num_slots; i++)
{
- slot = &slots[i];
- if (slot->group == group)
- break;
+ if (slots[i].group == group)
+ {
+ MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slots[i].state);
+ slots[i].state = MALI_PP_SLOT_STATE_IDLE;
+ slots[i].session = NULL;
+ num_slots_idle++;
+ mali_pp_job_mark_sub_job_completed(job, success);
+ }
}
- MALI_DEBUG_ASSERT_POINTER(slot);
-
- slot->state = MALI_PP_SLOT_STATE_IDLE;
- slot->session = NULL;
- slot->job = NULL;
- slot->subjob = 0;
-
- num_slots_idle++;
-
/* If paused, then this was the last job, so wake up sleeping workers */
if (pause_count > 0)
{
@@ -378,6 +373,10 @@ void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *jo
*/
_mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
}
+ else
+ {
+ mali_pp_scheduler_schedule();
+ }
job_is_done = mali_pp_job_is_complete(job);
@@ -389,8 +388,6 @@ void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *jo
MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for job %u (0x%08X)\n", mali_pp_job_get_id(job), job));
mali_pp_scheduler_return_job_to_user(job);
}
-
- mali_pp_scheduler_schedule();
}
void mali_pp_scheduler_suspend(void)
@@ -399,7 +396,11 @@ void mali_pp_scheduler_suspend(void)
pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
mali_pp_scheduler_unlock();
- /* Go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
+ /*mali_pp_scheduler_working_lock();*/
+ /* We have now aquired the working lock, which means that we have successfully paused the scheduler */
+ /*mali_pp_scheduler_working_unlock();*/
+
+ /* go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
* mali_pp_scheduler_suspended() function will be called. This will return true
* iff state is idle and pause_count > 0, so if the core is active this
* will not do anything.
@@ -418,17 +419,17 @@ void mali_pp_scheduler_resume(void)
mali_pp_scheduler_unlock();
}
-_mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *uargs)
+_mali_osk_errcode_t _mali_ukk_pp_start_job(_mali_uk_pp_start_job_s *args)
{
struct mali_session_data *session;
struct mali_pp_job *job;
- MALI_DEBUG_ASSERT_POINTER(uargs);
- MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
- session = (struct mali_session_data*)ctx;
+ session = (struct mali_session_data*)args->ctx;
- job = mali_pp_job_create(session, uargs, mali_scheduler_get_new_id());
+ job = mali_pp_job_create(session, args, mali_scheduler_get_new_id());
if (NULL == job)
{
return _MALI_OSK_ERR_NOMEM;
@@ -450,15 +451,13 @@ _mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *u
mali_pp_scheduler_lock();
- job_queue_depth += mali_pp_job_get_sub_job_count(job);
_mali_osk_list_addtail(&job->list, &job_queue);
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n",
- mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n", mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
- mali_pp_scheduler_unlock();
+ mali_pp_scheduler_schedule();
- if (slots_available()) mali_pp_scheduler_schedule();
+ mali_pp_scheduler_unlock();
return _MALI_OSK_ERR_OK;
}
@@ -490,8 +489,9 @@ void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
session = (struct mali_session_data*)args->ctx;
- /* Check queue for jobs that match */
mali_pp_scheduler_lock();
+
+ /* Check queue for jobs that match */
_MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list)
{
if (mali_pp_job_get_session(job) == session &&
@@ -513,6 +513,7 @@ void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
break;
}
}
+
mali_pp_scheduler_unlock();
}
@@ -530,7 +531,6 @@ void mali_pp_scheduler_abort_session(struct mali_session_data *session)
if (mali_pp_job_get_session(job) == session)
{
_mali_osk_list_del(&(job->list));
- job_queue_depth -= mali_pp_job_get_sub_job_count(job) - mali_pp_job_get_first_unstarted_sub_job(job);
if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) )
{
@@ -551,9 +551,14 @@ void mali_pp_scheduler_abort_session(struct mali_session_data *session)
{
struct mali_group *group = slots[i].group;
- MALI_DEBUG_PRINT(5, ("PP sched abort: Attempting abort for session 0x%08x on group 0x%08x\n", session, group));
+ MALI_DEBUG_PRINT(5, ("PP sched abort: Looking at group 0x%08x\n", group));
+
+ if (MALI_PP_SLOT_STATE_WORKING == slots[i].state)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborting session 0x%08x from group 0x%08x\n", session, group));
- mali_group_abort_session(group, session);
+ mali_group_abort_session(group, session);
+ }
}
}
@@ -568,11 +573,6 @@ static mali_bool mali_pp_scheduler_is_suspended(void)
return ret;
}
-int mali_pp_scheduler_get_queue_depth(void)
-{
- return job_queue_depth;
-}
-
#if MALI_STATE_TRACKING
u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
{
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
index 59bf403..48eb3bd 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
+++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
@@ -33,7 +33,6 @@ void mali_pp_scheduler_resume(void);
*/
void mali_pp_scheduler_abort_session(struct mali_session_data *session);
-int mali_pp_scheduler_get_queue_depth(void);
u32 mali_pp_scheduler_dump_state(char *buf, u32 size);
#endif /* __MALI_PP_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_ukk.h b/drivers/media/video/samsung/mali/common/mali_ukk.h
index 6d41b6e..6b018d0 100644
--- a/drivers/media/video/samsung/mali/common/mali_ukk.h
+++ b/drivers/media/video/samsung/mali/common/mali_ukk.h
@@ -449,11 +449,10 @@ _mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args );
*
* Job completion can be awaited with _mali_ukk_wait_for_notification().
*
- * @oaram ctx user-kernel context (mali_session)
- * @param uargs see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
+ * @param args see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h"
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
*/
-_mali_osk_errcode_t _mali_ukk_pp_start_job( void *ctx, _mali_uk_pp_start_job_s *uargs );
+_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args );
/** @brief Returns the number of Fragment Processors in the system
*
@@ -503,11 +502,10 @@ void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args);
*
* Job completion can be awaited with _mali_ukk_wait_for_notification().
*
- * @oaram ctx user-kernel context (mali_session)
- * @param uargs see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
+ * @param args see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h"
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
*/
-_mali_osk_errcode_t _mali_ukk_gp_start_job( void *ctx, _mali_uk_gp_start_job_s *uargs );
+_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args );
/** @brief Returns the number of Vertex Processors in the system.
*