aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
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
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')
-rw-r--r--drivers/media/video/samsung/mali/Kbuild_module9
-rw-r--r--drivers/media/video/samsung/mali/Makefile24
-rw-r--r--drivers/media/video/samsung/mali/arch-orion-m400/config.h154
-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
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h24
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_linux.c112
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c22
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_locks.c27
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_mali.c2
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_notification.c43
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_profiling.c)0
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c324
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_specific.h14
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_profiling_internal.c294
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_profiling_internal.h36
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_uk_types.h3
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_gp.c37
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_pp.c13
-rw-r--r--drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c46
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c54
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c38
-rw-r--r--drivers/media/video/samsung/mali/regs/mali_gp_regs.h2
-rw-r--r--drivers/media/video/samsung/ump/Kconfig13
-rw-r--r--drivers/media/video/samsung/ump/Makefile9
-rw-r--r--drivers/media/video/samsung/ump/Makefile.common4
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_api.c23
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_common.c20
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c33
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h7
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c63
-rw-r--r--drivers/media/video/samsung/ump/common/ump_osk.h6
-rw-r--r--drivers/media/video/samsung/ump/common/ump_uk_types.h4
-rw-r--r--drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h8
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_linux.c9
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c11
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c290
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h22
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_memory_backend.c7
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c141
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c7
58 files changed, 1762 insertions, 951 deletions
diff --git a/drivers/media/video/samsung/mali/Kbuild_module b/drivers/media/video/samsung/mali/Kbuild_module
index d861b72..e865954 100644
--- a/drivers/media/video/samsung/mali/Kbuild_module
+++ b/drivers/media/video/samsung/mali/Kbuild_module
@@ -16,13 +16,16 @@ OSKOS=linux
USING_UMP ?= 0
USING_OS_MEMORY ?= 0
USING_MALI_PMM_TESTSUITE ?= 0
-OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6
+OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
USING_PROFILING ?= 1
USING_INTERNAL_PROFILING ?= 0
DISABLE_PP0 ?= 0
DISABLE_PP1 ?= 0
DISABLE_PP2 ?= 0
DISABLE_PP3 ?= 0
+PROFILING_SKIP_PP_JOBS ?= 0
+PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
+PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0
TIMESTAMP ?= default
BUILD ?= debug
TARGET_PLATFORM ?= default
@@ -129,6 +132,10 @@ DEFINES += -DDISABLE_PP0=$(DISABLE_PP0)
DEFINES += -DDISABLE_PP1=$(DISABLE_PP1)
DEFINES += -DDISABLE_PP2=$(DISABLE_PP2)
DEFINES += -DDISABLE_PP3=$(DISABLE_PP3)
+DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
+DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
+DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH)
+
DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
diff --git a/drivers/media/video/samsung/mali/Makefile b/drivers/media/video/samsung/mali/Makefile
index 524f910..3e25b61 100644
--- a/drivers/media/video/samsung/mali/Makefile
+++ b/drivers/media/video/samsung/mali/Makefile
@@ -49,10 +49,15 @@ USING_GPU_UTILIZATION=1
USING_MALI_DVFS_ENABLED=1
endif
-ifeq ($(CONFIG_VIDEO_MALI400MP_DEBUG),y)
+ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y)
BUILD=debug
endif
+ifeq ($(CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING),y)
+USING_PROFILING=1
+USING_TRACEPOINTS=1
+endif
+
# set up defaults if not defined by the user
USE_UMPV2 ?= 0
PANIC_ON_WATCHDOG_TIMEOUT ?= 1
@@ -68,7 +73,7 @@ USING_MALI_RUN_TIME_PM ?= 0
USING_MALI_PMM_TESTSUITE ?= 0
USING_MALI_PMU ?= 0
USING_GPU_UTILIZATION ?= 0
-OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6
+OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
USING_PROFILING ?= 0
USING_INTERNAL_PROFILING ?= 0
USING_TRACEPOINTS ?= 0
@@ -81,6 +86,9 @@ DISABLE_PP0 ?= 0
DISABLE_PP1 ?= 0
DISABLE_PP2 ?= 0
DISABLE_PP3 ?= 0
+PROFILING_SKIP_PP_JOBS ?= 0
+PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
+PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0
TIMESTAMP ?= default
BUILD ?= release
TARGET_PLATFORM ?= default
@@ -145,6 +153,9 @@ DEFINES += -DDISABLE_PP0=$(DISABLE_PP0)
DEFINES += -DDISABLE_PP1=$(DISABLE_PP1)
DEFINES += -DDISABLE_PP2=$(DISABLE_PP2)
DEFINES += -DDISABLE_PP3=$(DISABLE_PP3)
+DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
+DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
+DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH)
DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
@@ -168,7 +179,7 @@ else
endif
# Target build file
-obj-$(CONFIG_VIDEO_MALI400MP) += mali.o
+obj-$(CONFIG_VIDEO_UMP) += mali.o
# Use our defines when compiling
# MALI
@@ -179,10 +190,9 @@ INCLUDES = \
-I$(MALI_INCLUDE_PREFIX)linux \
-I$(MALI_INCLUDE_PREFIX)platform\
-I$(MALI_INCLUDE_PREFIX)regs
-
EXTRA_CFLAGS += $(INCLUDES)\
- $(DEFINES)
+ $(DEFINES)
EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)linux/license/gpl
EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)common/pmm
@@ -266,7 +276,7 @@ mali-y := \
linux/mali_pmu_power_up_down.o \
$(MALI_PLATFORM_FILE) \
$(OSKFILES) \
- $(UKKFILES)
+ $(UKKFILES)
# __malidrv_build_info.c
# Selecting files to compile by parsing the config file
@@ -279,7 +289,7 @@ EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)timestamp-$(TIMESTAMP)
else
ifeq ($(USING_PROFILING),1)
PROFILING_BACKEND_SOURCES = \
- linux/mali_osk_profiling.o
+ linux/mali_osk_profiling_gator.o
endif
endif
diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h
new file mode 100644
index 0000000..5c4d79d
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-orion-m400/config.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARCH_CONFIG_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the EB platform with ZBT memory enabled */
+/*zepplin added 2010.08.17 for orion configuration*/
+#define MALI_BASE_ADDR 0x13000000
+#define GP_ADDR MALI_BASE_ADDR
+#define L2_ADDR MALI_BASE_ADDR+0x1000
+#define PMU_ADDR MALI_BASE_ADDR+0x2000
+#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
+#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000
+#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000
+#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000
+#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000
+#define PP0_ADDR MALI_BASE_ADDR+0x8000
+#define PP1_ADDR MALI_BASE_ADDR+0xA000
+#define PP2_ADDR MALI_BASE_ADDR+0xC000
+#define PP3_ADDR MALI_BASE_ADDR+0xE000
+
+/*for mmu and os memory*/
+#define MEM_BASE_ADDR 0x40000000
+#define MEM_TOTAL_SIZE 0x40000000
+#define MEM_MALI_OS_SIZE 0x40000000
+
+/*for dedicated memory*/
+//#define MEM_MALI_BASE 0x58000000
+//#define MEM_MALI_SIZE 0x08000000
+#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024
+#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = GP_ADDR,
+ .irq = IRQ_GP_3D,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = PP0_ADDR,
+ .irq = IRQ_PP0_3D,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = PP1_ADDR,
+ .irq = IRQ_PP1_3D,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MALI400PP,
+ .base = PP2_ADDR,
+ .irq = IRQ_PP2_3D,
+ .description = "Mali-400 PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MALI400PP,
+ .base = PP3_ADDR,
+ .irq = IRQ_PP3_3D,
+ .description = "Mali-400 PP 3",
+ .mmu_id = 5
+ },
+#if USING_MMU
+ {
+ .type = MMU,
+ .base = GP_MMU_ADDR,
+ .irq = IRQ_GPMMU_3D,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = PP0_MMU_ADDR,
+ .irq = IRQ_PPMMU0_3D,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = PP1_MMU_ADDR,
+ .irq = IRQ_PPMMU1_3D,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = PP2_MMU_ADDR,
+ .irq = IRQ_PPMMU2_3D,
+ .description = "Mali-400 MMU for PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MMU,
+ .base = PP3_MMU_ADDR,
+ .irq = IRQ_PPMMU3_3D,
+ .description = "Mali-400 MMU for PP 3",
+ .mmu_id = 5
+ },
+#if USING_OS_MEMORY
+ {
+ .type = OS_MEMORY,
+ .description = "System Memory",
+ .size = MEM_MALI_OS_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+#endif
+#if USING_DED /* Dedicated Memory */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
+ },
+#endif/* if USING_OS_MEMORY*/
+ {
+ .type = MEM_VALIDATION,
+ .description = "memory validation",
+ .base = MEM_BASE_ADDR,
+ .size = MEM_TOTAL_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
+ },
+#else /* Not using MMU */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
+ },
+#endif
+ {
+ .type = MALI400L2,
+ .base = L2_ADDR,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
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.
*
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h
index 92ca058..b96596e 100644
--- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h
+++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h
@@ -71,7 +71,6 @@ typedef enum
MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_TRY_LOCK = 53,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK = 54,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK = 55,
- MALI_PROFILING_EVENT_REASON_SINGLE_LOCK_CONTENDED = 56,
} cinstr_profiling_event_reason_single_sw_t;
/**
@@ -81,7 +80,6 @@ typedef enum
{
MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0,
MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1,
- MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF = 2,
} cinstr_profiling_event_reason_start_stop_sw_t;
/**
@@ -126,26 +124,4 @@ typedef enum
MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
} cinstr_profiling_event_reason_single_gpu_t;
-/**
- * These values are applicable for the 3rd data parameter when
- * the type MALI_PROFILING_EVENT_TYPE_START is used from the software channel
- * with the MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF reason.
- */
-typedef enum
-{
- MALI_PROFILING_EVENT_DATA_CORE_GP0 = 1,
- MALI_PROFILING_EVENT_DATA_CORE_PP0 = 5,
- MALI_PROFILING_EVENT_DATA_CORE_PP1 = 6,
- MALI_PROFILING_EVENT_DATA_CORE_PP2 = 7,
- MALI_PROFILING_EVENT_DATA_CORE_PP3 = 8,
- MALI_PROFILING_EVENT_DATA_CORE_PP4 = 9,
- MALI_PROFILING_EVENT_DATA_CORE_PP5 = 10,
- MALI_PROFILING_EVENT_DATA_CORE_PP6 = 11,
- MALI_PROFILING_EVENT_DATA_CORE_PP7 = 12,
-} cinstr_profiling_event_data_core_t;
-
-#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(num) (MALI_PROFILING_EVENT_DATA_CORE_GP0 + (num))
-#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(num) (MALI_PROFILING_EVENT_DATA_CORE_PP0 + (num))
-
-
#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
index 8367515..233c0ca 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
@@ -29,9 +29,6 @@
#include "mali_platform.h"
#include "mali_kernel_license.h"
#include "mali_dma_buf.h"
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
-#include "mali_profiling_internal.h"
-#endif
/* Streamline support for the Mali driver */
#if defined(CONFIG_TRACEPOINTS) && MALI_TIMELINE_PROFILING_ENABLED
@@ -54,10 +51,17 @@ module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IR
MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output");
/* By default the module uses any available major, but it's possible to set it at load time to a specific number */
+#if MALI_MAJOR_PREDEFINE
+int mali_major = 244;
+#else
int mali_major = 0;
+#endif
module_param(mali_major, int, S_IRUGO); /* r--r--r-- */
MODULE_PARM_DESC(mali_major, "Device major number");
+module_param(mali_hang_check_interval, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_hang_check_interval, "Interval at which to check for progress after the hw watchdog has been triggered");
+
module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what");
@@ -75,6 +79,92 @@ MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver
#include "mali_user_settings_db.h"
EXPORT_SYMBOL(mali_set_user_setting);
EXPORT_SYMBOL(mali_get_user_setting);
+#if MALI_DVFS_ENABLED
+extern int mali_dvfs_control;
+module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
+#if defined(CONFIG_CPU_EXYNOS4210)
+#else
+extern int step0_clk;
+module_param(step0_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step0_clk, "Mali Current step0_clk");
+#ifdef DEBUG
+extern int step0_vol;
+module_param(step0_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step0_vol, "Mali Current step0_vol");
+#endif
+
+#if (MALI_DVFS_STEPS > 1)
+extern int step1_clk;
+module_param(step1_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step1_clk, "Mali Current step1_clk");
+
+extern int step0_up;
+module_param(step0_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step0_up, "Mali Current step0_up");
+
+extern int step1_down;
+module_param(step1_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step1_down, "Mali Current step1_down");
+#ifdef DEBUG
+extern int step1_vol;
+module_param(step1_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step1_vol, "Mali Current step1_vol");
+#endif
+
+#if (MALI_DVFS_STEPS > 2)
+extern int step2_clk;
+module_param(step2_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step2_clk, "Mali Current step2_clk");
+
+extern int step1_up;
+module_param(step1_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step1_up, "Mali Current step1_up");
+
+extern int step2_down;
+module_param(step2_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step2_down, "Mali Current step2_down");
+#ifdef DEBUG
+extern int step2_vol;
+module_param(step2_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step2_vol, "Mali Current step2_vol");
+#endif
+
+#if (MALI_DVFS_STEPS > 3)
+extern int step3_clk;
+module_param(step3_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step3_clk, "Mali Current step3_clk");
+
+extern int step2_up;
+module_param(step2_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step2_up, "Mali Current step2_up");
+
+extern int step3_down;
+module_param(step3_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step3_down, "Mali Current step3_down");
+#ifdef DEBUG
+extern int step3_vol;
+module_param(step3_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(step3_vol, "Mali Current step3_vol");
+#endif
+#endif
+#endif
+#endif
+#endif
+
+extern int mali_gpu_clk;
+module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock");
+
+extern int mali_gpu_vol;
+module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
+
+extern int gpu_power_state;
+module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(gpu_power_state, "Mali Power State");
+#endif
+
static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
@@ -129,15 +219,6 @@ int mali_driver_init(void)
ret = map_errcode(mali_initialize_subsystems());
if (0 != ret) goto initialize_subsystems_failed;
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- ret = _mali_internal_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
- if (0 != ret)
- {
- /* No biggie if we wheren't able to initialize the profiling */
- MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
- }
-#endif
-
ret = initialize_sysfs();
if (0 != ret) goto initialize_sysfs_failed;
@@ -147,9 +228,6 @@ int mali_driver_init(void)
/* Error handling */
initialize_sysfs_failed:
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_internal_profiling_term();
-#endif
mali_terminate_subsystems();
initialize_subsystems_failed:
mali_osk_low_level_mem_term();
@@ -169,10 +247,6 @@ void mali_driver_exit(void)
/* No need to terminate sysfs, this will be done automatically along with device termination */
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_internal_profiling_term();
-#endif
-
mali_terminate_subsystems();
mali_osk_low_level_mem_term();
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
index 77ebc9d..e2dc17b 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
@@ -44,7 +44,6 @@
#include "mali_kernel_core.h"
#include "mali_user_settings_db.h"
#include "mali_device_pause_resume.h"
-#include "mali_profiling_internal.h"
#define POWER_BUFFER_SIZE 3
@@ -70,7 +69,6 @@ static const char* const mali_power_events[_MALI_MAX_EVENTS] = {
static u32 virtual_power_status_register=0;
static char pwr_buf[POWER_BUFFER_SIZE];
-
static int open_copy_private_data(struct inode *inode, struct file *filp)
{
filp->private_data = inode->i_private;
@@ -792,7 +790,7 @@ static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_
char buf[64];
int r;
- r = sprintf(buf, "%u\n", _mali_internal_profiling_is_recording() ? 1 : 0);
+ r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0);
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
@@ -825,16 +823,16 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */
/* check if we are already recording */
- if (MALI_TRUE == _mali_internal_profiling_is_recording())
+ if (MALI_TRUE == _mali_osk_profiling_is_recording())
{
MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n"));
return -EFAULT;
}
/* check if we need to clear out an old recording first */
- if (MALI_TRUE == _mali_internal_profiling_have_recording())
+ if (MALI_TRUE == _mali_osk_profiling_have_recording())
{
- if (_MALI_OSK_ERR_OK != _mali_internal_profiling_clear())
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear())
{
MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
return -EFAULT;
@@ -842,7 +840,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
}
/* start recording profiling data */
- if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
{
MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
return -EFAULT;
@@ -854,7 +852,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
{
/* stop recording profiling data */
u32 count = 0;
- if (_MALI_OSK_ERR_OK != _mali_internal_profiling_stop(&count))
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count))
{
MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
return -EFAULT;
@@ -878,7 +876,7 @@ static void *profiling_events_start(struct seq_file *s, loff_t *pos)
loff_t *spos;
/* check if we have data avaiable */
- if (MALI_TRUE != _mali_internal_profiling_have_recording())
+ if (MALI_TRUE != _mali_osk_profiling_have_recording())
{
return NULL;
}
@@ -898,13 +896,13 @@ static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos)
loff_t *spos = v;
/* check if we have data avaiable */
- if (MALI_TRUE != _mali_internal_profiling_have_recording())
+ if (MALI_TRUE != _mali_osk_profiling_have_recording())
{
return NULL;
}
/* check if the next entry actually is avaiable */
- if (_mali_internal_profiling_get_count() <= (u32)(*spos + 1))
+ if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1))
{
return NULL;
}
@@ -929,7 +927,7 @@ static int profiling_events_show(struct seq_file *seq_file, void *v)
index = (u32)*spos;
/* Retrieve all events */
- if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
+ if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, &timestamp, &event_id, data))
{
seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
return 0;
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
index d007d93..ee857d5 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
@@ -13,12 +13,19 @@
* Implemenation of the OS abstraction layer for the kernel device driver
*/
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
#include <linux/spinlock.h>
#include <linux/rwsem.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else /* pre 2.6.26 the file was in the arch specific location */
+#include <asm/semaphore.h>
+#endif
+#include <linux/slab.h>
#include "mali_osk.h"
#include "mali_kernel_common.h"
@@ -27,9 +34,9 @@ typedef enum
{
_MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */
_MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ, /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */
- _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use mutex_unlock()/down_interruptable() */
- _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use mutex_unlock()/down() */
- _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {mutex_unlock,down}{read,write}() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use up()/down_interruptable() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use up()/down() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {up,down}{read,write}() */
/* Linux supports, but we do not support:
* Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off
@@ -48,7 +55,7 @@ struct _mali_osk_lock_t_struct
union
{
spinlock_t spinlock;
- struct mutex mutex;
+ struct semaphore sema;
struct rw_semaphore rw_sema;
} obj;
MALI_DEBUG_CODE(
@@ -125,7 +132,7 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
}
/* Initially unlocked */
- mutex_init(&lock->obj.mutex);
+ sema_init( &lock->obj.sema, 1 );
}
#ifdef DEBUG
@@ -187,7 +194,7 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
- if (mutex_lock_interruptible(&lock->obj.mutex))
+ if ( down_interruptible(&lock->obj.sema) )
{
MALI_PRINT_ERROR(("Can not lock mutex\n"));
err = _MALI_OSK_ERR_RESTARTSYSCALL;
@@ -195,7 +202,7 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
- mutex_lock(&lock->obj.mutex);
+ down(&lock->obj.sema);
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
@@ -301,7 +308,7 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
/* FALLTHROUGH */
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
- mutex_unlock(&lock->obj.mutex);
+ up(&lock->obj.sema);
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
index 8dc90fd..06cb215 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
@@ -14,11 +14,11 @@
*/
#include <linux/kernel.h>
#include <asm/uaccess.h>
+#include <mach/irqs.h>
#include "mali_kernel_common.h" /* MALI_xxx macros */
#include "mali_osk.h" /* kernel side OS functions */
#include "mali_uk_types.h"
-#include <mach/irqs.h>
#include "arch/config.h" /* contains the configuration of the arch we are compiling for */
_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources )
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
index 2cfb5ef..c14c0d5 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
@@ -21,7 +21,11 @@
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/spinlock.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else /* pre 2.6.26 the file was in the arch specific location */
+#include <asm/semaphore.h>
+#endif
/**
* Declaration of the notification queue object type
@@ -31,7 +35,7 @@
*/
struct _mali_osk_notification_queue_t_struct
{
- spinlock_t mutex; /**< Mutex protecting the list */
+ struct semaphore mutex; /**< Mutex protecting the list */
wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */
struct list_head head; /**< List of notifications waiting to be picked up */
};
@@ -49,7 +53,7 @@ _mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL);
if (NULL == result) return NULL;
- spin_lock_init(&result->mutex);
+ sema_init(&result->mutex, 1);
init_waitqueue_head(&result->receive_queue);
INIT_LIST_HEAD(&result->head);
@@ -117,22 +121,39 @@ void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _
notification = container_of( object, _mali_osk_notification_wrapper_t, data );
/* lock queue access */
- spin_lock(&queue->mutex);
+ down(&queue->mutex);
/* add to list */
list_add_tail(&notification->list, &queue->head);
/* unlock the queue */
- spin_unlock(&queue->mutex);
+ up(&queue->mutex);
/* and wake up one possible exclusive waiter */
wake_up(&queue->receive_queue);
}
+static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *queue )
+{
+ int ret;
+
+ down(&queue->mutex);
+ ret = list_empty(&queue->head);
+ up(&queue->mutex);
+ return ret;
+}
+
+#if MALI_STATE_TRACKING
+mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue )
+{
+ return _mali_notification_queue_is_empty(queue) ? MALI_TRUE : MALI_FALSE;
+}
+#endif
+
_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
{
_mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND;
_mali_osk_notification_wrapper_t *wrapper_object;
- spin_lock(&queue->mutex);
+ down(&queue->mutex);
if (!list_empty(&queue->head))
{
@@ -142,7 +163,7 @@ _mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification
ret = _MALI_OSK_ERR_OK;
}
- spin_unlock(&queue->mutex);
+ up(&queue->mutex);
return ret;
}
@@ -156,10 +177,12 @@ _mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification
/* default result */
*result = NULL;
- if (wait_event_interruptible(queue->receive_queue,
- _MALI_OSK_ERR_OK == _mali_osk_notification_queue_dequeue(queue, result)))
+ while (_MALI_OSK_ERR_OK != _mali_osk_notification_queue_dequeue(queue, result))
{
- return _MALI_OSK_ERR_RESTARTSYSCALL;
+ if (wait_event_interruptible(queue->receive_queue, !_mali_notification_queue_is_empty(queue)))
+ {
+ return _MALI_OSK_ERR_RESTARTSYSCALL;
+ }
}
return _MALI_OSK_ERR_OK; /* all ok */
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c
index 95bee53..95bee53 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c
new file mode 100644
index 0000000..2df935d
--- /dev/null
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+#include "mali_timestamp.h"
+#include "mali_osk_profiling.h"
+#include "mali_user_settings_db.h"
+
+typedef struct mali_profiling_entry
+{
+ u64 timestamp;
+ u32 event_id;
+ u32 data[5];
+} mali_profiling_entry;
+
+
+typedef enum mali_profiling_state
+{
+ MALI_PROFILING_STATE_UNINITIALIZED,
+ MALI_PROFILING_STATE_IDLE,
+ MALI_PROFILING_STATE_RUNNING,
+ MALI_PROFILING_STATE_RETURN,
+} mali_profiling_state;
+
+static _mali_osk_lock_t *lock = NULL;
+static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
+static mali_profiling_entry* profile_entries = NULL;
+static u32 profile_entry_count = 0;
+static _mali_osk_atomic_t profile_insert_index;
+static _mali_osk_atomic_t profile_entries_written;
+
+_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
+{
+ profile_entries = NULL;
+ profile_entry_count = 0;
+ _mali_osk_atomic_init(&profile_insert_index, 0);
+ _mali_osk_atomic_init(&profile_entries_written, 0);
+
+ lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
+ if (NULL == lock)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ prof_state = MALI_PROFILING_STATE_IDLE;
+
+ if (MALI_TRUE == auto_start)
+ {
+ u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
+
+ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_osk_profiling_term(void)
+{
+ prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
+
+ /* wait for all elements to be completely inserted into array */
+ while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written))
+ {
+ /* do nothing */;
+ }
+
+ if (NULL != profile_entries)
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ if (NULL != lock)
+ {
+ _mali_osk_lock_term(lock);
+ lock = NULL;
+ }
+}
+
+inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit)
+{
+ _mali_osk_errcode_t ret;
+
+ mali_profiling_entry *new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry));
+
+ if(NULL == new_profile_entries)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (prof_state != MALI_PROFILING_STATE_IDLE)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_vfree(new_profile_entries);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ if (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES)
+ {
+ *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
+ }
+
+ profile_entries = new_profile_entries;
+ profile_entry_count = *limit;
+
+ ret = _mali_timestamp_reset();
+
+ if (ret == _MALI_OSK_ERR_OK)
+ {
+ prof_state = MALI_PROFILING_STATE_RUNNING;
+ }
+ else
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return ret;
+}
+
+inline void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
+{
+ if (prof_state == MALI_PROFILING_STATE_RUNNING)
+ {
+ u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) % profile_entry_count;
+
+ 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;
+
+ /* If event is "leave API function", add current memory usage to the event
+ * as data point 4. This is used in timeline profiling to indicate how
+ * much memory was used when leaving a function. */
+ if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC))
+ {
+ profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage();
+ }
+
+ _mali_osk_atomic_inc(&profile_entries_written);
+ }
+}
+
+inline void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value)
+{
+ /* Not implemented */
+}
+
+void _mali_osk_profiling_report_sw_counters(u32 *counters)
+{
+ /* Not implemented */
+}
+
+inline _mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count)
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (prof_state != MALI_PROFILING_STATE_RUNNING)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ /* go into return state (user to retreive events), no more events will be added after this */
+ prof_state = MALI_PROFILING_STATE_RETURN;
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* wait for all elements to be completely inserted into array */
+ while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written))
+ {
+ /* do nothing */;
+ }
+
+ *count = _mali_osk_atomic_read(&profile_insert_index);
+ if(*count>profile_entry_count) *count=profile_entry_count;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+inline u32 _mali_osk_profiling_get_count(void)
+{
+ u32 retval = 0;
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+ if (prof_state == MALI_PROFILING_STATE_RETURN)
+ {
+ retval = _mali_osk_atomic_read(&profile_entries_written);
+ if(retval>profile_entry_count) retval = profile_entry_count;
+ }
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+
+ return retval;
+}
+
+inline _mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if(index<profile_entry_count)
+ {
+ u32 idx = index;
+ if(_mali_osk_atomic_read(&profile_insert_index)>=profile_entry_count)
+ {
+ idx = (index + _mali_osk_atomic_read(&profile_insert_index)) % profile_entry_count;
+ }
+
+ 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 (idx >= _mali_osk_atomic_read(&profile_entries_written))
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ *timestamp = profile_entries[idx].timestamp;
+ *event_id = profile_entries[idx].event_id;
+ data[0] = profile_entries[idx].data[0];
+ data[1] = profile_entries[idx].data[1];
+ data[2] = profile_entries[idx].data[2];
+ data[3] = profile_entries[idx].data[3];
+ data[4] = profile_entries[idx].data[4];
+ }
+ else
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_OK;
+}
+
+inline _mali_osk_errcode_t _mali_osk_profiling_clear(void)
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (prof_state != MALI_PROFILING_STATE_RETURN)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ prof_state = MALI_PROFILING_STATE_IDLE;
+ profile_entry_count = 0;
+ _mali_osk_atomic_init(&profile_insert_index, 0);
+ _mali_osk_atomic_init(&profile_entries_written, 0);
+ if (NULL != profile_entries)
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_OK;
+}
+
+mali_bool _mali_osk_profiling_is_recording(void)
+{
+ return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
+}
+
+mali_bool _mali_osk_profiling_have_recording(void)
+{
+ return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
+{
+ return _mali_osk_profiling_start(&args->limit);
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args)
+{
+ /* Always add process and thread identificator in the first two data elements for events from user space */
+ _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]);
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args)
+{
+ return _mali_osk_profiling_stop(&args->count);
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args)
+{
+ return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data);
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args)
+{
+ return _mali_osk_profiling_clear();
+}
+
+_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args)
+{
+ _mali_osk_profiling_report_sw_counters(args->counters);
+ return _MALI_OSK_ERR_OK;
+}
+
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
index 157368b..83ee906 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
@@ -17,15 +17,17 @@
#ifndef __MALI_OSK_SPECIFIC_H__
#define __MALI_OSK_SPECIFIC_H__
-#include <asm/uaccess.h>
+#ifdef __cplusplus
+extern "C"
+{
+#endif
#define MALI_STATIC_INLINE static inline
#define MALI_NON_STATIC_INLINE inline
-MALI_STATIC_INLINE u32 _mali_osk_copy_from_user(void *to, void *from, u32 n)
-{
- return (u32)copy_from_user(to, from, (unsigned long)n);
+#ifdef __cplusplus
}
+#endif
/** The list of events supported by the Mali DDK. */
typedef enum
@@ -37,7 +39,7 @@ typedef enum
ACTIVITY_FP0,
ACTIVITY_FP1,
ACTIVITY_FP2,
- ACTIVITY_FP3,
+ ACTIVITY_FP3,
/* L2 cache counters */
COUNTER_L2_C0,
@@ -57,7 +59,7 @@ typedef enum
COUNTER_FP3_C0,
COUNTER_FP3_C1,
- /*
+ /*
* If more hardware counters are added, the _mali_osk_hw_counter_table
* below should also be updated.
*/
diff --git a/drivers/media/video/samsung/mali/linux/mali_profiling_internal.c b/drivers/media/video/samsung/mali/linux/mali_profiling_internal.c
deleted file mode 100644
index 8202497..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_profiling_internal.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_ukk.h"
-#include "mali_timestamp.h"
-#include "mali_osk_profiling.h"
-#include "mali_user_settings_db.h"
-#include "mali_profiling_internal.h"
-
-typedef struct mali_profiling_entry
-{
- u64 timestamp;
- u32 event_id;
- u32 data[5];
-} mali_profiling_entry;
-
-
-typedef enum mali_profiling_state
-{
- MALI_PROFILING_STATE_UNINITIALIZED,
- MALI_PROFILING_STATE_IDLE,
- MALI_PROFILING_STATE_RUNNING,
- MALI_PROFILING_STATE_RETURN,
-} mali_profiling_state;
-
-static _mali_osk_lock_t *lock = NULL;
-static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
-static mali_profiling_entry* profile_entries = NULL;
-static _mali_osk_atomic_t profile_insert_index;
-static u32 profile_mask = 0;
-static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
-
-void probe_mali_timeline_event(void *data, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned
- int d2, unsigned int d3, unsigned int d4))
-{
- add_event(event_id, d0, d1, d2, d3, d4);
-}
-
-_mali_osk_errcode_t _mali_internal_profiling_init(mali_bool auto_start)
-{
- profile_entries = NULL;
- profile_mask = 0;
- _mali_osk_atomic_init(&profile_insert_index, 0);
-
- lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
- if (NULL == lock)
- {
- return _MALI_OSK_ERR_FAULT;
- }
-
- prof_state = MALI_PROFILING_STATE_IDLE;
-
- if (MALI_TRUE == auto_start)
- {
- u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
-
- mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
- if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
- {
- return _MALI_OSK_ERR_FAULT;
- }
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-void _mali_internal_profiling_term(void)
-{
- u32 count;
-
- /* Ensure profiling is stopped */
- _mali_internal_profiling_stop(&count);
-
- prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
-
- if (NULL != profile_entries)
- {
- _mali_osk_vfree(profile_entries);
- profile_entries = NULL;
- }
-
- if (NULL != lock)
- {
- _mali_osk_lock_term(lock);
- lock = NULL;
- }
-}
-
-_mali_osk_errcode_t _mali_internal_profiling_start(u32 * limit)
-{
- _mali_osk_errcode_t ret;
-
- mali_profiling_entry *new_profile_entries;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (MALI_PROFILING_MAX_BUFFER_ENTRIES < *limit)
- {
- *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
- }
-
- profile_mask = 1;
- while (profile_mask <= *limit)
- {
- profile_mask <<= 1;
- }
- profile_mask >>= 1;
-
- *limit = profile_mask;
-
- profile_mask--; /* turns the power of two into a mask of one less */
-
- new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry));
-
- if (NULL == new_profile_entries)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_NOMEM;
- }
-
- if (MALI_PROFILING_STATE_IDLE != prof_state)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_vfree(new_profile_entries);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- profile_entries = new_profile_entries;
-
- ret = _mali_timestamp_reset();
-
- if (_MALI_OSK_ERR_OK == ret)
- {
- prof_state = MALI_PROFILING_STATE_RUNNING;
- }
- else
- {
- _mali_osk_vfree(profile_entries);
- profile_entries = NULL;
- }
-
- register_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return ret;
-}
-
-static inline void 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) & profile_mask;
-
- 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;
-
- /* If event is "leave API function", add current memory usage to the event
- * as data point 4. This is used in timeline profiling to indicate how
- * much memory was used when leaving a function. */
- if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC))
- {
- profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage();
- }
-}
-
-_mali_osk_errcode_t _mali_internal_profiling_stop(u32 * count)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (MALI_PROFILING_STATE_RUNNING != prof_state)
- {
- _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;
-
- unregister_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
- tracepoint_synchronize_unregister();
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
-
- *count = _mali_osk_atomic_read(&profile_insert_index);
- if (*count > profile_mask) *count = profile_mask;
-
- return _MALI_OSK_ERR_OK;
-}
-
-u32 _mali_internal_profiling_get_count(void)
-{
- u32 retval = 0;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if (MALI_PROFILING_STATE_RETURN == prof_state)
- {
- retval = _mali_osk_atomic_read(&profile_insert_index);
- if (retval > profile_mask) retval = profile_mask;
- }
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
-
- return retval;
-}
-
-_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
-{
- u32 raw_index = _mali_osk_atomic_read(&profile_insert_index);
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (index < profile_mask)
- {
- if ((raw_index & ~profile_mask) != 0)
- {
- index += raw_index;
- index &= profile_mask;
- }
-
- 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 >= raw_index)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_FAULT;
- }
-
- *timestamp = profile_entries[index].timestamp;
- *event_id = profile_entries[index].event_id;
- data[0] = profile_entries[index].data[0];
- data[1] = profile_entries[index].data[1];
- data[2] = profile_entries[index].data[2];
- data[3] = profile_entries[index].data[3];
- data[4] = profile_entries[index].data[4];
- }
- else
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_FAULT;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t _mali_internal_profiling_clear(void)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (MALI_PROFILING_STATE_RETURN != prof_state)
- {
- _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_mask = 0;
- _mali_osk_atomic_init(&profile_insert_index, 0);
-
- if (NULL != profile_entries)
- {
- _mali_osk_vfree(profile_entries);
- profile_entries = NULL;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_OK;
-}
-
-mali_bool _mali_internal_profiling_is_recording(void)
-{
- return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
-}
-
-mali_bool _mali_internal_profiling_have_recording(void)
-{
- return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
-}
diff --git a/drivers/media/video/samsung/mali/linux/mali_profiling_internal.h b/drivers/media/video/samsung/mali/linux/mali_profiling_internal.h
deleted file mode 100644
index 092b9b0..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_profiling_internal.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __MALI_PROFILING_INTERNAL_H__
-#define __MALI_PROFILING_INTERNAL_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include "mali_osk.h"
-
-int _mali_internal_profiling_init(mali_bool auto_start);
-void _mali_internal_profiling_term(void);
-
-mali_bool _mali_internal_profiling_is_recording(void);
-mali_bool _mali_internal_profiling_have_recording(void);
-_mali_osk_errcode_t _mali_internal_profiling_clear(void);
-_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
-u32 _mali_internal_profiling_get_count(void);
-int _mali_internal_profiling_stop(u32 * count);
-int _mali_internal_profiling_start(u32 * limit);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PROFILING_INTERNAL_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_uk_types.h b/drivers/media/video/samsung/mali/linux/mali_uk_types.h
index fbe902a..1a81246 100644
--- a/drivers/media/video/samsung/mali/linux/mali_uk_types.h
+++ b/drivers/media/video/samsung/mali/linux/mali_uk_types.h
@@ -12,6 +12,7 @@
#define __MALI_UK_TYPES_H__
/* Simple wrapper in order to find the OS specific location of this file */
-#include <linux/mali/mali_utgard_uk_types.h>
+//#include <linux/mali/mali_utgard_uk_types.h>
+#include "../include/linux/mali/mali_utgard_uk_types.h"
#endif /* __MALI_UK_TYPES_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
index 4ee4a81..7070016 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
@@ -18,15 +18,40 @@
int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs)
{
- _mali_osk_errcode_t err;
+ _mali_uk_gp_start_job_s kargs;
+ _mali_osk_errcode_t err;
- MALI_CHECK_NON_NULL(uargs, -EINVAL);
- MALI_CHECK_NON_NULL(session_data, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- err = _mali_ukk_gp_start_job(session_data, uargs);
- if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+ if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_gp_start_job_s)))
+ {
+ return -EFAULT;
+ }
- return 0;
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_start_job_s))) return -EFAULT;
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_gp_start_job(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_gp_start_job_s)))
+ {
+ /*
+ * If this happens, then user space will not know that the job was actually started,
+ * and if we return a queued job, then user space will still think that one is still queued.
+ * This will typically lead to a deadlock in user space.
+ * This could however only happen if user space deliberately passes a user buffer which
+ * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user().
+ * The official Mali driver will never attempt to do that, and kernel space should not be affected.
+ * That is why we do not bother to do a complex rollback in this very very very rare case.
+ */
+ return -EFAULT;
+ }
+
+ return 0;
}
int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs)
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
index 00a84f7..c11c61b 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
@@ -18,15 +18,24 @@
int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs)
{
+ _mali_uk_pp_start_job_s kargs;
_mali_osk_errcode_t err;
MALI_CHECK_NON_NULL(uargs, -EINVAL);
MALI_CHECK_NON_NULL(session_data, -EINVAL);
- err = _mali_ukk_pp_start_job(session_data, uargs);
+ if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_pp_start_job_s)))
+ {
+ return -EFAULT;
+ }
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_start_job_s))) return -EFAULT;
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_pp_start_job(&kargs);
if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
- return 0;
+ return 0;
}
int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs)
diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
index 792b9a9..119831d 100644
--- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
+++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -19,7 +19,7 @@
#include "mali_linux_pm.h"
#if USING_MALI_PMM
-#include "mali_pmm.h"
+#include "mali_pm.h"
#endif
#include <linux/clk.h>
@@ -156,7 +156,7 @@ void mali_regulator_set_voltage(int min_uV, int max_uV)
return;
}
MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
-
+
#if MALI_TIMELINE_PROFILING_ENABLED
_mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
@@ -166,7 +166,7 @@ void mali_regulator_set_voltage(int min_uV, int max_uV)
regulator_set_voltage(g3d_regulator,min_uV,max_uV);
voltage = regulator_get_voltage(g3d_regulator);
-
+
#if MALI_TIMELINE_PROFILING_ENABLED
_mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
@@ -178,7 +178,7 @@ void mali_regulator_set_voltage(int min_uV, int max_uV)
_mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
}
-#endif
+#endif
unsigned long mali_clk_get_rate(void)
{
@@ -228,7 +228,7 @@ mali_bool mali_clk_get(mali_bool bis_vpll)
if (mali_parent_clock == NULL)
{
mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
-
+
if (IS_ERR(mali_parent_clock)) {
MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
return MALI_FALSE;
@@ -279,7 +279,7 @@ void mali_clk_put(mali_bool binc_mali_clock)
clk_put(mali_parent_clock);
mali_parent_clock = 0;
}
-
+
if (mpll_clock)
{
clk_put(mpll_clock);
@@ -303,7 +303,7 @@ void mali_clk_put(mali_bool binc_mali_clock)
clk_put(vpll_src_clock);
vpll_src_clock = 0;
}
-
+
if (ext_xtal_clock)
{
clk_put(ext_xtal_clock);
@@ -382,14 +382,14 @@ mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz)
mali_clk_put(MALI_FALSE);
_mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
+
return MALI_TRUE;
}
static mali_bool init_mali_clock(void)
{
mali_bool ret = MALI_TRUE;
-
+
gpu_power_state = 0;
if (mali_clock != 0)
@@ -416,7 +416,7 @@ static mali_bool init_mali_clock(void)
g3d_regulator = regulator_get(NULL, "vdd_g3d");
#endif
- if (IS_ERR(g3d_regulator))
+ if (IS_ERR(g3d_regulator))
{
MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
ret = MALI_FALSE;
@@ -429,8 +429,6 @@ static mali_bool init_mali_clock(void)
#endif
MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n"));
-
-
MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__));
MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__));
@@ -443,7 +441,7 @@ static mali_bool init_mali_clock(void)
err_regulator:
regulator_put(g3d_regulator);
#endif
-
+
err_clock_get:
mali_clk_put(MALI_TRUE);
@@ -456,7 +454,7 @@ static mali_bool deinit_mali_clock(void)
return MALI_TRUE;
#ifdef CONFIG_REGULATOR
- if (g3d_regulator)
+ if (g3d_regulator)
{
regulator_put(g3d_regulator);
g3d_regulator=NULL;
@@ -506,8 +504,8 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
if (bpower_on)
{
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT(3,("_mali_osk_pmm_dev_activate \n"));
- _mali_osk_pmm_dev_activate();
+ MALI_DEBUG_PRINT(3,("_mali_osk_pm_dev_activate \n"));
+ _mali_osk_pm_dev_activate();
#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
void __iomem *status;
u32 timeout;
@@ -529,14 +527,14 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
else
{
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT( 4,("_mali_osk_pmm_dev_idle\n"));
- _mali_osk_pmm_dev_idle();
+ MALI_DEBUG_PRINT( 4,("_mali_osk_pm_dev_idle\n"));
+ _mali_osk_pm_dev_idle();
#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
void __iomem *status;
u32 timeout;
__raw_writel(0, S5P_PMU_G3D_CONF);
-
+
status = S5P_PMU_G3D_CONF + 0x4;
/* Wait max 1ms */
timeout = 10;
@@ -561,7 +559,7 @@ _mali_osk_errcode_t mali_platform_init()
#if MALI_DVFS_ENABLED
if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP))
- MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
+ MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
#endif
MALI_SUCCESS;
@@ -593,7 +591,7 @@ _mali_osk_errcode_t mali_platform_powerdown(u32 cores)
if (gpu_power_state == 0)
{
MALI_DEBUG_PRINT( 3,("disable clock\n"));
- disable_mali_clocks();
+ disable_mali_clocks();
}
}
else
@@ -635,7 +633,7 @@ _mali_osk_errcode_t mali_platform_powerup(u32 cores)
void mali_gpu_utilization_handler(u32 utilization)
{
- if (bPoweroff==0)
+ if (bPoweroff==0)
{
#if MALI_DVFS_ENABLED
if(!mali_dvfs_handler(utilization))
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
index 8fc26cd..a08bc97 100644
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
+++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
@@ -33,7 +33,8 @@
#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
#include "mali_osk_profiling.h"
-#include "cinstr/mali_cinstr_profiling_events_m200.h"
+unsigned long gFreq = 366;
+int gVolt = 5000;
#endif
#include <asm/io.h>
@@ -58,7 +59,7 @@ typedef struct mali_runtime_resumeTag{
int vol;
}mali_runtime_resume_table;
-mali_runtime_resume_table mali_runtime_resume = {350, 950000};
+mali_runtime_resume_table mali_runtime_resume = {266, 900000};
/* lock/unlock CPU freq by Mali */
extern int cpufreq_lock_by_mali(unsigned int freq);
@@ -84,11 +85,11 @@ static struct clk *mali_clock = 0;
static unsigned int GPU_MHZ = 1000000;
-int mali_gpu_clk = 350;
-int mali_gpu_vol = 950000;
+int mali_gpu_clk = 266;
+int mali_gpu_vol = 900000;
#if MALI_DVFS_ENABLED
-#define MALI_DVFS_DEFAULT_STEP 2
+#define MALI_DVFS_DEFAULT_STEP 1
#endif
#if MALI_VOLTAGE_LOCK
int mali_lock_vol = 0;
@@ -204,21 +205,15 @@ void mali_regulator_set_voltage(int min_uV, int max_uV)
MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS,
- min_uV, max_uV, 1, 0, 0);
-#endif
-
regulator_set_voltage(g3d_regulator,min_uV,max_uV);
voltage = regulator_get_voltage(g3d_regulator);
#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS,
- voltage, 0, 2, 0, 0);
+ gVolt = voltage/1000;
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, gFreq, gVolt,
+ 0, 0, 0);
#endif
mali_gpu_vol = voltage;
@@ -379,7 +374,7 @@ mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz)
#if !MALI_DVFS_ENABLED
clk = mali_gpu_clk;
#endif
-
+ trace_printk("SPI_GPUFREQ_%uMHz\n", mali_gpu_clk);
_mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
if (mali_clk_get(bis_vpll) == MALI_FALSE)
@@ -406,23 +401,16 @@ mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz)
if (clk_enable(mali_clock) < 0)
return MALI_FALSE;
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- unsigned long previous_rate = 0;
- previous_rate = clk_get_rate(mali_clock);
- _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ,
- previous_rate, 0, 0, 0, 0);
-#endif
clk_set_rate(mali_clock, rate);
rate = clk_get_rate(mali_clock);
#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ,
- rate, 1, 0, 0, 0);
+ gFreq = rate/1000000;
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ gFreq, gVolt, 0, 0, 0);
#endif
if (bis_vpll)
@@ -539,7 +527,7 @@ static _mali_osk_errcode_t enable_mali_clocks(void)
}
#if CPUFREQ_LOCK_DURING_440
/* lock/unlock CPU freq by Mali */
- if (mali_gpu_clk == 440)
+ if (mali_gpu_clk >= 440)
err = cpufreq_lock_by_mali(1200);
#endif
#else
@@ -557,7 +545,7 @@ static _mali_osk_errcode_t disable_mali_clocks(void)
clk_disable(mali_clock);
MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
-#if MALI_DVFS_ENABLED
+#if MALI_DVFS_ENABLED && CPUFREQ_LOCK_DURING_440
/* lock/unlock CPU freq by Mali */
cpufreq_unlock_by_mali();
#endif
@@ -598,7 +586,6 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
timeout--;
_mali_osk_time_ubusydelay(100);
}
- MALI_PRINTF(("MALI Power domain enabled"));
#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
}
else
@@ -623,7 +610,6 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
timeout--;
_mali_osk_time_ubusydelay( 100);
}
- MALI_PRINTF(("MALI Power domain disabled"));
#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
}
@@ -665,6 +651,7 @@ _mali_osk_errcode_t mali_platform_deinit()
_mali_osk_errcode_t mali_platform_powerdown(u32 cores)
{
+ trace_printk("SPI_GPU_PWR Idle\n");
MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores));
if (gpu_power_state != 0) // power down after state is 0
@@ -686,6 +673,7 @@ _mali_osk_errcode_t mali_platform_powerdown(u32 cores)
_mali_osk_errcode_t mali_platform_powerup(u32 cores)
{
+ trace_printk("SPI_GPU_PWR Start\n");
MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores));
if (gpu_power_state == 0) // power up only before state is 0
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
index e83addd..cc1164e 100644
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
+++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
@@ -175,6 +175,7 @@ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
#ifdef EXYNOS4_ASV_ENABLED
#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */
+#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */
static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
{ 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */
@@ -202,7 +203,7 @@ static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
#endif
};
-static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL] = {
+static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = {
{ 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000}, /* L4(160Mhz) */
#if (MALI_DVFS_STEPS > 1)
{ 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 862500}, /* L3(266Mhz) */
@@ -211,7 +212,7 @@ static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL] =
#if (MALI_DVFS_STEPS > 3)
{ 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500, 975000}, /* L1(440Mhz) */
#if (MALI_DVFS_STEPS > 4)
- { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(533Mhz) */
+ { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(600Mhz) */
#endif
#endif
#endif
@@ -330,10 +331,12 @@ static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
}
#ifdef EXYNOS4_ASV_ENABLED
- if (mali_dvfs[step].clock == 160)
- exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
- else
- exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_dvfs[step].clock == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
#endif
@@ -390,26 +393,33 @@ static mali_bool mali_dvfs_table_update(void)
unsigned int i;
unsigned int step_num = MALI_DVFS_STEPS;
+ if(samsung_rev() < EXYNOS4412_REV_2_0)
+ step_num = MALI_DVFS_STEPS - 1;
+
if(soc_is_exynos4412()) {
if (exynos_armclk_max == 1000000) {
- step_num = MALI_DVFS_STEPS - 1;
+ MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv));
for (i = 0; i < step_num; i++) {
- MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv));
mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d 1ghz_type\n", i, mali_dvfs[i].vol));
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+ }
+ } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) {
+ MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000;
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol));
}
} else if (samsung_rev() >= EXYNOS4412_REV_2_0) {
+ MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv));
for (i = 0; i < step_num; i++) {
- MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv));
mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d 1.6ghz_type\n", i, mali_dvfs[i].vol));
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
}
} else {
- step_num = MALI_DVFS_STEPS - 1;
+ MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv));
for (i = 0; i < step_num; i++) {
- MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv));
mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d 1.4ghz_type\n", i, mali_dvfs[i].vol));
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
}
}
}
diff --git a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
index dd259cf..21c83c0 100644
--- a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
+++ b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
@@ -145,6 +145,7 @@ typedef enum
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
+ MALIGP2_REG_VAL_IRQ_HANG | \
MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
@@ -155,6 +156,7 @@ typedef enum
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
+ MALIGP2_REG_VAL_IRQ_HANG | \
MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig
index aaae26e..9d8e5e6 100644
--- a/drivers/media/video/samsung/ump/Kconfig
+++ b/drivers/media/video/samsung/ump/Kconfig
@@ -17,10 +17,18 @@ config UMP_VCM_ALLOC
help
Use VCM(virtual-contiguous-memory) to allocate physical memory.
+
+config UMP_R3P1_LSI
+ bool "Uses the R3P1 as a ump module"
+ depends on VIDEO_UMP
+ default n
+ ---help---
+ This uses the r3p1 as a UMP kernel module
+
choice
depends on VIDEO_UMP
prompt "UMP MEMEMORY OPTION"
-default UMP_OSMEM_ONLY
+default UMP_OSMEM_ONLY
config UMP_DED_ONLY
bool "ump dedicated memory only"
---help---
@@ -37,7 +45,7 @@ config UMP_VCM_ONLY
endchoice
config UMP_MEM_SIZE
int "UMP Memory Size"
- depends on VIDEO_UMP
+ depends on VIDEO_UMP
default "512"
---help---
This value is dedicated memory size of UMP (unit is MByte).
@@ -48,4 +56,3 @@ config VIDEO_UMP_DEBUG
default n
help
This enables UMP driver debug messages.
-
diff --git a/drivers/media/video/samsung/ump/Makefile b/drivers/media/video/samsung/ump/Makefile
index 0ba1253..3a1aac0 100644
--- a/drivers/media/video/samsung/ump/Makefile
+++ b/drivers/media/video/samsung/ump/Makefile
@@ -18,6 +18,12 @@ UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE)
USING_MEMORY=1
endif
+ifeq ($(CONFIG_UMP_VCM_ONLY),y)
+UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE)
+USING_MEMORY=2
+endif
+
+
# For UMP Debug
ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y)
DEFINES += -DDEBUG
@@ -72,6 +78,9 @@ ump-y := \
$(KBUILDROOT)common/ump_kernel_ref_drv.o\
$(OSKFILES)
+ump-$(CONFIG_UMP_VCM_ALLOC) += \
+ $(KBUILDROOT)linux/ump_kernel_memory_backend_vcm.o \
+
EXTRA_CFLAGS += $(INCLUDES) \
$(DEFINES)
diff --git a/drivers/media/video/samsung/ump/Makefile.common b/drivers/media/video/samsung/ump/Makefile.common
index 503a38d..26a3d6c 100644
--- a/drivers/media/video/samsung/ump/Makefile.common
+++ b/drivers/media/video/samsung/ump/Makefile.common
@@ -1,9 +1,9 @@
#
# 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.
#
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_api.c b/drivers/media/video/samsung/ump/common/ump_kernel_api.c
index 6569b02..83f0d30 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_api.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_api.c
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -55,7 +55,24 @@ UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secu
return (ump_dd_handle)mem;
}
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id)
+{
+ ump_dd_mem * mem;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id));
+ if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id));
+ return UMP_DD_HANDLE_INVALID;
+ }
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return (ump_dd_handle)mem;
+}
UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle memh)
{
@@ -260,7 +277,7 @@ _mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info )
}
_mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id));
+ DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id));
DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret));
return ret;
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.c b/drivers/media/video/samsung/ump/common/ump_kernel_common.c
index b1545e8..a27bc77 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_common.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.c
@@ -233,7 +233,12 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
return _MALI_OSK_ERR_INVALID_ARGS;
}
-
+ /* SEC kernel stability 2012-02-17 */
+ if (NULL == session_data->cookies_map)
+ {
+ MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n"));
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
descriptor = (ump_memory_allocation*) _mali_osk_calloc( 1, sizeof(ump_memory_allocation));
if (NULL == descriptor)
{
@@ -283,6 +288,12 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
args->is_cached = 1;
DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id));
}
+ else if ( args->is_cached)
+ {
+ mem->is_cached = 1;
+ descriptor->is_cached = 1;
+ DBG_MSG(3, ("Warning mapping UMP secure_id: %d. As cached, while it was allocated uncached.\n", args->secure_id));
+ }
else
{
descriptor->is_cached = 0;
@@ -360,7 +371,12 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args )
MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
return;
}
-
+ /* SEC kernel stability 2012-02-17 */
+ if (NULL == session_data->cookies_map)
+ {
+ MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n"));
+ return;
+ }
if (0 != ump_descriptor_mapping_get( session_data->cookies_map, (int)args->cookie, (void**)&descriptor) )
{
MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie ));
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
index d6b59b7..cc7b8be 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -65,9 +65,9 @@ void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map)
int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target)
{
- int descriptor = -1;/*-EFAULT;*/
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
- descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
+ int descriptor = -1;/*-EFAULT;*/
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
if (descriptor == map->current_nr_mappings)
{
int nr_mappings_new;
@@ -89,8 +89,8 @@ int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void *
goto unlock_and_exit;
}
- _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
- _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
+ _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
+ _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
map->table = new_table;
map->current_nr_mappings = nr_mappings_new;
descriptor_table_free(old_table);
@@ -107,10 +107,10 @@ unlock_and_exit:
int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target)
{
- int result = -1;/*-EFAULT;*/
- DEBUG_ASSERT(map);
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ int result = -1;/*-EFAULT;*/
+ DEBUG_ASSERT(map);
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
{
*target = map->table->mappings[descriptor];
result = 0;
@@ -122,9 +122,9 @@ int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, voi
int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target)
{
- int result = -1;/*-EFAULT;*/
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ int result = -1;/*-EFAULT;*/
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
{
map->table->mappings[descriptor] = target;
result = 0;
@@ -135,8 +135,8 @@ int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, voi
void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor)
{
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
- if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
{
map->table->mappings[descriptor] = NULL;
_mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
@@ -163,4 +163,3 @@ static void descriptor_table_free(ump_descriptor_table * table)
{
_mali_osk_free(table);
}
-
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
index a91ae28..73915ee 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -40,6 +40,8 @@ typedef struct ump_memory_backend
u32 (*stat)(struct ump_memory_backend *backend);
int (*pre_allocate_physical_check)(void *ctx, u32 size);
u32 (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys);
+ void *(*get)(ump_dd_mem *mem, void *args);
+ void (*set)(ump_dd_mem *mem, void *args);
void * ctx;
} ump_memory_backend;
@@ -47,4 +49,3 @@ ump_memory_backend * ump_memory_backend_create ( void );
void ump_memory_backend_destroy( void );
#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */
-
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
index cd5825e..cb13232 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
@@ -195,3 +195,66 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
return _MALI_OSK_ERR_OK;
}
+
+
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args)
+{
+ ump_dd_mem * mem;
+ ump_secure_id secure_id;
+
+ DEBUG_ASSERT_POINTER(memh);
+
+ secure_id = ump_dd_secure_id_get(memh);
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ device.backend->set(mem, args);
+ }
+ else
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_set(). ID: %u\n", (ump_secure_id)secure_id));
+ return UMP_DD_INVALID;
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return UMP_DD_SUCCESS;
+}
+
+UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args)
+{
+ ump_dd_mem * mem;
+ void *result;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ result = device.backend->get(mem, args);
+ }
+ else
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_get(). ID: %u\n", (ump_secure_id)secure_id));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return result;
+}
+
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr)
+{
+ ump_dd_mem * mem;
+
+ DBG_MSG(5, ("Getting handle from Virtual address. vaddr: %u\n", vaddr));
+
+ _ump_osk_mem_mapregion_get(&mem, vaddr);
+
+ DBG_MSG(1, ("Getting handle's Handle : 0x%8lx\n", mem));
+
+ return (ump_dd_handle)mem;
+}
+
diff --git a/drivers/media/video/samsung/ump/common/ump_osk.h b/drivers/media/video/samsung/ump/common/ump_osk.h
index cae0433..dabdc7f 100644
--- a/drivers/media/video/samsung/ump/common/ump_osk.h
+++ b/drivers/media/video/samsung/ump/common/ump_osk.h
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -42,6 +42,8 @@ void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor );
void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data );
+void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/media/video/samsung/ump/common/ump_uk_types.h b/drivers/media/video/samsung/ump/common/ump_uk_types.h
index 4fd1ef7..143588d 100644
--- a/drivers/media/video/samsung/ump/common/ump_uk_types.h
+++ b/drivers/media/video/samsung/ump/common/ump_uk_types.h
@@ -49,7 +49,9 @@ typedef enum
_UMP_IOC_SWITCH_HW_USAGE,
_UMP_IOC_LOCK,
_UMP_IOC_UNLOCK,
+#ifdef CONFIG_ION_EXYNOS
_UMP_IOC_ION_IMPORT,
+#endif
}_ump_uk_functions;
typedef enum
@@ -108,6 +110,7 @@ typedef struct _ump_uk_allocate_s
ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
} _ump_uk_allocate_s;
+#ifdef CONFIG_ION_EXYNOS
typedef struct _ump_uk_ion_import_s
{
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
@@ -116,6 +119,7 @@ typedef struct _ump_uk_ion_import_s
u32 size; /**< Input and output. Requested size; input. Returned size; output */
ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
} _ump_uk_ion_import_s;
+#endif
/**
* SIZE_GET ([in] u32 secure_id, [out]size )
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
index c993746..36c5c9d 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
+++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -23,6 +23,10 @@ extern "C" {
/** Turn specified physical memory into UMP memory. */
UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks);
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id);
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args);
+UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args);
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr);
#ifdef __cplusplus
}
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
index 158cc88..a358a3c 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
@@ -92,7 +92,7 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
#endif
static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma);
-#if defined(CONFIG_VIDEO_MALI400MP)
+#if defined(CONFIG_VIDEO_UMP)
extern int map_errcode( _mali_osk_errcode_t err );
#endif
@@ -400,7 +400,7 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
return err;
}
-#ifndef CONFIG_VIDEO_MALI400MP
+#ifndef CONFIG_VIDEO_UMP
int map_errcode( _mali_osk_errcode_t err )
{
switch(err)
@@ -429,7 +429,7 @@ static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma)
/* Validate the session data */
session_data = (struct ump_session_data *)filp->private_data;
- if (NULL == session_data)
+ if (NULL == session_data || NULL == session_data->cookies_map->table->mappings)
{
MSG_ERR(("mmap() called without any session data available\n"));
return -EFAULT;
@@ -474,6 +474,9 @@ EXPORT_SYMBOL(ump_dd_phys_blocks_get);
EXPORT_SYMBOL(ump_dd_size_get);
EXPORT_SYMBOL(ump_dd_reference_add);
EXPORT_SYMBOL(ump_dd_reference_release);
+EXPORT_SYMBOL(ump_dd_meminfo_get);
+EXPORT_SYMBOL(ump_dd_meminfo_set);
+EXPORT_SYMBOL(ump_dd_handle_get_from_vaddr);
/* Export our own extended kernel space allocator */
EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks);
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
index 463e609..82c16cc 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
@@ -1,9 +1,9 @@
/*
* 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.
*/
@@ -108,6 +108,8 @@ ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size)
backend->stat = block_allocator_stat;
backend->pre_allocate_physical_check = NULL;
backend->adjust_to_mali_phys = NULL;
+ backend->get = NULL;
+ backend->set = NULL;
return backend;
}
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
index fc3afa8..8f6a9b3 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
@@ -77,6 +77,8 @@ ump_memory_backend * ump_os_memory_backend_create(const int max_allocation)
backend->stat = os_stat;
backend->pre_allocate_physical_check = NULL;
backend->adjust_to_mali_phys = NULL;
+ backend->get = NULL;
+ backend->set = NULL;
return backend;
}
@@ -134,19 +136,20 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
return 0; /* failure */
}
- while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max))
+ while (left > 0)
{
struct page * new_page;
if (is_cached)
{
- new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN);
+ new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN );
} else
{
- new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
+ new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD);
}
if (NULL == new_page)
{
+ MSG_ERR(("UMP memory allocated: Out of Memory !!\n"));
break;
}
@@ -180,6 +183,8 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
if (left)
{
DBG_MSG(1, ("Failed to allocate needed pages\n"));
+ DBG_MSG(1, ("UMP memory allocated: %d kB Configured maximum OS memory usage: %d kB\n",
+ (pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
while(pages_allocated)
{
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
new file mode 100644
index 0000000..46797ea
--- /dev/null
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
@@ -0,0 +1,290 @@
+/*
+ * 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.
+ */
+
+/* create by boojin.kim@samsung.com */
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else /* pre 2.6.26 the file was in the arch specific location */
+#include <asm/semaphore.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/atomic.h>
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
+#include "ump_kernel_common.h"
+#include "ump_kernel_memory_backend.h"
+#include "ump_kernel_interface_ref_drv.h"
+#include "ump_kernel_memory_backend_vcm.h"
+#include "../common/ump_uk_types.h"
+#include <linux/vcm-drv.h>
+#include <plat/s5p-vcm.h>
+#include <linux/dma-mapping.h>
+
+#define UMP_REF_DRV_UK_VCM_DEV_G2D 12
+
+typedef struct ump_vcm {
+ struct vcm *vcm;
+ struct vcm_res *vcm_res;
+ unsigned int dev_id;
+} ump_vcm;
+
+typedef struct vcm_allocator {
+ struct semaphore mutex;
+ u32 num_vcm_blocks;
+} vcm_allocator;
+
+static void ump_vcm_free(void* ctx, ump_dd_mem * descriptor);
+static int ump_vcm_allocate(void* ctx, ump_dd_mem * descriptor);
+static void *vcm_res_get(ump_dd_mem *mem, void* args);
+static void vcm_attr_set(ump_dd_mem *mem, void* args);
+static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor);
+static void vcm_memory_backend_destroy(ump_memory_backend * backend);
+
+
+/*
+ * Create VCM memory backend
+ */
+ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation)
+{
+ ump_memory_backend * backend;
+ vcm_allocator * info;
+
+ info = kmalloc(sizeof(vcm_allocator), GFP_KERNEL);
+ if (NULL == info)
+ {
+ return NULL;
+ }
+
+ info->num_vcm_blocks = 0;
+
+
+ sema_init(&info->mutex, 1);
+
+ backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL);
+ if (NULL == backend)
+ {
+ kfree(info);
+ return NULL;
+ }
+
+ backend->ctx = info;
+ backend->allocate = ump_vcm_allocate;
+ backend->release = ump_vcm_free;
+ backend->shutdown = vcm_memory_backend_destroy;
+ backend->pre_allocate_physical_check = NULL;
+ backend->adjust_to_mali_phys = NULL;
+
+ backend->get = vcm_res_get;
+ backend->set = vcm_attr_set;
+
+
+ return backend;
+}
+
+/*
+ * Destroy specified VCM memory backend
+ */
+static void vcm_memory_backend_destroy(ump_memory_backend * backend)
+{
+ vcm_allocator * info = (vcm_allocator*)backend->ctx;
+#if 0
+ DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated));
+#endif
+ kfree(info);
+ kfree(backend);
+}
+
+/*
+ * Allocate UMP memory
+ */
+static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor)
+{
+ int ret; /* success */
+ vcm_allocator *info;
+ struct ump_vcm *ump_vcm;
+
+ BUG_ON(!descriptor);
+ BUG_ON(!ctx);
+
+ info = (vcm_allocator*)ctx;
+
+ ump_vcm = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL);
+ if (NULL == ump_vcm)
+ {
+ return 0;
+ }
+
+ ump_vcm->dev_id = (int)descriptor->backend_info & ~UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE;
+
+ if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_NONE) { /* None */
+ ump_vcm->dev_id = UMP_REF_DRV_UK_VCM_DEV_G2D; /* this ID is G2D */
+ }
+ else if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR) { /* Physical Linear */
+ return 0;
+ }
+ else { /* Other VCM */
+ ump_vcm->dev_id -= 2;
+ }
+
+ DBG_MSG(5, ("Device ID for VCM : %d\n", ump_vcm->dev_id));
+ ump_vcm->vcm = vcm_find_vcm(ump_vcm->dev_id);
+
+ if (!ump_vcm->vcm)
+ {
+ return 0;
+ }
+ descriptor->backend_info = (void*)ump_vcm;
+
+ if (down_interruptible(&info->mutex)) {
+ DBG_MSG(1, ("Failed to get mutex in ump_vcm_allocate\n"));
+ return 0; /* failure */
+ }
+
+ ret = vcm_mem_allocator(info, descriptor);
+ up(&info->mutex);
+
+ return ret; /* success */
+}
+
+static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor)
+{
+ unsigned long num_blocks;
+ int i;
+ struct vcm_phys *phys;
+ struct vcm_phys_part *part;
+ int size_total = 0;
+ struct ump_vcm *ump_vcm;
+
+ ump_vcm = (struct ump_vcm*)descriptor->backend_info;
+
+ ump_vcm->vcm_res =
+ vcm_make_binding(ump_vcm->vcm, descriptor->size_bytes,
+ ump_vcm->dev_id, 0);
+
+ phys = ump_vcm->vcm_res->phys;
+ part = phys->parts;
+ num_blocks = phys->count;
+
+ DBG_MSG(5,
+ ("Allocating page array. Size: %lu, VCM Reservation : 0x%x\n",
+ phys->count * sizeof(ump_dd_physical_block),
+ ump_vcm->vcm_res->start));
+
+ /* Now, make a copy of the block information supplied by the user */
+ descriptor->block_array =
+ (ump_dd_physical_block *) vmalloc(sizeof(ump_dd_physical_block) *
+ num_blocks);
+
+ if (NULL == descriptor->block_array) {
+ vfree(descriptor->block_array);
+ DBG_MSG(1, ("Could not allocate a mem handle for function.\n"));
+ return 0; /* failure */
+ }
+
+ for (i = 0; i < num_blocks; i++) {
+ descriptor->block_array[i].addr = part->start;
+ descriptor->block_array[i].size = part->size;
+
+ dmac_unmap_area(phys_to_virt(part->start), part->size, DMA_FROM_DEVICE);
+ outer_inv_range(part->start, part->start + part->size);
+
+ ++part;
+ size_total += descriptor->block_array[i].size;
+ DBG_MSG(6,
+ ("UMP memory created with VCM. addr 0x%x, size: 0x%x\n",
+ descriptor->block_array[i].addr,
+ descriptor->block_array[i].size));
+ }
+
+ descriptor->size_bytes = size_total;
+ descriptor->nr_blocks = num_blocks;
+ descriptor->ctx = NULL;
+
+ info->num_vcm_blocks += num_blocks;
+ return 1;
+}
+
+/*
+ * Free specified UMP memory
+ */
+static void ump_vcm_free(void *ctx, ump_dd_mem * descriptor)
+{
+ struct ump_vcm *ump_vcm;
+ vcm_allocator *info;
+
+ BUG_ON(!descriptor);
+ BUG_ON(!ctx);
+
+ ump_vcm = (struct ump_vcm*)descriptor->backend_info;
+ info = (vcm_allocator*)ctx;
+
+ BUG_ON(descriptor->nr_blocks > info->num_vcm_blocks);
+
+ if (down_interruptible(&info->mutex)) {
+ DBG_MSG(1, ("Failed to get mutex in ump_vcm_free\n"));
+ return;
+ }
+
+ DBG_MSG(5, ("Releasing %lu VCM pages\n", descriptor->nr_blocks));
+
+ info->num_vcm_blocks -= descriptor->nr_blocks;
+
+ up(&info->mutex);
+
+ DBG_MSG(6, ("Freeing physical page by VCM\n"));
+ vcm_destroy_binding(ump_vcm->vcm_res);
+ ump_vcm->vcm = NULL;
+ ump_vcm->vcm_res = NULL;
+
+ kfree(ump_vcm);
+ vfree(descriptor->block_array);
+}
+
+static void *vcm_res_get(ump_dd_mem *mem, void *args)
+{
+ struct ump_vcm *ump_vcm;
+ enum vcm_dev_id vcm_id;
+
+ ump_vcm = (struct ump_vcm*)mem->backend_info;
+ vcm_id = (enum vcm_dev_id)args;
+
+ if (vcm_reservation_in_vcm
+ (vcm_find_vcm(vcm_id), ump_vcm->vcm_res)
+ == S5PVCM_RES_NOT_IN_VCM)
+ return NULL;
+ else
+ return ump_vcm->vcm_res;
+}
+
+static void vcm_attr_set(ump_dd_mem *mem, void *args)
+{
+ struct ump_vcm *ump_vcm, *ump_vcmh;
+
+ ump_vcm = (struct ump_vcm*)args;
+
+ ump_vcmh = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL);
+ if (NULL == ump_vcmh)
+ {
+ return;
+ }
+
+ ump_vcmh->dev_id = ump_vcm->dev_id;
+ ump_vcmh->vcm = ump_vcm->vcm;
+ ump_vcmh->vcm_res = ump_vcm->vcm_res;
+
+ mem->backend_info= (void*)ump_vcmh;
+
+ return;
+}
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
new file mode 100644
index 0000000..c1ead0d
--- /dev/null
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file ump_kernel_memory_backend_vcm.h
+ */
+
+#ifndef __UMP_KERNEL_MEMORY_BACKEND_VCM_H__
+#define __UMP_KERNEL_MEMORY_BACKEND_VCM_H__
+
+#include "ump_kernel_memory_backend.h"
+
+ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation);
+
+#endif /* __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ */
diff --git a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
index 23357f4..d067cfe 100644
--- a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
+++ b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
@@ -56,6 +56,13 @@ ump_memory_backend* ump_memory_backend_create ( void )
DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size));
backend = ump_os_memory_backend_create(ump_memory_size);
}
+#ifdef CONFIG_UMP_VCM_ALLOC
+ else if (2 == ump_backend)
+ {
+ DBG_MSG(2, ("Using VCM memory backend, allocation limit: %d\n", ump_memory_size));
+ backend = ump_vcm_memory_backend_create(ump_memory_size);
+ }
+#endif
return backend;
}
diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
index 0073c4d..8ae169a 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
+++ b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
@@ -23,6 +23,7 @@
#include <linux/module.h> /* kernel module definitions */
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <asm/memory.h>
@@ -210,6 +211,95 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript
return retval;
}
+static u32 _ump_osk_virt_to_phys_start(ump_dd_mem * mem, u32 start, u32 address, int *index)
+{
+ int i;
+ u32 offset = address - start;
+ ump_dd_physical_block *block;
+ u32 sum = 0;
+
+ for (i=0; i<mem->nr_blocks; i++) {
+ block = &mem->block_array[i];
+ sum += block->size;
+ if (sum > offset) {
+ *index = i;
+ DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size)));
+ return (u32)block->addr + offset - (sum -block->size);
+ }
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+static u32 _ump_osk_virt_to_phys_end(ump_dd_mem * mem, u32 start, u32 address, int *index)
+{
+ int i;
+ u32 offset = address - start;
+ ump_dd_physical_block *block;
+ u32 sum = 0;
+
+ for (i=0; i<mem->nr_blocks; i++) {
+ block = &mem->block_array[i];
+ sum += block->size;
+ if (sum >= offset) {
+ *index = i;
+ DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size)));
+ return (u32)block->addr + offset - (sum -block->size);
+ }
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size)
+{
+ int start_index, end_index;
+ u32 start_p, end_p;
+
+ DBG_MSG(3, ("Cache flush with user virtual address. start : 0x%x, end : 0x%x, address 0x%x, size 0x%x\n", start, start+mem->size_bytes, address, size));
+
+ start_p = _ump_osk_virt_to_phys_start(mem, start, address, &start_index);
+ end_p = _ump_osk_virt_to_phys_end(mem, start, address+size, &end_index);
+
+ if (start_index==end_index) {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)
+ outer_flush_range(start_p, end_p);
+ else
+ outer_clean_range(start_p, end_p);
+ } else {
+ ump_dd_physical_block *block;
+ int i;
+
+ for (i=start_index; i<=end_index; i++) {
+ block = &mem->block_array[i];
+
+ if (i == start_index) {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
+ outer_flush_range(start_p, block->addr+block->size);
+ } else {
+ outer_clean_range(start_p, block->addr+block->size);
+ }
+ }
+ else if (i == end_index) {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
+ outer_flush_range(block->addr, end_p);
+ } else {
+ outer_clean_range(block->addr, end_p);
+ }
+ break;
+ }
+ else {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
+ outer_flush_range(block->addr, block->addr+block->size);
+ } else {
+ outer_clean_range(block->addr, block->addr+block->size);
+ }
+ }
+ }
+ }
+ return;
+}
+
static void level1_cache_flush_all(void)
{
DBG_MSG(4, ("UMP[xx] Flushing complete L1 cache\n"));
@@ -229,7 +319,11 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
end_v = (void *)(start_v + size - 1);
/* There is no dmac_clean_range, so the L1 is always flushed,
* also for UMP_MSYNC_CLEAN. */
- dmac_flush_range(start_v, end_v);
+ if (size >= SZ_64K)
+ flush_all_cpu_caches();
+ else
+ dmac_flush_range(start_v, end_v);
+
DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v));
}
else
@@ -278,6 +372,14 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
/* Flush L2 using physical addresses, block for block. */
+ if ((virt!=NULL) && (mem->size_bytes >= SZ_1M)) {
+ if (op == _UMP_UK_MSYNC_CLEAN)
+ outer_clean_all();
+ else if ((op == _UMP_UK_MSYNC_INVALIDATE) || (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE))
+ outer_flush_all();
+ return;
+ }
+
for (i=0 ; i < mem->nr_blocks; i++)
{
u32 start_p, end_p;
@@ -344,3 +446,40 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
return;
}
+
+void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ ump_vma_usage_tracker * vma_usage_tracker;
+ ump_memory_allocation *descriptor;
+ ump_dd_handle handle;
+
+ DBG_MSG(3, ("_ump_osk_mem_mapregion_get: vaddr 0x%08lx\n", vaddr));
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, vaddr);
+ up_read(&mm->mmap_sem);
+ if(!vma)
+ {
+ DBG_MSG(3, ("Not found VMA\n"));
+ *mem = NULL;
+ return;
+ }
+ DBG_MSG(4, ("Get vma: 0x%08lx vma->vm_start: 0x%08lx\n", (unsigned long)vma, vma->vm_start));
+
+ vma_usage_tracker = (struct ump_vma_usage_tracker*)vma->vm_private_data;
+ if(vma_usage_tracker == NULL)
+ {
+ DBG_MSG(3, ("Not found vma_usage_tracker\n"));
+ *mem = NULL;
+ return;
+ }
+
+ descriptor = (struct ump_memory_allocation*)vma_usage_tracker->descriptor;
+ handle = (ump_dd_handle)descriptor->handle;
+
+ DBG_MSG(3, ("Get handle: 0x%08lx\n", handle));
+ *mem = (ump_dd_mem*)handle;
+}
+
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
index 9692e5b..a6691ed 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
+++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
@@ -89,7 +89,6 @@ int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * sessi
return 0; /* success */
}
-
#ifdef CONFIG_ION_EXYNOS
/*
* IOCTL operation; Import fd to UMP memory
@@ -130,6 +129,12 @@ int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * ses
sg_ion = ion_map_dma(ion_client_ump,ion_hnd);
blocks = (ump_dd_physical_block*)_mali_osk_malloc(sizeof(ump_dd_physical_block)*1024);
+
+ if (NULL == blocks) {
+ MSG_ERR(("Failed to allocate blocks in ump_ioctl_allocate()\n"));
+ return -ENOMEM;
+ }
+
sg = sg_ion;
do {
blocks[i].addr = sg_phys(sg);