summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Beykun <rzk333@gmail.com>2012-10-21 20:12:55 +0400
committerDmitriy Beykun <rzk333@gmail.com>2012-10-21 20:12:55 +0400
commit23debc5a26ce858ef020405dbf91b2f268a72f44 (patch)
tree5d96039ba958c1ff45934eb4c4ede9e287044c5c
parentb8d60809c6d9165415d14141b8ffe8090e040ce8 (diff)
downloadmali-400-kernel-drivers-23debc5a26ce858ef020405dbf91b2f268a72f44.tar.xz
added r3p0-04rel0 kernel driversHEADr3p0-04rel0
-rw-r--r--driver/src/devicedrv/mali/.version2
-rw-r--r--driver/src/devicedrv/mali/Kbuild233
-rw-r--r--driver/src/devicedrv/mali/Kconfig30
-rw-r--r--driver/src/devicedrv/mali/Makefile8
-rw-r--r--driver/src/devicedrv/mali/Makefile.common59
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h2
-rw-r--r--driver/src/devicedrv/mali/arch-ve-virtex6-m450-8/config.h168
-rw-r--r--driver/src/devicedrv/mali/common/mali_block_allocator.c4
-rw-r--r--driver/src/devicedrv/mali/common/mali_block_allocator.h2
-rw-r--r--driver/src/devicedrv/mali/common/mali_cluster.c218
-rw-r--r--driver/src/devicedrv/mali/common/mali_cluster.h44
-rw-r--r--driver/src/devicedrv/mali/common/mali_device_pause_resume.c46
-rw-r--r--driver/src/devicedrv/mali/common/mali_device_pause_resume.h31
-rw-r--r--driver/src/devicedrv/mali/common/mali_dlbu.c285
-rw-r--r--driver/src/devicedrv/mali/common/mali_dlbu.h45
-rw-r--r--driver/src/devicedrv/mali/common/mali_gp.c693
-rw-r--r--driver/src/devicedrv/mali/common/mali_gp.h46
-rw-r--r--driver/src/devicedrv/mali/common/mali_gp_job.c49
-rw-r--r--driver/src/devicedrv/mali/common/mali_gp_job.h131
-rw-r--r--driver/src/devicedrv/mali/common/mali_gp_scheduler.c438
-rw-r--r--driver/src/devicedrv/mali/common/mali_gp_scheduler.h30
-rw-r--r--driver/src/devicedrv/mali/common/mali_group.c841
-rw-r--r--driver/src/devicedrv/mali/common/mali_group.h146
-rw-r--r--driver/src/devicedrv/mali/common/mali_hw_core.c46
-rw-r--r--driver/src/devicedrv/mali/common/mali_hw_core.h71
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_GP2.c1462
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_MALI200.c1242
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_common.h2
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_core.c1356
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_core.h124
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c13
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h4
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c517
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_l2_cache.h25
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c1426
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c3158
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h75
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_mem_os.c2
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_mem_os.h2
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c24
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h3
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_rendercore.c2021
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_rendercore.h565
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_subsystem.h107
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_utilization.c11
-rw-r--r--driver/src/devicedrv/mali/common/mali_kernel_vsync.c30
-rw-r--r--driver/src/devicedrv/mali/common/mali_l2_cache.c398
-rw-r--r--driver/src/devicedrv/mali/common/mali_l2_cache.h43
-rw-r--r--driver/src/devicedrv/mali/common/mali_mem_validation.c71
-rw-r--r--driver/src/devicedrv/mali/common/mali_mem_validation.h19
-rw-r--r--driver/src/devicedrv/mali/common/mali_memory.c1321
-rw-r--r--driver/src/devicedrv/mali/common/mali_memory.h80
-rw-r--r--driver/src/devicedrv/mali/common/mali_mmu.c619
-rw-r--r--driver/src/devicedrv/mali/common/mali_mmu.h55
-rw-r--r--driver/src/devicedrv/mali/common/mali_mmu_page_directory.c459
-rw-r--r--driver/src/devicedrv/mali/common/mali_mmu_page_directory.h83
-rw-r--r--driver/src/devicedrv/mali/common/mali_osk.h152
-rw-r--r--driver/src/devicedrv/mali/common/mali_osk_bitops.h2
-rw-r--r--driver/src/devicedrv/mali/common/mali_osk_list.h2
-rw-r--r--driver/src/devicedrv/mali/common/mali_osk_mali.h30
-rw-r--r--driver/src/devicedrv/mali/common/mali_osk_profiling.h (renamed from driver/src/devicedrv/mali/common/mali_kernel_profiling.h)80
-rw-r--r--driver/src/devicedrv/mali/common/mali_pm.c547
-rw-r--r--driver/src/devicedrv/mali/common/mali_pm.h56
-rw-r--r--driver/src/devicedrv/mali/common/mali_pmu.c199
-rw-r--r--driver/src/devicedrv/mali/common/mali_pmu.h70
-rw-r--r--driver/src/devicedrv/mali/common/mali_pp.c710
-rw-r--r--driver/src/devicedrv/mali/common/mali_pp.h47
-rw-r--r--driver/src/devicedrv/mali/common/mali_pp_job.c92
-rw-r--r--driver/src/devicedrv/mali/common/mali_pp_job.h255
-rw-r--r--driver/src/devicedrv/mali/common/mali_pp_scheduler.c542
-rw-r--r--driver/src/devicedrv/mali/common/mali_pp_scheduler.h38
-rw-r--r--driver/src/devicedrv/mali/common/mali_scheduler.c37
-rw-r--r--driver/src/devicedrv/mali/common/mali_scheduler.h21
-rw-r--r--driver/src/devicedrv/mali/common/mali_session.c47
-rw-r--r--driver/src/devicedrv/mali/common/mali_session.h65
-rw-r--r--driver/src/devicedrv/mali/common/mali_ukk.h175
-rw-r--r--driver/src/devicedrv/mali/common/mali_user_settings_db.c88
-rw-r--r--driver/src/devicedrv/mali/common/mali_user_settings_db.h40
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm.c1006
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm.h348
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.c350
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_pmu.h87
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.c243
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_policy.h155
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.c80
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_alwayson.h62
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.c470
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_policy_jobcontrol.h80
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_state.c721
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_state.h295
-rw-r--r--driver/src/devicedrv/mali/common/pmm/mali_pmm_system.h66
-rw-r--r--driver/src/devicedrv/mali/include/linux/mali/mali_utgard.h (renamed from driver/src/devicedrv/mali/common/mali_kernel_session_manager.h)21
-rw-r--r--driver/src/devicedrv/mali/include/linux/mali/mali_utgard_counters.h264
-rw-r--r--driver/src/devicedrv/mali/include/linux/mali/mali_utgard_ioctl.h (renamed from driver/src/devicedrv/mali/linux/mali_kernel_ioctl.h)18
-rw-r--r--driver/src/devicedrv/mali/include/linux/mali/mali_utgard_profiling_events.h121
-rw-r--r--driver/src/devicedrv/mali/include/linux/mali/mali_utgard_uk_types.h (renamed from driver/src/devicedrv/mali/common/mali_uk_types.h)330
-rw-r--r--driver/src/devicedrv/mali/linux/license/gpl/mali_kernel_license.h2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_device_pause_resume.c72
-rw-r--r--driver/src/devicedrv/mali/linux/mali_kernel_linux.c208
-rw-r--r--driver/src/devicedrv/mali/linux/mali_kernel_linux.h3
-rw-r--r--driver/src/devicedrv/mali/linux/mali_kernel_pm.c625
-rw-r--r--driver/src/devicedrv/mali/linux/mali_kernel_pm.h2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_kernel_sysfs.c972
-rw-r--r--driver/src/devicedrv/mali/linux/mali_kernel_sysfs.h2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_linux_pm.h3
-rw-r--r--driver/src/devicedrv/mali/linux/mali_linux_pm_testsuite.h11
-rw-r--r--driver/src/devicedrv/mali/linux/mali_linux_trace.h126
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_atomics.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_indir_mmap.h2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_irq.c27
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_locks.c107
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_low_level_mem.c14
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_mali.c18
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_math.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_memory.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_misc.c3
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_notification.c5
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_pm.c199
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_profiling_gator.c261
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_profiling_internal.c (renamed from driver/src/devicedrv/mali/common/mali_kernel_profiling.c)68
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_specific.h100
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_time.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_timers.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_osk_wait_queue.c73
-rw-r--r--driver/src/devicedrv/mali/linux/mali_pmu_power_up_down.c65
-rw-r--r--driver/src/devicedrv/mali/linux/mali_profiling_events.h17
-rw-r--r--driver/src/devicedrv/mali/linux/mali_uk_types.h (renamed from driver/src/devicedrv/mali/linux/mali_device_pause_resume.h)14
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_core.c22
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_gp.c19
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_mem.c79
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_pp.c47
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_profiling.c42
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_vsync.c2
-rw-r--r--driver/src/devicedrv/mali/linux/mali_ukk_wrappers.h9
-rw-r--r--driver/src/devicedrv/mali/platform/default/mali_platform.c2
-rw-r--r--driver/src/devicedrv/mali/platform/mali_platform.h29
-rw-r--r--driver/src/devicedrv/mali/platform/mali_platform_pmu_testing/mali_platform.c66
-rw-r--r--driver/src/devicedrv/mali/readme.txt4
-rw-r--r--driver/src/devicedrv/mali/regs/mali_200_regs.h30
-rw-r--r--driver/src/devicedrv/mali/regs/mali_gp_regs.h25
-rw-r--r--driver/src/devicedrv/mali/timestamp-arm11-cc/mali_timestamp.c2
-rw-r--r--driver/src/devicedrv/mali/timestamp-arm11-cc/mali_timestamp.h2
-rw-r--r--driver/src/devicedrv/mali/timestamp-default/mali_timestamp.c2
-rw-r--r--driver/src/devicedrv/mali/timestamp-default/mali_timestamp.h2
-rw-r--r--driver/src/devicedrv/ump/.version2
-rw-r--r--driver/src/devicedrv/ump/Kbuild68
-rw-r--r--driver/src/devicedrv/ump/Kconfig16
-rw-r--r--driver/src/devicedrv/ump/Makefile88
-rw-r--r--driver/src/devicedrv/ump/Makefile.common2
-rw-r--r--driver/src/devicedrv/ump/arch-pb-virtex5/config.h2
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_api.c182
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_common.c3
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_common.h8
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.c2
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_descriptor_mapping.h2
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_memory_backend.h2
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_ref_drv.c5
-rw-r--r--driver/src/devicedrv/ump/common/ump_kernel_types.h18
-rw-r--r--driver/src/devicedrv/ump/common/ump_osk.h3
-rw-r--r--driver/src/devicedrv/ump/common/ump_uk_types.h55
-rw-r--r--driver/src/devicedrv/ump/common/ump_ukk.h8
-rw-r--r--driver/src/devicedrv/ump/linux/license/gpl/ump_kernel_license.h2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_ioctl.h7
-rw-r--r--driver/src/devicedrv/ump/linux/ump_kernel_linux.c16
-rw-r--r--driver/src/devicedrv/ump/linux/ump_kernel_linux.h4
-rw-r--r--driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.c2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_dedicated.h2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.c2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_kernel_memory_backend_os.h2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_memory_backend.c2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_osk_atomics.c2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_osk_low_level_mem.c60
-rw-r--r--driver/src/devicedrv/ump/linux/ump_osk_misc.c2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.c2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_ukk_ref_wrappers.h2
-rw-r--r--driver/src/devicedrv/ump/linux/ump_ukk_wrappers.c133
-rw-r--r--driver/src/devicedrv/ump/linux/ump_ukk_wrappers.h6
-rw-r--r--driver/src/devicedrv/umplock/umplock_ioctl.h66
-rw-r--r--driver/src/shared/essl_compiler/src/Makefile.offline44
-rw-r--r--driver/src/shared/essl_compiler/src/backend/Makefile.offline42
-rw-r--r--driver/src/shared/essl_compiler/src/common/Makefile.offline61
-rw-r--r--driver/src/shared/essl_compiler/src/frontend/Makefile.offline34
-rw-r--r--driver/src/shared/essl_compiler/src/libMali400SC.vcxproj343
-rw-r--r--driver/src/shared/essl_compiler/src/mali200/Makefile.offline55
-rw-r--r--driver/src/shared/essl_compiler/src/mali200/mali200_grad.h (renamed from driver/src/devicedrv/mali/common/mali_kernel_mem.h)10
-rw-r--r--driver/src/shared/essl_compiler/src/maligp2/Makefile.offline45
-rw-r--r--driver/src/shared/essl_compiler/src/middle/Makefile.offline38
-rw-r--r--driver/src/shared/essl_compiler/src/middle/proactive_calculations.c1025
-rw-r--r--driver/src/shared/essl_compiler/src/middle/proactive_calculations.h (renamed from driver/src/devicedrv/mali/common/mali_kernel_gp.h)15
-rw-r--r--driver/src/shared/essl_compiler/src/middle/rewrite_sampler_accesses.c113
-rw-r--r--driver/src/shared/essl_compiler/src/middle/rewrite_sampler_accesses.h (renamed from driver/src/devicedrv/mali/common/mali_kernel_pp.h)15
-rw-r--r--driver/src/shared/m200_fbdump.c317
-rw-r--r--driver/src/shared/m200_fbdump.h59
-rw-r--r--driver/src/shared/m200_hw_workarounds.c157
-rw-r--r--driver/src/shared/m200_plbuheap.c115
-rw-r--r--driver/src/shared/m200_plbuheap.h94
-rw-r--r--driver/src/shared/m200_projob.c412
-rw-r--r--driver/src/shared/m200_projob.h153
-rw-r--r--driver/src/shared/mali_sw_counters.c46
-rw-r--r--driver/src/shared/mali_sw_counters.h85
-rw-r--r--driver/src/ump/include/ump/ump_kernel_interface.h2
-rw-r--r--driver/src/ump/include/ump/ump_kernel_interface_ref_drv.h2
-rw-r--r--driver/src/ump/include/ump/ump_kernel_platform.h2
-rw-r--r--x11/mali_drm/README.txt24
-rw-r--r--x11/mali_drm/mali/Makefile20
-rw-r--r--x11/mali_drm/mali/mali_drv.c149
-rw-r--r--x11/mali_drm/mali/mali_drv.h25
214 files changed, 17320 insertions, 17364 deletions
diff --git a/driver/src/devicedrv/mali/.version b/driver/src/devicedrv/mali/.version
index 46f69d1..881d3ea 100644
--- a/driver/src/devicedrv/mali/.version
+++ b/driver/src/devicedrv/mali/.version
@@ -1 +1 @@
-r2p4-02rel1
+r3p0-04rel0
diff --git a/driver/src/devicedrv/mali/Kbuild b/driver/src/devicedrv/mali/Kbuild
index 50109dc..a3f63ae 100644
--- a/driver/src/devicedrv/mali/Kbuild
+++ b/driver/src/devicedrv/mali/Kbuild
@@ -11,18 +11,14 @@
# This file is called by the Linux build system.
OSKOS=linux
-FILES_PREFIX=
# set up defaults if not defined by the user
USING_UMP ?= 0
USING_OS_MEMORY ?= 0
-USING_MALI_PMU ?= 0
-USING_PMM ?= 1
-USING_GPU_UTILIZATION ?= 0
-USING_MALI_RUN_TIME_PM ?= 1
USING_MALI_PMM_TESTSUITE ?= 0
OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6
-USING_PROFILING ?= 0
+USING_PROFILING ?= 1
+USING_INTERNAL_PROFILING ?= 0
DISABLE_PP0 ?= 0
DISABLE_PP1 ?= 0
DISABLE_PP2 ?= 0
@@ -32,12 +28,85 @@ BUILD ?= debug
TARGET_PLATFORM ?= default
KERNEL_RUNTIME_PM_ENABLED ?= 0
CONFIG ?= pb-virtex5-m200
+MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0
+MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0
+MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0
+
+DEFINES := $(EXTRA_DEFINES)
# Get path to driver source from Linux build system
DRIVER_DIR=$(src)
+# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
+# The ARM proprietary product will only include the license/proprietary directory
+# The GPL product will only include the license/gpl directory
+
+ifeq ($(wildcard $(DRIVER_DIR)/linux/license/gpl/*),)
+ccflags-y += -I$(DRIVER_DIR)/linux/license/proprietary
+# Disable profiling for proprietary
+override USING_PROFILING := 0
+$(warning "USING_PROFILING not supported, disabling.")
+else
+ccflags-y += -I$(DRIVER_DIR)/linux/license/gpl
+endif
+
+
+ifeq ($(USING_PROFILING),1)
+ifeq ($(USING_INTERNAL_PROFILING),0)
+ifndef CONFIG_TRACEPOINTS
+# Should default to gator profiling, but we dont have the kernel feature required, so disable profiling
+override USING_PROFILING = 0
+$(warning "CONFIG_TRACEPOINTS required for USING_PROFILING")
+endif
+endif
+endif
+
+ifeq ($(USING_PROFILING),0)
+# make sure user hasnt selected incompatible flags
+override USING_INTERNAL_PROFILING = 0
+endif
+
MALI_RELEASE_NAME=$(shell cat $(DRIVER_DIR)/.version 2> /dev/null)
-include $(DRIVER_DIR)/Makefile.common
+
+# Check if a Mali Core sub module should be enabled, true or false returned
+submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2))
+
+OSKFILES = \
+ $(OSKOS)/mali_osk_atomics.c \
+ $(OSKOS)/mali_osk_irq.c \
+ $(OSKOS)/mali_osk_locks.c \
+ $(OSKOS)/mali_osk_wait_queue.c \
+ $(OSKOS)/mali_osk_low_level_mem.c \
+ $(OSKOS)/mali_osk_math.c \
+ $(OSKOS)/mali_osk_memory.c \
+ $(OSKOS)/mali_osk_misc.c \
+ $(OSKOS)/mali_osk_mali.c \
+ $(OSKOS)/mali_osk_notification.c \
+ $(OSKOS)/mali_osk_time.c \
+ $(OSKOS)/mali_osk_timers.c
+
+UKKFILES = \
+ $(OSKOS)/mali_ukk_mem.c \
+ $(OSKOS)/mali_ukk_gp.c \
+ $(OSKOS)/mali_ukk_pp.c \
+ $(OSKOS)/mali_ukk_core.c
+
+ifeq ($(USING_PROFILING),1)
+UKKFILES += \
+ $(OSKOS)/mali_ukk_profiling.c
+endif
+
+ifeq ($(MALI_PLATFORM_FILE),)
+MALI_PLATFORM_FILE = platform/default/mali_platform.c
+endif
+
+# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
+SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -qv exported && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null )
+ifeq ($(SVN_REV),)
+SVN_REV := $(MALI_RELEASE_NAME)
+else
+SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
+endif
# Validate selected config
ifneq ($(shell [ -d $(DRIVER_DIR)/arch-$(CONFIG) ] && [ -f $(DRIVER_DIR)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
@@ -55,11 +124,15 @@ DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY)
DEFINES += -DUSING_MMU=1
DEFINES += -DUSING_UMP=$(USING_UMP)
DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP
-DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING)
+DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING)
DEFINES += -DDISABLE_PP0=$(DISABLE_PP0)
DEFINES += -DDISABLE_PP1=$(DISABLE_PP1)
DEFINES += -DDISABLE_PP2=$(DISABLE_PP2)
DEFINES += -DDISABLE_PP3=$(DISABLE_PP3)
+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)
+DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING)
DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE)
ifeq ($(shell test $(SUBLEVEL) -gt 32 -a $(PATCHLEVEL) = 6 -a $(VERSION) = 2 -o $(VERSION) -gt 2 && echo "OK"),OK)
# MALI_STATE_TRACKING is only supported on Linux kernels from version 2.6.32.
@@ -71,22 +144,13 @@ DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_S
MALI_PLATFORM_FILE = platform/$(TARGET_PLATFORM)/mali_platform.c
-DEFINES += -DUSING_MALI_PMM=$(USING_PMM)
-DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), PMU),0)
- USING_MALI_PMU = 1
-endif
-
-ifeq ($(USING_MALI_RUN_TIME_PM),1)
ifdef CONFIG_PM
ifdef CONFIG_PM_RUNTIME
KERNEL_RUNTIME_PM_ENABLED = 1
endif
endif
-endif
-DEFINES += -DUSING_MALI_PMU=$(USING_MALI_PMU)
DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED)
ifeq ($(BUILD), debug)
@@ -95,7 +159,7 @@ endif
DEFINES += -DSVN_REV=$(SVN_REV)
DEFINES += -DSVN_REV_STRING=\"$(SVN_REV)\"
-# Linux has its own mmap cleanup handlers (see mali_kernel_mem_mmu.c)
+# Linux has its own mmap cleanup handlers (see mali_kernel_memory.c)
DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
ifeq ($(USING_UMP),1)
@@ -106,131 +170,108 @@ else
endif
# Use our defines when compiling
-ccflags-y += $(DEFINES) -I$(DRIVER_DIR) -I$(DRIVER_DIR)/common -I$(DRIVER_DIR)/linux -I$(DRIVER_DIR)/platform
-
-# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
-# The ARM proprietary product will only include the license/proprietary directory
-# The GPL product will only include the license/gpl directory
-
-ifeq ($(wildcard $(DRIVER_DIR)/linux/license/gpl/*),)
-ccflags-y += -I$(DRIVER_DIR)/linux/license/proprietary
-else
-ccflags-y += -I$(DRIVER_DIR)/linux/license/gpl
-endif
-ccflags-y += -I$(DRIVER_DIR)/common/pmm
+ccflags-y += $(DEFINES) -I$(DRIVER_DIR) -I$(DRIVER_DIR)/include -I$(DRIVER_DIR)/common -I$(DRIVER_DIR)/linux -I$(DRIVER_DIR)/platform
# Source files which always are included in a build
SRC = \
common/mali_kernel_core.c \
linux/mali_kernel_linux.c \
$(OSKOS)/mali_osk_indir_mmap.c \
- common/mali_kernel_rendercore.c \
common/mali_kernel_descriptor_mapping.c \
+ common/mali_session.c \
+ common/mali_device_pause_resume.c \
common/mali_kernel_vsync.c \
linux/mali_ukk_vsync.c \
linux/mali_kernel_sysfs.c \
- common/mali_kernel_mem_mmu.c \
+ common/mali_mmu.c \
+ common/mali_mmu_page_directory.c \
+ common/mali_memory.c \
common/mali_kernel_memory_engine.c \
common/mali_block_allocator.c \
common/mali_kernel_mem_os.c \
+ common/mali_mem_validation.c \
+ common/mali_hw_core.c \
+ common/mali_gp.c \
+ common/mali_pp.c \
+ common/mali_pp_job.c \
+ common/mali_gp_job.c \
+ common/mali_scheduler.c \
+ common/mali_gp_scheduler.c \
+ common/mali_pp_scheduler.c \
+ common/mali_cluster.c \
+ common/mali_group.c \
+ common/mali_dlbu.c \
+ common/mali_pm.c \
+ common/mali_pmu.c \
+ common/mali_user_settings_db.c \
+ $(OSKOS)/mali_osk_pm.c \
+ linux/mali_kernel_pm.c \
+ linux/mali_pmu_power_up_down.c \
$(MALI_PLATFORM_FILE) \
$(OSKFILES) \
$(UKKFILES) \
__malidrv_build_info.c
-ifeq ($(USING_PROFILING),1)
-SRC += \
- common/mali_kernel_profiling.c \
- timestamp-$(TIMESTAMP)/mali_timestamp.c
-ccflags-y += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP)
-endif
-
# Selecting files to compile by parsing the config file
-ifeq ($(USING_PMM),1)
-ifeq ($(USING_MALI_PMU),1)
-SRC += \
- common/pmm/mali_pmm_pmu.c
-endif
-SRC += \
- common/pmm/mali_pmm.c \
- common/pmm/mali_pmm_policy.c \
- common/pmm/mali_pmm_policy_alwayson.c \
- common/pmm/mali_pmm_policy_jobcontrol.c \
- common/pmm/mali_pmm_state.c \
- linux/mali_kernel_pm.c \
- linux/mali_osk_pm.c \
- linux/mali_device_pause_resume.c
+ifeq ($(USING_INTERNAL_PROFILING),1)
+PROFILING_BACKEND_SOURCES = \
+ linux/mali_osk_profiling_internal.c \
+ timestamp-$(TIMESTAMP)/mali_timestamp.c
+ccflags-y += -I$(DRIVER_DIR)/timestamp-$(TIMESTAMP)
+else
+ifeq ($(USING_PROFILING),1)
+PROFILING_BACKEND_SOURCES = \
+ linux/mali_osk_profiling_gator.c
+endif
endif
+# Add the profiling sources
+SRC += $(PROFILING_BACKEND_SOURCES)
+
ifeq ($(USING_MALI_PMM_TESTSUITE),1)
ccflags-y += -I$(DRIVER_DIR)/platform/mali_pmu_testing
-ifeq ($(USING_MALI_PMU),0)
-SRC += \
- platform/mali_pmu_testing/mali_platform_pmu_internal_testing.c
-endif
endif
-ifeq ($(USING_GPU_UTILIZATION),1)
-SRC += \
- common/mali_kernel_utilization.c
-endif
+mali-$(CONFIG_MALI400_GPU_UTILIZATION) += common/mali_kernel_utilization.o
ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400PP),0)
# Mali-400 PP in use
ccflags-y += -DUSING_MALI400
- SRC += common/mali_kernel_MALI200.c
-endif
-
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400GP),0)
- # Mali-400 GP in use
- SRC += common/mali_kernel_GP2.c
endif
ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300PP),0)
# Mali-400 PP in use
ccflags-y += -DUSING_MALI400
- SRC += common/mali_kernel_MALI200.c
-endif
-
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300GP),0)
- # Mali-400 GP in use
- SRC += common/mali_kernel_GP2.c
endif
ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI200),0)
# Mali200 in use
ccflags-y += -DUSING_MALI200
- SRC += common/mali_kernel_MALI200.c
endif
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALIGP2),0)
- # MaliGP2 in use
- SRC += common/mali_kernel_GP2.c
-endif
+# Always build in support for Mali L2 cache
+SRC += common/mali_l2_cache.c
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400L2),0)
- # Mali Level2 cache in use
- ccflags-y += -DUSING_MALI400_L2_CACHE
- SRC += common/mali_kernel_l2_cache.c
-endif
+# Tell the Linux build system to enable building of our .c files
+mali-y += $(SRC:.c=.o)
+# Tell the Linux build system from which .o file to create the kernel module
+obj-$(CONFIG_MALI400) := mali.o
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300L2),0)
- # Mali Level2 cache in use
- ccflags-y += -DUSING_MALI400_L2_CACHE
- SRC += common/mali_kernel_l2_cache.c
-endif
-# Tell the Linux build system from which .o file to create the kernel module
-obj-m := mali.o
-# Tell the Linux build system to enable building of our .c files
-mali-y := $(SRC:.c=.o)
+VERSION_STRINGS :=
+VERSION_STRINGS += CONFIG=$(CONFIG)
+VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY)
+VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 )
+VERSION_STRINGS += REPO_URL=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'URL: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^URL: ' | cut -d: -f2- | cut -b2-)
+VERSION_STRINGS += REVISION=$(SVN_REV)
+VERSION_STRINGS += CHANGED_REVISION=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Rev: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
+VERSION_STRINGS += CHANGE_DATE=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Date: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
+VERSION_STRINGS += BUILD_DATE=$(shell date)
-# Extend common version-string
VERSION_STRINGS += BUILD=$(shell echo $(BUILD) | tr a-z A-Z)
VERSION_STRINGS += CPU=$(CPU)
VERSION_STRINGS += USING_UMP=$(USING_UMP)
-VERSION_STRINGS += USING_PMM=$(USING_PMM)
VERSION_STRINGS += USING_MALI200=$(call submodule_enabled, $(DRIVER_DIR), MALI200)
VERSION_STRINGS += USING_MALI400=$(call submodule_enabled, $(DRIVER_DIR), MALI400)
VERSION_STRINGS += USING_MALI400_L2_CACHE=$(call submodule_enabled, $(DRIVER_DIR), MALI400L2)
@@ -239,8 +280,8 @@ VERSION_STRINGS += KDIR=$(KDIR)
VERSION_STRINGS += MALI_PLATFORM_FILE=$(MALI_PLATFORM_FILE)
VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
VERSION_STRINGS += USING_PROFILING=$(USING_PROFILING)
-VERSION_STRINGS += USING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
-VERSION_STRINGS += USING_MALI_RUN_TIME_PM=$(USING_MALI_RUN_TIME_PM)
+VERSION_STRINGS += USING_INTERNAL_PROFILING=$(USING_INTERNAL_PROFILING)
+VERSION_STRINGS += USING_GPU_UTILIZATION=$(CONFIG_MALI400_GPU_UTILIZATION)
# Create file with Mali driver configuration
$(DRIVER_DIR)/__malidrv_build_info.c:
diff --git a/driver/src/devicedrv/mali/Kconfig b/driver/src/devicedrv/mali/Kconfig
new file mode 100644
index 0000000..dabb36e
--- /dev/null
+++ b/driver/src/devicedrv/mali/Kconfig
@@ -0,0 +1,30 @@
+config MALI400
+ tristate "Mali-300/400/450 support"
+ depends on ARM
+ select FB
+ ---help---
+ This enables support for the Mali-300, Mali-400, and Mali-450 GPUs.
+
+ To compile this driver as a module, choose M here: the module will be
+ called mali.
+
+config MALI400_DEBUG
+ bool "Enable debug in Mali driver"
+ depends on MALI400
+ ---help---
+ This enabled extra debug checks and messages in the Mali-300/400/450
+ driver.
+
+config MALI400_PROFILING
+ bool "Enable Mali profiling"
+ depends on MALI400 && TRACEPOINTS
+ ---help---
+ This enables gator profiling of Mali GPU events.
+
+config MALI400_GPU_UTILIZATION
+ bool "Enable Mali GPU utilization tracking"
+ depends on MALI400
+ ---help---
+ This enables gathering and processing of the utilization of Mali GPU.
+ This data can be used as a basis to change GPU operating frequency.
+
diff --git a/driver/src/devicedrv/mali/Makefile b/driver/src/devicedrv/mali/Makefile
index d9e8ed4..4fb0226 100644
--- a/driver/src/devicedrv/mali/Makefile
+++ b/driver/src/devicedrv/mali/Makefile
@@ -68,6 +68,14 @@ $(warning Host CPU $(CPU))
$(warning OS_MEMORY $(USING_OS_MEMORY))
endif
+# Set up build config
+export CONFIG_MALI400=m
+
+ifeq ($(USING_GPU_UTILIZATION),1)
+export EXTRA_DEFINES += -DCONFIG_MALI400_GPU_UTILIZATION=1
+export CONFIG_MALI400_GPU_UTILIZATION := y
+endif
+
all: $(UMP_SYMVERS_FILE)
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules
@rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o
diff --git a/driver/src/devicedrv/mali/Makefile.common b/driver/src/devicedrv/mali/Makefile.common
deleted file mode 100644
index c2be3cf..0000000
--- a/driver/src/devicedrv/mali/Makefile.common
+++ /dev/null
@@ -1,59 +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.
-#
-
-# Check if a Mali Core sub module should be enabled, true or false returned
-submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2))
-
-OSKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_locks.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_math.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_memory.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_misc.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_time.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.c
-
-UKKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.c \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.c \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_pp.c \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.c
-
-ifeq ($(USING_PROFILING),1)
-UKKFILES+=\
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.c
-endif
-
-ifeq ($(MALI_PLATFORM_FILE),)
-MALI_PLATFORM_FILE=platform/default/mali_platform.c
-endif
-
-# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
-SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -qv exported && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null )
-ifeq ($(SVN_REV),)
-SVN_REV := $(MALI_RELEASE_NAME)
-else
-SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
-endif
-
-# Common version-string, will be extended by OS-specifc sections
-VERSION_STRINGS :=
-VERSION_STRINGS += CONFIG=$(CONFIG)
-VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY)
-VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)common\/mali_uk_types.h | cut -d' ' -f 3 )
-VERSION_STRINGS += REPO_URL=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'URL: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^URL: ' | cut -d: -f2- | cut -b2-)
-VERSION_STRINGS += REVISION=$(SVN_REV)
-VERSION_STRINGS += CHANGED_REVISION=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Rev: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
-VERSION_STRINGS += CHANGE_DATE=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Date: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
-VERSION_STRINGS += BUILD_DATE=$(shell date)
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h
index e579526..5d5ef16 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m300/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h
index 3893d72..58fc5f2 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-direct/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h
index 6d84ab1..d85c090 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1-pmu/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h
index 568ac0a..50393a2 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-1/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h
index 98b8059..ec45706 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-2/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h
index 7b10925..03d8fae 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-3/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h
index a15a6bd..71da797 100644
--- a/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h
+++ b/driver/src/devicedrv/mali/arch-pb-virtex5-m400-4/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/arch-ve-virtex6-m450-8/config.h b/driver/src/devicedrv/mali/arch-ve-virtex6-m450-8/config.h
new file mode 100644
index 0000000..9b38f35
--- /dev/null
+++ b/driver/src/devicedrv/mali/arch-ve-virtex6-m450-8/config.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARCH_CONFIG_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the Versatile Express platform */
+
+#define MALI_BASE_ADDRESS 0xFC040000
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ /* GP cluster */
+ {
+ .type = MALI400L2,
+ .base = MALI_BASE_ADDRESS + 0x10000,
+ .description = "Mali-450 L2 cache for GP"
+ },
+ {
+ .type = MALI400GP,
+ .description = "Mali-450 GP",
+ .base = MALI_BASE_ADDRESS,
+ .irq = -1,
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x3000,
+ .irq = 70,
+ .description = "Mali-450 MMU for GP",
+ },
+
+ /* PP0-3 cluster */
+ {
+ .type = MALI400L2,
+ .base = MALI_BASE_ADDRESS + 0x1000,
+ .description = "Mali-450 L2 cache for PP0-3"
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x8000,
+ .irq = 70,
+ .description = "Mali-450 PP0",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x4000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP0",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0xA000,
+ .irq = 70,
+ .description = "Mali-450 PP1",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x5000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP1",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0xC000,
+ .irq = 70,
+ .description = "Mali-450 PP2",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x6000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP2",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0xE000,
+ .irq = 70,
+ .description = "Mali-450 PP3",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x7000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP3",
+ },
+
+ /* PP4-7 cluster */
+ {
+ .type = MALI400L2,
+ .base = MALI_BASE_ADDRESS + 0x11000,
+ .description = "Mali-450 L2 cache for PP4-7"
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x28000,
+ .irq = 70,
+ .description = "Mali-450 PP4",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1C000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP4",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x2A000,
+ .irq = 70,
+ .description = "Mali-450 PP5",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1D000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP5",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x2C000,
+ .irq = 70,
+ .description = "Mali-450 PP6",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1E000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP6",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x2E000,
+ .irq = 70,
+ .description = "Mali-450 PP7",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1F000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP7",
+ },
+
+ /* Memory */
+ {
+ .type = OS_MEMORY,
+ .description = "Mali OS memory",
+ .cpu_usage_adjust = 0,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0x0,
+ .size = 256 * 1024 * 1024,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_block_allocator.c b/driver/src/devicedrv/mali/common/mali_block_allocator.c
index 5c2c49a..269e662 100644
--- a/driver/src/devicedrv/mali/common/mali_block_allocator.c
+++ b/driver/src/devicedrv/mali/common/mali_block_allocator.c
@@ -76,7 +76,7 @@ mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u
info = _mali_osk_malloc(sizeof(block_allocator));
if (NULL != info)
{
- info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, 105);
+ info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
if (NULL != info->mutex)
{
info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks);
@@ -355,7 +355,7 @@ static void block_allocator_release_page_table_block( mali_page_table_block *pag
_mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping );
/** @note This loop handles the case where more than one block_info was linked.
- * Probably unnecssary for page table block releasing. */
+ * Probably unnecessary for page table block releasing. */
while (block)
{
next = block->next;
diff --git a/driver/src/devicedrv/mali/common/mali_block_allocator.h b/driver/src/devicedrv/mali/common/mali_block_allocator.h
index 6c6f13e..d3f0f9b 100644
--- a/driver/src/devicedrv/mali/common/mali_block_allocator.h
+++ b/driver/src/devicedrv/mali/common/mali_block_allocator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/common/mali_cluster.c b/driver/src/devicedrv/mali/common/mali_cluster.c
new file mode 100644
index 0000000..f0fb2b6
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_cluster.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2011-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_cluster.h"
+#include "mali_osk.h"
+#include "mali_group.h"
+#include "mali_l2_cache.h"
+#include "mali_scheduler.h"
+
+static struct mali_cluster *mali_global_clusters[MALI_MAX_NUMBER_OF_CLUSTERS] = { NULL, NULL, NULL };
+static u32 mali_global_num_clusters = 0;
+
+/**
+ * The structure represents a render cluster
+ * A render cluster is defined by all the cores that share the same Mali L2 cache
+ */
+struct mali_cluster
+{
+ struct mali_l2_cache_core *l2;
+ u32 number_of_groups;
+ struct mali_group* groups[MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER];
+ u32 last_invalidated_id;
+ mali_bool power_is_enabled;
+};
+
+struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache)
+{
+ struct mali_cluster *cluster = NULL;
+
+ if (mali_global_num_clusters >= MALI_MAX_NUMBER_OF_CLUSTERS)
+ {
+ MALI_PRINT_ERROR(("Mali cluster: Too many cluster objects created\n"));
+ return NULL;
+ }
+
+ cluster = _mali_osk_malloc(sizeof(struct mali_cluster));
+ if (NULL != cluster)
+ {
+ _mali_osk_memset(cluster, 0, sizeof(struct mali_cluster));
+ cluster->l2 = l2_cache; /* This cluster now owns this L2 cache object */
+ cluster->last_invalidated_id = 0;
+ cluster->power_is_enabled = MALI_TRUE;
+
+ mali_global_clusters[mali_global_num_clusters] = cluster;
+ mali_global_num_clusters++;
+
+ return cluster;
+ }
+
+ return NULL;
+}
+
+void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled)
+{
+ cluster->power_is_enabled = power_is_enabled;
+}
+
+mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster)
+{
+ return cluster->power_is_enabled;
+}
+
+
+void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (cluster->number_of_groups < MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER)
+ {
+ /* This cluster now owns the group object */
+ cluster->groups[cluster->number_of_groups] = group;
+ cluster->number_of_groups++;
+ }
+}
+
+void mali_cluster_delete(struct mali_cluster *cluster)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ /* Free all the resources we own */
+ for (i = 0; i < cluster->number_of_groups; i++)
+ {
+ mali_group_delete(cluster->groups[i]);
+ }
+
+ if (NULL != cluster->l2)
+ {
+ mali_l2_cache_delete(cluster->l2);
+ }
+
+ for (i = 0; i < mali_global_num_clusters; i++)
+ {
+ if (mali_global_clusters[i] == cluster)
+ {
+ mali_global_clusters[i] = NULL;
+ mali_global_num_clusters--;
+ break;
+ }
+ }
+
+ _mali_osk_free(cluster);
+}
+
+void mali_cluster_reset(struct mali_cluster *cluster)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ /* Free all the resources we own */
+ for (i = 0; i < cluster->number_of_groups; i++)
+ {
+ struct mali_group *group = cluster->groups[i];
+
+ mali_group_reset(group);
+ }
+
+ if (NULL != cluster->l2)
+ {
+ mali_l2_cache_reset(cluster->l2);
+ }
+}
+
+struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+ return cluster->l2;
+}
+
+struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (index < cluster->number_of_groups)
+ {
+ return cluster->groups[index];
+ }
+
+ return NULL;
+}
+
+struct mali_cluster *mali_cluster_get_global_cluster(u32 index)
+{
+ if (MALI_MAX_NUMBER_OF_CLUSTERS > index)
+ {
+ return mali_global_clusters[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_cluster_get_glob_num_clusters(void)
+{
+ return mali_global_num_clusters;
+}
+
+mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (NULL != cluster->l2)
+ {
+ /* If the last cache invalidation was done by a job with a higher id we
+ * don't have to flush. Since user space will store jobs w/ their
+ * corresponding memory in sequence (first job #0, then job #1, ...),
+ * we don't have to flush for job n-1 if job n has already invalidated
+ * the cache since we know for sure that job n-1's memory was already
+ * written when job n was started. */
+ if (((s32)id) <= ((s32)cluster->last_invalidated_id))
+ {
+ return MALI_FALSE;
+ }
+ else
+ {
+ cluster->last_invalidated_id = mali_scheduler_get_new_id();
+ }
+
+ mali_l2_cache_invalidate_all(cluster->l2);
+ }
+ return MALI_TRUE;
+}
+
+void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (NULL != cluster->l2)
+ {
+ cluster->last_invalidated_id = mali_scheduler_get_new_id();
+ mali_l2_cache_invalidate_all(cluster->l2);
+ }
+}
+
+void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages)
+{
+ u32 i;
+
+ for (i = 0; i < mali_global_num_clusters; i++)
+ {
+ /*additional check for cluster*/
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_clusters[i]->l2))
+ {
+ mali_l2_cache_invalidate_pages(mali_global_clusters[i]->l2, pages, num_pages);
+ }
+ mali_l2_cache_unlock_power_state(mali_global_clusters[i]->l2);
+ /*check for failed power locking???*/
+ }
+}
diff --git a/driver/src/devicedrv/mali/common/mali_cluster.h b/driver/src/devicedrv/mali/common/mali_cluster.h
new file mode 100644
index 0000000..33debdb
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_cluster.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011-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_CLUSTER_H__
+#define __MALI_CLUSTER_H__
+
+#include "mali_osk.h"
+#include "mali_l2_cache.h"
+
+/* Maximum 1 GP and 4 PP for a cluster (Mali-400 Quad-core) */
+#define MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER 5
+#define MALI_MAX_NUMBER_OF_CLUSTERS 3
+
+struct mali_cluster;
+struct mali_group;
+
+struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache);
+void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group);
+void mali_cluster_delete(struct mali_cluster *cluster);
+
+void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled);
+mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster);
+
+void mali_cluster_reset(struct mali_cluster *cluster);
+
+struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster);
+struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index);
+
+struct mali_cluster *mali_cluster_get_global_cluster(u32 index);
+u32 mali_cluster_get_glob_num_clusters(void);
+
+/* Returns MALI_TRUE if it did the flush */
+mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id);
+void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster);
+void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages);
+
+#endif /* __MALI_CLUSTER_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_device_pause_resume.c b/driver/src/devicedrv/mali/common/mali_device_pause_resume.c
new file mode 100644
index 0000000..6af1279
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_device_pause_resume.c
@@ -0,0 +1,46 @@
+/**
+ * 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 mali_device_pause_resume.c
+ * Implementation of the Mali pause/resume functionality
+ */
+
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_pm.h"
+
+void mali_dev_pause(mali_bool *power_is_on)
+{
+ mali_gp_scheduler_suspend();
+ mali_pp_scheduler_suspend();
+
+ /*
+ * Take and hold the PM lock to be sure we don't change power state as well.
+ * (it might be unsafe to for instance change frequency if Mali GPU is powered off)
+ */
+ mali_pm_execute_state_change_lock();
+ if (NULL != power_is_on)
+ {
+ *power_is_on = mali_pm_is_powered_on();
+ }
+}
+
+void mali_dev_resume(void)
+{
+ mali_pm_execute_state_change_unlock();
+ mali_gp_scheduler_resume();
+ mali_pp_scheduler_resume();
+}
+
+/*
+EXPORT_SYMBOL(mali_dev_pause);
+EXPORT_SYMBOL(mali_dev_resume);
+*/
diff --git a/driver/src/devicedrv/mali/common/mali_device_pause_resume.h b/driver/src/devicedrv/mali/common/mali_device_pause_resume.h
new file mode 100644
index 0000000..6be75b0
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_device_pause_resume.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_DEVICE_PAUSE_RESUME_H__
+#define __MALI_DEVICE_PAUSE_RESUME_H__
+
+#include "mali_osk.h"
+
+/**
+ * Pause the scheduling and power state changes of Mali device driver.
+ * mali_dev_resume() must always be called as soon as possible after this function
+ * in order to resume normal operation of the Mali driver.
+ *
+ * @param power_is_on Receives the power current status of Mali GPU. MALI_TRUE if GPU is powered on
+ */
+void mali_dev_pause(mali_bool *power_is_on);
+
+/**
+ * Resume scheduling and allow power changes in Mali device driver.
+ * This must always be called after mali_dev_pause().
+ */
+void mali_dev_resume(void);
+
+#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_dlbu.c b/driver/src/devicedrv/mali/common/mali_dlbu.c
new file mode 100644
index 0000000..fcc51fa
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_dlbu.c
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+#include "mali_dlbu.h"
+#include "mali_memory.h"
+#include "mali_pp.h"
+#include "mali_group.h"
+#include "mali_osk.h"
+#include "mali_hw_core.h"
+
+/**
+ * Size of DLBU registers in bytes
+ */
+#define MALI_DLBU_SIZE 0x400
+
+u32 mali_dlbu_phys_addr = 0;
+static mali_io_address mali_dlbu_cpu_addr = 0;
+
+static u32 mali_dlbu_tile_position;
+
+/**
+ * DLBU register numbers
+ * Used in the register read/write routines.
+ * See the hardware documentation for more information about each register
+ */
+typedef enum mali_dlbu_register {
+ MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR = 0x0000, /**< Master tile list physical base address;
+ 31:12 Physical address to the page used for the DLBU
+ 0 DLBU enable - set this bit to 1 enables the AXI bus
+ between PPs and L2s, setting to 0 disables the router and
+ no further transactions are sent to DLBU */
+ MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR = 0x0004, /**< Master tile list virtual base address;
+ 31:12 Virtual address to the page used for the DLBU */
+ MALI_DLBU_REGISTER_TLLIST_VBASEADDR = 0x0008, /**< Tile list virtual base address;
+ 31:12 Virtual address to the tile list. This address is used when
+ calculating the call address sent to PP.*/
+ MALI_DLBU_REGISTER_FB_DIM = 0x000C, /**< Framebuffer dimension;
+ 23:16 Number of tiles in Y direction-1
+ 7:0 Number of tiles in X direction-1 */
+ MALI_DLBU_REGISTER_TLLIST_CONF = 0x0010, /**< Tile list configuration;
+ 29:28 select the size of each allocated block: 0=128 bytes, 1=256, 2=512, 3=1024
+ 21:16 2^n number of tiles to be binned to one tile list in Y direction
+ 5:0 2^n number of tiles to be binned to one tile list in X direction */
+ MALI_DLBU_REGISTER_START_TILE_POS = 0x0014, /**< Start tile positions;
+ 31:24 start position in Y direction for group 1
+ 23:16 start position in X direction for group 1
+ 15:8 start position in Y direction for group 0
+ 7:0 start position in X direction for group 0 */
+ MALI_DLBU_REGISTER_PP_ENABLE_MASK = 0x0018, /**< PP enable mask;
+ 7 enable PP7 for load balancing
+ 6 enable PP6 for load balancing
+ 5 enable PP5 for load balancing
+ 4 enable PP4 for load balancing
+ 3 enable PP3 for load balancing
+ 2 enable PP2 for load balancing
+ 1 enable PP1 for load balancing
+ 0 enable PP0 for load balancing */
+} mali_dlbu_register;
+
+typedef enum
+{
+ PP0ENABLE = 0,
+ PP1ENABLE,
+ PP2ENABLE,
+ PP3ENABLE,
+ PP4ENABLE,
+ PP5ENABLE,
+ PP6ENABLE,
+ PP7ENABLE
+} mali_dlbu_pp_enable;
+
+struct mali_dlbu_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ u32 pp_cores_mask; /**< This is a mask for the PP cores whose operation will be controlled by LBU
+ see MALI_DLBU_REGISTER_PP_ENABLE_MASK register */
+};
+
+_mali_osk_errcode_t mali_dlbu_initialize(void)
+{
+
+ MALI_DEBUG_PRINT(2, ("Dynamic Load Balancing Unit initializing\n"));
+
+ if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr))
+ {
+ MALI_SUCCESS;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_dlbu_terminate(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali DLBU: terminating\n"));
+
+ mali_mmu_release_table_page(mali_dlbu_phys_addr);
+}
+
+struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource)
+{
+ struct mali_dlbu_core *core = NULL;
+
+ MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description));
+
+ core = _mali_osk_malloc(sizeof(struct mali_dlbu_core));
+ if (NULL != core)
+ {
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE))
+ {
+ if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core))
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR, MALI_DLB_VIRT_ADDR);
+
+ return core;
+ }
+ MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description));
+ mali_hw_core_delete(&core->hw_core);
+ }
+
+ _mali_osk_free(core);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_dlbu_delete(struct mali_dlbu_core *dlbu)
+{
+ mali_dlbu_reset(dlbu);
+ mali_hw_core_delete(&dlbu->hw_core);
+ _mali_osk_free(dlbu);
+}
+
+void mali_dlbu_enable(struct mali_dlbu_core *dlbu)
+{
+ u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR);
+
+ wval |= 0x1;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval);
+}
+
+void mali_dlbu_disable(struct mali_dlbu_core *dlbu)
+{
+ u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR);
+
+ wval |= (wval & 0xFFFFFFFE);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval);
+}
+
+_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val)
+{
+ u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK);
+
+ if((pp_core_enable < mali_pp_get_glob_num_pp_cores()) && ((0 == val) || (1 == val))) /* check for valid input parameters */
+ {
+ if (val == 1)
+ {
+ val = (wval | (pp_core_enable <<= 0x1));
+ }
+ if (val == 0)
+ {
+ val = (wval & ~(pp_core_enable << 0x1));
+ }
+ wval |= val;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, wval);
+ dlbu->pp_cores_mask = wval;
+
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu)
+{
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
+}
+
+void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu)
+{
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, 0x0);
+}
+
+void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1)
+{
+ u32 wval = 0x0;
+
+ /* write the framebuffer dimensions */
+ wval = (16 << (u32)fb_ydim) | (u32)fb_xdim;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, wval);
+
+ /* write the tile list configuration */
+ wval = 0x0;
+ wval = (28 << (u32)blocksize) | (16 << (u32)ytilesize) | ((u32)xtilesize);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, wval);
+
+ /* write the start tile position */
+ wval = 0x0;
+ wval = (24 << (u32)ygr1 | (16 << (u32)xgr1) | 8 << (u32)ygr0) | (u32)xgr0;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, wval);
+}
+
+_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ MALI_DEBUG_ASSERT_POINTER(dlbu);
+
+ MALI_DEBUG_PRINT(4, ("Mali DLBU: mali_dlbu_reset: %s\n", dlbu->hw_core.description));
+
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, mali_dlbu_phys_addr);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, 0x00);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, 0x00);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, 0x00);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, 0x00);
+
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
+
+ err = _MALI_OSK_ERR_OK;
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ u32 wval, rval;
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+
+ /* find the core id and set the mask */
+
+ if (NULL != pp_core)
+ {
+ wval = mali_pp_core_get_id(pp_core);
+ rval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, (wval << 0x1) | rval);
+ err = _MALI_OSK_ERR_OK;
+ }
+
+ return err;
+}
+
+void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val)
+{
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, val);
+}
+
+void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu)
+{
+ /* this function to implement (see documentation):
+ * 1) clear all bits in the enable register
+ * 2) wait until all PPs have finished - mali_pp_scheduler.c code - this done in interrupts call?
+ * 3) read the current tile position registers to get current tile positions -
+ * note that current tile position register is the same as start tile position - perhaps the name should be changed!!! */
+
+ /* 1) */
+ mali_dlbu_disable_all_pp_cores(dlbu);
+
+ /* 3) */
+ mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS);
+}
+
+void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu)
+{
+ /* this function to implement (see the document):
+ * 1) configure the dynamic load balancing unit as normal
+ * 2) set the current tile position registers as read when stopping the job
+ * 3) configure the PPs to start the job as normal - done by another part of the system - scheduler */
+
+ /* 1) */
+ mali_dlbu_reset(dlbu);
+ /* ++ setup the needed values - see this */
+
+ /* 2) */
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, mali_dlbu_tile_position);
+}
diff --git a/driver/src/devicedrv/mali/common/mali_dlbu.h b/driver/src/devicedrv/mali/common/mali_dlbu.h
new file mode 100644
index 0000000..e3c3b9d
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_dlbu.h
@@ -0,0 +1,45 @@
+/*
+ * 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_DLBU_H__
+#define __MALI_DLBU_H__
+
+#include "mali_osk.h"
+#include "mali_group.h"
+
+#define MALI_DLB_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */
+
+extern u32 mali_dlbu_phys_addr;
+
+struct mali_dlbu_core;
+
+_mali_osk_errcode_t mali_dlbu_initialize(void);
+void mali_dlbu_terminate(void);
+
+struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource);
+void mali_dlbu_delete(struct mali_dlbu_core *dlbu);
+
+void mali_dlbu_enable(struct mali_dlbu_core *dlbu);
+void mali_dlbu_disable(struct mali_dlbu_core *dlbu);
+
+_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val);
+void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu);
+void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu);
+
+_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu);
+void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1);
+
+_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
+void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val);
+
+void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu);
+void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu);
+
+#endif /* __MALI_DLBU_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_gp.c b/driver/src/devicedrv/mali/common/mali_gp.c
new file mode 100644
index 0000000..d03721c
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_gp.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2011-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_gp.h"
+#include "mali_hw_core.h"
+#include "mali_group.h"
+#include "mali_osk.h"
+#include "regs/mali_gp_regs.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#if MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
+#endif
+
+/**
+ * Definition of the GP core struct
+ * Used to track a GP core in the system.
+ */
+struct mali_gp_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ struct mali_group *group; /**< Parent group for this core */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ struct mali_gp_job *running_job; /**< Current running job */
+ _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */
+ u32 timeout_job_id; /**< job id for the timed out job - relevant only if gp_core_timed_out == MALI_TRUE */
+ mali_bool core_timed_out; /**< if MALI_TRUE, this gp core has timed out; if MALI_FALSE, no timeout on this gp core */
+ u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
+ u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
+ u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */
+ u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */
+};
+
+static struct mali_gp_core *mali_global_gp_core = NULL;
+
+/* Interrupt handlers */
+static _mali_osk_errcode_t mali_gp_upper_half(void *data);
+static void mali_gp_bottom_half(void *data);
+static void mali_gp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data);
+static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend);
+static void mali_gp_timeout(void *data);
+
+struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group)
+{
+ struct mali_gp_core* core = NULL;
+
+ MALI_DEBUG_ASSERT(NULL == mali_global_gp_core);
+ MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description));
+
+ core = _mali_osk_malloc(sizeof(struct mali_gp_core));
+ if (NULL != core)
+ {
+ core->group = group;
+ core->running_job = NULL;
+ core->counter_src0 = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src1 = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src0_used = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src1_used = MALI_HW_CORE_NO_COUNTER;
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE))
+ {
+ _mali_osk_errcode_t ret;
+
+ mali_group_lock(group);
+ ret = mali_gp_reset(core);
+ mali_group_unlock(group);
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ core->irq = _mali_osk_irq_init(resource->irq,
+ mali_gp_upper_half,
+ mali_gp_bottom_half,
+ mali_gp_irq_probe_trigger,
+ mali_gp_irq_probe_ack,
+ core,
+ "mali_gp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ /* Initialise the timeout timer */
+ core->timeout_timer = _mali_osk_timer_init();
+ if(NULL != core->timeout_timer)
+ {
+ _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core);
+ MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core));
+ mali_global_gp_core = core;
+
+ return core;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description));
+ /* Release IRQ handlers */
+ _mali_osk_irq_term(core->irq);
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
+ }
+ }
+ mali_hw_core_delete(&core->hw_core);
+ }
+
+ _mali_osk_free(core);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_gp_delete(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ _mali_osk_timer_term(core->timeout_timer);
+ _mali_osk_irq_term(core->irq);
+ mali_hw_core_delete(&core->hw_core);
+ mali_global_gp_core = NULL;
+ _mali_osk_free(core);
+}
+
+void mali_gp_stop_bus(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
+}
+
+_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core)
+{
+ int i;
+ const int request_loop_count = 20;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ /* Send the stop bus command. */
+ mali_gp_stop_bus(core);
+
+ /* Wait for bus to be stopped */
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_hard_reset(struct mali_gp_core *core)
+{
+ const int reset_finished_loop_count = 15;
+ const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW;
+ const u32 reset_invalid_value = 0xC0FFE000;
+ const u32 reset_check_value = 0xC01A0000;
+ const u32 reset_default_value = 0;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description));
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_gp_post_process_job(core, MALI_FALSE);
+
+ mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value);
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET);
+
+ for (i = 0; i < reset_finished_loop_count; i++)
+ {
+ mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value);
+ if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register))
+ {
+ break;
+ }
+ }
+
+ if (i == reset_finished_loop_count)
+ {
+ MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n"));
+ }
+
+ mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
+
+}
+
+_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core)
+{
+ int i;
+ const int request_loop_count = 20;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description));
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_gp_post_process_job(core, MALI_FALSE);
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_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 */
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
+
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* the bus was stopped OK, do the hard reset */
+ mali_gp_hard_reset(core);
+
+#elif defined(USING_MALI400)
+
+ /* Mali-300 and Mali-400 have a safe reset command which we use */
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET);
+
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, unable to recover\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+#else
+#error "no supported mali core defined"
+#endif
+
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
+{
+ u32 startcmd = 0;
+ u32 *frame_registers = mali_gp_job_get_frame_registers(job);
+ core->counter_src0_used = core->counter_src0;
+ core->counter_src1_used = core->counter_src1;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ if (mali_gp_job_has_vs_job(job))
+ {
+ startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
+ }
+
+ if (mali_gp_job_has_plbu_job(job))
+ {
+ startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
+ }
+
+ MALI_DEBUG_ASSERT(0 != startcmd);
+
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME);
+
+ /* This selects which performance counters we are reading */
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ /* 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(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
+ }
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
+ }
+ }
+ else
+ {
+ /* Use HW counters from job object, if any */
+ u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
+ if (0 != perf_counter_flag)
+ {
+ if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
+ {
+ core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
+ }
+
+ if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
+ {
+ core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
+ }
+ }
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd));
+
+ /* Barrier to make sure the previous register write is finished */
+ _mali_osk_write_mem_barrier();
+
+ /* This is the command that starts the core. */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd);
+
+ /* Barrier to make sure the previous register write is finished */
+ _mali_osk_write_mem_barrier();
+
+ /* Setup the timeout timer value and save the job id for the job running on the gp core */
+
+ _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+ core->timeout_job_id = mali_gp_job_get_id(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,
+ 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;
+}
+
+void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr)
+{
+ u32 irq_readout;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
+
+ if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n"));
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
+ _mali_osk_write_mem_barrier();
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0);
+#endif
+ }
+ /*
+ * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response.
+ * A timeout or a page fault on Mali-200 PP core can cause this behaviour.
+ */
+}
+
+void mali_gp_abort_job(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core))
+ {
+ _mali_osk_timer_del(core->timeout_timer);
+ }
+}
+
+u32 mali_gp_core_get_version(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION);
+}
+
+mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ core->counter_src0 = counter;
+ return MALI_TRUE;
+}
+
+mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ core->counter_src1 = counter;
+ return MALI_TRUE;
+}
+
+u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->counter_src0;
+}
+
+u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->counter_src1;
+}
+
+struct mali_gp_core *mali_gp_get_global_gp_core(void)
+{
+ return mali_global_gp_core;
+}
+
+/* ------------- interrupt handling below ------------------ */
+static _mali_osk_errcode_t mali_gp_upper_half(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+ u32 irq_readout;
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
+ if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
+#endif
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_irq_schedulework(core->irq);
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+static void mali_gp_bottom_half(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+ u32 irq_readout;
+ u32 irq_errors;
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+#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 */
+
+ if ( MALI_FALSE == mali_group_power_is_on(core->group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
+ mali_group_unlock(core->group);
+ return;
+ }
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
+ MALI_DEBUG_PRINT(4, ("Mali GP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description));
+
+ if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST))
+ {
+ u32 core_status = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS);
+ if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
+ {
+ 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 */
+ return;
+ }
+ }
+
+ /*
+ * Now lets look at the possible error cases (IRQ indicating error or timeout)
+ * END_CMD_LST, HANG and PLBU_OOM interrupts are not considered error.
+ */
+ irq_errors = irq_readout & ~(MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_HANG|MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM);
+ if (0 != irq_errors)
+ {
+ 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 */
+ return;
+ }
+ else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
+ {
+ if (core->timeout_job_id == mali_gp_job_get_id(core->running_job))
+ {
+ mali_gp_post_process_job(core, MALI_FALSE);
+ MALI_DEBUG_PRINT(2, ("Mali GP: Job %d timed out\n", mali_gp_job_get_id(core->running_job)));
+ mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_TIMED_OUT);
+ }
+ core->core_timed_out = MALI_FALSE;
+ return;
+ }
+ else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
+ {
+ /* GP wants more memory in order to continue.
+ *
+ * This must be handled prior to HANG because this actually can
+ * generate a HANG while waiting for more memory.
+ * And it must be handled before the completion interrupts,
+ * since the PLBU can run out of memory after VS is complete;
+ * in which case the OOM must be handled before to complete the
+ * PLBU work.
+ */
+ 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 */
+ return;
+ }
+ else if (irq_readout & MALIGP2_REG_VAL_IRQ_HANG)
+ {
+ /* 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 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
+#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
+}
+
+static void mali_gp_irq_probe_trigger(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG);
+ _mali_osk_mem_barrier();
+}
+
+static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+ u32 irq_readout;
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
+ if (MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG);
+ _mali_osk_mem_barrier();
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+/* ------ local helper functions below --------- */
+
+static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend)
+{
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ if (NULL != core->running_job)
+ {
+ u32 val0 = 0;
+ u32 val1 = 0;
+#if MALI_TIMELINE_PROFILING_ENABLED
+ u32 event_id;
+#endif
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
+ if (mali_gp_job_get_perf_counter_flag(core->running_job) &&
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used)
+ {
+ /* We retrieved the counter that user space asked for, so return the value through the job object */
+ mali_gp_job_set_perf_counter_value0(core->running_job, val0);
+ }
+ else
+ {
+ /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */
+ mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE);
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0);
+#endif
+
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+ if (mali_gp_job_get_perf_counter_flag(core->running_job) &&
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used)
+ {
+ /* We retrieved the counter that user space asked for, so return the value through the job object */
+ mali_gp_job_set_perf_counter_value1(core->running_job, val1);
+ }
+ else
+ {
+ /* User space asked for a counter, but this is not what we retrieved (overridden by counter src set on core) */
+ mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE);
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1);
+#endif
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ if (MALI_TRUE == suspend)
+ {
+ event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0);
+ }
+ else
+ {
+ event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0);
+ }
+ _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0);
+#endif
+
+ mali_gp_job_set_current_heap_addr(core->running_job,
+ mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR));
+
+ if (MALI_TRUE != suspend)
+ {
+ /* We are no longer running a job... */
+ core->running_job = NULL;
+ _mali_osk_timer_del(core->timeout_timer);
+ }
+ }
+}
+
+/* callback function for gp core timeout */
+static void mali_gp_timeout(void *data)
+{
+ struct mali_gp_core * core = ((struct mali_gp_core *)data);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP: TIMEOUT callback \n"));
+ core->core_timed_out = MALI_TRUE;
+ _mali_osk_irq_schedulework(core->irq);
+}
+
+#if 0
+void mali_gp_print_state(struct mali_gp_core *core)
+{
+ MALI_DEBUG_PRINT(2, ("Mali GP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) ));
+}
+#endif
+
+#if MALI_STATE_TRACKING
+u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description);
+
+ return n;
+}
+#endif
diff --git a/driver/src/devicedrv/mali/common/mali_gp.h b/driver/src/devicedrv/mali/common/mali_gp.h
new file mode 100644
index 0000000..3175b75
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_gp.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011-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_GP_H__
+#define __MALI_GP_H__
+
+#include "mali_osk.h"
+#include "mali_gp_job.h"
+
+struct mali_gp_core;
+struct mali_group;
+
+_mali_osk_errcode_t mali_gp_initialize(void);
+void mali_gp_terminate(void);
+
+struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group);
+void mali_gp_delete(struct mali_gp_core *core);
+
+void mali_gp_stop_bus(struct mali_gp_core *core);
+_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core);
+void mali_gp_hard_reset(struct mali_gp_core *core);
+_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core);
+
+void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job);
+void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr);
+
+void mali_gp_abort_job(struct mali_gp_core *core);
+
+u32 mali_gp_core_get_version(struct mali_gp_core *core);
+
+mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter);
+mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter);
+u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core);
+u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core);
+struct mali_gp_core *mali_gp_get_global_gp_core(void);
+
+u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size);
+
+#endif /* __MALI_GP_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_gp_job.c b/driver/src/devicedrv/mali/common/mali_gp_job.c
new file mode 100644
index 0000000..abe1d93
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_gp_job.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011-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_gp_job.h"
+#include "mali_osk.h"
+#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 *args, u32 id)
+{
+ struct mali_gp_job *job;
+
+ job = _mali_osk_malloc(sizeof(struct mali_gp_job));
+ if (NULL != job)
+ {
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ job->id = id;
+ 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;
+ }
+
+ return NULL;
+}
+
+void mali_gp_job_delete(struct mali_gp_job *job)
+{
+ _mali_osk_free(job);
+}
diff --git a/driver/src/devicedrv/mali/common/mali_gp_job.h b/driver/src/devicedrv/mali/common/mali_gp_job.h
new file mode 100644
index 0000000..9c29f1c
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_gp_job.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011-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_GP_JOB_H__
+#define __MALI_GP_JOB_H__
+
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_uk_types.h"
+#include "mali_session.h"
+
+/**
+ * The structure represends a GP job, including all sub-jobs
+ * (This struct unfortunatly needs to be public because of how the _mali_osk_list_*
+ * mechanism works)
+ */
+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 */
+ 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 *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)
+{
+ return (NULL == job) ? 0 : job->id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job)
+{
+ return job->user_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
+{
+ return job->frame_builder_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
+{
+ return job->flush_id;
+}
+
+MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job)
+{
+ return job->frame_registers;
+}
+
+MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job)
+{
+ return job->session;
+}
+
+MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job)
+{
+ 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->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)
+{
+ return job->heap_current_addr;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr)
+{
+ job->heap_current_addr = heap_addr;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job)
+{
+ return job->perf_counter_flag;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
+{
+ return job->perf_counter_src0;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
+{
+ return job->perf_counter_src1;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job)
+{
+ return job->perf_counter_value0;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job)
+{
+ return job->perf_counter_value1;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value)
+{
+ job->perf_counter_value0 = value;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value)
+{
+ job->perf_counter_value1 = value;
+}
+
+#endif /* __MALI_GP_JOB_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_gp_scheduler.c b/driver/src/devicedrv/mali/common/mali_gp_scheduler.c
new file mode 100644
index 0000000..05f00fc
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_gp_scheduler.c
@@ -0,0 +1,438 @@
+/*
+ * 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.
+ */
+
+#include "mali_gp_scheduler.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_scheduler.h"
+#include "mali_gp.h"
+#include "mali_gp_job.h"
+#include "mali_group.h"
+#include "mali_cluster.h"
+
+enum mali_gp_slot_state
+{
+ MALI_GP_SLOT_STATE_IDLE,
+ MALI_GP_SLOT_STATE_WORKING,
+};
+
+/* A render slot is an entity which jobs can be scheduled onto */
+struct mali_gp_slot
+{
+ struct mali_group *group;
+ /*
+ * We keep track of the state here as well as in the group object
+ * so we don't need to take the group lock so often (and also avoid clutter with the working lock)
+ */
+ enum mali_gp_slot_state state;
+ u32 returned_cookie;
+};
+
+static u32 gp_version = 0;
+static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */
+static struct mali_gp_slot slot;
+
+/* Variables to allow safe pausing of the scheduler */
+static _mali_osk_wait_queue_t *gp_scheduler_working_wait_queue = NULL;
+static u32 pause_count = 0;
+
+static mali_bool mali_gp_scheduler_is_suspended(void);
+
+static _mali_osk_lock_t *gp_scheduler_lock = NULL;
+/* Contains tid of thread that locked the scheduler or 0, if not locked */
+
+_mali_osk_errcode_t mali_gp_scheduler_initialize(void)
+{
+ u32 i;
+
+ _MALI_OSK_INIT_LIST_HEAD(&job_queue);
+
+ gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
+
+ if (NULL == gp_scheduler_lock)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ if (NULL == gp_scheduler_working_wait_queue)
+ {
+ _mali_osk_lock_term(gp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ /* Find all the available GP cores */
+ for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++)
+ {
+ u32 group_id = 0;
+ struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i);
+ struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id);
+ while (NULL != group)
+ {
+ struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
+ if (NULL != gp_core)
+ {
+ if (0 == gp_version)
+ {
+ /* Retrieve GP version */
+ gp_version = mali_gp_core_get_version(gp_core);
+ }
+ slot.group = group;
+ slot.state = MALI_GP_SLOT_STATE_IDLE;
+ break; /* There are only one GP, no point in looking for more */
+ }
+ group_id++;
+ group = mali_cluster_get_group(curr_cluster, group_id);
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_scheduler_terminate(void)
+{
+ _mali_osk_wait_queue_term(gp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(gp_scheduler_lock);
+}
+
+MALI_STATIC_INLINE void mali_gp_scheduler_lock(void)
+{
+ if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
+ {
+ /* Non-interruptable lock failed: this should never happen. */
+ MALI_DEBUG_ASSERT(0);
+ }
+ MALI_DEBUG_PRINT(5, ("Mali GP scheduler: GP scheduler lock taken\n"));
+}
+
+MALI_STATIC_INLINE void mali_gp_scheduler_unlock(void)
+{
+ MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n"));
+ _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+#ifdef DEBUG
+MALI_STATIC_INLINE void mali_gp_scheduler_assert_locked(void)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);
+}
+#define MALI_ASSERT_GP_SCHEDULER_LOCKED() mali_gp_scheduler_assert_locked()
+#else
+#define MALI_ASSERT_GP_SCHEDULER_LOCKED()
+#endif
+
+static void mali_gp_scheduler_schedule(void)
+{
+ struct mali_gp_job *job;
+
+ MALI_ASSERT_GP_SCHEDULER_LOCKED();
+
+ if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
+ pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0));
+ return; /* Nothing to do, so early out */
+ }
+
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
+ if (_MALI_OSK_ERR_OK == mali_group_start_gp_job(slot.group, job))
+ {
+ /* Mark slot as busy */
+ slot.state = MALI_GP_SLOT_STATE_WORKING;
+
+ /* Remove from queue of unscheduled jobs */
+ _mali_osk_list_del(&job->list);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n"));
+ }
+}
+
+static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
+{
+ _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
+ if (NULL != notobj)
+ {
+ _mali_uk_gp_job_finished_s *jobres = notobj->result_buffer;
+ _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
+ jobres->user_job_ptr = mali_gp_job_get_user_id(job);
+ if (MALI_TRUE == success)
+ {
+ jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
+ }
+ else
+ {
+ jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
+ }
+
+ jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job);
+ jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job);
+ jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job);
+
+ mali_session_send_notification(mali_gp_job_get_session(job), notobj);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n"));
+ }
+
+ mali_gp_job_delete(job);
+}
+
+
+void mali_gp_scheduler_do_schedule(void)
+{
+ mali_gp_scheduler_lock();
+
+ mali_gp_scheduler_schedule();
+
+ mali_gp_scheduler_unlock();
+}
+
+void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success)
+{
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) completed (%s)\n", mali_gp_job_get_id(job), job, success ? "success" : "failure"));
+
+ mali_gp_scheduler_lock();
+
+ /* Mark slot as idle again */
+ slot.state = MALI_GP_SLOT_STATE_IDLE;
+
+ /* If paused, then this was the last job, so wake up sleeping workers */
+ if (pause_count > 0)
+ {
+ _mali_osk_wait_queue_wake_up(gp_scheduler_working_wait_queue);
+ }
+ else
+ {
+ mali_gp_scheduler_schedule();
+ }
+
+ mali_gp_scheduler_unlock();
+
+ mali_gp_scheduler_return_job_to_user(job, success);
+}
+
+void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
+{
+ _mali_osk_notification_t *notobj;
+
+ notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
+
+ if (NULL != notobj)
+ {
+ _mali_uk_gp_job_suspended_s * jobres;
+
+ mali_gp_scheduler_lock();
+
+ jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer;
+
+ jobres->user_job_ptr = mali_gp_job_get_user_id(job);
+ jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
+ jobres->cookie = mali_gp_job_get_id(job);
+ slot.returned_cookie = jobres->cookie;
+
+ mali_session_send_notification(mali_gp_job_get_session(job), notobj);
+
+ mali_gp_scheduler_unlock();
+ }
+
+ /*
+ * If this function failed, then we could return the job to user space right away,
+ * but there is a job timer anyway that will do that eventually.
+ * This is not exactly a common case anyway.
+ */
+}
+
+void mali_gp_scheduler_suspend(void)
+{
+ mali_gp_scheduler_lock();
+ pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
+ mali_gp_scheduler_unlock();
+
+ _mali_osk_wait_queue_wait_event(gp_scheduler_working_wait_queue, mali_gp_scheduler_is_suspended);
+}
+
+void mali_gp_scheduler_resume(void)
+{
+ mali_gp_scheduler_lock();
+ pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
+ if (0 == pause_count)
+ {
+ mali_gp_scheduler_schedule();
+ }
+ mali_gp_scheduler_unlock();
+}
+
+_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(args);
+
+ if (NULL == args->ctx)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ session = (struct mali_session_data*)args->ctx;
+ if (NULL == session)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ job = mali_gp_job_create(session, args, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ mali_gp_scheduler_lock();
+
+ _mali_osk_list_addtail(&job->list, &job_queue);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job));
+
+ mali_gp_scheduler_schedule();
+
+ mali_gp_scheduler_unlock();
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores(_mali_uk_get_gp_number_of_cores_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ args->number_of_cores = 1;
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_gp_core_version(_mali_uk_get_gp_core_version_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ args->version = gp_version;
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_gp_suspend_response(_mali_uk_gp_suspend_response_s *args)
+{
+ struct mali_session_data *session;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ if (NULL == args->ctx)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ session = (struct mali_session_data*)args->ctx;
+ if (NULL == session)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mali_gp_scheduler_lock();
+
+ /* Make sure that the cookie returned by user space is the same as we provided in the first place */
+ if (args->cookie != slot.returned_cookie)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: Got an illegal cookie from user space, expected %u but got %u (job id)\n", slot.returned_cookie, args->cookie)) ;
+ mali_gp_scheduler_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mali_gp_scheduler_unlock();
+
+ switch (args->code)
+ {
+ case _MALIGP_JOB_RESUME_WITH_NEW_HEAP:
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Resuming job %u with new heap; 0x%08X - 0x%08X\n", args->cookie, args->arguments[0], args->arguments[1]));
+ mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]);
+ ret = _MALI_OSK_ERR_OK;
+ break;
+
+ case _MALIGP_JOB_ABORT:
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting job %u, no new heap provided\n", args->cookie));
+ mali_group_abort_gp_job(slot.group, args->cookie);
+ ret = _MALI_OSK_ERR_OK;
+ break;
+
+ default:
+ MALI_PRINT_ERROR(("Mali GP scheduler: Wrong suspend response from user space\n"));
+ ret = _MALI_OSK_ERR_FAULT;
+ break;
+ }
+
+ return ret;
+
+}
+
+void mali_gp_scheduler_abort_session(struct mali_session_data *session)
+{
+ struct mali_gp_job *job, *tmp;
+
+ mali_gp_scheduler_lock();
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session));
+
+ /* Check queue for jobs and remove */
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list)
+ {
+ if (mali_gp_job_get_session(job) == session)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job));
+ _mali_osk_list_del(&(job->list));
+ mali_gp_job_delete(job);
+ }
+ }
+
+ mali_gp_scheduler_unlock();
+
+ /* Abort running jobs from this session. It is safe to do this outside
+ * the scheduler lock as there is only one GP core, and the queue has
+ * already been emptied, as long as there are no new jobs coming in
+ * from user space. */
+ mali_group_abort_session(slot.group, session);
+}
+
+static mali_bool mali_gp_scheduler_is_suspended(void)
+{
+ mali_bool ret;
+
+ mali_gp_scheduler_lock();
+ ret = pause_count > 0 && slot.state == MALI_GP_SLOT_STATE_IDLE;
+ mali_gp_scheduler_unlock();
+
+ return ret;
+}
+
+
+#if MALI_STATE_TRACKING
+u32 mali_gp_scheduler_dump_state(char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "GP\n");
+ n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
+
+ n += mali_group_dump_state(slot.group, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", mali_group_gp_state(slot.group));
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+
+ return n;
+}
+#endif
diff --git a/driver/src/devicedrv/mali/common/mali_gp_scheduler.h b/driver/src/devicedrv/mali/common/mali_gp_scheduler.h
new file mode 100644
index 0000000..ef58509
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_gp_scheduler.h
@@ -0,0 +1,30 @@
+/*
+ * 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_GP_SCHEDULER_H__
+#define __MALI_GP_SCHEDULER_H__
+
+#include "mali_osk.h"
+#include "mali_cluster.h"
+#include "mali_gp_job.h"
+
+_mali_osk_errcode_t mali_gp_scheduler_initialize(void);
+void mali_gp_scheduler_terminate(void);
+
+void mali_gp_scheduler_do_schedule(void);
+void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success);
+void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job);
+void mali_gp_scheduler_abort_session(struct mali_session_data *session);
+u32 mali_gp_scheduler_dump_state(char *buf, u32 size);
+
+void mali_gp_scheduler_suspend(void);
+void mali_gp_scheduler_resume(void);
+
+#endif /* __MALI_GP_SCHEDULER_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_group.c b/driver/src/devicedrv/mali/common/mali_group.c
new file mode 100644
index 0000000..9202bc1
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_group.c
@@ -0,0 +1,841 @@
+/*
+ * Copyright (C) 2011-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_group.h"
+#include "mali_osk.h"
+#include "mali_cluster.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_mmu.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_pm.h"
+
+/*
+ * The group object is the most important object in the device driver,
+ * and acts as the center of many HW operations.
+ * The reason for this is that operations on the MMU will affect all
+ * cores connected to this MMU (a group is defined by the MMU and the
+ * cores which are connected to this).
+ * The group lock is thus the most important lock, followed by the
+ * GP and PP scheduler locks. They must be taken in the following
+ * order:
+ * GP/PP lock first, then group lock(s).
+ */
+
+/**
+ * The structure represents a render group
+ * A render group is defined by all the cores that share the same Mali MMU
+ */
+
+struct mali_group
+{
+ struct mali_cluster *cluster;
+
+ struct mali_mmu_core *mmu;
+ struct mali_session_data *session;
+ int page_dir_ref_count;
+ mali_bool power_is_on;
+#if defined(USING_MALI200)
+ mali_bool pagedir_activation_failed;
+#endif
+
+ struct mali_gp_core *gp_core;
+ enum mali_group_core_state gp_state;
+ struct mali_gp_job *gp_running_job;
+
+ struct mali_pp_core *pp_core;
+ enum mali_group_core_state pp_state;
+ struct mali_pp_job *pp_running_job;
+ u32 pp_running_sub_job;
+
+ _mali_osk_lock_t *lock;
+};
+
+static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS];
+static u32 mali_global_num_groups = 0;
+
+enum mali_group_activate_pd_status
+{
+ MALI_GROUP_ACTIVATE_PD_STATUS_FAILED,
+ MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD,
+ MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD,
+};
+
+/* local helper functions */
+static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session);
+static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session);
+static void mali_group_recovery_reset(struct mali_group *group);
+static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success);
+
+void mali_group_lock(struct mali_group *group)
+{
+ if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(group->lock, _MALI_OSK_LOCKMODE_RW))
+ {
+ /* Non-interruptable lock failed: this should never happen. */
+ MALI_DEBUG_ASSERT(0);
+ }
+ MALI_DEBUG_PRINT(5, ("Mali group: Group lock taken 0x%08X\n", group));
+}
+
+void mali_group_unlock(struct mali_group *group)
+{
+ MALI_DEBUG_PRINT(5, ("Mali group: Releasing group lock 0x%08X\n", group));
+ _mali_osk_lock_signal(group->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+#ifdef DEBUG
+void mali_group_assert_locked(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+}
+#endif
+
+
+struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu)
+{
+ struct mali_group *group = NULL;
+
+ if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS)
+ {
+ MALI_PRINT_ERROR(("Mali group: Too many group objects created\n"));
+ return NULL;
+ }
+
+ group = _mali_osk_malloc(sizeof(struct mali_group));
+ if (NULL != group)
+ {
+ _mali_osk_memset(group, 0, sizeof(struct mali_group));
+ group->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_GROUP);
+ if (NULL != group->lock)
+ {
+ group->cluster = cluster;
+ group->mmu = mmu; /* This group object now owns the MMU object */
+ group->session = NULL;
+ group->page_dir_ref_count = 0;
+ group->power_is_on = MALI_TRUE;
+
+ group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
+#if defined(USING_MALI200)
+ group->pagedir_activation_failed = MALI_FALSE;
+#endif
+ mali_global_groups[mali_global_num_groups] = group;
+ mali_global_num_groups++;
+
+ return group;
+ }
+ _mali_osk_free(group);
+ }
+
+ return NULL;
+}
+
+void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core)
+{
+ /* This group object now owns the GP core object */
+ group->gp_core = gp_core;
+}
+
+void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core)
+{
+ /* This group object now owns the PP core object */
+ group->pp_core = pp_core;
+}
+
+void mali_group_delete(struct mali_group *group)
+{
+ u32 i;
+
+ /* Delete the resources that this group owns */
+ if (NULL != group->gp_core)
+ {
+ mali_gp_delete(group->gp_core);
+ }
+
+ if (NULL != group->pp_core)
+ {
+ mali_pp_delete(group->pp_core);
+ }
+
+ if (NULL != group->mmu)
+ {
+ mali_mmu_delete(group->mmu);
+ }
+
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ if (mali_global_groups[i] == group)
+ {
+ mali_global_groups[i] = NULL;
+ mali_global_num_groups--;
+ break;
+ }
+ }
+
+ _mali_osk_lock_term(group->lock);
+
+ _mali_osk_free(group);
+}
+
+/* Called from mali_cluster_reset() when the system is re-turned on */
+void mali_group_reset(struct mali_group *group)
+{
+ mali_group_lock(group);
+
+ group->session = NULL;
+
+ if (NULL != group->mmu)
+ {
+ mali_mmu_reset(group->mmu);
+ }
+
+ if (NULL != group->gp_core)
+ {
+ mali_gp_reset(group->gp_core);
+ }
+
+ if (NULL != group->pp_core)
+ {
+ mali_pp_reset(group->pp_core);
+ }
+
+ mali_group_unlock(group);
+}
+
+struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group)
+{
+ return group->gp_core;
+}
+
+struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group)
+{
+ return group->pp_core;
+}
+
+_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job)
+{
+ struct mali_session_data *session;
+ enum mali_group_activate_pd_status activate_status;
+
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+
+ mali_pm_core_event(MALI_CORE_EVENT_GP_START);
+
+ session = mali_gp_job_get_session(job);
+
+ mali_group_lock(group);
+
+ mali_cluster_l2_cache_invalidate_all(group->cluster, mali_gp_job_get_id(job));
+
+ activate_status = mali_group_activate_page_directory(group, session);
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
+ {
+ /* if session is NOT kept Zapping is done as part of session switch */
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
+ {
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+ }
+ mali_gp_job_start(group->gp_core, job);
+ group->gp_running_job = job;
+ group->gp_state = MALI_GROUP_CORE_STATE_WORKING;
+
+ mali_group_unlock(group);
+
+ return _MALI_OSK_ERR_OK;
+ }
+
+#if defined(USING_MALI200)
+ group->pagedir_activation_failed = MALI_TRUE;
+#endif
+
+ mali_group_unlock(group);
+
+ mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_GP_START */
+ return _MALI_OSK_ERR_FAULT;
+}
+
+_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job)
+{
+ struct mali_session_data *session;
+ enum mali_group_activate_pd_status activate_status;
+
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+
+ mali_pm_core_event(MALI_CORE_EVENT_PP_START);
+
+ session = mali_pp_job_get_session(job);
+
+ mali_group_lock(group);
+
+ mali_cluster_l2_cache_invalidate_all(group->cluster, mali_pp_job_get_id(job));
+
+ activate_status = mali_group_activate_page_directory(group, session);
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
+ {
+ /* if session is NOT kept Zapping is done as part of session switch */
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
+ {
+ MALI_DEBUG_PRINT(3, ("PP starting job PD_Switch 0 Flush 1 Zap 1\n"));
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+ }
+ mali_pp_job_start(group->pp_core, job, sub_job);
+ group->pp_running_job = job;
+ group->pp_running_sub_job = sub_job;
+ group->pp_state = MALI_GROUP_CORE_STATE_WORKING;
+
+ mali_group_unlock(group);
+
+ return _MALI_OSK_ERR_OK;
+ }
+
+#if defined(USING_MALI200)
+ group->pagedir_activation_failed = MALI_TRUE;
+#endif
+
+ mali_group_unlock(group);
+
+ mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_PP_START */
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr)
+{
+ mali_group_lock(group);
+
+ if (group->gp_state != MALI_GROUP_CORE_STATE_OOM ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ mali_group_unlock(group);
+ return; /* Illegal request or job has already been aborted */
+ }
+
+ mali_cluster_l2_cache_invalidate_all_force(group->cluster);
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+
+ mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr);
+ group->gp_state = MALI_GROUP_CORE_STATE_WORKING;
+
+ mali_group_unlock(group);
+}
+
+void mali_group_abort_gp_job(struct mali_group *group, u32 job_id)
+{
+ mali_group_lock(group);
+
+ if (group->gp_state == MALI_GROUP_CORE_STATE_IDLE ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ mali_group_unlock(group);
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* Will release group lock */
+}
+
+void mali_group_abort_pp_job(struct mali_group *group, u32 job_id)
+{
+ mali_group_lock(group);
+
+ if (group->pp_state == MALI_GROUP_CORE_STATE_IDLE ||
+ mali_pp_job_get_id(group->pp_running_job) != job_id)
+ {
+ mali_group_unlock(group);
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* Will release group lock */
+}
+
+void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session)
+{
+ struct mali_gp_job *gp_job;
+ struct mali_pp_job *pp_job;
+ u32 gp_job_id = 0;
+ u32 pp_job_id = 0;
+ mali_bool abort_pp = MALI_FALSE;
+ mali_bool abort_gp = MALI_FALSE;
+
+ mali_group_lock(group);
+
+ gp_job = group->gp_running_job;
+ pp_job = group->pp_running_job;
+
+ if (gp_job && mali_gp_job_get_session(gp_job) == session)
+ {
+ MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session));
+
+ gp_job_id = mali_gp_job_get_id(gp_job);
+ abort_gp = MALI_TRUE;
+ }
+
+ if (pp_job && mali_pp_job_get_session(pp_job) == session)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session));
+
+ pp_job_id = mali_pp_job_get_id(pp_job);
+ abort_pp = MALI_TRUE;
+ }
+
+ mali_group_unlock(group);
+
+ /* These functions takes and releases the group lock */
+ if (0 != abort_gp)
+ {
+ mali_group_abort_gp_job(group, gp_job_id);
+ }
+ if (0 != abort_pp)
+ {
+ mali_group_abort_pp_job(group, pp_job_id);
+ }
+
+ mali_group_lock(group);
+ mali_group_remove_session_if_unused(group, session);
+ mali_group_unlock(group);
+}
+
+enum mali_group_core_state mali_group_gp_state(struct mali_group *group)
+{
+ return group->gp_state;
+}
+
+enum mali_group_core_state mali_group_pp_state(struct mali_group *group)
+{
+ return group->pp_state;
+}
+
+/* group lock need to be taken before calling mali_group_bottom_half */
+void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ switch (event)
+ {
+ case GROUP_EVENT_PP_JOB_COMPLETED:
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_TRUE); /* PP job SUCCESS */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_PP_JOB_FAILED:
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job FAIL */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_PP_JOB_TIMED_OUT:
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job TIMEOUT */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_JOB_COMPLETED:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_TRUE); /* GP job SUCCESS */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_JOB_FAILED:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job FAIL */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_JOB_TIMED_OUT:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job TIMEOUT */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_OOM:
+ group->gp_state = MALI_GROUP_CORE_STATE_OOM;
+ mali_group_unlock(group); /* Nothing to do on the HW side, so just release group lock right away */
+ mali_gp_scheduler_oom(group, group->gp_running_job);
+ break;
+ case GROUP_EVENT_MMU_PAGE_FAULT:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_TRUE, MALI_FALSE); /* GP and PP job FAIL */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ default:
+ break;
+ }
+}
+
+struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group)
+{
+ return group->mmu;
+}
+
+struct mali_session_data *mali_group_get_session(struct mali_group *group)
+{
+ return group->session;
+}
+
+struct mali_group *mali_group_get_glob_group(u32 index)
+{
+ if(mali_global_num_groups > index)
+ {
+ return mali_global_groups[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_group_get_glob_num_groups(void)
+{
+ return mali_global_num_groups;
+}
+
+/* Used to check if scheduler for the other core type needs to be called on job completion.
+ *
+ * Used only for Mali-200, where job start may fail if the only MMU is busy
+ * with another session's address space.
+ */
+static inline mali_bool mali_group_other_reschedule_needed(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+#if defined(USING_MALI200)
+ if (group->pagedir_activation_failed)
+ {
+ group->pagedir_activation_failed = MALI_FALSE;
+ return MALI_TRUE;
+ }
+ else
+#endif
+ {
+ return MALI_FALSE;
+ }
+}
+
+static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session)
+{
+ enum mali_group_activate_pd_status retval;
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group 0x%08X\n", mali_session_get_page_directory(session), session, group));
+ MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count);
+
+ if (0 != group->page_dir_ref_count)
+ {
+ if (group->session != session)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Activating session FAILED: 0x%08x on group 0x%08X. Existing session: 0x%08x\n", session, group, group->session));
+ return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Activating session already activated: 0x%08x on group 0x%08X. New Ref: %d\n", session, group, 1+group->page_dir_ref_count));
+ retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD;
+
+ }
+ }
+ else
+ {
+ /* There might be another session here, but it is ok to overwrite it since group->page_dir_ref_count==0 */
+ if (group->session != session)
+ {
+ mali_bool activate_success;
+ MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group 0x%08X. Ref: %d\n", session, group->session, group, 1+group->page_dir_ref_count));
+
+ activate_success = mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session));
+ MALI_DEBUG_ASSERT(activate_success);
+ if ( MALI_FALSE== activate_success ) return MALI_FALSE;
+ group->session = session;
+ retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group 0x%08X. Ref: %d\n", session->page_directory, group, 1+group->page_dir_ref_count));
+ retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD;
+ }
+ }
+
+ group->page_dir_ref_count++;
+ return retval;
+}
+
+static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ MALI_DEBUG_ASSERT(0 < group->page_dir_ref_count);
+ MALI_DEBUG_ASSERT(session == group->session);
+
+ group->page_dir_ref_count--;
+
+ /* As an optimization, the MMU still points to the group->session even if (0 == group->page_dir_ref_count),
+ and we do not call mali_mmu_activate_empty_page_directory(group->mmu); */
+ MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count);
+}
+
+void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (0 == group->page_dir_ref_count)
+ {
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+
+ if (group->session == session)
+ {
+ MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
+ MALI_DEBUG_PRINT(3, ("Mali group: Deactivating unused session 0x%08X on group %08X\n", session, group));
+ mali_mmu_activate_empty_page_directory(group->mmu);
+ group->session = NULL;
+ }
+ }
+}
+
+void mali_group_power_on(void)
+{
+ int i;
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ struct mali_group *group = mali_global_groups[i];
+ mali_group_lock(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+ MALI_DEBUG_ASSERT_POINTER(group->cluster);
+ group->power_is_on = MALI_TRUE;
+ mali_cluster_power_is_enabled_set(group->cluster, MALI_TRUE);
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(3,("group: POWER ON\n"));
+}
+
+mali_bool mali_group_power_is_on(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+ return group->power_is_on;
+}
+
+void mali_group_power_off(void)
+{
+ int i;
+ /* It is necessary to set group->session = NULL; so that the powered off MMU is not written to on map /unmap */
+ /* It is necessary to set group->power_is_on=MALI_FALSE so that pending bottom_halves does not access powered off cores. */
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ struct mali_group *group = mali_global_groups[i];
+ mali_group_lock(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+ MALI_DEBUG_ASSERT_POINTER(group->cluster);
+ group->session = NULL;
+ MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
+ group->power_is_on = MALI_FALSE;
+ mali_cluster_power_is_enabled_set(group->cluster, MALI_FALSE);
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(3,("group: POWER OFF\n"));
+}
+
+
+static void mali_group_recovery_reset(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ /* Stop cores, bus stop */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_stop_bus(group->pp_core);
+ }
+ if (NULL != group->gp_core)
+ {
+ mali_gp_stop_bus(group->gp_core);
+ }
+
+ /* Flush MMU */
+ mali_mmu_activate_fault_flush_page_directory(group->mmu);
+ mali_mmu_page_fault_done(group->mmu);
+
+ /* Wait for cores to stop bus */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_stop_bus_wait(group->pp_core);
+ }
+ if (NULL != group->gp_core)
+ {
+ mali_gp_stop_bus_wait(group->gp_core);
+ }
+
+ /* Reset cores */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_hard_reset(group->pp_core);
+ }
+ if (NULL != group->gp_core)
+ {
+ mali_gp_hard_reset(group->gp_core);
+ }
+
+ /* Reset MMU */
+ mali_mmu_reset(group->mmu);
+ group->session = NULL;
+}
+
+/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */
+static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success)
+{
+ mali_bool need_group_reset = MALI_FALSE;
+ mali_bool gp_success = success;
+ mali_bool pp_success = success;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (complete_gp && !complete_pp)
+ {
+ MALI_DEBUG_ASSERT_POINTER(group->gp_core);
+ if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core))
+ {
+ struct mali_gp_job *gp_job_to_return = group->gp_running_job;
+ group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->gp_running_job = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(gp_job_to_return);
+
+ mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));
+
+ if(mali_group_other_reschedule_needed(group))
+ {
+ mali_group_unlock(group);
+ mali_pp_scheduler_do_schedule();
+ }
+ else
+ {
+ mali_group_unlock(group);
+ }
+
+ mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+
+ return;
+ }
+ else
+ {
+ need_group_reset = MALI_TRUE;
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
+ pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */
+ }
+ }
+ if (complete_pp && !complete_gp)
+ {
+ MALI_DEBUG_ASSERT_POINTER(group->pp_core);
+ if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core))
+ {
+ struct mali_pp_job *pp_job_to_return = group->pp_running_job;
+ u32 pp_sub_job_to_return = group->pp_running_sub_job;
+ group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->pp_running_job = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(pp_job_to_return);
+
+ mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));
+
+ if(mali_group_other_reschedule_needed(group))
+ {
+ mali_group_unlock(group);
+ mali_gp_scheduler_do_schedule();
+ }
+ else
+ {
+ mali_group_unlock(group);
+ }
+
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+
+ return;
+ }
+ else
+ {
+ need_group_reset = MALI_TRUE;
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
+ gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */
+ }
+ }
+ else if (complete_gp && complete_pp)
+ {
+ need_group_reset = MALI_TRUE;
+ }
+
+ if (MALI_TRUE == need_group_reset)
+ {
+ struct mali_gp_job *gp_job_to_return = group->gp_running_job;
+ struct mali_pp_job *pp_job_to_return = group->pp_running_job;
+ u32 pp_sub_job_to_return = group->pp_running_sub_job;
+ mali_bool schedule_other = MALI_FALSE;
+
+ MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n"));
+
+ group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->gp_running_job = NULL;
+ if (NULL != gp_job_to_return)
+ {
+ mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));
+ }
+
+ group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->pp_running_job = NULL;
+ if (NULL != pp_job_to_return)
+ {
+ mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));
+ }
+
+ /* The reset has to be done after mali_group_deactivate_page_directory() */
+ mali_group_recovery_reset(group);
+
+ if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return))
+ {
+ schedule_other = MALI_TRUE;
+ }
+
+ mali_group_unlock(group);
+
+ if (NULL != gp_job_to_return)
+ {
+ mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+ }
+ else if (schedule_other)
+ {
+ mali_pp_scheduler_do_schedule();
+ }
+
+ if (NULL != pp_job_to_return)
+ {
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+ }
+ else if (schedule_other)
+ {
+ mali_gp_scheduler_do_schedule();
+ }
+
+ return;
+ }
+
+ mali_group_unlock(group);
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "Group: %p\n", group);
+ if (group->gp_core)
+ {
+ n += mali_gp_dump_state(group->gp_core, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tGP state: %d\n", group->gp_state);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tGP job: %p\n", group->gp_running_job);
+ }
+ if (group->pp_core)
+ {
+ n += mali_pp_dump_state(group->pp_core, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tPP state: %d\n", group->pp_state);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tPP job: %p, subjob %d \n",
+ group->pp_running_job, group->pp_running_sub_job);
+ }
+
+ return n;
+}
+#endif
diff --git a/driver/src/devicedrv/mali/common/mali_group.h b/driver/src/devicedrv/mali/common/mali_group.h
new file mode 100644
index 0000000..1561d6b
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_group.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2011-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_GROUP_H__
+#define __MALI_GROUP_H__
+
+#include "linux/jiffies.h"
+#include "mali_osk.h"
+#include "mali_cluster.h"
+#include "mali_mmu.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_session.h"
+
+/* max runtime [ms] for a core job - used by timeout timers */
+#define MAX_RUNTIME 5000
+/** @brief A mali group object represents a MMU and a PP and/or a GP core.
+ *
+ */
+#define MALI_MAX_NUMBER_OF_GROUPS 9
+
+struct mali_group;
+
+enum mali_group_event_t
+{
+ GROUP_EVENT_PP_JOB_COMPLETED, /**< PP job completed successfully */
+ GROUP_EVENT_PP_JOB_FAILED, /**< PP job completed with failure */
+ GROUP_EVENT_PP_JOB_TIMED_OUT, /**< PP job reached max runtime */
+ GROUP_EVENT_GP_JOB_COMPLETED, /**< GP job completed successfully */
+ GROUP_EVENT_GP_JOB_FAILED, /**< GP job completed with failure */
+ GROUP_EVENT_GP_JOB_TIMED_OUT, /**< GP job reached max runtime */
+ GROUP_EVENT_GP_OOM, /**< GP job ran out of heap memory */
+ GROUP_EVENT_MMU_PAGE_FAULT, /**< MMU page fault */
+};
+
+enum mali_group_core_state
+{
+ MALI_GROUP_CORE_STATE_IDLE,
+ MALI_GROUP_CORE_STATE_WORKING,
+ MALI_GROUP_CORE_STATE_OOM
+};
+
+/** @brief Create a new Mali group object
+ *
+ * @param cluster Pointer to the cluster to which the group is connected.
+ * @param mmu Pointer to the MMU that defines this group
+ * @return A pointer to a new group object
+ */
+struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu);
+void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core);
+void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core);
+void mali_group_delete(struct mali_group *group);
+
+/** @brief Reset group
+ *
+ * This function will reset the entire group, including all the cores present in the group.
+ *
+ * @param group Pointer to the group to reset
+ */
+void mali_group_reset(struct mali_group *group);
+
+/** @brief Get pointer to GP core object
+ */
+struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group);
+
+/** @brief Get pointer to PP core object
+ */
+struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group);
+
+/** @brief Lock group object
+ *
+ * Most group functions will lock the group object themselves. The expection is
+ * the group_bottom_half which requires the group to be locked on entry.
+ *
+ * @param group Pointer to group to lock
+ */
+void mali_group_lock(struct mali_group *group);
+
+/** @brief Unlock group object
+ *
+ * @param group Pointer to group to unlock
+ */
+void mali_group_unlock(struct mali_group *group);
+#ifdef DEBUG
+void mali_group_assert_locked(struct mali_group *group);
+#define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group)
+#else
+#define MALI_ASSERT_GROUP_LOCKED(group)
+#endif
+
+/** @brief Start GP job
+ */
+_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
+/** @brief Start fragment of PP job
+ */
+_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
+ */
+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
+ *
+ * Used to abort suspended OOM jobs when user space failed to allocte more memory.
+ */
+void mali_group_abort_gp_job(struct mali_group *group, u32 job_id);
+/** @brief Abort all GP jobs from \a session
+ *
+ * Used on session close when terminating all running and queued jobs from \a session.
+ */
+void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session);
+
+enum mali_group_core_state mali_group_gp_state(struct mali_group *group);
+enum mali_group_core_state mali_group_pp_state(struct mali_group *group);
+
+/** @brief The common group bottom half interrupt handler
+ *
+ * This is only called from the GP and PP bottom halves.
+ *
+ * The action taken is dictated by the \a event.
+ *
+ * @param event The event code
+ */
+void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event);
+
+struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group);
+struct mali_session_data *mali_group_get_session(struct mali_group *group);
+
+void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session_data);
+
+void mali_group_power_on(void);
+void mali_group_power_off(void);
+mali_bool mali_group_power_is_on(struct mali_group *group);
+
+struct mali_group *mali_group_get_glob_group(u32 index);
+u32 mali_group_get_glob_num_groups(void);
+
+u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size);
+
+#endif /* __MALI_GROUP_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_hw_core.c b/driver/src/devicedrv/mali/common/mali_hw_core.c
new file mode 100644
index 0000000..0b08622
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_hw_core.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011-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_hw_core.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size)
+{
+ core->phys_addr = resource->base;
+ core->description = resource->description;
+ core->size = reg_size;
+ if (_MALI_OSK_ERR_OK == _mali_osk_mem_reqregion(core->phys_addr, core->size, core->description))
+ {
+ core->mapped_registers = _mali_osk_mem_mapioregion(core->phys_addr, core->size, core->description);
+ if (NULL != core->mapped_registers)
+ {
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to map memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr));
+ }
+ _mali_osk_mem_unreqregion(core->phys_addr, core->size);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to request memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr));
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_hw_core_delete(struct mali_hw_core *core)
+{
+ _mali_osk_mem_unmapioregion(core->phys_addr, core->size, core->mapped_registers);
+ core->mapped_registers = NULL;
+ _mali_osk_mem_unreqregion(core->phys_addr, core->size);
+}
diff --git a/driver/src/devicedrv/mali/common/mali_hw_core.h b/driver/src/devicedrv/mali/common/mali_hw_core.h
new file mode 100644
index 0000000..c797804
--- /dev/null
+++ b/driver/src/devicedrv/mali/common/mali_hw_core.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011-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_HW_CORE_H__
+#define __MALI_HW_CORE_H__
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+/**
+ * The common parts for all Mali HW cores (GP, PP, MMU, L2 and PMU)
+ * This struct is embedded inside all core specific structs.
+ */
+struct mali_hw_core
+{
+ u32 phys_addr; /**< Physical address of the registers */
+ u32 size; /**< Size of registers */
+ mali_io_address mapped_registers; /**< Virtual mapping of the registers */
+ const char* description; /**< Name of unit (as specified in device configuration) */
+};
+
+#define MALI_HW_CORE_NO_COUNTER ((u32)-1)
+#define MALI_HW_CORE_INVALID_VALUE ((u32)-1)
+
+_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size);
+void mali_hw_core_delete(struct mali_hw_core *core);
+
+MALI_STATIC_INLINE u32 mali_hw_core_register_read(struct mali_hw_core *core, u32 relative_address)
+{
+ u32 read_val;
+ read_val = _mali_osk_mem_ioread32(core->mapped_registers, relative_address);
+ MALI_DEBUG_PRINT(6, ("register_read for core %s, relative addr=0x%04X, val=0x%08X\n",
+ core->description, relative_address, read_val));
+ return read_val;
+}
+
+MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core *core, u32 relative_address, u32 new_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));
+ _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",
+ core->description, relative_address, new_val));
+ _mali_osk_mem_iowrite32(core->mapped_registers, relative_address, new_val);
+}
+
+MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs)
+{
+ 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++)
+ {
+ mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
+ }
+}
+
+#endif /* __MALI_HW_CORE_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_GP2.c b/driver/src/devicedrv/mali/common/mali_kernel_GP2.c
deleted file mode 100644
index 0006d6f..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_GP2.c
+++ /dev/null
@@ -1,1462 +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_kernel_core.h"
-#include "mali_kernel_subsystem.h"
-#include "regs/mali_gp_regs.h"
-#include "mali_kernel_rendercore.h"
-#include "mali_osk.h"
-#include "mali_osk_list.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-#if defined(USING_MALI400_L2_CACHE)
-#include "mali_kernel_l2_cache.h"
-#endif
-#if USING_MMU
-#include "mali_kernel_mem_mmu.h" /* Needed for mali_kernel_mmu_force_bus_reset() */
-#endif
-
-#if defined(USING_MALI200)
-#define MALI_GP_SUBSYSTEM_NAME "MaliGP2"
-#define MALI_GP_CORE_TYPE _MALI_GP2
-#elif defined(USING_MALI400)
-#define MALI_GP_SUBSYSTEM_NAME "Mali-400 GP"
-#define MALI_GP_CORE_TYPE _MALI_400_GP
-#else
-#error "No supported mali core defined"
-#endif
-
-#define GET_JOB_EMBEDDED_PTR(job) (&((job)->embedded_core_job))
-#define GET_JOBGP2_PTR(job_extern) _MALI_OSK_CONTAINER_OF(job_extern, maligp_job, embedded_core_job)
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_gp_id = -1;
-
-static mali_core_renderunit * last_gp_core_cookie = NULL;
-
-/* Describing a maligp job settings */
-typedef struct maligp_job
-{
- /* The general job struct common for all mali cores */
- mali_core_job embedded_core_job;
- _mali_uk_gp_start_job_s user_input;
-
- u32 irq_status;
- u32 status_reg_on_stop;
- u32 perf_counter0;
- u32 perf_counter1;
- u32 vscl_stop_addr;
- u32 plbcl_stop_addr;
- u32 heap_current_addr;
-
- /* The data we will return back to the user */
- _mali_osk_notification_t *notification_obj;
-
- int is_stalled_waiting_for_more_memory;
-
- u32 active_mask;
- /* progress checking */
- u32 last_vscl;
- u32 last_plbcl;
- /* extended progress checking, only enabled when we can use one of the performance counters */
- u32 have_extended_progress_checking;
- u32 vertices;
-
-#if defined(USING_MALI400_L2_CACHE)
- u32 perf_counter_l2_src0;
- u32 perf_counter_l2_src1;
- u32 perf_counter_l2_val0;
- u32 perf_counter_l2_val1;
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- u32 pid;
- u32 tid;
-#endif
-} maligp_job;
-
-/*Functions Exposed to the General External System through
- function pointers.*/
-
-static _mali_osk_errcode_t maligp_subsystem_startup(mali_kernel_subsystem_identifier id);
-#if USING_MMU
-static _mali_osk_errcode_t maligp_subsystem_mmu_connect(mali_kernel_subsystem_identifier id);
-#endif
-static void maligp_subsystem_terminate(mali_kernel_subsystem_identifier id);
-static _mali_osk_errcode_t maligp_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-static void maligp_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-static _mali_osk_errcode_t maligp_subsystem_core_system_info_fill(_mali_system_info* info);
-static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resource);
-#if USING_MMU
-static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
-#endif
-#if MALI_STATE_TRACKING
-u32 maligp_subsystem_dump_state(char *buf, u32 size);
-#endif
-
-/* Internal support functions */
-static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core );
-static void maligp_raw_reset( mali_core_renderunit *core);
-static void maligp_reset_hard(struct mali_core_renderunit * core);
-static void maligp_reset(mali_core_renderunit *core);
-static void maligp_initialize_registers_mgmt(mali_core_renderunit *core );
-
-#ifdef DEBUG
-static void maligp_print_regs(int debug_level, mali_core_renderunit *core);
-#endif
-
-/* Functions exposed to mali_core system through functionpointers
- in the subsystem struct. */
-static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_core_renderunit * core);
-static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core);
-static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core);
-static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument);
-static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_session * session, void * argument);
-static void subsystem_maligp_return_job_to_user(mali_core_job * job, mali_subsystem_job_end_code end_status);
-static void subsystem_maligp_renderunit_delete(mali_core_renderunit * core);
-static void subsystem_maligp_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style );
-static void subsystem_maligp_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core);
-static _mali_osk_errcode_t subsystem_maligp_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core);
-static void subsystem_maligp_renderunit_stop_bus(struct mali_core_renderunit* core);
-
-/* Variables */
-static register_address_and_value default_mgmt_regs[] =
-{
- { MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED }
-};
-
-
-/* This will be one of the subsystems in the array of subsystems:
- static struct mali_kernel_subsystem * subsystems[];
- found in file: mali_kernel_core.c
-*/
-
-struct mali_kernel_subsystem mali_subsystem_gp2=
-{
- maligp_subsystem_startup, /* startup */
- maligp_subsystem_terminate, /* shutdown */
-#if USING_MMU
- maligp_subsystem_mmu_connect, /* load_complete */
-#else
- NULL,
-#endif
- maligp_subsystem_core_system_info_fill, /* system_info_fill */
- maligp_subsystem_session_begin, /* session_begin */
- maligp_subsystem_session_end, /* session_end */
-#if USING_MMU
- maligp_subsystem_broadcast_notification, /* broadcast_notification */
-#else
- NULL,
-#endif
-#if MALI_STATE_TRACKING
- maligp_subsystem_dump_state, /* dump_state */
-#endif
-} ;
-
-static mali_core_subsystem subsystem_maligp ;
-
-static _mali_osk_errcode_t maligp_subsystem_startup(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem * subsystem;
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_startup\n") ) ;
-
- mali_subsystem_gp_id = id;
-
- /* All values get 0 as default */
- _mali_osk_memset(&subsystem_maligp, 0, sizeof(*subsystem));
-
- subsystem = &subsystem_maligp;
- subsystem->start_job = &subsystem_maligp_start_job;
- subsystem->irq_handler_upper_half = &subsystem_maligp_irq_handler_upper_half;
- subsystem->irq_handler_bottom_half = &subsystem_maligp_irq_handler_bottom_half;
- subsystem->get_new_job_from_user = &subsystem_maligp_get_new_job_from_user;
- subsystem->suspend_response = &subsystem_maligp_suspend_response;
- subsystem->return_job_to_user = &subsystem_maligp_return_job_to_user;
- subsystem->renderunit_delete = &subsystem_maligp_renderunit_delete;
- subsystem->reset_core = &subsystem_maligp_renderunit_reset_core;
- subsystem->stop_bus = &subsystem_maligp_renderunit_stop_bus;
- subsystem->probe_core_irq_trigger = &subsystem_maligp_renderunit_probe_core_irq_trigger;
- subsystem->probe_core_irq_acknowledge = &subsystem_maligp_renderunit_probe_core_irq_finished;
-
- /* Setting variables in the general core part of the subsystem.*/
- subsystem->name = MALI_GP_SUBSYSTEM_NAME;
- subsystem->core_type = MALI_GP_CORE_TYPE;
- subsystem->id = id;
-
- /* Initiates the rest of the general core part of the subsystem */
- MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem ));
-
- /* This will register the function for adding MALIGP2 cores to the subsystem */
-#if defined(USING_MALI200)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALIGP2, maligp_renderunit_create));
-#endif
-#if defined(USING_MALI400)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400GP, maligp_renderunit_create));
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_startup\n") ) ;
-
- MALI_SUCCESS;
-}
-
-#if USING_MMU
-static _mali_osk_errcode_t maligp_subsystem_mmu_connect(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem_attach_mmu(&subsystem_maligp);
- MALI_SUCCESS; /* OK */
-}
-#endif
-
-static void maligp_subsystem_terminate(mali_kernel_subsystem_identifier id)
-{
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_terminate\n") ) ;
- mali_core_subsystem_cleanup(&subsystem_maligp);
-}
-
-static _mali_osk_errcode_t maligp_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- mali_core_session * session;
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_session_begin\n") ) ;
- MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(*session) ), _MALI_OSK_ERR_FAULT);
-
- _mali_osk_memset(session, 0, sizeof(*session) );
- *slot = (mali_kernel_subsystem_session_slot)session;
-
- session->subsystem = &subsystem_maligp;
-
- session->notification_queue = queue;
-
-#if USING_MMU
- session->mmu_session = mali_session_data;
-#endif
-
- mali_core_session_begin(session);
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_session_begin\n") ) ;
-
- MALI_SUCCESS;
-}
-
-static void maligp_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- mali_core_session * session;
- /** @note mali_session_data not needed here */
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_session_end\n") ) ;
- if ( NULL==slot || NULL==*slot)
- {
- MALI_PRINT_ERROR(("Input slot==NULL"));
- return;
- }
- session = (mali_core_session *)*slot;
- mali_core_session_close(session);
-
- _mali_osk_free(session);
- *slot = NULL;
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_session_end\n") ) ;
-}
-
-/**
- * We fill in info about all the cores we have
- * @param info Pointer to system info struct to update
- * @return _MALI_OSK_ERR_OK on success, or another _mali_osk_errcode_t for errors.
- */
-static _mali_osk_errcode_t maligp_subsystem_core_system_info_fill(_mali_system_info* info)
-{
- return mali_core_subsystem_system_info_fill(&subsystem_maligp, info);
-}
-
-static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resource)
-{
- mali_core_renderunit *core;
- int err;
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_renderunit_create\n") ) ;
- /* Checking that the resource settings are correct */
-#if defined(USING_MALI200)
- if(MALIGP2 != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_GP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#elif defined(USING_MALI400)
- if(MALI400GP != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_GP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
- if ( 0 != resource->size )
- {
- MALI_PRINT_ERROR(("Memory size set to " MALI_GP_SUBSYSTEM_NAME " core should be zero."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- if ( NULL == resource->description )
- {
- MALI_PRINT_ERROR(("A " MALI_GP_SUBSYSTEM_NAME " core needs a unique description field"));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Create a new core object */
- core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core));
- if ( NULL == core )
- {
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Variables set to be able to open and register the core */
- core->subsystem = &subsystem_maligp ;
- core->registers_base_addr = resource->base ;
- core->size = MALIGP2_REGISTER_ADDRESS_SPACE_SIZE ;
- core->description = resource->description;
- core->irq_nr = resource->irq ;
-#if USING_MMU
- core->mmu_id = resource->mmu_id;
- core->mmu = NULL;
-#endif
-#if USING_MALI_PMM
- /* Set up core's PMM id */
- core->pmm_id = MALI_PMM_CORE_GP;
-#endif
-
- err = mali_core_renderunit_init( core );
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n"));
- goto exit_on_error0;
- }
-
- /* Map the new core object, setting: core->registers_mapped */
- err = mali_core_renderunit_map_registers(core);
- if (_MALI_OSK_ERR_OK != err) goto exit_on_error1;
-
- /* Check that the register mapping of the core works.
- Return 0 if maligp core is present and accessible. */
- if (mali_benchmark) {
- core->core_version = MALI_GP_PRODUCT_ID << 16;
- } else {
- core->core_version = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VERSION);
- }
-
- err = maligp_core_version_legal(core);
- if (_MALI_OSK_ERR_OK != err) goto exit_on_error2;
-
- /* Reset the core. Put the core into a state where it can start to render. */
- maligp_reset(core);
-
- /* Registering IRQ, init the work_queue_irq_handle */
- /* Adding this core as an available renderunit in the subsystem. */
- err = mali_core_subsystem_register_renderunit(&subsystem_maligp, core);
- if (_MALI_OSK_ERR_OK != err) goto exit_on_error2;
-
-#ifdef DEBUG
- MALI_DEBUG_PRINT(4, ("Mali GP: Initial Register settings:\n"));
- maligp_print_regs(4, core);
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_renderunit_create\n") ) ;
-
- MALI_SUCCESS;
-
-exit_on_error2:
- mali_core_renderunit_unmap_registers(core);
-exit_on_error1:
- mali_core_renderunit_term(core);
-exit_on_error0:
- _mali_osk_free( core ) ;
- MALI_PRINT_ERROR(("Renderunit NOT created."));
- MALI_ERROR((_mali_osk_errcode_t)err);
-}
-
-#if USING_MMU
-/* Used currently only for signalling when MMU has a pagefault */
-static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data)
-{
- mali_core_subsystem_broadcast_notification(&subsystem_maligp, message, data);
-}
-#endif
-
-#ifdef DEBUG
-static void maligp_print_regs(int debug_level, mali_core_renderunit *core)
-{
- if (debug_level <= mali_debug_level)
- {
- MALI_DEBUG_PRINT(1, (" VS 0x%08X 0x%08X, PLBU 0x%08X 0x%08X ALLOC 0x%08X 0x%08X\n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR))
- );
- MALI_DEBUG_PRINT(1, (" IntRaw 0x%08X IntMask 0x%08X, Status 0x%02X Ver: 0x%08X \n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_MASK),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VERSION)));
-
- MALI_DEBUG_PRINT(1, (" PERF_CNT Enbl:%d %d Src: %02d %02d VAL: 0x%08X 0x%08X\n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
-
- MALI_DEBUG_PRINT(1, (" VS_START 0x%08X PLBU_START 0x%08X AXI_ERR 0x%08X\n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ),
- mali_core_renderunit_register_read(core, MALIGP2_CONTR_AXI_BUS_ERROR_STAT)));
- }
-}
-#endif
-
-static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core )
-{
- u32 mali_type;
-
- mali_type = core->core_version >> 16;
-
-#if defined(USING_MALI400)
- if ( MALI400_GP_PRODUCT_ID != mali_type && MALI300_GP_PRODUCT_ID != mali_type )
-#else
- if ( MALI_GP_PRODUCT_ID != mali_type )
-#endif
- {
- MALI_PRINT_ERROR(("Error: reading this from maligp version register: 0x%x\n", core->core_version));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- MALI_DEBUG_PRINT(3, ("Mali GP: core_version_legal: Reads correct mali version: %d\n", core->core_version )) ;
- MALI_SUCCESS;
-}
-
-static void subsystem_maligp_renderunit_stop_bus(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
-}
-
-static void maligp_reset( mali_core_renderunit *core )
-{
- if (!mali_benchmark) {
- maligp_raw_reset(core);
- maligp_initialize_registers_mgmt(core);
- }
-}
-
-
-static void maligp_reset_hard( mali_core_renderunit *core )
-{
- const int reset_finished_loop_count = 15;
- const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW;
- const u32 reset_invalid_value = 0xC0FFE000;
- const u32 reset_check_value = 0xC01A0000;
- const u32 reset_default_value = 0;
- int i;
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_invalid_value);
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET);
-
- for (i = 0; i < reset_finished_loop_count; i++)
- {
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_check_value);
- if (reset_check_value == mali_core_renderunit_register_read(core, reset_wait_target_register))
- {
- MALI_DEBUG_PRINT(5, ("Reset loop exiting after %d iterations\n", i));
- break;
- }
- }
-
- if (i == reset_finished_loop_count)
- {
- MALI_DEBUG_PRINT(1, ("The reset loop didn't work\n"));
- }
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_default_value); /* set it back to the default */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
-
-
-}
-
-static void maligp_raw_reset( mali_core_renderunit *core )
-{
- int i;
- const int request_loop_count = 20;
-
- MALI_DEBUG_PRINT(4, ("Mali GP: maligp_raw_reset: %s\n", core->description)) ;
- if (mali_benchmark) return;
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
-
-#if defined(USING_MALI200)
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- MALI_DEBUG_PRINT_IF(1, request_loop_count == i, ("Mali GP: Bus was never stopped during core reset\n"));
-
- if (request_loop_count==i)
- {
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
-#if USING_MMU
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- MALI_DEBUG_PRINT(1, ("Mali GP: Forcing MMU bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow GP to stop its bus, system failure, unable to recover\n"));
- return;
- }
-
- /* the bus was stopped OK, complete the reset */
- /* use the hard reset routine to do the actual reset */
- maligp_reset_hard(core);
-
-#elif defined(USING_MALI400)
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & /*Bitwise OR*/
- MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- if ( request_loop_count==i )
- {
-#if USING_MMU
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- MALI_DEBUG_PRINT(1, ("Mali GP: Forcing Bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow GP to stop its bus, system failure, unable to recover\n"));
- }
- else
- {
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
- }
-
-#else
-#error "no supported mali core defined"
-#endif
-}
-
-/* Sets the registers on maligp according to the const default_mgmt_regs array. */
-static void maligp_initialize_registers_mgmt(mali_core_renderunit *core )
-{
- int i;
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_initialize_registers_mgmt: %s\n", core->description)) ;
- for(i=0 ; i< (sizeof(default_mgmt_regs)/sizeof(*default_mgmt_regs)) ; ++i)
- {
- mali_core_renderunit_register_write_relaxed(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value);
- }
- _mali_osk_write_mem_barrier();
-}
-
-
-/* Start this job on this core. Return MALI_TRUE if the job was started. */
-static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_core_renderunit * core)
-{
- maligp_job *jobgp;
- u32 startcmd;
- /* The local extended version of the general structs */
- jobgp = _MALI_OSK_CONTAINER_OF(job, maligp_job, embedded_core_job);
-
- startcmd = 0;
- if ( jobgp->user_input.frame_registers[0] != jobgp->user_input.frame_registers[1] )
- {
- startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
- }
-
- if ( jobgp->user_input.frame_registers[2] != jobgp->user_input.frame_registers[3] )
- {
- startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
- }
-
- if(0 == startcmd)
- {
- MALI_DEBUG_PRINT(4, ("Mali GP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n",
- (u32)jobgp->user_input.user_job_ptr));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
-
-#ifdef DEBUG
- MALI_DEBUG_PRINT(4, ("Mali GP: Registers Start\n"));
- maligp_print_regs(4, core);
-#endif
-
-
- mali_core_renderunit_register_write_array(
- core,
- MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR,
- &(jobgp->user_input.frame_registers[0]),
- sizeof(jobgp->user_input.frame_registers)/sizeof(jobgp->user_input.frame_registers[0]));
-
- /* This selects which performance counters we are reading */
- if ( 0 != jobgp->user_input.perf_counter_flag )
- {
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC,
- jobgp->user_input.perf_counter_src0);
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE,
- MALIGP2_REG_VAL_PERF_CNT_ENABLE);
- }
-
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC,
- jobgp->user_input.perf_counter_src1);
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
- MALIGP2_REG_VAL_PERF_CNT_ENABLE);
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if ( jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- int force_reset = ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0;
- u32 src0 = 0;
- u32 src1 = 0;
-
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE )
- {
- src0 = jobgp->user_input.perf_counter_l2_src0;
- }
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE )
- {
- src1 = jobgp->user_input.perf_counter_l2_src1;
- }
-
- mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */
-
- /* Now, retrieve the current values, so we can substract them when the job has completed */
- mali_kernel_l2_cache_get_perf_counters(&jobgp->perf_counter_l2_src0,
- &jobgp->perf_counter_l2_val0,
- &jobgp->perf_counter_l2_src1,
- &jobgp->perf_counter_l2_val1);
- }
-#endif
- }
-
- if ( 0 == (jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE))
- {
- /* extended progress checking can be enabled */
-
- jobgp->have_extended_progress_checking = 1;
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC,
- MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED
- );
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
- MALIGP2_REG_VAL_PERF_CNT_ENABLE);
- }
-
- subsystem_flush_mapped_mem_cache();
-
- MALI_DEBUG_PRINT(4, ("Mali GP: STARTING GP WITH CMD: 0x%x\n", startcmd));
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_started);
-#endif
-
- /* This is the command that starts the Core */
- mali_core_renderunit_register_write(core,
- MALIGP2_REG_ADDR_MGMT_CMD,
- startcmd);
- _mali_osk_write_mem_barrier();
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
- jobgp->user_input.frame_builder_id, jobgp->user_input.flush_id, 0, 0, 0);
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0);
-#endif
-
- MALI_SUCCESS;
-}
-
-/* Check if given core has an interrupt pending. Return MALI_TRUE and set mask to 0 if pending */
-
-static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core)
-{
- u32 irq_readout;
-
- if (mali_benchmark) {
- return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */
- }
-
- irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
-
- if ( MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout )
- {
- /* Mask out all IRQs from this core until IRQ is handled */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
-#endif
-
- /* We do need to handle this in a bottom half, return 1 */
- return 1;
- }
- return 0;
-}
-
-/* This function should check if the interrupt indicates that job was finished.
-If so it should update the job-struct, reset the core registers, and return MALI_TRUE, .
-If the job is still working after this function it should return MALI_FALSE.
-The function must also enable the bits in the interrupt mask for the core.
-Called by the bottom half interrupt function. */
-static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
-{
- mali_core_job * job;
- maligp_job * jobgp;
- u32 irq_readout;
- u32 core_status;
- u32 vscl;
- u32 plbcl;
-
- job = core->current_job;
-
- if (mali_benchmark) {
- MALI_DEBUG_PRINT(3, ("MaliGP: Job: Benchmark\n") );
- irq_readout = MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST;
- core_status = 0;
- } else {
- irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
- core_status = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS);
- }
-
- if (NULL == job)
- {
- MALI_DEBUG_ASSERT(CORE_IDLE==core->state);
- if ( 0 != irq_readout )
- {
- MALI_PRINT_ERROR(("Interrupt from a core not running a job. IRQ: 0x%04x Status: 0x%04x", irq_readout, core_status));
- }
- return JOB_STATUS_END_UNKNOWN_ERR;
- }
- MALI_DEBUG_ASSERT(CORE_IDLE!=core->state);
-
- jobgp = GET_JOBGP2_PTR(job);
-
- jobgp->heap_current_addr = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR);
-
- vscl = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR);
- plbcl = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR);
-
- MALI_DEBUG_PRINT(3, ("Mali GP: Job: 0x%08x IRQ RECEIVED Rawstat: 0x%x Status: 0x%x\n",
- (u32)jobgp->user_input.user_job_ptr, irq_readout , core_status )) ;
-
- jobgp->irq_status |= irq_readout;
- jobgp->status_reg_on_stop = core_status;
-
- if ( 0 != jobgp->is_stalled_waiting_for_more_memory )
- {
- /* Readback the performance counters */
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
- {
- jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- u32 src0;
- u32 val0;
- u32 src1;
- u32 val1;
- mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1);
-
- if (jobgp->perf_counter_l2_src0 == src0)
- {
- jobgp->perf_counter_l2_val0 = val0 - jobgp->perf_counter_l2_val0;
- }
- else
- {
- jobgp->perf_counter_l2_val0 = 0;
- }
-
- if (jobgp->perf_counter_l2_src1 == src1)
- {
- jobgp->perf_counter_l2_val1 = val1 - jobgp->perf_counter_l2_val1;
- }
- else
- {
- jobgp->perf_counter_l2_val1 = 0;
- }
- }
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- MALI_DEBUG_PRINT(2, ("Mali GP: Job aborted - userspace would not provide more heap memory.\n"));
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/
- }
- /* finished ? */
- else if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
- {
-#ifdef DEBUG
- MALI_DEBUG_PRINT(4, ("Mali GP: Registers On job end:\n"));
- maligp_print_regs(4, core);
-#endif
- MALI_DEBUG_PRINT_IF(5, irq_readout & 0x04, ("OOM when done, ignoring (reg.current = 0x%x, reg.end = 0x%x)\n",
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR),
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR))
- );
-
-
- if (0 != jobgp->user_input.perf_counter_flag )
- {
- /* Readback the performance counters */
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
- {
- jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- u32 src0;
- u32 val0;
- u32 src1;
- u32 val1;
- mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1);
-
- if (jobgp->perf_counter_l2_src0 == src0)
- {
- jobgp->perf_counter_l2_val0 = val0 - jobgp->perf_counter_l2_val0;
- }
- else
- {
- jobgp->perf_counter_l2_val0 = 0;
- }
-
- if (jobgp->perf_counter_l2_src1 == src1)
- {
- jobgp->perf_counter_l2_val1 = val1 - jobgp->perf_counter_l2_val1;
- }
- else
- {
- jobgp->perf_counter_l2_val1 = 0;
- }
- }
-#endif
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number),
- jobgp->perf_counter0, jobgp->perf_counter1,
- jobgp->user_input.perf_counter_src0 | (jobgp->user_input.perf_counter_src1 << 8)
-#if defined(USING_MALI400_L2_CACHE)
- | (jobgp->user_input.perf_counter_l2_src0 << 16) | (jobgp->user_input.perf_counter_l2_src1 << 24),
- jobgp->perf_counter_l2_val0,
- jobgp->perf_counter_l2_val1
-#else
- ,0, 0
-#endif
- );
-#endif
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_SUCCESS; /* core idle */
- }
- /* sw watchdog timeout handling or time to do hang checking ? */
- else if (
- (CORE_WATCHDOG_TIMEOUT == core->state) ||
- (
- (CORE_HANG_CHECK_TIMEOUT == core->state) &&
- (
- (jobgp->have_extended_progress_checking ? (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE) == jobgp->vertices) : 1/*TRUE*/) &&
- ((core_status & MALIGP2_REG_VAL_STATUS_VS_ACTIVE) ? (vscl == jobgp->last_vscl) : 1/*TRUE*/) &&
- ((core_status & MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) ? (plbcl == jobgp->last_plbcl) : 1/*TRUE*/)
- )
- )
- )
- {
- /* no progress detected, killed by the watchdog */
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- MALI_DEBUG_PRINT(1, ("Mali GP: SW-Timeout. Regs:\n"));
- if (core_status & MALIGP2_REG_VAL_STATUS_VS_ACTIVE) MALI_DEBUG_PRINT(1, ("vscl current = 0x%x last = 0x%x\n", (void*)vscl, (void*)jobgp->last_vscl));
- if (core_status & MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) MALI_DEBUG_PRINT(1, ("plbcl current = 0x%x last = 0x%x\n", (void*)plbcl, (void*)jobgp->last_plbcl));
- if (jobgp->have_extended_progress_checking) MALI_DEBUG_PRINT(1, ("vertices processed = %d, last = %d\n", mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE),
- jobgp->vertices));
-#ifdef DEBUG
- maligp_print_regs(2, core);
-#endif
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
-
- return JOB_STATUS_END_HANG;
- }
- /* if hang timeout checking was enabled and we detected progress, will be fall down to this check */
- /* check for PLBU OOM before the hang check to avoid the race condition of the hw wd trigging while waiting for us to handle the OOM interrupt */
- else if ( 0 != (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM))
- {
- mali_core_session *session;
- _mali_osk_notification_t *notific;
- _mali_uk_gp_job_suspended_s * suspended_job;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- session = job->session;
-
- MALI_DEBUG_PRINT(4, ("OOM, new heap requested by GP\n"));
- MALI_DEBUG_PRINT(4, ("Status when OOM: current = 0x%x, end = 0x%x\n",
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR),
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR))
- );
-
- notific = _mali_osk_notification_create(
-
- _MALI_NOTIFICATION_GP_STALLED,
- sizeof( _mali_uk_gp_job_suspended_s )
- );
- if ( NULL == notific)
- {
- MALI_PRINT_ERROR( ("Mali GP: Could not get notification object\n")) ;
- return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/
- }
-
- core->state = CORE_WORKING;
- jobgp->is_stalled_waiting_for_more_memory = 1;
- suspended_job = (_mali_uk_gp_job_suspended_s *)notific->result_buffer; /* this is ok - result_buffer was malloc'd */
-
- suspended_job->user_job_ptr = jobgp->user_input.user_job_ptr;
- suspended_job->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY ;
- suspended_job->cookie = (u32) core;
- last_gp_core_cookie = core;
-
- _mali_osk_notification_queue_send( session->notification_queue, notific);
-
-#ifdef DEBUG
- maligp_print_regs(4, core);
-#endif
-
- /* stop all active timers */
- _mali_osk_timer_del( core->timer);
- _mali_osk_timer_del( core->timer_hang_detection);
- MALI_DEBUG_PRINT(4, ("Mali GP: PLBU heap empty, sending memory request to userspace\n"));
- /* save to watchdog_jiffies what was remaining WD timeout value when OOM was triggered */
- job->watchdog_jiffies = (long)job->watchdog_jiffies - (long)_mali_osk_time_tickcount();
- /* reuse core->timer as the userspace response timeout handler */
- _mali_osk_timer_add( core->timer, _mali_osk_time_mstoticks(1000) ); /* wait max 1 sec for userspace to respond */
- return JOB_STATUS_CONTINUE_RUN; /* The core is NOT available for new jobs. */
- }
- /* hw watchdog is reporting a new hang or an existing progress-during-hang check passed? */
- else if ((CORE_HANG_CHECK_TIMEOUT == core->state) || (irq_readout & jobgp->active_mask & MALIGP2_REG_VAL_IRQ_HANG))
- {
- /* check interval in ms */
- u32 timeout = mali_core_hang_check_timeout_get();
- MALI_DEBUG_PRINT(3, ("Mali GP: HW/SW Watchdog triggered, checking for progress in %d ms\n", timeout));
- core->state = CORE_WORKING;
-
- /* save state for the progress checking */
- jobgp->last_vscl = vscl;
- jobgp->last_plbcl = plbcl;
- if (jobgp->have_extended_progress_checking)
- {
- jobgp->vertices = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
- }
- /* hw watchdog triggered, set up a progress checker every HANGCHECK ms */
- _mali_osk_timer_add( core->timer_hang_detection, _mali_osk_time_mstoticks(timeout));
- jobgp->active_mask &= ~MALIGP2_REG_VAL_IRQ_HANG; /* ignore the hw watchdog from now on */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, irq_readout);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- return JOB_STATUS_CONTINUE_RUN; /* not finihsed */ }
- /* no errors, but still working */
- else if ( ( 0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ERROR)) &&
- ( 0 != (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE ))
- )
- {
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, irq_readout);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- return JOB_STATUS_CONTINUE_RUN;
- }
- /* Else there must be some error */
- else
- {
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- MALI_DEBUG_PRINT(1, ("Mali GP: Core crashed? *IRQ: 0x%x Status: 0x%x\n", irq_readout, core_status ));
- #ifdef DEBUG
- MALI_DEBUG_PRINT(1, ("Mali GP: Registers Before reset:\n"));
- maligp_print_regs(1, core);
- #endif
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_UNKNOWN_ERR;
- }
-}
-
-
-/* This function is called from the ioctl function and should return a mali_core_job pointer
-to a created mali_core_job object with the data given from userspace */
-static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument)
-{
- maligp_job *jobgp;
- mali_core_job *job = NULL;
- mali_core_job *previous_replaced_job;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_uk_gp_start_job_s * user_ptr_job_input;
-
- user_ptr_job_input = (_mali_uk_gp_start_job_s *)argument;
-
- MALI_CHECK_NON_NULL(jobgp = (maligp_job *) _mali_osk_calloc(1, sizeof(maligp_job)), _MALI_OSK_ERR_FAULT);
-
- /* Copy the job data from the U/K interface */
- if ( NULL == _mali_osk_memcpy(&jobgp->user_input, user_ptr_job_input, sizeof(_mali_uk_gp_start_job_s) ) )
- {
- MALI_PRINT_ERROR( ("Mali GP: Could not copy data from U/K interface.\n")) ;
- err = _MALI_OSK_ERR_FAULT;
- goto function_exit;
- }
-
- MALI_DEBUG_PRINT(3, ("Mali GP: subsystem_maligp_get_new_job_from_user 0x%x\n", (void*)jobgp->user_input.user_job_ptr));
-
- MALI_DEBUG_PRINT(3, ("Mali GP: Job Regs: 0x%08X 0x%08X, 0x%08X 0x%08X 0x%08X 0x%08X\n",
- jobgp->user_input.frame_registers[0],
- jobgp->user_input.frame_registers[1],
- jobgp->user_input.frame_registers[2],
- jobgp->user_input.frame_registers[3],
- jobgp->user_input.frame_registers[4],
- jobgp->user_input.frame_registers[5]) );
-
-
- job = GET_JOB_EMBEDDED_PTR(jobgp);
-
- job->session = session;
- job->flags = MALI_UK_START_JOB_FLAG_DEFAULT; /* Current flags only make sence for PP jobs */
- job_priority_set(job, jobgp->user_input.priority);
- job_watchdog_set(job, jobgp->user_input.watchdog_msecs );
- jobgp->heap_current_addr = jobgp->user_input.frame_registers[4];
-
- job->abort_id = jobgp->user_input.abort_id;
-
- jobgp->is_stalled_waiting_for_more_memory = 0;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- jobgp->pid = _mali_osk_get_pid();
- jobgp->tid = _mali_osk_get_tid();
-#endif
-
- if (mali_job_queue_full(session))
- {
- /* Cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- goto function_exit;
- }
-
- /* We now know that we have a job, and a slot to put it in */
-
- jobgp->active_mask = MALIGP2_REG_VAL_IRQ_MASK_USED;
-
- /* Allocating User Return Data */
- jobgp->notification_obj = _mali_osk_notification_create(
- _MALI_NOTIFICATION_GP_FINISHED,
- sizeof(_mali_uk_gp_job_finished_s) );
-
- if ( NULL == jobgp->notification_obj )
- {
- MALI_PRINT_ERROR( ("Mali GP: Could not get notification_obj.\n")) ;
- err = _MALI_OSK_ERR_NOMEM;
- goto function_exit;
- }
-
- _MALI_OSK_INIT_LIST_HEAD( &(job->list) ) ;
-
- MALI_DEBUG_PRINT(4, ("Mali GP: Job: 0x%08x INPUT from user.\n", (u32)jobgp->user_input.user_job_ptr)) ;
-
- /* This should not happen since we have the checking of priority above */
- err = mali_core_session_add_job(session, job, &previous_replaced_job);
- if ( _MALI_OSK_ERR_OK != err )
- {
- MALI_PRINT_ERROR( ("Mali GP: Internal error\n")) ;
- /* Cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- _mali_osk_notification_delete( jobgp->notification_obj );
- goto function_exit;
- }
-
- /* If MALI_TRUE: This session had a job with lower priority which were removed.
- This replaced job is given back to userspace. */
- if ( NULL != previous_replaced_job )
- {
- maligp_job *previous_replaced_jobgp;
-
- previous_replaced_jobgp = GET_JOBGP2_PTR(previous_replaced_job);
-
- MALI_DEBUG_PRINT(4, ("Mali GP: Replacing job: 0x%08x\n", (u32)previous_replaced_jobgp->user_input.user_job_ptr)) ;
-
- /* Copy to the input data (which also is output data) the
- pointer to the job that were replaced, so that the userspace
- driver can put this job in the front of its job-queue */
- user_ptr_job_input->returned_user_job_ptr = previous_replaced_jobgp->user_input.user_job_ptr;
-
- /** @note failure to 'copy to user' at this point must not free jobgp,
- * and so no transaction rollback required in the U/K interface */
-
- /* This does not cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED;
- MALI_DEBUG_PRINT(5, ("subsystem_maligp_get_new_job_from_user: Job added, prev returned\n")) ;
- }
- else
- {
- /* This does not cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED;
- MALI_DEBUG_PRINT(5, ("subsystem_maligp_get_new_job_from_user: Job added\n")) ;
- }
-
-function_exit:
- if ( _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE == user_ptr_job_input->status
- || _MALI_OSK_ERR_OK != err )
- {
- _mali_osk_free(jobgp);
- }
-#if MALI_STATE_TRACKING
- if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status)
- {
- if(job)
- {
- job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received);
- }
- }
-#endif
-
- MALI_ERROR(err);
-}
-
-
-static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_session * session, void * argument)
-{
- mali_core_renderunit *core;
- maligp_job *jobgp;
- mali_core_job *job;
-
- _mali_uk_gp_suspend_response_s * suspend_response;
-
- MALI_DEBUG_PRINT(5, ("subsystem_maligp_suspend_response\n"));
-
- suspend_response = (_mali_uk_gp_suspend_response_s *)argument;
-
- /* We read job data from User */
- /* On a single mali_gp system we can only have one Stalled GP,
- and therefore one stalled request with a cookie. This checks
- that we get the correct cookie */
- if ( last_gp_core_cookie != (mali_core_renderunit *)suspend_response->cookie )
- {
- MALI_DEBUG_PRINT(2, ("Mali GP: Got an illegal cookie from Userspace.\n")) ;
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- core = (mali_core_renderunit *)suspend_response->cookie;
- last_gp_core_cookie = NULL;
- job = core->current_job;
- jobgp = GET_JOBGP2_PTR(job);
-
- switch( suspend_response->code )
- {
- case _MALIGP_JOB_RESUME_WITH_NEW_HEAP :
- MALI_DEBUG_PRINT(5, ("MALIGP_JOB_RESUME_WITH_NEW_HEAP jiffies: %li\n", _mali_osk_time_tickcount()));
- MALI_DEBUG_PRINT(4, ("New Heap addr 0x%08x - 0x%08x\n", suspend_response->arguments[0], suspend_response->arguments[1]));
-
- jobgp->is_stalled_waiting_for_more_memory = 0;
- job->watchdog_jiffies += _mali_osk_time_tickcount(); /* convert to absolute time again */
- _mali_osk_timer_mod( core->timer, job->watchdog_jiffies); /* update the timer */
-
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]);
- mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
- _mali_osk_write_mem_barrier();
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0);
-#endif
-
- MALI_DEBUG_PRINT(4, ("GP resumed with new heap\n"));
-
- break;
-
- case _MALIGP_JOB_ABORT:
- MALI_DEBUG_PRINT(3, ("MALIGP_JOB_ABORT on heap extend request\n"));
- _mali_osk_irq_schedulework( core->irq );
- break;
-
- default:
- MALI_PRINT_ERROR(("Wrong Suspend response from userspace\n"));
- }
- MALI_SUCCESS;
-}
-
-/* This function is called from the ioctl function and should write the necessary data
-to userspace telling which job was finished and the status and debuginfo for this job.
-The function must also free and cleanup the input job object. */
-static void subsystem_maligp_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status )
-{
- maligp_job *jobgp;
- _mali_uk_gp_job_finished_s * job_out;
- _mali_uk_gp_start_job_s* job_input;
- mali_core_session *session;
-
-
- jobgp = _MALI_OSK_CONTAINER_OF(job, maligp_job, embedded_core_job);
- job_out = (_mali_uk_gp_job_finished_s *)jobgp->notification_obj->result_buffer; /* OK - this should've been malloc'd */
- job_input= &(jobgp->user_input);
- session = job->session;
-
- MALI_DEBUG_PRINT(5, ("Mali GP: Job: 0x%08x OUTPUT to user. Runtime: %d us, irq readout %x\n",
- (u32)jobgp->user_input.user_job_ptr,
- job->render_time_usecs,
- jobgp->irq_status)) ;
-
- _mali_osk_memset(job_out, 0 , sizeof(_mali_uk_gp_job_finished_s));
-
- job_out->user_job_ptr = job_input->user_job_ptr;
-
- switch( end_status )
- {
- case JOB_STATUS_CONTINUE_RUN:
- case JOB_STATUS_END_SUCCESS:
- case JOB_STATUS_END_OOM:
- case JOB_STATUS_END_ABORT:
- case JOB_STATUS_END_TIMEOUT_SW:
- case JOB_STATUS_END_HANG:
- case JOB_STATUS_END_SEG_FAULT:
- case JOB_STATUS_END_ILLEGAL_JOB:
- case JOB_STATUS_END_UNKNOWN_ERR:
- case JOB_STATUS_END_SHUTDOWN:
- case JOB_STATUS_END_SYSTEM_UNUSABLE:
- job_out->status = (mali_subsystem_job_end_code) end_status;
- break;
- default:
- job_out->status = JOB_STATUS_END_UNKNOWN_ERR ;
- }
-
- job_out->irq_status = jobgp->irq_status;
- job_out->status_reg_on_stop = jobgp->status_reg_on_stop;
- job_out->vscl_stop_addr = 0;
- job_out->plbcl_stop_addr = 0;
- job_out->heap_current_addr = jobgp->heap_current_addr;
- job_out->perf_counter0 = jobgp->perf_counter0;
- job_out->perf_counter1 = jobgp->perf_counter1;
- job_out->perf_counter_src0 = jobgp->user_input.perf_counter_src0 ;
- job_out->perf_counter_src1 = jobgp->user_input.perf_counter_src1 ;
- job_out->render_time = job->render_time_usecs;
-#if defined(USING_MALI400_L2_CACHE)
- job_out->perf_counter_l2_src0 = jobgp->perf_counter_l2_src0;
- job_out->perf_counter_l2_src1 = jobgp->perf_counter_l2_src1;
- job_out->perf_counter_l2_val0 = jobgp->perf_counter_l2_val0;
- job_out->perf_counter_l2_val1 = jobgp->perf_counter_l2_val1;
-#endif
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&session->jobs_returned);
-#endif
- _mali_osk_notification_queue_send( session->notification_queue, jobgp->notification_obj);
- jobgp->notification_obj = NULL;
-
- _mali_osk_free(jobgp);
-
- last_gp_core_cookie = NULL;
-}
-
-static void subsystem_maligp_renderunit_delete(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Mali GP: maligp_renderunit_delete\n"));
- _mali_osk_free(core);
-}
-
-static void subsystem_maligp_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style)
-{
- MALI_DEBUG_PRINT(5, ("Mali GP: renderunit_reset_core\n"));
-
- switch (style)
- {
- case MALI_CORE_RESET_STYLE_RUNABLE:
- maligp_reset(core);
- break;
- case MALI_CORE_RESET_STYLE_DISABLE:
- maligp_raw_reset(core); /* do the raw reset */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* then disable the IRQs */
- break;
- case MALI_CORE_RESET_STYLE_HARD:
- maligp_reset_hard(core);
- maligp_initialize_registers_mgmt(core);
- break;
- default:
- MALI_DEBUG_PRINT(1, ("Unknown reset type %d\n", style));
- break;
- }
-}
-
-static void subsystem_maligp_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core , MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
- mali_core_renderunit_register_write(core , MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG );
- _mali_osk_mem_barrier();
-}
-
-static _mali_osk_errcode_t subsystem_maligp_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core)
-{
- u32 irq_readout;
-
- irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
-
- if ( MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout )
- {
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
- MALI_SUCCESS;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_start_job(session, args);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_number_of_cores_get(session, &args->number_of_cores);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_core_version_get(session, &args->version);
-}
-
-_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_suspend_response(session, args);
-}
-
-void _mali_ukk_gp_abort_job( _mali_uk_gp_abort_job_s * args)
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- if (NULL == args->ctx) return;
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- if (NULL == session) return;
- mali_core_subsystem_ioctl_abort_job(session, args->abort_id);
-
-}
-
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t maligp_signal_power_up( mali_bool queue_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali GP: signal power up core - queue_only: %d\n", queue_only ));
-
- return( mali_core_subsystem_signal_power_up( &subsystem_maligp, 0, queue_only ) );
-}
-
-_mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali GP: signal power down core - immediate_only: %d\n", immediate_only ));
-
- return( mali_core_subsystem_signal_power_down( &subsystem_maligp, 0, immediate_only ) );
-}
-
-#endif
-
-#if MALI_STATE_TRACKING
-u32 maligp_subsystem_dump_state(char *buf, u32 size)
-{
- return mali_core_renderunit_dump_state(&subsystem_maligp, buf, size);
-}
-#endif
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c b/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c
deleted file mode 100644
index 21d5166..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_MALI200.c
+++ /dev/null
@@ -1,1242 +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_kernel_pp.h"
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_core.h"
-#include "regs/mali_200_regs.h"
-#include "mali_kernel_rendercore.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-#ifdef USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
-#endif
-#if USING_MMU
-#include "mali_kernel_mem_mmu.h" /* Needed for mali_kernel_mmu_force_bus_reset() */
-#endif
-
-#include "mali_osk_list.h"
-
-#if defined(USING_MALI200)
-#define MALI_PP_SUBSYSTEM_NAME "Mali200"
-#define MALI_PP_CORE_TYPE _MALI_200
-#elif defined(USING_MALI400)
-#define MALI_PP_SUBSYSTEM_NAME "Mali-400 PP"
-#define MALI_PP_CORE_TYPE _MALI_400_PP
-#else
-#error "No supported mali core defined"
-#endif
-
-#define GET_JOB_EMBEDDED_PTR(job) (&((job)->embedded_core_job))
-#define GET_JOB200_PTR(job_extern) _MALI_OSK_CONTAINER_OF(job_extern, mali200_job, embedded_core_job)
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_mali200_id = -1;
-
-/* Describing a mali200 job settings */
-typedef struct mali200_job
-{
- /* The general job struct common for all mali cores */
- mali_core_job embedded_core_job;
- _mali_uk_pp_start_job_s user_input;
-
- u32 irq_status;
- u32 perf_counter0;
- u32 perf_counter1;
- u32 last_tile_list_addr; /* Neccessary to continue a stopped job */
-
- u32 active_mask;
-
- /* The data we will return back to the user */
- _mali_osk_notification_t *notification_obj;
-
-#if defined(USING_MALI400_L2_CACHE)
- u32 perf_counter_l2_src0;
- u32 perf_counter_l2_src1;
- u32 perf_counter_l2_val0;
- u32 perf_counter_l2_val1;
- u32 perf_counter_l2_val0_raw;
- u32 perf_counter_l2_val1_raw;
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- u32 pid;
- u32 tid;
-#endif
-} mali200_job;
-
-
-/*Functions Exposed to the General External System through
- funciont pointers.*/
-
-static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id);
-#if USING_MMU
-static _mali_osk_errcode_t mali200_subsystem_mmu_connect(mali_kernel_subsystem_identifier id);
-#endif
-static void mali200_subsystem_terminate(mali_kernel_subsystem_identifier id);
-static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-static void mali200_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-static _mali_osk_errcode_t mali200_subsystem_core_system_info_fill(_mali_system_info* info);
-static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource);
-#if USING_MMU
-static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
-#endif
-#if MALI_STATE_TRACKING
-u32 mali200_subsystem_dump_state(char *buf, u32 size);
-#endif
-
-/* Internal support functions */
-static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core );
-static void mali200_reset(mali_core_renderunit *core);
-static void mali200_reset_hard(struct mali_core_renderunit * core);
-static void mali200_raw_reset(mali_core_renderunit * core);
-static void mali200_initialize_registers_mgmt(mali_core_renderunit *core );
-
-/* Functions exposed to mali_core system through functionpointers
- in the subsystem struct. */
-static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core);
-static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument);
-static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status);
-static void subsystem_mali200_renderunit_delete(mali_core_renderunit * core);
-static void subsystem_mali200_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style);
-static void subsystem_mali200_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core);
-static _mali_osk_errcode_t subsystem_mali200_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core);
-
-static void subsystem_mali200_renderunit_stop_bus(struct mali_core_renderunit* core);
-static u32 subsystem_mali200_irq_handler_upper_half(struct mali_core_renderunit * core);
-static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit* core);
-
-/* This will be one of the subsystems in the array of subsystems:
- static struct mali_kernel_subsystem * subsystems[];
- found in file: mali_kernel_core.c
-*/
-
-struct mali_kernel_subsystem mali_subsystem_mali200=
-{
- mali200_subsystem_startup, /* startup */
- mali200_subsystem_terminate, /* shutdown */
-#if USING_MMU
- mali200_subsystem_mmu_connect, /* load_complete */
-#else
- NULL,
-#endif
- mali200_subsystem_core_system_info_fill, /* system_info_fill */
- mali200_subsystem_session_begin, /* session_begin */
- mali200_subsystem_session_end, /* session_end */
-#if USING_MMU
- mali200_subsystem_broadcast_notification, /* broadcast_notification */
-#else
- NULL,
-#endif
-#if MALI_STATE_TRACKING
- mali200_subsystem_dump_state, /* dump_state */
-#endif
-} ;
-
-static mali_core_subsystem subsystem_mali200 ;
-
-static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem * subsystem;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_startup\n") ) ;
-
- mali_subsystem_mali200_id = id;
-
- /* All values get 0 as default */
- _mali_osk_memset(&subsystem_mali200, 0, sizeof(subsystem_mali200));
-
- subsystem = &subsystem_mali200;
- subsystem->start_job = &subsystem_mali200_start_job;
- subsystem->irq_handler_upper_half = &subsystem_mali200_irq_handler_upper_half;
- subsystem->irq_handler_bottom_half = &subsystem_mali200_irq_handler_bottom_half;
- subsystem->get_new_job_from_user = &subsystem_mali200_get_new_job_from_user;
- subsystem->return_job_to_user = &subsystem_mali200_return_job_to_user;
- subsystem->renderunit_delete = &subsystem_mali200_renderunit_delete;
- subsystem->reset_core = &subsystem_mali200_renderunit_reset_core;
- subsystem->stop_bus = &subsystem_mali200_renderunit_stop_bus;
- subsystem->probe_core_irq_trigger = &subsystem_mali200_renderunit_probe_core_irq_trigger;
- subsystem->probe_core_irq_acknowledge = &subsystem_mali200_renderunit_probe_core_irq_finished;
-
- /* Setting variables in the general core part of the subsystem.*/
- subsystem->name = MALI_PP_SUBSYSTEM_NAME;
- subsystem->core_type = MALI_PP_CORE_TYPE;
- subsystem->id = id;
-
- /* Initiates the rest of the general core part of the subsystem */
- MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem ));
-
- /* This will register the function for adding MALI200 cores to the subsystem */
-#if defined(USING_MALI200)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI200, mali200_renderunit_create));
-#endif
-#if defined(USING_MALI400)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400PP, mali200_renderunit_create));
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_startup\n") ) ;
-
- MALI_SUCCESS;
-}
-
-#if USING_MMU
-static _mali_osk_errcode_t mali200_subsystem_mmu_connect(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem_attach_mmu(&subsystem_mali200);
- MALI_SUCCESS; /* OK */
-}
-#endif
-
-static void mali200_subsystem_terminate(mali_kernel_subsystem_identifier id)
-{
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_terminate\n") ) ;
- mali_core_subsystem_cleanup(&subsystem_mali200);
-}
-
-static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- mali_core_session * session;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_begin\n") ) ;
- MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(mali_core_session) ), _MALI_OSK_ERR_NOMEM);
-
- _mali_osk_memset(session, 0, sizeof(*session) );
- *slot = (mali_kernel_subsystem_session_slot)session;
-
- session->subsystem = &subsystem_mali200;
-
- session->notification_queue = queue;
-
-#if USING_MMU
- session->mmu_session = mali_session_data;
-#endif
-
- mali_core_session_begin(session);
-
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_begin\n") ) ;
-
- MALI_SUCCESS;
-}
-
-static void mali200_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- mali_core_session * session;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_end\n") ) ;
- if ( NULL==slot || NULL==*slot)
- {
- MALI_PRINT_ERROR(("Input slot==NULL"));
- return;
- }
- session = (mali_core_session*) *slot;
- mali_core_session_close(session);
-
- _mali_osk_free(session);
- *slot = NULL;
-
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_end\n") ) ;
-}
-
-/**
- * We fill in info about all the cores we have
- * @param info Pointer to system info struct to update
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali200_subsystem_core_system_info_fill(_mali_system_info* info)
-{
- return mali_core_subsystem_system_info_fill(&subsystem_mali200, info);
-}
-
-
-static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource)
-{
- mali_core_renderunit *core;
- _mali_osk_errcode_t err;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_renderunit_create\n") ) ;
- /* Checking that the resource settings are correct */
-#if defined(USING_MALI200)
- if(MALI200 != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#elif defined(USING_MALI400)
- if(MALI400PP != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
- if ( 0 != resource->size )
- {
- MALI_PRINT_ERROR(("Memory size set to " MALI_PP_SUBSYSTEM_NAME " core should be zero."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- if ( NULL == resource->description )
- {
- MALI_PRINT_ERROR(("A " MALI_PP_SUBSYSTEM_NAME " core needs a unique description field"));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Create a new core object */
- core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core));
- if ( NULL == core )
- {
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* Variables set to be able to open and register the core */
- core->subsystem = &subsystem_mali200 ;
- core->registers_base_addr = resource->base ;
- core->size = MALI200_REG_SIZEOF_REGISTER_BANK ;
- core->irq_nr = resource->irq ;
- core->description = resource->description;
-#if USING_MMU
- core->mmu_id = resource->mmu_id;
- core->mmu = NULL;
-#endif
-#if USING_MALI_PMM
- /* Set up core's PMM id */
- switch( subsystem_mali200.number_of_cores )
- {
- case 0:
- core->pmm_id = MALI_PMM_CORE_PP0;
- break;
- case 1:
- core->pmm_id = MALI_PMM_CORE_PP1;
- break;
- case 2:
- core->pmm_id = MALI_PMM_CORE_PP2;
- break;
- case 3:
- core->pmm_id = MALI_PMM_CORE_PP3;
- break;
- default:
- MALI_DEBUG_PRINT(1, ("Unknown supported core for PMM\n"));
- err = _MALI_OSK_ERR_FAULT;
- goto exit_on_error0;
- }
-#endif
-
- err = mali_core_renderunit_init( core );
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n"));
- goto exit_on_error0;
- }
-
- /* Map the new core object, setting: core->registers_mapped */
- err = mali_core_renderunit_map_registers(core);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to map register\n"));
- goto exit_on_error1;
- }
-
- /* Check that the register mapping of the core works.
- Return 0 if Mali PP core is present and accessible. */
- if (mali_benchmark) {
-#if defined(USING_MALI200)
- core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 5 /* Fake Mali200-r0p5 */;
-#elif defined(USING_MALI400)
- core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 0x0101 /* Fake Mali400-r1p1 */;
-#else
-#error "No supported mali core defined"
-#endif
- } else {
- core->core_version = mali_core_renderunit_register_read(
- core,
- MALI200_REG_ADDR_MGMT_VERSION);
- }
-
- err = mali200_core_version_legal(core);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Invalid core\n"));
- goto exit_on_error2;
- }
-
- /* Reset the core. Put the core into a state where it can start to render. */
- mali200_reset(core);
-
- /* Registering IRQ, init the work_queue_irq_handle */
- /* Adding this core as an available renderunit in the subsystem. */
- err = mali_core_subsystem_register_renderunit(&subsystem_mali200, core);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to register with core\n"));
- goto exit_on_error2;
- }
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_renderunit_create\n") ) ;
-
- MALI_SUCCESS;
-
-exit_on_error2:
- mali_core_renderunit_unmap_registers(core);
-exit_on_error1:
- mali_core_renderunit_term(core);
-exit_on_error0:
- _mali_osk_free( core ) ;
- MALI_PRINT_ERROR(("Renderunit NOT created."));
- MALI_ERROR(err);
-}
-
-#if USING_MMU
-/* Used currently only for signalling when MMU has a pagefault */
-static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data)
-{
- mali_core_subsystem_broadcast_notification(&subsystem_mali200, message, data);
-}
-#endif
-
-static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core )
-{
- u32 mali_type;
-
- mali_type = core->core_version >> 16;
-#if defined(USING_MALI400)
- /* Mali300 and Mali400 is compatible, accept either core. */
- if (MALI400_PP_PRODUCT_ID != mali_type && MALI300_PP_PRODUCT_ID != mali_type)
-#else
- if (MALI_PP_PRODUCT_ID != mali_type)
-#endif
- {
- MALI_PRINT_ERROR(("Error: reading this from " MALI_PP_SUBSYSTEM_NAME " version register: 0x%x\n", core->core_version));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- MALI_DEBUG_PRINT(3, ("Mali PP: core_version_legal: Reads correct mali version: %d\n", mali_type) ) ;
- MALI_SUCCESS;
-}
-
-static void subsystem_mali200_renderunit_stop_bus(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
-}
-
-static void mali200_raw_reset( mali_core_renderunit *core )
-{
- int i;
- const int request_loop_count = 20;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: mali200_raw_reset: %s\n", core->description));
- if (mali_benchmark) return;
-
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable IRQs */
-
-#if defined(USING_MALI200)
-
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- MALI_DEBUG_PRINT_IF(1, request_loop_count == i, ("Mali PP: Bus was never stopped during core reset\n"));
-
-
- if (request_loop_count==i)
- {
-#if USING_MMU
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
- MALI_DEBUG_PRINT(1, ("Mali PP: Forcing Bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow PP to stop its bus, system failure, unable to recover\n"));
- return;
- }
-
- /* use the hard reset routine to do the actual reset */
- mali200_reset_hard(core);
-
-#elif defined(USING_MALI400)
-
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- if (request_loop_count==i)
- {
-#if USING_MMU
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
- MALI_DEBUG_PRINT(1, ("Mali PP: Forcing Bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow PP to stop its bus, system failure, unable to recover\n"));
- return;
- }
- else
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
-
-#else
-#error "no supported mali core defined"
-#endif
-}
-
-static void mali200_reset( mali_core_renderunit *core )
-{
- if (!mali_benchmark) {
- mali200_raw_reset(core);
- mali200_initialize_registers_mgmt(core);
- }
-}
-
-/* Sets the registers on mali200 according to the const default_mgmt_regs array. */
-static void mali200_initialize_registers_mgmt(mali_core_renderunit *core )
-{
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_initialize_registers_mgmt: %s\n", core->description)) ;
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
-}
-
-/* Start this job on this core. Return MALI_TRUE if the job was started. */
-static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core)
-{
- mali200_job *job200;
-
- /* The local extended version of the general structs */
- job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job);
-
- if ( (0 == job200->user_input.frame_registers[0]) ||
- (0 == job200->user_input.frame_registers[1]) )
- {
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n",
- (u32)job200->user_input.user_job_ptr));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x START_RENDER Tile_list: 0x%08x\n",
- (u32)job200->user_input.user_job_ptr,
- job200->user_input.frame_registers[0]));
- MALI_DEBUG_PRINT(6, ("Mali PP: RSW base addr: 0x%08x Vertex base addr: 0x%08x\n",
- job200->user_input.frame_registers[1], job200->user_input.frame_registers[2]));
-
- /* Frame registers. Copy from mem to physical registers */
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_FRAME,
- &(job200->user_input.frame_registers[0]),
- MALI200_NUM_REGS_FRAME);
-
- /* Write Back unit 0. Copy from mem to physical registers only if the WB unit will be used. */
- if (job200->user_input.wb0_registers[0])
- {
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_WB0,
- &(job200->user_input.wb0_registers[0]),
- MALI200_NUM_REGS_WBx);
- }
-
- /* Write Back unit 1. Copy from mem to physical registers only if the WB unit will be used. */
- if (job200->user_input.wb1_registers[0])
- {
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_WB1,
- &(job200->user_input.wb1_registers[0]),
- MALI200_NUM_REGS_WBx);
- }
-
- /* Write Back unit 2. Copy from mem to physical registers only if the WB unit will be used. */
- if (job200->user_input.wb2_registers[0])
- {
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_WB2,
- &(job200->user_input.wb2_registers[0]),
- MALI200_NUM_REGS_WBx);
- }
-
-
- /* This selects which performance counters we are reading */
- if ( 0 != job200->user_input.perf_counter_flag )
- {
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE,
- MALI200_REG_VAL_PERF_CNT_ENABLE);
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC,
- job200->user_input.perf_counter_src0);
-
- }
-
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
- MALI200_REG_VAL_PERF_CNT_ENABLE);
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC,
- job200->user_input.perf_counter_src1);
-
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if ( job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- int force_reset = ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0;
- u32 src0 = 0;
- u32 src1 = 0;
-
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE )
- {
- src0 = job200->user_input.perf_counter_l2_src0;
- }
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE )
- {
- src1 = job200->user_input.perf_counter_l2_src1;
- }
-
- mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */
-
- /* Now, retrieve the current values, so we can substract them when the job has completed */
- mali_kernel_l2_cache_get_perf_counters(&job200->perf_counter_l2_src0,
- &job200->perf_counter_l2_val0,
- &job200->perf_counter_l2_src1,
- &job200->perf_counter_l2_val1);
- }
-#endif
- }
-
- subsystem_flush_mapped_mem_cache();
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_started);
-#endif
-
- /* This is the command that starts the Core */
- mali_core_renderunit_register_write(
- core,
- MALI200_REG_ADDR_MGMT_CTRL_MGMT,
- MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
- _mali_osk_write_mem_barrier();
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job200->user_input.frame_builder_id, job200->user_input.flush_id, 0, 0, 0);
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid,
-#if defined(USING_MALI400_L2_CACHE)
- (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24),
- job200->perf_counter_l2_val0, job200->perf_counter_l2_val1
-#else
- 0, 0, 0
-#endif
- );
-#endif
-
- MALI_SUCCESS;
-}
-
-static u32 subsystem_mali200_irq_handler_upper_half(mali_core_renderunit * core)
-{
- u32 irq_readout;
-
- if (mali_benchmark) {
- return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */
- }
-
- irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS);
-
- if ( MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout )
- {
- /* Mask out all IRQs from this core until IRQ is handled */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
-#endif
-
- return 1;
- }
- return 0;
-}
-
-static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit* core)
-{
- u32 irq_readout;
- u32 current_tile_addr;
- u32 core_status;
- mali_core_job * job;
- mali200_job * job200;
-
- job = core->current_job;
- job200 = GET_JOB200_PTR(job);
-
-
- if (mali_benchmark) {
- irq_readout = MALI200_REG_VAL_IRQ_END_OF_FRAME;
- current_tile_addr = 0;
- core_status = 0;
- } else {
- irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
- current_tile_addr = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR);
- core_status = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_STATUS);
- }
-
- if (NULL == job)
- {
- MALI_DEBUG_ASSERT(CORE_IDLE==core->state);
- if ( 0 != irq_readout )
- {
- MALI_PRINT_ERROR(("Interrupt from a core not running a job. IRQ: 0x%04x Status: 0x%04x", irq_readout, core_status));
- }
- return JOB_STATUS_END_UNKNOWN_ERR;
- }
- MALI_DEBUG_ASSERT(CORE_IDLE!=core->state);
-
- job200->irq_status |= irq_readout;
-
- MALI_DEBUG_PRINT_IF( 3, ( 0 != irq_readout ),
- ("Mali PP: Job: 0x%08x IRQ RECEIVED Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n",
- (u32)job200->user_input.user_job_ptr, irq_readout ,current_tile_addr ,core_status));
-
- if ( MALI200_REG_VAL_IRQ_END_OF_FRAME & irq_readout)
- {
-#if defined(USING_MALI200)
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES);
-#endif
-
- if (0 != job200->user_input.perf_counter_flag )
- {
- if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
- {
- job200->perf_counter0 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- job200->perf_counter1 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- u32 src0;
- u32 val0;
- u32 src1;
- u32 val1;
- mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1);
-
- if (job200->perf_counter_l2_src0 == src0)
- {
- job200->perf_counter_l2_val0_raw = val0;
- job200->perf_counter_l2_val0 = val0 - job200->perf_counter_l2_val0;
- }
- else
- {
- job200->perf_counter_l2_val0_raw = 0;
- job200->perf_counter_l2_val0 = 0;
- }
-
- if (job200->perf_counter_l2_src1 == src1)
- {
- job200->perf_counter_l2_val1_raw = val1;
- job200->perf_counter_l2_val1 = val1 - job200->perf_counter_l2_val1;
- }
- else
- {
- job200->perf_counter_l2_val1_raw = 0;
- job200->perf_counter_l2_val1 = 0;
- }
- }
-#endif
-
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number),
- job200->perf_counter0, job200->perf_counter1,
- job200->user_input.perf_counter_src0 | (job200->user_input.perf_counter_src1 << 8)
-#if defined(USING_MALI400_L2_CACHE)
- | (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24),
- job200->perf_counter_l2_val0_raw, job200->perf_counter_l2_val1_raw
-#else
- , 0, 0
-#endif
- );
-#endif
-
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_SUCCESS; /* reschedule */
- }
- /* Overall SW watchdog timeout or (time to do hang checking and progress detected)? */
- else if (
- (CORE_WATCHDOG_TIMEOUT == core->state) ||
- ((CORE_HANG_CHECK_TIMEOUT == core->state) && (current_tile_addr == job200->last_tile_list_addr))
- )
- {
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
-#endif
- /* no progress detected, killed by the watchdog */
- MALI_DEBUG_PRINT(2, ("M200: SW-Timeout Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x.\n", irq_readout ,current_tile_addr ,core_status) );
- /* In this case will the system outside cleanup and reset the core */
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
-
- return JOB_STATUS_END_HANG;
- }
- /* HW watchdog triggered or an existing hang check passed? */
- else if ((CORE_HANG_CHECK_TIMEOUT == core->state) || (irq_readout & job200->active_mask & MALI200_REG_VAL_IRQ_HANG))
- {
- /* check interval in ms */
- u32 timeout = mali_core_hang_check_timeout_get();
- MALI_DEBUG_PRINT(3, ("M200: HW/SW Watchdog triggered, checking for progress in %d ms\n", timeout));
- job200->last_tile_list_addr = current_tile_addr;
- /* hw watchdog triggered, set up a progress checker every HANGCHECK ms */
- _mali_osk_timer_add(core->timer_hang_detection, _mali_osk_time_mstoticks(timeout));
- job200->active_mask &= ~MALI200_REG_VAL_IRQ_HANG; /* ignore the hw watchdoig from now on */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, irq_readout & ~MALI200_REG_VAL_IRQ_HANG);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, job200->active_mask);
- return JOB_STATUS_CONTINUE_RUN; /* not finished */
- }
- /* No irq pending, core still busy */
- else if ((0 == (irq_readout & MALI200_REG_VAL_IRQ_MASK_USED)) && ( 0 != (core_status & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)))
- {
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, irq_readout);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, job200->active_mask);
- return JOB_STATUS_CONTINUE_RUN; /* Not finished */
- }
- else
- {
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
-#endif
-
- MALI_DEBUG_PRINT(1, ("Mali PP: Job: 0x%08x CRASH? Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n",
- (u32)job200->user_input.user_job_ptr, irq_readout ,current_tile_addr ,core_status) ) ;
-
- if (irq_readout & MALI200_REG_VAL_IRQ_BUS_ERROR)
- {
- u32 bus_error = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS);
-
- MALI_DEBUG_PRINT(1, ("Bus error status: 0x%08X\n", bus_error));
- MALI_DEBUG_PRINT_IF(1, (bus_error & 0x01), ("Bus write error from id 0x%02x\n", (bus_error>>2) & 0x0F));
- MALI_DEBUG_PRINT_IF(1, (bus_error & 0x02), ("Bus read error from id 0x%02x\n", (bus_error>>6) & 0x0F));
- MALI_DEBUG_PRINT_IF(1, (0 == (bus_error & 0x03)), ("Bus error but neither read or write was set as the error reason\n"));
- (void)bus_error;
- }
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_UNKNOWN_ERR; /* reschedule */
- }
-}
-
-
-/* This function is called from the ioctl function and should return a mali_core_job pointer
-to a created mali_core_job object with the data given from userspace */
-static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument)
-{
- mali200_job *job200;
- mali_core_job *job = NULL;
- mali_core_job *previous_replaced_job;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_uk_pp_start_job_s * user_ptr_job_input;
-
- user_ptr_job_input = (_mali_uk_pp_start_job_s *)argument;
-
- MALI_CHECK_NON_NULL(job200 = (mali200_job *) _mali_osk_malloc(sizeof(mali200_job)), _MALI_OSK_ERR_NOMEM);
- _mali_osk_memset(job200, 0 , sizeof(mali200_job) );
-
- /* We read job data from Userspace pointer */
- if ( NULL == _mali_osk_memcpy((void*)&job200->user_input, user_ptr_job_input, sizeof(job200->user_input)) )
- {
- MALI_PRINT_ERROR( ("Mali PP: Could not copy data from U/K interface.\n")) ;
- err = _MALI_OSK_ERR_FAULT;
- goto function_exit;
- }
-
- MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_get_new_job_from_user 0x%x\n", (void*)job200->user_input.user_job_ptr));
-
- MALI_DEBUG_PRINT(5, ("Mali PP: Frameregs: 0x%x 0x%x 0x%x Writeback[1] 0x%x, Pri:%d; Watchd:%d\n",
- job200->user_input.frame_registers[0], job200->user_input.frame_registers[1], job200->user_input.frame_registers[2],
- job200->user_input.wb0_registers[1], job200->user_input.priority,
- job200->user_input.watchdog_msecs));
-
- if ( job200->user_input.perf_counter_flag)
- {
-#if defined(USING_MALI400_L2_CACHE)
- MALI_DEBUG_PRINT(5, ("Mali PP: Performance counters: flag:0x%x src0:0x%x src1:0x%x l2_src0:0x%x l2_src1:0x%x\n",
- job200->user_input.perf_counter_flag,
- job200->user_input.perf_counter_src0,
- job200->user_input.perf_counter_src1,
- job200->user_input.perf_counter_l2_src0,
- job200->user_input.perf_counter_l2_src1));
-#else
- MALI_DEBUG_PRINT(5, ("Mali PP: Performance counters: flag:0x%x src0:0x%x src1:0x%x\n",
- job200->user_input.perf_counter_flag,
- job200->user_input.perf_counter_src0,
- job200->user_input.perf_counter_src1));
-#endif
- }
-
- job = GET_JOB_EMBEDDED_PTR(job200);
-
- job->session = session;
- job->flags = user_ptr_job_input->flags;
- job_priority_set(job, job200->user_input.priority);
- job_watchdog_set(job, job200->user_input.watchdog_msecs );
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- job200->pid = _mali_osk_get_pid();
- job200->tid = _mali_osk_get_tid();
-#endif
-
- job->abort_id = job200->user_input.abort_id;
- if (mali_job_queue_full(session))
- {
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- goto function_exit;
- }
-
- /* We now know that we has a job, and a empty session slot to put it in */
-
- job200->active_mask = MALI200_REG_VAL_IRQ_MASK_USED;
-
- /* Allocating User Return Data */
- job200->notification_obj = _mali_osk_notification_create(
- _MALI_NOTIFICATION_PP_FINISHED,
- sizeof(_mali_uk_pp_job_finished_s) );
-
- if ( NULL == job200->notification_obj )
- {
- MALI_PRINT_ERROR( ("Mali PP: Could not get notification_obj.\n")) ;
- err = _MALI_OSK_ERR_NOMEM;
- goto function_exit;
- }
-
- _MALI_OSK_INIT_LIST_HEAD( &(job->list) ) ;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x INPUT from user.\n", (u32)job200->user_input.user_job_ptr)) ;
-
- /* This should not happen since we have the checking of priority above */
- if ( _MALI_OSK_ERR_OK != mali_core_session_add_job(session, job, &previous_replaced_job))
- {
- MALI_PRINT_ERROR( ("Mali PP: Internal error\n")) ;
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- _mali_osk_notification_delete( job200->notification_obj );
- goto function_exit;
- }
-
- /* If MALI_TRUE: This session had a job with lower priority which were removed.
- This replaced job is given back to userspace. */
- if ( NULL != previous_replaced_job )
- {
- mali200_job *previous_replaced_job200;
-
- previous_replaced_job200 = GET_JOB200_PTR(previous_replaced_job);
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Replacing job: 0x%08x\n", (u32)previous_replaced_job200->user_input.user_job_ptr)) ;
-
- /* Copy to the input data (which also is output data) the
- pointer to the job that were replaced, so that the userspace
- driver can put this job in the front of its job-queue */
-
- user_ptr_job_input->returned_user_job_ptr = previous_replaced_job200->user_input.user_job_ptr;
-
- /** @note failure to 'copy to user' at this point must not free job200,
- * and so no transaction rollback required in the U/K interface */
-
- /* This does not cause job200 to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED;
- MALI_DEBUG_PRINT(5, ("subsystem_mali200_get_new_job_from_user: Job added, prev returned\n")) ;
- }
- else
- {
- /* This does not cause job200 to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED;
- MALI_DEBUG_PRINT(5, ("subsystem_mali200_get_new_job_from_user: Job added\n")) ;
- }
-
-function_exit:
- if (_MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE == user_ptr_job_input->status
- || _MALI_OSK_ERR_OK != err )
- {
- _mali_osk_free(job200);
- }
-#if MALI_STATE_TRACKING
- if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status)
- {
- if(job)
- {
- job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received);
- }
- }
-#endif
-
- MALI_ERROR(err);
-}
-
-/* This function is called from the ioctl function and should write the necessary data
-to userspace telling which job was finished and the status and debuginfo for this job.
-The function must also free and cleanup the input job object. */
-static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status)
-{
- mali200_job *job200;
- _mali_uk_pp_job_finished_s * job_out;
- _mali_uk_pp_start_job_s * job_input;
- mali_core_session *session;
-
- if (NULL == job)
- {
- MALI_DEBUG_PRINT(1, ("subsystem_mali200_return_job_to_user received a NULL ptr\n"));
- return;
- }
-
- job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job);
-
- if (NULL == job200->notification_obj)
- {
- MALI_DEBUG_PRINT(1, ("Found job200 with NULL notification object, abandoning userspace sending\n"));
- return;
- }
-
- job_out = job200->notification_obj->result_buffer;
- job_input= &(job200->user_input);
- session = job->session;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x OUTPUT to user. Runtime: %dus\n",
- (u32)job200->user_input.user_job_ptr,
- job->render_time_usecs)) ;
-
- _mali_osk_memset(job_out, 0 , sizeof(_mali_uk_pp_job_finished_s));
-
- job_out->user_job_ptr = job_input->user_job_ptr;
-
- switch( end_status )
- {
- case JOB_STATUS_CONTINUE_RUN:
- case JOB_STATUS_END_SUCCESS:
- case JOB_STATUS_END_OOM:
- case JOB_STATUS_END_ABORT:
- case JOB_STATUS_END_TIMEOUT_SW:
- case JOB_STATUS_END_HANG:
- case JOB_STATUS_END_SEG_FAULT:
- case JOB_STATUS_END_ILLEGAL_JOB:
- case JOB_STATUS_END_UNKNOWN_ERR:
- case JOB_STATUS_END_SHUTDOWN:
- case JOB_STATUS_END_SYSTEM_UNUSABLE:
- job_out->status = (mali_subsystem_job_end_code) end_status;
- break;
-
- default:
- job_out->status = JOB_STATUS_END_UNKNOWN_ERR ;
- }
- job_out->irq_status = job200->irq_status;
- job_out->perf_counter0 = job200->perf_counter0;
- job_out->perf_counter1 = job200->perf_counter1;
- job_out->render_time = job->render_time_usecs;
-
-#if defined(USING_MALI400_L2_CACHE)
- job_out->perf_counter_l2_src0 = job200->perf_counter_l2_src0;
- job_out->perf_counter_l2_src1 = job200->perf_counter_l2_src1;
- job_out->perf_counter_l2_val0 = job200->perf_counter_l2_val0;
- job_out->perf_counter_l2_val1 = job200->perf_counter_l2_val1;
- job_out->perf_counter_l2_val0_raw = job200->perf_counter_l2_val0_raw;
- job_out->perf_counter_l2_val1_raw = job200->perf_counter_l2_val1_raw;
-#endif
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&session->jobs_returned);
-#endif
- _mali_osk_notification_queue_send( session->notification_queue, job200->notification_obj);
- job200->notification_obj = NULL;
-
- _mali_osk_free(job200);
-}
-
-static void subsystem_mali200_renderunit_delete(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Mali PP: mali200_renderunit_delete\n"));
- _mali_osk_free(core);
-}
-
-static void mali200_reset_hard(struct mali_core_renderunit * core)
-{
- const int reset_finished_loop_count = 15;
- const u32 reset_wait_target_register = MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW;
- const u32 reset_invalid_value = 0xC0FFE000;
- const u32 reset_check_value = 0xC01A0000;
- const u32 reset_default_value = 0;
- int i;
-
- MALI_DEBUG_PRINT(5, ("subsystem_mali200_renderunit_reset_core_hard called for core %s\n", core->description));
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_invalid_value);
-
- mali_core_renderunit_register_write(
- core,
- MALI200_REG_ADDR_MGMT_CTRL_MGMT,
- MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
-
- for (i = 0; i < reset_finished_loop_count; i++)
- {
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_check_value);
- if (reset_check_value == mali_core_renderunit_register_read(core, reset_wait_target_register))
- {
- MALI_DEBUG_PRINT(5, ("Reset loop exiting after %d iterations\n", i));
- break;
- }
- _mali_osk_time_ubusydelay(10);
- }
-
- if (i == reset_finished_loop_count)
- {
- MALI_DEBUG_PRINT(1, ("The reset loop didn't work\n"));
- }
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_default_value); /* set it back to the default */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
-}
-
-static void subsystem_mali200_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style)
-{
- MALI_DEBUG_PRINT(5, ("Mali PP: renderunit_reset_core\n"));
-
- switch (style)
- {
- case MALI_CORE_RESET_STYLE_RUNABLE:
- mali200_reset(core);
- break;
- case MALI_CORE_RESET_STYLE_DISABLE:
- mali200_raw_reset(core); /* do the raw reset */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* then disable the IRQs */
- break;
- case MALI_CORE_RESET_STYLE_HARD:
- mali200_reset_hard(core);
- break;
- default:
- MALI_DEBUG_PRINT(1, ("Unknown reset type %d\n", style));
- }
-}
-
-static void subsystem_mali200_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
-}
-
-static _mali_osk_errcode_t subsystem_mali200_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core)
-{
- u32 irq_readout;
-
- irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS);
-
- if ( MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout )
- {
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
- MALI_SUCCESS;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_start_job(session, args);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_number_of_cores_get(session, &args->number_of_cores);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_core_version_get(session, &args->version);
-}
-
-void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s * args)
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- if (NULL == args->ctx) return;
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- if (NULL == session) return;
- mali_core_subsystem_ioctl_abort_job(session, args->abort_id);
-
-}
-
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t malipp_signal_power_up( u32 core_num, mali_bool queue_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali PP: signal power up core: %d - queue_only: %d\n", core_num, queue_only ));
-
- return( mali_core_subsystem_signal_power_up( &subsystem_mali200, core_num, queue_only ) );
-}
-
-_mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali PP: signal power down core: %d - immediate_only: %d\n", core_num, immediate_only ));
-
- return( mali_core_subsystem_signal_power_down( &subsystem_mali200, core_num, immediate_only ) );
-}
-
-#endif
-
-#if MALI_STATE_TRACKING
-u32 mali200_subsystem_dump_state(char *buf, u32 size)
-{
- return mali_core_renderunit_dump_state(&subsystem_mali200, buf, size);
-}
-#endif
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_common.h b/driver/src/devicedrv/mali/common/mali_kernel_common.h
index d9388ff..a33660b 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_common.h
+++ b/driver/src/devicedrv/mali/common/mali_kernel_common.h
@@ -118,7 +118,9 @@
} while (0)
#ifdef DEBUG
+#ifndef mali_debug_level
extern int mali_debug_level;
+#endif
#define MALI_DEBUG_CODE(code) code
#define MALI_DEBUG_PRINT(level, args) do { \
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_core.c b/driver/src/devicedrv/mali/common/mali_kernel_core.c
index 5e3626d..7d2d3c3 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_core.c
+++ b/driver/src/devicedrv/mali/common/mali_kernel_core.c
@@ -8,344 +8,804 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_mem.h"
-#include "mali_kernel_session_manager.h"
-#include "mali_kernel_pp.h"
-#include "mali_kernel_gp.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
#include "mali_osk.h"
#include "mali_osk_mali.h"
#include "mali_ukk.h"
#include "mali_kernel_core.h"
-#include "mali_kernel_rendercore.h"
-#if defined USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
+#include "mali_memory.h"
+#include "mali_mem_validation.h"
+#include "mali_mmu.h"
+#include "mali_mmu_page_directory.h"
+#include "mali_dlbu.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_cluster.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_pmu.h"
+#include "mali_scheduler.h"
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+#include "mali_kernel_utilization.h"
+#endif
+#include "mali_l2_cache.h"
+#if MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
#endif
-#if USING_MALI_PMM
-#include "mali_pmm.h"
-#endif /* USING_MALI_PMM */
-
-/* platform specific set up */
-#include "mali_platform.h"
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_core_id = -1;
/** Pointer to table of resource definitions available to the Mali driver.
* _mali_osk_resources_init() sets up the pointer to this table.
*/
static _mali_osk_resource_t *arch_configuration = NULL;
+/** Start profiling from module load? */
+int mali_boot_profiling = 0;
+
/** Number of resources initialized by _mali_osk_resources_init() */
static u32 num_resources;
-static _mali_osk_errcode_t register_resources( _mali_osk_resource_t **arch_configuration, u32 num_resources );
-
-static _mali_osk_errcode_t initialize_subsystems(void);
-static void terminate_subsystems(void);
-
-static _mali_osk_errcode_t mali_kernel_subsystem_core_setup(mali_kernel_subsystem_identifier id);
-static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier id);
-static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_system_info* info);
-static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
+static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN;
+static u32 global_gpu_base_address = 0;
+static u32 global_gpu_major_version = 0;
+static u32 global_gpu_minor_version = 0;
static _mali_osk_errcode_t build_system_info(void);
static void cleanup_system_info(_mali_system_info *cleanup);
-/**
- * @brief handler for MEM_VALIDATION resources
- *
- * This resource handler is common to all memory systems. It provides a default
- * means for validating requests to map in external memory via
- * _mali_ukk_map_external_mem. In addition, if _mali_ukk_va_to_pa is
- * implemented, then _mali_ukk_va_to_pa can make use of this MEM_VALIDATION
- * resource.
- *
- * MEM_VALIDATION also provide a CPU physical to Mali physical address
- * translation, for use by _mali_ukk_map_external_mem.
- *
- * @note MEM_VALIDATION resources are only to handle simple cases where a
- * certain physical address range is allowed to be mapped in by any process,
- * e.g. a framebuffer at a fixed location. If the implementor has more complex
- * mapping requirements, then they must either:
- * - implement their own memory validation function
- * - or, integrate with UMP.
- *
- * @param resource The resource to handle (type MEM_VALIDATION)
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-static _mali_osk_errcode_t mali_kernel_core_resource_mem_validation(_mali_osk_resource_t * resource);
-
-/* MEM_VALIDATION handler state */
-typedef struct
-{
- u32 phys_base; /**< Mali physical base of the memory, page aligned */
- u32 size; /**< size in bytes of the memory, multiple of page size */
- s32 cpu_usage_adjust; /**< Offset to add to Mali Physical address to obtain CPU physical address */
-} _mali_mem_validation_t;
+/* system info variables */
+static _mali_osk_lock_t *system_info_lock = NULL;
+static _mali_system_info *system_info = NULL;
+static u32 system_info_size = 0;
+static u32 first_pp_offset = 0;
-#define INVALID_MEM 0xffffffff
+#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
-static _mali_mem_validation_t mem_validator = { INVALID_MEM, INVALID_MEM, -1 };
+/* timer related */
+int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
-static struct mali_kernel_subsystem mali_subsystem_core =
+static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset)
{
- mali_kernel_subsystem_core_setup, /* startup */
- mali_kernel_subsystem_core_cleanup, /* shutdown */
- NULL, /* load_complete */
- mali_kernel_subsystem_core_system_info_fill, /* system_info_fill */
- mali_kernel_subsystem_core_session_begin, /* session_begin */
- NULL, /* session_end */
- NULL, /* broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-};
+ int i;
+ u32 addr = global_gpu_base_address + offset;
-static struct mali_kernel_subsystem * subsystems[] =
-{
+ for (i = 0; i < num_resources; i++)
+ {
+ if (type == arch_configuration[i].type && arch_configuration[i].base == addr)
+ {
+ return &(arch_configuration[i]);
+ }
+ }
-#if USING_MALI_PMM
- /* The PMM must be initialized before any cores - including L2 cache */
- &mali_subsystem_pmm,
-#endif
+ return NULL;
+}
- /* always included */
- &mali_subsystem_memory,
+static u32 mali_count_resources(_mali_osk_resource_type_t type)
+{
+ int i;
+ u32 retval = 0;
- /* The rendercore subsystem must be initialized before any subsystem based on the
- * rendercores is started e.g. mali_subsystem_mali200 and mali_subsystem_gp2 */
- &mali_subsystem_rendercore,
+ for (i = 0; i < num_resources; i++)
+ {
+ if (type == arch_configuration[i].type)
+ {
+ retval++;
+ }
+ }
- /* add reference to the subsystem */
- &mali_subsystem_mali200,
+ return retval;
+}
- /* add reference to the subsystem */
- &mali_subsystem_gp2,
-#if defined USING_MALI400_L2_CACHE
- &mali_subsystem_l2_cache,
-#endif
+static _mali_osk_errcode_t mali_parse_gpu_base_and_first_pp_offset_address(void)
+{
+ int i;
+ _mali_osk_resource_t *first_gp_resource = NULL;
+ _mali_osk_resource_t *first_pp_resource = NULL;
+
+ for (i = 0; i < num_resources; i++)
+ {
+ if (MALI_GP == arch_configuration[i].type)
+ {
+ if (NULL == first_gp_resource || first_gp_resource->base > arch_configuration[i].base)
+ {
+ first_gp_resource = &(arch_configuration[i]);
+ }
+ }
+ if (MALI_PP == arch_configuration[i].type)
+ {
+ if (NULL == first_pp_resource || first_pp_resource->base > arch_configuration[i].base)
+ {
+ first_pp_resource = &(arch_configuration[i]);
+ }
+ }
+ }
- /* always included */
- /* NOTE Keep the core entry at the tail of the list */
- &mali_subsystem_core
-};
+ if (NULL == first_gp_resource || NULL == first_pp_resource)
+ {
+ MALI_PRINT_ERROR(("No GP+PP core specified in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
-#define SUBSYSTEMS_COUNT ( sizeof(subsystems) / sizeof(subsystems[0]) )
+ if (first_gp_resource->base < first_pp_resource->base)
+ {
+ /* GP is first, so we are dealing with Mali-300, Mali-400 or Mali-450 */
+ global_gpu_base_address = first_gp_resource->base;
+ first_pp_offset = 0x8000;
+ }
+ else
+ {
+ /* PP is first, so we are dealing with Mali-200 */
+ global_gpu_base_address = first_pp_resource->base;
+ first_pp_offset = 0x0;
+ }
+ MALI_SUCCESS;
+}
-/* Pointers to this type available as incomplete struct in mali_kernel_session_manager.h */
-struct mali_session_data
+static _mali_osk_errcode_t mali_parse_product_info(void)
{
- void * subsystem_data[SUBSYSTEMS_COUNT];
- _mali_osk_notification_queue_t * ioctl_queue;
-};
+ _mali_osk_resource_t *first_pp_resource = NULL;
-static mali_kernel_resource_registrator resource_handler[RESOURCE_TYPE_COUNT] = { NULL, };
+ /* Find the first PP core */
+ first_pp_resource = mali_find_resource(MALI_PP, first_pp_offset);
+ if (NULL != first_pp_resource)
+ {
+ /* Create a dummy PP object for this core so that we can read the version register */
+ struct mali_group *group = mali_group_create(NULL, NULL);
+ if (NULL != group)
+ {
+ /*struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group, 0);*/
+ struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group);
+ if (NULL != pp_core)
+ {
+ u32 pp_version = mali_pp_core_get_version(pp_core);
+ mali_pp_delete(pp_core);
+ mali_group_delete(group);
+
+ global_gpu_major_version = (pp_version >> 8) & 0xFF;
+ global_gpu_minor_version = pp_version & 0xFF;
+
+ switch (pp_version >> 16)
+ {
+ case MALI200_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI200;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ case MALI300_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI300;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ case MALI400_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI400;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ case MALI450_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI450;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ default:
+ MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to create initial PP object\n"));
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to create initial group object\n"));
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("First PP core not specified in config file\n"));
+ }
-/* system info variables */
-static _mali_osk_lock_t *system_info_lock = NULL;
-static _mali_system_info * system_info = NULL;
-static u32 system_info_size = 0;
+ return _MALI_OSK_ERR_FAULT;
+}
-/* is called from OS specific driver entry point */
-_mali_osk_errcode_t mali_kernel_constructor( void )
+static void mali_delete_clusters(void)
{
- _mali_osk_errcode_t err;
-
- err = mali_platform_init();
- if (_MALI_OSK_ERR_OK != err) goto error1;
+ u32 i;
+ u32 number_of_clusters = mali_cluster_get_glob_num_clusters();
- err = _mali_osk_init();
- if (_MALI_OSK_ERR_OK != err) goto error2;
+ for (i = 0; i < number_of_clusters; i++)
+ {
+ mali_cluster_delete(mali_cluster_get_global_cluster(i));
+ }
+}
- MALI_DEBUG_PRINT(2, ("\n"));
- MALI_DEBUG_PRINT(2, ("Inserting Mali v%d device driver. \n",_MALI_API_VERSION));
- MALI_DEBUG_PRINT(2, ("Compiled: %s, time: %s.\n", __DATE__, __TIME__));
- MALI_DEBUG_PRINT(2, ("Svn revision: %s\n", SVN_REV_STRING));
+static _mali_osk_errcode_t mali_create_cluster(_mali_osk_resource_t *resource)
+{
+ if (NULL != resource)
+ {
+ struct mali_l2_cache_core *l2_cache;
- err = initialize_subsystems();
- if (_MALI_OSK_ERR_OK != err) goto error3;
+ if (mali_l2_cache_core_get_glob_num_l2_cores() >= mali_l2_cache_core_get_max_num_l2_cores())
+ {
+ MALI_PRINT_ERROR(("Found too many L2 cache core objects, max %u is supported\n", mali_l2_cache_core_get_max_num_l2_cores()));
+ return _MALI_OSK_ERR_FAULT;
+ }
- MALI_PRINT(("Mali device driver %s loaded\n", SVN_REV_STRING));
+ MALI_DEBUG_PRINT(3, ("Found L2 cache %s, starting new cluster\n", resource->description));
- MALI_SUCCESS;
+ /*l2_cache = mali_l2_cache_create(resource, global_num_l2_cache_cores);*/
+ l2_cache = mali_l2_cache_create(resource);
+ if (NULL == l2_cache)
+ {
+ MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
-error3:
- MALI_PRINT(("Mali subsystems failed\n"));
- _mali_osk_term();
-error2:
- MALI_PRINT(("Mali device driver init failed\n"));
- if (_MALI_OSK_ERR_OK != mali_platform_deinit())
+ if (NULL == mali_cluster_create(l2_cache))
+ {
+ MALI_PRINT_ERROR(("Failed to create cluster object\n"));
+ mali_l2_cache_delete(l2_cache);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+ else
{
- MALI_PRINT(("Failed to deinit platform\n"));
+ mali_cluster_create(NULL);
+ if (NULL == mali_cluster_get_global_cluster(0))
+ {
+ MALI_PRINT_ERROR(("Failed to create cluster object\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
}
-error1:
- MALI_PRINT(("Failed to init platform\n"));
- MALI_ERROR(err);
+
+ MALI_DEBUG_PRINT(3, ("Created cluster object\n"));
+ return _MALI_OSK_ERR_OK;
}
-/* is called from OS specific driver exit point */
-void mali_kernel_destructor( void )
+static _mali_osk_errcode_t mali_parse_config_cluster(void)
{
- MALI_DEBUG_PRINT(2, ("\n"));
- MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
-#if USING_MALI_PMM
- malipmm_force_powerup();
-#endif
- terminate_subsystems(); /* subsystems are responsible for their registered resources */
- _mali_osk_term();
-
- if (_MALI_OSK_ERR_OK != mali_platform_deinit())
+ if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
{
- MALI_PRINT(("Failed to deinit platform\n"));
+ /* Create dummy cluster without L2 cache */
+ return mali_create_cluster(NULL);
}
- MALI_DEBUG_PRINT(2, ("Module unloaded.\n"));
-}
+ else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || _MALI_PRODUCT_ID_MALI400 == global_product_id)
+ {
+ _mali_osk_resource_t *l2_resource = mali_find_resource(MALI_L2, 0x1000);
+ if (NULL == l2_resource)
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
-_mali_osk_errcode_t register_resources( _mali_osk_resource_t **arch_configuration, u32 num_resources )
-{
- _mali_osk_resource_t *arch_resource = *arch_configuration;
- u32 i;
-#if USING_MALI_PMM
- u32 is_pmu_first_resource = 1;
-#endif /* USING_MALI_PMM */
-
- /* loop over arch configuration */
- for (i = 0; i < num_resources; ++i, arch_resource++)
- {
- if ( (arch_resource->type >= RESOURCE_TYPE_FIRST) &&
- (arch_resource->type < RESOURCE_TYPE_COUNT) &&
- (NULL != resource_handler[arch_resource->type])
- )
- {
-#if USING_MALI_PMM
- if((arch_resource->type != PMU) && (is_pmu_first_resource == 1))
+ return mali_create_cluster(l2_resource);
+ }
+ else if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ /*
+ * L2 for GP at 0x10000
+ * L2 for PP0-3 at 0x01000
+ * L2 for PP4-7 at 0x11000 (optional)
+ */
+
+ _mali_osk_resource_t *l2_gp_resource;
+ _mali_osk_resource_t *l2_pp_grp0_resource;
+ _mali_osk_resource_t *l2_pp_grp1_resource;
+
+ /* Make cluster for GP's L2 */
+ l2_gp_resource = mali_find_resource(MALI_L2, 0x10000);
+ if (NULL != l2_gp_resource)
+ {
+ _mali_osk_errcode_t ret;
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for GP\n"));
+ ret = mali_create_cluster(l2_gp_resource);
+ if (_MALI_OSK_ERR_OK != ret)
{
- _mali_osk_resource_t mali_pmu_virtual_resource;
- mali_pmu_virtual_resource.type = PMU;
- mali_pmu_virtual_resource.description = "Virtual PMU";
- mali_pmu_virtual_resource.base = 0x00000000;
- mali_pmu_virtual_resource.cpu_usage_adjust = 0;
- mali_pmu_virtual_resource.size = 0;
- mali_pmu_virtual_resource.irq = 0;
- mali_pmu_virtual_resource.flags = 0;
- mali_pmu_virtual_resource.mmu_id = 0;
- mali_pmu_virtual_resource.alloc_order = 0;
- MALI_CHECK_NO_ERROR(resource_handler[mali_pmu_virtual_resource.type](&mali_pmu_virtual_resource));
+ return ret;
}
- is_pmu_first_resource = 0;
-#endif /* USING_MALI_PMM */
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
- MALI_CHECK_NO_ERROR(resource_handler[arch_resource->type](arch_resource));
- /* the subsystem shutdown process will release all the resources already registered */
+ /* Make cluster for first PP core group */
+ l2_pp_grp0_resource = mali_find_resource(MALI_L2, 0x1000);
+ if (NULL != l2_pp_grp0_resource)
+ {
+ _mali_osk_errcode_t ret;
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n"));
+ ret = mali_create_cluster(l2_pp_grp0_resource);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ return ret;
+ }
}
else
{
- MALI_DEBUG_PRINT(1, ("No handler installed for resource %s, type %d\n", arch_resource->description, arch_resource->type));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Second PP core group is optional, don't fail if we don't find it */
+ l2_pp_grp1_resource = mali_find_resource(MALI_L2, 0x11000);
+ if (NULL != l2_pp_grp1_resource)
+ {
+ _mali_osk_errcode_t ret;
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n"));
+ ret = mali_create_cluster(l2_pp_grp1_resource);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ return ret;
+ }
}
}
- MALI_SUCCESS;
+ return _MALI_OSK_ERR_OK;
}
-static _mali_osk_errcode_t initialize_subsystems(void)
+static _mali_osk_errcode_t mali_create_group(struct mali_cluster *cluster,
+ _mali_osk_resource_t *resource_mmu,
+ _mali_osk_resource_t *resource_gp,
+ _mali_osk_resource_t *resource_pp)
{
- int i, j;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; /* default error code */
+ struct mali_mmu_core *mmu;
+ struct mali_group *group;
+ struct mali_pp_core *pp;
- MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT);
+ MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
- for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i)
+ /* Create the MMU object */
+ mmu = mali_mmu_create(resource_mmu);
+ if (NULL == mmu)
{
- if (NULL != subsystems[i]->startup)
+ MALI_PRINT_ERROR(("Failed to create MMU object\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the group object */
+ group = mali_group_create(cluster, mmu);
+ if (NULL == group)
+ {
+ MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
+ mali_mmu_delete(mmu);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Set pointer back to group in mmu.*/
+ mali_mmu_set_group(mmu, group);
+
+ /* Add this group to current cluster */
+ mali_cluster_add_group(cluster, group);
+
+ if (NULL != resource_gp)
+ {
+ /* Create the GP core object inside this group */
+ /* global_gp_core = mali_gp_create(resource_gp, group); */
+ if (NULL == mali_gp_create(resource_gp, group))
{
- /* the subsystem has a startup function defined */
- err = subsystems[i]->startup(i); /* the subsystem identifier is the offset in our subsystems array */
- if (_MALI_OSK_ERR_OK != err) goto cleanup;
+ /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
+ MALI_PRINT_ERROR(("Failed to create GP object\n"));
+ return _MALI_OSK_ERR_FAULT;
}
+
+ /* Add GP object to this group */
+ MALI_DEBUG_PRINT(3, ("Adding GP %s to group\n", resource_gp->description));
+ mali_group_add_gp_core(group, mali_gp_get_global_gp_core());
}
- for (j = 0; j < (int)SUBSYSTEMS_COUNT; ++j)
+ if (NULL != resource_pp)
{
- if (NULL != subsystems[j]->load_complete)
+ /* Create the PP core object inside this group */
+ pp = mali_pp_create(resource_pp, group);
+
+ if (NULL == pp)
{
- /* the subsystem has a load_complete function defined */
- err = subsystems[j]->load_complete(j);
- if (_MALI_OSK_ERR_OK != err) goto cleanup;
+ /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
+ MALI_PRINT_ERROR(("Failed to create PP object\n"));
+ return _MALI_OSK_ERR_FAULT;
}
+
+ /* Add PP object to this group */
+ MALI_DEBUG_PRINT(3, ("Adding PP %s to group\n", resource_pp->description));
+ mali_group_add_pp_core(group, pp);
}
- /* All systems loaded and resources registered */
- /* Build system info */
- if (_MALI_OSK_ERR_OK != build_system_info()) goto cleanup;
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_groups(void)
+{
+ if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
+ {
+ _mali_osk_resource_t *resource_gp;
+ _mali_osk_resource_t *resource_pp;
+ _mali_osk_resource_t *resource_mmu;
+
+ MALI_DEBUG_ASSERT(1 == mali_cluster_get_glob_num_clusters());
- MALI_SUCCESS; /* all ok */
+ resource_gp = mali_find_resource(MALI_GP, 0x02000);
+ resource_pp = mali_find_resource(MALI_PP, 0x00000);
+ resource_mmu = mali_find_resource(MMU, 0x03000);
-cleanup:
- /* i is index of subsystem which failed to start, all indices before that has to be shut down */
- for (i = i - 1; i >= 0; --i)
+ if (NULL == resource_mmu || NULL == resource_gp || NULL == resource_pp)
+ {
+ /* Missing mandatory core(s) */
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /*return mali_create_group(global_clusters[0], resource_mmu, resource_gp, resource_pp);*/
+ return mali_create_group(mali_cluster_get_global_cluster(0), resource_mmu, resource_gp, resource_pp);
+ }
+ else if (_MALI_PRODUCT_ID_MALI300 == global_product_id ||
+ _MALI_PRODUCT_ID_MALI400 == global_product_id ||
+ _MALI_PRODUCT_ID_MALI450 == global_product_id)
{
- /* the subsystem identifier is the offset in our subsystems array */
- /* Call possible shutdown notficiation functions */
- if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i);
+ _mali_osk_errcode_t err;
+ int cluster_id_gp = 0;
+ int cluster_id_pp_grp0 = 0;
+ int cluster_id_pp_grp1 = 0;
+ int i;
+ _mali_osk_resource_t *resource_gp;
+ _mali_osk_resource_t *resource_gp_mmu;
+ _mali_osk_resource_t *resource_pp[mali_pp_get_max_num_pp_cores()];
+ _mali_osk_resource_t *resource_pp_mmu[mali_pp_get_max_num_pp_cores()];
+ u32 max_num_pp_cores = mali_pp_get_max_num_pp_cores();
+
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ /* Mali-450 has separate L2s for GP, and PP core group(s) */
+ cluster_id_pp_grp0 = 1;
+ cluster_id_pp_grp1 = 2;
+ }
+
+ resource_gp = mali_find_resource(MALI_GP, 0x00000);
+ resource_gp_mmu = mali_find_resource(MMU, 0x03000);
+ resource_pp[0] = mali_find_resource(MALI_PP, 0x08000);
+ resource_pp[1] = mali_find_resource(MALI_PP, 0x0A000);
+ resource_pp[2] = mali_find_resource(MALI_PP, 0x0C000);
+ resource_pp[3] = mali_find_resource(MALI_PP, 0x0E000);
+ resource_pp[4] = mali_find_resource(MALI_PP, 0x28000);
+ resource_pp[5] = mali_find_resource(MALI_PP, 0x2A000);
+ resource_pp[6] = mali_find_resource(MALI_PP, 0x2C000);
+ resource_pp[7] = mali_find_resource(MALI_PP, 0x2E000);
+ resource_pp_mmu[0] = mali_find_resource(MMU, 0x04000);
+ resource_pp_mmu[1] = mali_find_resource(MMU, 0x05000);
+ resource_pp_mmu[2] = mali_find_resource(MMU, 0x06000);
+ resource_pp_mmu[3] = mali_find_resource(MMU, 0x07000);
+ resource_pp_mmu[4] = mali_find_resource(MMU, 0x1C000);
+ resource_pp_mmu[5] = mali_find_resource(MMU, 0x1D000);
+ resource_pp_mmu[6] = mali_find_resource(MMU, 0x1E000);
+ resource_pp_mmu[7] = mali_find_resource(MMU, 0x1F000);
+
+ if (NULL == resource_gp || NULL == resource_gp_mmu || NULL == resource_pp[0] || NULL == resource_pp_mmu[0])
+ {
+ /* Missing mandatory core(s) */
+ MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU (0x%08X, 0x%08X, 0x%08X, 0x%08X)\n",
+ resource_gp, resource_gp_mmu, resource_pp[0], resource_pp_mmu[0]));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ MALI_DEBUG_ASSERT(1 <= mali_cluster_get_glob_num_clusters());
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_gp), resource_gp_mmu, resource_gp, NULL);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+
+ /* Create group for first (and mandatory) PP core */
+ MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[0], NULL, resource_pp[0]);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+
+ /* Create groups for rest of the cores in the first PP core group */
+ for (i = 1; i < 4; i++) /* First half of the PP cores belong to first core group */
+ {
+ if (NULL != resource_pp[i])
+ {
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[i], NULL, resource_pp[i]);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+ }
+ }
+
+ /* Create groups for cores in the second PP core group */
+ for (i = 4; i < max_num_pp_cores; i++) /* Second half of the PP cores belong to second core group */
+ {
+ if (NULL != resource_pp[i])
+ {
+ MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= 2); /* Only Mali-450 have more than 4 PPs, and these cores belong to second core group */
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp1), resource_pp_mmu[i], NULL, resource_pp[i]);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+ }
+ }
}
- _mali_osk_lock_term( system_info_lock );
- MALI_ERROR(err); /* err is what the module which failed its startup returned, or the default */
+ return _MALI_OSK_ERR_OK;
}
-static void terminate_subsystems(void)
+static _mali_osk_errcode_t mali_parse_config_pmu(void)
{
- int i;
- /* shut down subsystems in reverse order from startup */
- for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i)
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+ _mali_osk_resource_t *resource_pmu;
+ u32 number_of_pp_cores;
+ u32 number_of_l2_caches;
+
+ resource_pmu = mali_find_resource(PMU, 0x02000);
+ number_of_pp_cores = mali_count_resources(MALI_PP);
+ number_of_l2_caches = mali_count_resources(MALI_L2);
+
+ if (NULL != resource_pmu)
{
- /* the subsystem identifier is the offset in our subsystems array */
- if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i);
+ if (NULL == mali_pmu_create(resource_pmu, number_of_pp_cores, number_of_l2_caches))
+ {
+ err = _MALI_OSK_ERR_FAULT;
+ }
}
- if (system_info_lock) _mali_osk_lock_term( system_info_lock );
-
- /* Free _mali_system_info struct */
- cleanup_system_info(system_info);
+ return err;
}
-void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data)
+static _mali_osk_errcode_t mali_parse_config_memory(void)
{
int i;
+ _mali_osk_errcode_t ret;
- for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i)
+ for(i = 0; i < num_resources; i++)
{
- if (NULL != subsystems[i]->broadcast_notification)
+ switch(arch_configuration[i].type)
{
- subsystems[i]->broadcast_notification(message, data);
+ case OS_MEMORY:
+ ret = mali_memory_core_resource_os_memory(&arch_configuration[i]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register OS_MEMORY\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ break;
+ case MEMORY:
+ ret = mali_memory_core_resource_dedicated_memory(&arch_configuration[i]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register MEMORY\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ break;
+ case MEM_VALIDATION:
+ ret = mali_mem_validation_add_range(&arch_configuration[i]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register MEM_VALIDATION\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ break;
+ default:
+ break;
}
}
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_initialize_subsystems(void)
+{
+ _mali_osk_errcode_t err;
+ mali_bool is_pmu_enabled;
+
+ MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK
+ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT);
+
+ err = mali_session_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto session_init_failed;
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ /* No biggie if we wheren't able to initialize the profiling */
+ MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
+ }
+#endif
+
+ /* Build dummy system info. Will be removed in the future. */
+ err = build_system_info();
+ if (_MALI_OSK_ERR_OK != err) goto build_system_info_failed;
+
+ /* Get data from config.h */
+ err = _mali_osk_resources_init(&arch_configuration, &num_resources);
+ if (_MALI_OSK_ERR_OK != err) goto osk_resources_init_failed;
+
+ /* Initialize driver subsystems */
+ err = mali_memory_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto memory_init_failed;
+
+ /* Configure memory early. Memory allocation needed for mali_mmu_initialize. */
+ err = mali_parse_config_memory();
+ if (_MALI_OSK_ERR_OK != err) goto parse_memory_config_failed;
+
+ /* Parsing the GPU base address and first pp offset */
+ err = mali_parse_gpu_base_and_first_pp_offset_address();
+ if (_MALI_OSK_ERR_OK != err) goto parse_gpu_base_address_failed;
+
+ /* Initialize the MALI PMU */
+ err = mali_parse_config_pmu();
+ if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed;
+
+ is_pmu_enabled = mali_pmu_get_global_pmu_core() != NULL ? MALI_TRUE : MALI_FALSE;
+
+ /* Initialize the power management module */
+ err = mali_pm_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pm_init_failed;
+
+ /* Make sure the power stays on for the rest of this function */
+ mali_pm_always_on(MALI_TRUE);
+
+ /* Detect which Mali GPU we are dealing with */
+ err = mali_parse_product_info();
+ if (_MALI_OSK_ERR_OK != err) goto product_info_parsing_failed;
+
+ /* The global_product_id is now populated with the correct Mali GPU */
+
+ /* Initialize MMU module */
+ err = mali_mmu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed;
+
+ /* Initialize the DLBU module for Mali-450 */
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ err = mali_dlbu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed;
+ }
+
+ /* Start configuring the actual Mali hardware. */
+ err = mali_parse_config_cluster();
+ if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed;
+ err = mali_parse_config_groups();
+ if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed;
+
+ /* Initialize the schedulers */
+ err = mali_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto scheduler_init_failed;
+ err = mali_gp_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto gp_scheduler_init_failed;
+ err = mali_pp_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed;
+
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+ /* Initialize the GPU utilization tracking */
+ err = mali_utilization_init();
+ if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed;
+#endif
+
+ /* We no longer need to stay */
+ mali_pm_always_on(MALI_FALSE);
+ MALI_SUCCESS; /* all ok */
+
+ /* Error handling */
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+utilization_init_failed:
+ mali_pp_scheduler_terminate();
+#endif
+pp_scheduler_init_failed:
+ mali_gp_scheduler_terminate();
+gp_scheduler_init_failed:
+ mali_scheduler_terminate();
+scheduler_init_failed:
+config_parsing_failed:
+ mali_delete_clusters(); /* Delete clusters even if config parsing failed. */
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ mali_dlbu_terminate();
+ }
+dlbu_init_failed:
+ mali_mmu_terminate();
+mmu_init_failed:
+ /* Nothing to roll back */
+product_info_parsing_failed:
+ mali_pm_terminate();
+pm_init_failed:
+ if (is_pmu_enabled)
+ {
+ mali_pmu_delete(mali_pmu_get_global_pmu_core());
+ }
+parse_pmu_config_failed:
+parse_gpu_base_address_failed:
+parse_memory_config_failed:
+ mali_memory_terminate();
+memory_init_failed:
+ _mali_osk_resources_term(&arch_configuration, num_resources);
+osk_resources_init_failed:
+ cleanup_system_info(system_info);
+build_system_info_failed:
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_term();
+#endif
+ mali_session_terminate();
+session_init_failed:
+ return err;
}
-static _mali_osk_errcode_t mali_kernel_subsystem_core_setup(mali_kernel_subsystem_identifier id)
+void mali_terminate_subsystems(void)
{
- mali_subsystem_core_id = id;
+ struct mali_pmu_core *pmu;
- /* Register our own resources */
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MEM_VALIDATION, mali_kernel_core_resource_mem_validation));
+ MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
- /* parse the arch resource definition and tell all the subsystems */
- /* this is why the core subsystem has to be specified last in the subsystem array */
- MALI_CHECK_NO_ERROR(_mali_osk_resources_init(&arch_configuration, &num_resources));
+ /* shut down subsystems in reverse order from startup */
- MALI_CHECK_NO_ERROR(register_resources(&arch_configuration, num_resources));
+ mali_pm_always_on(MALI_TRUE); /* Mali will be powered off once PM subsystem terminates */
- /* resource parsing succeeded and the subsystem have corretly accepted their resources */
- MALI_SUCCESS;
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+ mali_utilization_term();
+#endif
+
+ mali_pp_scheduler_terminate();
+ mali_gp_scheduler_terminate();
+ mali_scheduler_terminate();
+
+ mali_delete_clusters(); /* Delete clusters even if config parsing failed. */
+
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ mali_dlbu_terminate();
+ }
+
+ mali_mmu_terminate();
+
+ pmu = mali_pmu_get_global_pmu_core();
+ if (NULL != pmu)
+ {
+ mali_pmu_delete(pmu);
+ }
+
+ mali_pm_terminate();
+
+ mali_memory_terminate();
+
+ _mali_osk_resources_term(&arch_configuration, num_resources);
+
+ cleanup_system_info(system_info);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_term();
+#endif
+
+ mali_session_terminate();
+
+ if (NULL != system_info_lock)
+ {
+ _mali_osk_lock_term( system_info_lock );
+ }
+}
+
+_mali_product_id_t mali_kernel_core_get_product_id(void)
+{
+ return global_product_id;
}
-static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier id)
+void mali_kernel_core_wakeup(void)
{
- _mali_osk_resources_term(&arch_configuration, num_resources);
+ u32 i;
+ u32 glob_num_clusters = mali_cluster_get_glob_num_clusters();
+ struct mali_cluster *cluster;
+
+ for (i = 0; i < glob_num_clusters; i++)
+ {
+ cluster = mali_cluster_get_global_cluster(i);
+ mali_cluster_reset(cluster);
+ }
}
static void cleanup_system_info(_mali_system_info *cleanup)
@@ -373,11 +833,10 @@ static void cleanup_system_info(_mali_system_info *cleanup)
_mali_osk_free(cleanup);
}
+/* Build a dummy system info struct. User space still need this. */
static _mali_osk_errcode_t build_system_info(void)
{
- unsigned int i;
- int err = _MALI_OSK_ERR_FAULT;
- _mali_system_info * new_info, * cleanup;
+ _mali_system_info * new_info;
_mali_core_info * current_core;
_mali_mem_info * current_mem;
u32 new_size = 0;
@@ -387,19 +846,25 @@ static _mali_osk_errcode_t build_system_info(void)
_mali_osk_memset(new_info, 0, sizeof(_mali_system_info));
- /* if an error happens during any of the system_info_fill calls cleanup the new info structs */
- cleanup = new_info;
+ /* fill in the info */
+ new_info->has_mmu = 1;
+ new_info->drivermode = _MALI_DRIVER_MODE_NORMAL;
+
+ new_info->core_info = NULL; /* Not used by user space */
- /* ask each subsystems to fill in their info */
- for (i = 0; i < SUBSYSTEMS_COUNT; ++i)
+ new_info->mem_info = _mali_osk_calloc(1, sizeof(_mali_mem_info));
+ if(NULL == new_info->mem_info)
{
- if (NULL != subsystems[i]->system_info_fill)
- {
- err = subsystems[i]->system_info_fill(new_info);
- if (_MALI_OSK_ERR_OK != err) goto error_exit;
- }
+ _mali_osk_free(new_info);
+ return _MALI_OSK_ERR_NOMEM;
}
+ new_info->mem_info->size = 1024 * 1024 * 1024; /* 1GiB */
+ new_info->mem_info->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;
+ new_info->mem_info->maximum_order_supported = 30;
+ new_info->mem_info->identifier = 0;
+ new_info->mem_info->next = NULL;
+
/* building succeeded, calculate the size */
/* size needed of the system info struct itself */
@@ -420,8 +885,6 @@ static _mali_osk_errcode_t build_system_info(void)
/* lock system info access so a user wont't get a corrupted version */
_mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW );
- /* cleanup the old one */
- cleanup = system_info;
/* set new info */
system_info = new_info;
system_info_size = new_size;
@@ -430,25 +893,15 @@ static _mali_osk_errcode_t build_system_info(void)
_mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW );
/* ok result */
- err = _MALI_OSK_ERR_OK;
-
- /* we share the cleanup routine with the error case */
-error_exit:
- if (NULL == cleanup) MALI_ERROR((_mali_osk_errcode_t)err); /* no cleanup needed, return what err contains */
-
- /* cleanup */
- cleanup_system_info(cleanup);
-
- /* return whatever err is, we could end up here in both the error and success cases */
- MALI_ERROR((_mali_osk_errcode_t)err);
+ return _MALI_OSK_ERR_OK;
}
_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args )
{
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- /* check compatability */
+ /* check compatability */
if ( args->version == _MALI_UK_API_VERSION )
{
args->compatible = 1;
@@ -461,14 +914,14 @@ _mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args
args->version = _MALI_UK_API_VERSION; /* report our version */
/* success regardless of being compatible or not */
- MALI_SUCCESS;
+ MALI_SUCCESS;
}
_mali_osk_errcode_t _mali_ukk_get_system_info_size(_mali_uk_get_system_info_size_s *args)
{
- MALI_DEBUG_ASSERT_POINTER(args);
- args->size = system_info_size;
- MALI_SUCCESS;
+ MALI_DEBUG_ASSERT_POINTER(args);
+ args->size = system_info_size;
+ MALI_SUCCESS;
}
_mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args )
@@ -477,12 +930,12 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
_mali_mem_info * current_mem;
_mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
void * current_write_pos, ** current_patch_pos;
- u32 adjust_ptr_base;
+ u32 adjust_ptr_base;
/* check input */
MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS);
/* lock the system info */
_mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW );
@@ -491,20 +944,20 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
if (args->size < system_info_size) goto exit_when_locked;
/* we build a copy of system_info in the user space buffer specified by the user and
- * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may
- * indicate a different base address for patching the pointers (normally the
- * address of the provided system_info buffer would be used). This is helpful when
- * the system_info buffer needs to get copied to user space and the pointers need
- * to be in user space.
- */
- if (0 == args->ukk_private)
- {
- adjust_ptr_base = (u32)args->system_info;
- }
- else
- {
- adjust_ptr_base = args->ukk_private;
- }
+ * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may
+ * indicate a different base address for patching the pointers (normally the
+ * address of the provided system_info buffer would be used). This is helpful when
+ * the system_info buffer needs to get copied to user space and the pointers need
+ * to be in user space.
+ */
+ if (0 == args->ukk_private)
+ {
+ adjust_ptr_base = (u32)args->system_info;
+ }
+ else
+ {
+ adjust_ptr_base = args->ukk_private;
+ }
/* copy each struct into the buffer, and update its pointers */
current_write_pos = (void *)args->system_info;
@@ -557,56 +1010,56 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
err = _MALI_OSK_ERR_OK;
exit_when_locked:
_mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW );
- MALI_ERROR(err);
+ MALI_ERROR(err);
}
_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args )
{
_mali_osk_errcode_t err;
- _mali_osk_notification_t * notification;
- _mali_osk_notification_queue_t *queue;
+ _mali_osk_notification_t *notification;
+ _mali_osk_notification_queue_t *queue;
- /* check input */
+ /* check input */
MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id);
+ queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
/* if the queue does not exist we're currently shutting down */
if (NULL == queue)
{
MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
- args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
+ args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
MALI_SUCCESS;
}
- /* receive a notification, might sleep */
+ /* receive a notification, might sleep */
err = _mali_osk_notification_queue_receive(queue, &notification);
if (_MALI_OSK_ERR_OK != err)
{
- MALI_ERROR(err); /* errcode returned, pass on to caller */
- }
+ MALI_ERROR(err); /* errcode returned, pass on to caller */
+ }
/* copy the buffer to the user */
- args->type = (_mali_uk_notification_type)notification->notification_type;
- _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size);
+ args->type = (_mali_uk_notification_type)notification->notification_type;
+ _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size);
/* finished with the notification */
_mali_osk_notification_delete( notification );
- MALI_SUCCESS; /* all ok */
+ MALI_SUCCESS; /* all ok */
}
_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args )
{
_mali_osk_notification_t * notification;
- _mali_osk_notification_queue_t *queue;
+ _mali_osk_notification_queue_t *queue;
- /* check input */
+ /* check input */
MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id);
+ queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
/* if the queue does not exist we're currently shutting down */
if (NULL == queue)
@@ -618,294 +1071,115 @@ _mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *a
notification = _mali_osk_notification_create(args->type, 0);
if ( NULL == notification)
{
- MALI_PRINT_ERROR( ("Failed to create notification object\n")) ;
+ MALI_PRINT_ERROR( ("Failed to create notification object\n"));
return _MALI_OSK_ERR_NOMEM;
}
_mali_osk_notification_queue_send(queue, notification);
- MALI_SUCCESS; /* all ok */
-}
-
-static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_system_info* info)
-{
- MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS);
-
- info->drivermode = _MALI_DRIVER_MODE_NORMAL;
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- MALI_CHECK_NON_NULL(slot, _MALI_OSK_ERR_INVALID_ARGS);
- *slot = queue;
- MALI_SUCCESS;
-}
-
-/* MEM_VALIDATION resource handler */
-static _mali_osk_errcode_t mali_kernel_core_resource_mem_validation(_mali_osk_resource_t * resource)
-{
- /* Check that no other MEM_VALIDATION resources exist */
- MALI_CHECK( ((u32)-1) == mem_validator.phys_base, _MALI_OSK_ERR_FAULT );
-
- /* Check restrictions on page alignment */
- MALI_CHECK( 0 == (resource->base & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
- MALI_CHECK( 0 == (resource->size & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
- MALI_CHECK( 0 == (resource->cpu_usage_adjust & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
-
- mem_validator.phys_base = resource->base;
- mem_validator.size = resource->size;
- mem_validator.cpu_usage_adjust = resource->cpu_usage_adjust;
- MALI_DEBUG_PRINT( 2, ("Memory Validator '%s' installed for Mali physical address base==0x%08X, size==0x%08X, cpu_adjust==0x%08X\n",
- resource->description, mem_validator.phys_base, mem_validator.size, mem_validator.cpu_usage_adjust ));
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_kernel_core_translate_cpu_to_mali_phys_range( u32 *phys_base, u32 size )
-{
- u32 mali_phys_base;
-
- mali_phys_base = *phys_base - mem_validator.cpu_usage_adjust;
-
- MALI_CHECK( 0 == ( mali_phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
- MALI_CHECK( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
-
- MALI_CHECK_NO_ERROR( mali_kernel_core_validate_mali_phys_range( mali_phys_base, size ) );
-
- *phys_base = mali_phys_base;
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size )
-{
- MALI_CHECK_GOTO( 0 == ( phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), failure );
- MALI_CHECK_GOTO( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), failure );
-
- if ( phys_base >= mem_validator.phys_base
- && (phys_base + size) >= mem_validator.phys_base
- && phys_base <= (mem_validator.phys_base + mem_validator.size)
- && (phys_base + size) <= (mem_validator.phys_base + mem_validator.size) )
- {
- MALI_SUCCESS;
- }
-
- failure:
- MALI_PRINTF( ("*******************************************************************************\n") );
- MALI_PRINTF( ("MALI PHYSICAL RANGE VALIDATION ERROR!\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("We failed to validate a Mali-Physical range that the user-side wished to map in\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("It is likely that the user-side wished to do Direct Rendering, but a suitable\n") );
- MALI_PRINTF( ("address range validation mechanism has not been correctly setup\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_base, size) );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("Please refer to the ARM Mali Software Integration Guide for more information.\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("*******************************************************************************\n") );
-
- MALI_ERROR( _MALI_OSK_ERR_FAULT );
-}
-
-
-_mali_osk_errcode_t _mali_kernel_core_register_resource_handler(_mali_osk_resource_type_t type, mali_kernel_resource_registrator handler)
-{
- MALI_CHECK(type < RESOURCE_TYPE_COUNT, _MALI_OSK_ERR_INVALID_ARGS);
- MALI_DEBUG_ASSERT(NULL == resource_handler[type]); /* A handler for resource already exists */
- resource_handler[type] = handler;
- MALI_SUCCESS;
-}
-
-void * mali_kernel_session_manager_slot_get(struct mali_session_data * session_data, int id)
-{
- MALI_DEBUG_ASSERT_POINTER(session_data);
- if(id >= SUBSYSTEMS_COUNT) { MALI_DEBUG_PRINT(3, ("mali_kernel_session_manager_slot_get: id %d out of range\n", id)); return NULL; }
-
- if (NULL == session_data) { MALI_DEBUG_PRINT(3, ("mali_kernel_session_manager_slot_get: got NULL session data\n")); return NULL; }
- return session_data->subsystem_data[id];
+ MALI_SUCCESS; /* all ok */
}
_mali_osk_errcode_t _mali_ukk_open(void **context)
{
- int i;
- _mali_osk_errcode_t err;
- struct mali_session_data * session_data;
+ struct mali_session_data *session_data;
/* allocated struct to track this session */
- session_data = (struct mali_session_data *)_mali_osk_malloc(sizeof(struct mali_session_data));
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM);
+ session_data = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
+ MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM);
- _mali_osk_memset(session_data->subsystem_data, 0, sizeof(session_data->subsystem_data));
+ MALI_DEBUG_PRINT(2, ("Session starting\n"));
/* create a response queue for this session */
session_data->ioctl_queue = _mali_osk_notification_queue_init();
if (NULL == session_data->ioctl_queue)
{
_mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
- MALI_DEBUG_PRINT(3, ("Session starting\n"));
-
- /* call session_begin on all subsystems */
- for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i)
+ session_data->page_directory = mali_mmu_pagedir_alloc();
+ if (NULL == session_data->page_directory)
{
- if (NULL != subsystems[i]->session_begin)
- {
- /* subsystem has a session_begin */
- err = subsystems[i]->session_begin(session_data, &session_data->subsystem_data[i], session_data->ioctl_queue);
- MALI_CHECK_GOTO(err == _MALI_OSK_ERR_OK, cleanup);
- }
+ _mali_osk_notification_queue_term(session_data->ioctl_queue);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
- *context = (void*)session_data;
+ if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session_data->page_directory, MALI_DLB_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE))
+ {
+ MALI_PRINT_ERROR(("Failed to map DLB page into session\n"));
+ _mali_osk_notification_queue_term(session_data->ioctl_queue);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
- MALI_DEBUG_PRINT(3, ("Session started\n"));
- MALI_SUCCESS;
+ if (0 != mali_dlbu_phys_addr)
+ {
+ mali_mmu_pagedir_update(session_data->page_directory, MALI_DLB_VIRT_ADDR, mali_dlbu_phys_addr, _MALI_OSK_MALI_PAGE_SIZE);
+ }
-cleanup:
- MALI_DEBUG_PRINT(2, ("Session startup failed\n"));
- /* i is index of subsystem which failed session begin, all indices before that has to be ended */
- /* end subsystem sessions in the reverse order they where started in */
- for (i = i - 1; i >= 0; --i)
+ if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session_data))
{
- if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]);
+ mali_mmu_pagedir_free(session_data->page_directory);
+ _mali_osk_notification_queue_term(session_data->ioctl_queue);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
- _mali_osk_notification_queue_term(session_data->ioctl_queue);
- _mali_osk_free(session_data);
+ *context = (void*)session_data;
+
+ /* Add session to the list of all sessions. */
+ mali_session_add(session_data);
- /* return what the subsystem which failed session start returned */
- MALI_ERROR(err);
+ MALI_DEBUG_PRINT(3, ("Session started\n"));
+ MALI_SUCCESS;
}
_mali_osk_errcode_t _mali_ukk_close(void **context)
{
- int i;
- struct mali_session_data * session_data;
-
- MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
+ struct mali_session_data *session;
+ MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
+ session = (struct mali_session_data *)*context;
- session_data = (struct mali_session_data *)*context;
+ MALI_DEBUG_PRINT(3, ("Session ending\n"));
- MALI_DEBUG_PRINT(2, ("Session ending\n"));
-
- /* end subsystem sessions in the reverse order they where started in */
- for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i)
- {
- if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]);
- }
+ /* Remove session from list of all sessions. */
+ mali_session_remove(session);
- _mali_osk_notification_queue_term(session_data->ioctl_queue);
- _mali_osk_free(session_data);
+ /* Abort queued and running jobs */
+ mali_gp_scheduler_abort_session(session);
+ mali_pp_scheduler_abort_session(session);
- *context = NULL;
+ /* Flush pending work.
+ * Needed to make sure all bottom half processing related to this
+ * session has been completed, before we free internal data structures.
+ */
+ _mali_osk_flush_workqueue(NULL);
- MALI_DEBUG_PRINT(2, ("Session has ended\n"));
+ /* Free remaining memory allocated to this session */
+ mali_memory_session_end(session);
- MALI_SUCCESS;
-}
+ /* Free session data structures */
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
-#if USING_MALI_PMM
+ *context = NULL;
-_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only )
-{
- switch( core )
- {
- case MALI_PMM_CORE_GP:
- MALI_CHECK_NO_ERROR(maligp_signal_power_up(queue_only));
- break;
-#if defined USING_MALI400_L2_CACHE
- case MALI_PMM_CORE_L2:
- if( !queue_only )
- {
- /* Enable L2 cache due to power up */
- mali_kernel_l2_cache_do_enable();
+ MALI_DEBUG_PRINT(2, ("Session has ended\n"));
- /* Invalidate the cache on power up */
- MALI_DEBUG_PRINT(5, ("L2 Cache: Invalidate all\n"));
- MALI_CHECK_NO_ERROR(mali_kernel_l2_cache_invalidate_all());
- }
- break;
-#endif
- case MALI_PMM_CORE_PP0:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(0, queue_only));
- break;
- case MALI_PMM_CORE_PP1:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(1, queue_only));
- break;
- case MALI_PMM_CORE_PP2:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(2, queue_only));
- break;
- case MALI_PMM_CORE_PP3:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(3, queue_only));
- break;
- default:
- /* Unknown core */
- MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power up: %d\n", core) );
- MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only )
-{
- switch( core )
- {
- case MALI_PMM_CORE_GP:
- MALI_CHECK_NO_ERROR(maligp_signal_power_down(immediate_only));
- break;
-#if defined USING_MALI400_L2_CACHE
- case MALI_PMM_CORE_L2:
- /* Nothing to do */
- break;
-#endif
- case MALI_PMM_CORE_PP0:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(0, immediate_only));
- break;
- case MALI_PMM_CORE_PP1:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(1, immediate_only));
- break;
- case MALI_PMM_CORE_PP2:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(2, immediate_only));
- break;
- case MALI_PMM_CORE_PP3:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(3, immediate_only));
- break;
- default:
- /* Unknown core */
- MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power down: %d\n", core) );
- MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
- }
-
MALI_SUCCESS;
}
-#endif
-
-
#if MALI_STATE_TRACKING
u32 _mali_kernel_core_dump_state(char* buf, u32 size)
{
- int i, n;
- char *original_buf = buf;
- for (i = 0; i < SUBSYSTEMS_COUNT; ++i)
- {
- if (NULL != subsystems[i]->dump_state)
- {
- n = subsystems[i]->dump_state(buf, size);
- size -= n;
- buf += n;
- }
- }
-#if USING_MALI_PMM
- n = mali_pmm_dump_os_thread_state(buf, size);
- size -= n;
- buf += n;
-#endif
- /* Return number of bytes written to buf */
- return (u32)(buf - original_buf);
+ int n = 0; /* Number of bytes written to buf */
+
+ n += mali_gp_scheduler_dump_state(buf + n, size - n);
+ n += mali_pp_scheduler_dump_state(buf + n, size - n);
+
+ return n;
}
#endif
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_core.h b/driver/src/devicedrv/mali/common/mali_kernel_core.h
index b2fc3f0..0ac967e 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_core.h
+++ b/driver/src/devicedrv/mali/common/mali_kernel_core.h
@@ -13,122 +13,26 @@
#include "mali_osk.h"
-#if USING_MALI_PMM
-#include "mali_ukk.h"
-#include "mali_pmm.h"
-#include "mali_pmm_system.h"
-#endif
+extern int mali_max_job_runtime;
-_mali_osk_errcode_t mali_kernel_constructor( void );
-void mali_kernel_destructor( void );
+typedef enum
+{
+ _MALI_PRODUCT_ID_UNKNOWN,
+ _MALI_PRODUCT_ID_MALI200,
+ _MALI_PRODUCT_ID_MALI300,
+ _MALI_PRODUCT_ID_MALI400,
+ _MALI_PRODUCT_ID_MALI450,
+} _mali_product_id_t;
-/**
- * @brief Tranlate CPU physical to Mali physical addresses.
- *
- * This function is used to convert CPU physical addresses to Mali Physical
- * addresses, such that _mali_ukk_map_external_mem may be used to map them
- * into Mali. This will be used by _mali_ukk_va_to_mali_pa.
- *
- * This function only supports physically contiguous regions.
- *
- * A default implementation is provided, which uses a registered MEM_VALIDATION
- * resource to do a static translation. Only an address range which will lie
- * in the range specified by MEM_VALIDATION will be successfully translated.
- *
- * If a more complex, or non-static translation is required, then the
- * implementor has the following options:
- * - Rewrite this function to provide such a translation
- * - Integrate the provider of the memory with UMP.
- *
- * @param[in,out] phys_base pointer to the page-aligned base address of the
- * physical range to be translated
- *
- * @param[in] size size of the address range to be translated, which must be a
- * multiple of the physical page size.
- *
- * @return on success, _MALI_OSK_ERR_OK and *phys_base is translated. If the
- * cpu physical address range is not in the valid range, then a suitable
- * _mali_osk_errcode_t error.
- *
- */
-_mali_osk_errcode_t mali_kernel_core_translate_cpu_to_mali_phys_range( u32 *phys_base, u32 size );
-
-
-/**
- * @brief Validate a Mali physical address range.
- *
- * This function is used to ensure that an address range passed to
- * _mali_ukk_map_external_mem is allowed to be mapped into Mali.
- *
- * This function only supports physically contiguous regions.
- *
- * A default implementation is provided, which uses a registered MEM_VALIDATION
- * resource to do a static translation. Only an address range which will lie
- * in the range specified by MEM_VALIDATION will be successfully validated.
- *
- * If a more complex, or non-static validation is required, then the
- * implementor has the following options:
- * - Rewrite this function to provide such a validation
- * - Integrate the provider of the memory with UMP.
- *
- * @param phys_base page-aligned base address of the Mali physical range to be
- * validated.
- *
- * @param size size of the address range to be validated, which must be a
- * multiple of the physical page size.
- *
- * @return _MALI_OSK_ERR_OK if the Mali physical range is valid. Otherwise, a
- * suitable _mali_osk_errcode_t error.
- *
- */
-_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size );
+_mali_osk_errcode_t mali_initialize_subsystems(void);
-#if USING_MALI_PMM
-/**
- * @brief Signal a power up on a Mali core.
- *
- * This function flags a core as powered up.
- * For PP and GP cores it calls functions that move the core from a power off
- * queue into the idle queue ready to run jobs. It also tries to schedule any
- * pending jobs to run on it.
- *
- * This function will fail if the core is not powered off - either running or
- * already idle.
- *
- * @param core The PMM core id to power up.
- * @param queue_only When MALI_TRUE only re-queue the core - do not reset.
- *
- * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a
- * suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only );
-
-/**
- * @brief Signal a power down on a Mali core.
- *
- * This function flags a core as powered down.
- * For PP and GP cores it calls functions that move the core from an idle
- * queue into the power off queue.
- *
- * This function will fail if the core is not idle - either running or
- * already powered down.
- *
- * @param core The PMM core id to power up.
- * @param immediate_only Do not set the core to pending power down if it can't
- * power down immediately
- *
- * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a
- * suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only );
+void mali_terminate_subsystems(void);
-#endif
+void mali_kernel_core_wakeup(void);
-/**
- * Flag to indicate whether or not mali_benchmark is turned on.
- */
-extern int mali_benchmark;
+_mali_product_id_t mali_kernel_core_get_product_id(void);
+u32 _mali_kernel_core_dump_state(char* buf, u32 size);
#endif /* __MALI_KERNEL_CORE_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c b/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c
index 2ea2d3d..b9f05ca 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c
+++ b/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.c
@@ -40,11 +40,7 @@ mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int m
map->table = descriptor_table_alloc(init_entries);
if (NULL != map->table)
{
-#if !USING_MMU
- map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 20);
-#else
- map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 116);
-#endif
+ map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP);
if (NULL != map->lock)
{
_mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
@@ -151,15 +147,20 @@ _mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, i
MALI_ERROR(result);
}
-void mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor)
+void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor)
{
+ void *old_value = NULL;
+
_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) )
{
+ old_value = map->table->mappings[descriptor];
map->table->mappings[descriptor] = NULL;
_mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
}
_mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
+
+ return old_value;
}
static mali_descriptor_table * descriptor_table_alloc(int count)
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h b/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h
index b02f16f..82ed94d 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h
+++ b/driver/src/devicedrv/mali/common/mali_kernel_descriptor_mapping.h
@@ -93,7 +93,9 @@ void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (
* For the descriptor to be reused it has to be freed
* @param map The map to free the descriptor from
* @param descriptor The descriptor ID to free
+ *
+ * @return old value of descriptor mapping
*/
-void mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor);
+void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor);
#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c b/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c
deleted file mode 100644
index 7177979..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.c
+++ /dev/null
@@ -1,517 +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_list.h"
-
-#include "mali_kernel_core.h"
-#include "mali_kernel_pp.h"
-#include "mali_kernel_subsystem.h"
-#include "regs/mali_200_regs.h"
-#include "mali_kernel_rendercore.h"
-#include "mali_kernel_l2_cache.h"
-
-/**
- * Size of the Mali L2 cache registers in bytes
- */
-#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30
-
-/**
- * Mali L2 cache register numbers
- * Used in the register read/write routines.
- * See the hardware documentation for more information about each register
- */
-typedef enum mali_l2_cache_register {
- MALI400_L2_CACHE_REGISTER_STATUS = 0x0002,
- /*unused = 0x0003 */
- MALI400_L2_CACHE_REGISTER_COMMAND = 0x0004, /**< Misc cache commands, e.g. clear */
- MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0005,
- MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0006, /**< Limit of outstanding read requests */
- MALI400_L2_CACHE_REGISTER_ENABLE = 0x0007, /**< Enable misc cache features */
- MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0008,
- MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0009,
- MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x000A,
- MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x000B,
-} mali_l2_cache_register;
-
-
-/**
- * Mali L2 cache commands
- * These are the commands that can be sent to the Mali L2 cache unit
- */
-typedef enum mali_l2_cache_command
-{
- MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */
- /* Read HW TRM carefully before adding/using other commands than the clear above */
-} mali_l2_cache_command;
-
-/**
- * Mali L2 cache commands
- * These are the commands that can be sent to the Mali L2 cache unit
- */
-typedef enum mali_l2_cache_enable
-{
- MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */
- MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */
- MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */
-} mali_l2_cache_enable;
-
-/**
- * Mali L2 cache status bits
- */
-typedef enum mali_l2_cache_status
-{
- MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */
- MALI400_L2_CACHE_STATUS_DATA_BUSY = 0x02, /**< L2 cache is busy handling data requests */
-} mali_l2_cache_status;
-
-
-/**
- * Definition of the L2 cache core struct
- * Used to track a L2 cache unit in the system.
- * Contains information about the mapping of the registers
- */
-typedef struct mali_kernel_l2_cache_core
-{
- unsigned long base; /**< Physical address of the registers */
- mali_io_address mapped_registers; /**< Virtual mapping of the registers */
- u32 mapping_size; /**< Size of registers in bytes */
- _mali_osk_list_t list; /**< Used to link multiple cache cores into a list */
- _mali_osk_lock_t *lock; /**< Serialize all L2 cache commands */
-} mali_kernel_l2_cache_core;
-
-
-#define MALI400_L2_MAX_READS_DEFAULT 0x1C
-
-int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT;
-
-
-/**
- * Mali L2 cache subsystem startup function
- * Called by the driver core when the driver is loaded.
- *
- * @param id Identifier assigned by the core to the L2 cache subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_l2_cache_initialize(mali_kernel_subsystem_identifier id);
-
-/**
- * Mali L2 cache subsystem shutdown function
- * Called by the driver core when the driver is unloaded.
- * Cleans up
- * @param id Identifier assigned by the core to the L2 cache subsystem
- */
-static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id);
-
-/**
- * L2 cache subsystem complete notification function.
- * Called by the driver core when all drivers have loaded and all resources has been registered
- * @param id Identifier assigned by the core to the L2 cache subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_l2_cache_load_complete(mali_kernel_subsystem_identifier id);
-
-/**
- * Mali L2 cache subsystem's notification handler for a Mali L2 cache resource instances.
- * Registered with the core during startup.
- * Called by the core for each Mali L2 cache described in the active architecture's config.h file.
- * @param resource The resource to handle (type MALI400L2)
- * @return 0 if the Mali L2 cache was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_l2_cache_core_create(_mali_osk_resource_t * resource);
-
-/**
- * Write to a L2 cache register
- * Writes the given value to the specified register
- * @param unit The L2 cache to write to
- * @param reg The register to write to
- * @param val The value to write to the register
- */
-static void mali_l2_cache_register_write(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg, u32 val);
-
-
-
-/**
- * Invalidate specified L2 cache
- * @param cache The L2 cache to invalidate
- * @return 0 if Mali L2 cache was successfully invalidated, otherwise error
- */
-static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all_cache(mali_kernel_l2_cache_core *cache);
-
-
-/*
- The fixed Mali L2 cache system's mali subsystem interface implementation.
- We currently handle module and session life-time management.
-*/
-struct mali_kernel_subsystem mali_subsystem_l2_cache =
-{
- mali_l2_cache_initialize, /**< startup */
- mali_l2_cache_terminate, /**< shutdown */
- mali_l2_cache_load_complete, /**< load_complete */
- NULL, /**< system_info_fill */
- NULL, /**< session_begin */
- NULL, /**< session_end */
- NULL, /**< broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /**< dump_state */
-#endif
-};
-
-
-
-static _MALI_OSK_LIST_HEAD(caches_head);
-
-
-
-
-/* called during module init */
-static _mali_osk_errcode_t mali_l2_cache_initialize(mali_kernel_subsystem_identifier id)
-{
- _mali_osk_errcode_t err;
-
- MALI_IGNORE( id );
-
- MALI_DEBUG_PRINT(2, ( "Mali L2 cache system initializing\n"));
-
- _MALI_OSK_INIT_LIST_HEAD(&caches_head);
-
- /* This will register the function for adding Mali L2 cache cores to the subsystem */
- err = _mali_kernel_core_register_resource_handler(MALI400L2, mali_l2_cache_core_create);
-
- MALI_ERROR(err);
-}
-
-
-
-/* called if/when our module is unloaded */
-static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- MALI_DEBUG_PRINT(2, ( "Mali L2 cache system terminating\n"));
-
- /* loop over all L2 cache units and shut them down */
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list )
- {
- /* reset to defaults */
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT);
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT);
-
- /* remove from the list of cacges on the system */
- _mali_osk_list_del( &cache->list );
-
- /* release resources */
- _mali_osk_mem_unmapioregion( cache->base, cache->mapping_size, cache->mapped_registers );
- _mali_osk_mem_unreqregion( cache->base, cache->mapping_size );
- _mali_osk_lock_term( cache->lock );
- _mali_osk_free( cache );
-
- #if USING_MALI_PMM
- /* Unregister the L2 cache with the PMM */
- malipmm_core_unregister( MALI_PMM_CORE_L2 );
- #endif
- }
-}
-
-static _mali_osk_errcode_t mali_l2_cache_core_create(_mali_osk_resource_t * resource)
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT ;
- mali_kernel_l2_cache_core * cache = NULL;
-
- MALI_DEBUG_PRINT(2, ( "Creating Mali L2 cache: %s\n", resource->description));
-
-#if USING_MALI_PMM
- /* Register the L2 cache with the PMM */
- err = malipmm_core_register( MALI_PMM_CORE_L2 );
- if( _MALI_OSK_ERR_OK != err )
- {
- MALI_DEBUG_PRINT(1, ( "Failed to register L2 cache unit with PMM"));
- return err;
- }
-#endif
-
- err = _mali_osk_mem_reqregion( resource->base, MALI400_L2_CACHE_REGISTERS_SIZE, resource->description);
-
- MALI_CHECK_GOTO( _MALI_OSK_ERR_OK == err, err_cleanup_requestmem_failed);
-
- /* Reset error that might be passed out */
- err = _MALI_OSK_ERR_FAULT;
-
- cache = _mali_osk_malloc(sizeof(mali_kernel_l2_cache_core));
-
- MALI_CHECK_GOTO( NULL != cache, err_cleanup);
-
- cache->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 104 );
-
- MALI_CHECK_GOTO( NULL != cache->lock, err_cleanup);
-
- /* basic setup */
- _MALI_OSK_INIT_LIST_HEAD(&cache->list);
-
- cache->base = resource->base;
- cache->mapping_size = MALI400_L2_CACHE_REGISTERS_SIZE;
-
- /* map the registers */
- cache->mapped_registers = _mali_osk_mem_mapioregion( cache->base, cache->mapping_size, resource->description );
-
- MALI_CHECK_GOTO( NULL != cache->mapped_registers, err_cleanup);
-
- /* Invalidate cache (just to keep it in a known state at startup) */
- err = mali_kernel_l2_cache_invalidate_all_cache(cache);
-
- MALI_CHECK_GOTO( _MALI_OSK_ERR_OK == err, err_cleanup);
-
- /* add to our list of L2 caches */
- _mali_osk_list_add( &cache->list, &caches_head );
-
- MALI_SUCCESS;
-
-err_cleanup:
- /* This cleanup used when resources have been requested successfully */
-
- if ( NULL != cache )
- {
- if (NULL != cache->mapped_registers)
- {
- _mali_osk_mem_unmapioregion( cache->base, cache->mapping_size, cache->mapped_registers);
- }
- else
- {
- MALI_DEBUG_PRINT(1, ( "Failed to map Mali L2 cache registers at 0x%08lX\n", cache->base));
- }
-
- if( NULL != cache->lock )
- {
- _mali_osk_lock_term( cache->lock );
- }
- else
- {
- MALI_DEBUG_PRINT(1, ( "Failed to allocate a lock for handling a L2 cache unit"));
- }
-
- _mali_osk_free( cache );
- }
- else
- {
- MALI_DEBUG_PRINT(1, ( "Failed to allocate memory for handling a L2 cache unit"));
- }
-
- /* A call is to request region, so this must always be reversed */
- _mali_osk_mem_unreqregion( resource->base, MALI400_L2_CACHE_REGISTERS_SIZE);
-#if USING_MALI_PMM
- malipmm_core_unregister( MALI_PMM_CORE_L2 );
-#endif
- return err;
-
-err_cleanup_requestmem_failed:
- MALI_DEBUG_PRINT(1, ("Failed to request Mali L2 cache '%s' register address space at (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + MALI400_L2_CACHE_REGISTERS_SIZE - 1) );
-#if USING_MALI_PMM
- malipmm_core_unregister( MALI_PMM_CORE_L2 );
-#endif
- return err;
-
-}
-
-
-static void mali_l2_cache_register_write(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg, u32 val)
-{
- _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val);
-}
-
-
-static u32 mali_l2_cache_register_read(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg)
-{
- return _mali_osk_mem_ioread32(unit->mapped_registers, (u32)reg * sizeof(u32));
-}
-
-void mali_kernel_l2_cache_do_enable(void)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- /* loop over all L2 cache units and enable them*/
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads);
- }
-}
-
-
-static _mali_osk_errcode_t mali_l2_cache_load_complete(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_l2_cache_do_enable();
- MALI_DEBUG_PRINT(2, ( "Mali L2 cache system load complete\n"));
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_kernel_l2_cache_send_command(mali_kernel_l2_cache_core *cache, u32 reg, u32 val)
-{
- int i = 0;
- const int loop_count = 100000;
-
- /*
- * Grab lock in order to send commands to the L2 cache in a serialized fashion.
- * The L2 cache will ignore commands if it is busy.
- */
- _mali_osk_lock_wait(cache->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* First, wait for L2 cache command handler to go idle */
-
- for (i = 0; i < loop_count; i++)
- {
- if (!(_mali_osk_mem_ioread32(cache->mapped_registers , (u32)MALI400_L2_CACHE_REGISTER_STATUS * sizeof(u32)) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY))
- {
- break;
- }
- }
-
- if (i == loop_count)
- {
- _mali_osk_lock_signal(cache->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n"));
- MALI_ERROR( _MALI_OSK_ERR_FAULT );
- }
-
- /* then issue the command */
- mali_l2_cache_register_write(cache, reg, val);
-
- _mali_osk_lock_signal(cache->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_SUCCESS;
-}
-
-
-static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all_cache(mali_kernel_l2_cache_core *cache)
-{
- return mali_kernel_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
-}
-
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all(void)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- /* loop over all L2 cache units and invalidate them */
-
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- MALI_CHECK_NO_ERROR( mali_kernel_l2_cache_invalidate_all_cache(cache) );
- }
-
- MALI_SUCCESS;
-}
-
-
-static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page_cache(mali_kernel_l2_cache_core *cache, u32 page)
-{
- return mali_kernel_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, page);
-}
-
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page(u32 page)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- /* loop over all L2 cache units and invalidate them */
-
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- MALI_CHECK_NO_ERROR( mali_kernel_l2_cache_invalidate_page_cache(cache, page) );
- }
-
- MALI_SUCCESS;
-}
-
-
-void mali_kernel_l2_cache_set_perf_counters(u32 src0, u32 src1, int force_reset)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
- int reset0 = force_reset;
- int reset1 = force_reset;
- MALI_DEBUG_CODE(
- int changed0 = 0;
- int changed1 = 0;
- )
-
- /* loop over all L2 cache units and activate the counters on them */
- _MALI_OSK_LIST_FOREACHENTRY(cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- u32 cur_src0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0);
- u32 cur_src1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1);
-
- if (src0 != cur_src0)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, src0);
- MALI_DEBUG_CODE(changed0 = 1;)
- reset0 = 1;
- }
-
- if (src1 != cur_src1)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, src1);
- MALI_DEBUG_CODE(changed1 = 1;)
- reset1 = 1;
- }
-
- if (reset0)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0, 0);
- }
-
- if (reset1)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1, 0);
- }
-
- MALI_DEBUG_PRINT(5, ("L2 cache counters set: SRC0=%u, CHANGED0=%d, RESET0=%d, SRC1=%u, CHANGED1=%d, RESET1=%d\n",
- src0, changed0, reset0,
- src1, changed1, reset1));
- }
-}
-
-
-void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
- int first_time = 1;
- *src0 = 0;
- *src1 = 0;
- *val0 = 0;
- *val1 = 0;
-
- /* loop over all L2 cache units and read the counters */
- _MALI_OSK_LIST_FOREACHENTRY(cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- u32 cur_src0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0);
- u32 cur_src1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1);
- u32 cur_val0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
- u32 cur_val1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
-
- MALI_DEBUG_PRINT(5, ("L2 cache counters get: SRC0=%u, VAL0=%u, SRC1=%u, VAL1=%u\n", cur_src0, cur_val0, cur_src1, cur_val1));
-
- /* Only update the counter source once, with the value from the first L2 cache unit. */
- if (first_time)
- {
- *src0 = cur_src0;
- *src1 = cur_src1;
- first_time = 0;
- }
-
- /* Bail out if the L2 cache units have different counters set. */
- if (*src0 == cur_src0 && *src1 == cur_src1)
- {
- *val0 += cur_val0;
- *val1 += cur_val1;
- }
- else
- {
- MALI_DEBUG_PRINT(1, ("Warning: Mali L2 caches has different performance counters set, not retrieving data\n"));
- }
- }
-}
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.h b/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.h
deleted file mode 100644
index 1588850..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_l2_cache.h
+++ /dev/null
@@ -1,25 +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.
- */
-
-#ifndef __MALI_KERNEL_L2_CACHE_H__
-#define __MALI_KERNEL_L2_CACHE_H__
-
-#include "mali_osk.h"
-#include "mali_kernel_subsystem.h"
-extern struct mali_kernel_subsystem mali_subsystem_l2_cache;
-
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all(void);
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page(u32 page);
-
-void mali_kernel_l2_cache_do_enable(void);
-void mali_kernel_l2_cache_set_perf_counters(u32 src0, u32 src1, int force_reset);
-void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1);
-
-#endif /* __MALI_KERNEL_L2_CACHE_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c b/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c
deleted file mode 100644
index 49190db..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_mem_buddy.c
+++ /dev/null
@@ -1,1426 +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_core.h"
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_mem.h"
-#include "mali_kernel_descriptor_mapping.h"
-#include "mali_kernel_session_manager.h"
-
-/* kernel side OS functions and user-kernel interface */
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_osk_list.h"
-#include "mali_ukk.h"
-
-#ifdef _MALI_OSK_SPECIFIC_INDIRECT_MMAP
-#include "mali_osk_indir_mmap.h"
-#endif
-
-#error Support for non-MMU builds is no longer supported and is planned for removal.
-
-/**
- * Minimum memory allocation size
- */
-#define MIN_BLOCK_SIZE (1024*1024UL)
-
-/**
- * Per-session memory descriptor mapping table sizes
- */
-#define MALI_MEM_DESCRIPTORS_INIT 64
-#define MALI_MEM_DESCRIPTORS_MAX 4096
-
-/**
- * Enum uses to store multiple fields in one u32 to keep the memory block struct small
- */
-enum MISC_SHIFT { MISC_SHIFT_FREE = 0, MISC_SHIFT_ORDER = 1, MISC_SHIFT_TOPLEVEL = 6 };
-enum MISC_MASK { MISC_MASK_FREE = 0x01, MISC_MASK_ORDER = 0x1F, MISC_MASK_TOPLEVEL = 0x1F };
-
-/* forward declaration of the block struct */
-struct mali_memory_block;
-
-/**
- * Definition of memory bank type.
- * Represents a memory bank (separate address space)
- * Each bank keeps track of its block usage.
- * A buddy system used to track the usage
-*/
-typedef struct mali_memory_bank
-{
- _mali_osk_list_t list; /* links multiple banks together */
- _mali_osk_lock_t *lock;
- u32 base_addr; /* Mali seen address of bank */
- u32 cpu_usage_adjust; /* Adjustment factor for what the CPU sees */
- u32 size; /* the effective size */
- u32 real_size; /* the real size of the bank, as given by to the subsystem */
- int min_order;
- int max_order;
- struct mali_memory_block * blocklist;
- _mali_osk_list_t *freelist;
- _mali_osk_atomic_t num_active_allocations;
- u32 used_for_flags;
- u32 alloc_order; /**< Order in which the bank will be used for allocations */
- const char *name; /**< Descriptive name of the bank */
-} mali_memory_bank;
-
-/**
- * Definition of the memory block type
- * Represents a memory block, which is the smallest memory unit operated on.
- * A block keeps info about its mapping, if in use by a user process
- */
-typedef struct mali_memory_block
-{
- _mali_osk_list_t link; /* used for freelist and process usage list*/
- mali_memory_bank * bank; /* the bank it belongs to */
- void __user * mapping; /* possible user space mapping of this block */
- u32 misc; /* used while a block is free to track the number blocks it represents */
- int descriptor;
- u32 mmap_cookie; /**< necessary for interaction with _mali_ukk_mem_mmap/munmap */
-} mali_memory_block;
-
-/**
- * Defintion of the type used to represent memory used by a session.
- * Containts the head of the list of memory currently in use by a session.
- */
-typedef struct memory_session
-{
- _mali_osk_lock_t *lock;
- _mali_osk_list_t memory_head; /* List of the memory blocks used by this session. */
- mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
-} memory_session;
-
-/*
- Subsystem interface implementation
-*/
-/**
- * Buddy block memory subsystem startup function
- * Called by the driver core when the driver is loaded.
- * Registers the memory systems ioctl handler, resource handlers and memory map function with the core.
- *
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id);
-
-/**
- * Buddy block memory subsystem shutdown function
- * Called by the driver core when the driver is unloaded.
- * Cleans up
- * @param id Identifier assigned by the core to the memory subsystem
- */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id);
-
-/**
- * Buddy block memory load complete notification function.
- * Called by the driver core when all drivers have loaded and all resources has been registered
- * Reports on the memory resources registered
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id);
-
-
-/**
- * Buddy block memory subsystem session begin notification
- * Called by the core when a new session to the driver is started.
- * Creates a memory session object and sets it as the subsystem slot data for this session
- * @param slot Pointer to the slot to use for storing per-session data
- * @param queue The user space event sink
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-
-/**
- * Buddy block memory subsystem session end notification
- * Called by the core when a session to the driver has ended.
- * Cleans up per session data, which includes checking and fixing memory leaks
- *
- * @param slot Pointer to the slot to use for storing per-session data
- */
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-
-/**
- * Buddy block memory subsystem system info filler
- * Called by the core when a system info update is needed
- * We fill in info about all the memory types we have
- * @param info Pointer to system info struct to update
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info);
-
-/* our registered resource handlers */
-/**
- * Buddy block memory subsystem's notification handler for MEMORY resource instances.
- * Registered with the core during startup.
- * Called by the core for each memory bank described in the active architecture's config.h file.
- * Requests memory region ownership and calls backend.
- * @param resource The resource to handle (type MEMORY)
- * @return 0 if the memory was claimed and accepted, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_memory(_mali_osk_resource_t * resource);
-
-/**
- * Buddy block memory subsystem's notification handler for MMU resource instances.
- * Registered with the core during startup.
- * Called by the core for each mmu described in the active architecture's config.h file.
- * @param resource The resource to handle (type MMU)
- * @return 0 if the MMU was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource);
-
-/**
- * Buddy block memory subsystem's notification handler for FPGA_FRAMEWORK resource instances.
- * Registered with the core during startup.
- * Called by the core for each fpga framework described in the active architecture's config.h file.
- * @param resource The resource to handle (type FPGA_FRAMEWORK)
- * @return 0 if the FPGA framework was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource);
-
-/* ioctl command implementations */
-/**
- * Buddy block memory subsystem's handler for MALI_IOC_MEM_GET_BIG_BLOCK ioctl
- * Called by the generic ioctl handler when the MALI_IOC_MEM_GET_BIG_BLOCK command is received.
- * Finds an available memory block and maps into the current process' address space.
- * @param ukk_private private word for use by the User/Kernel interface
- * @param session_data Pointer to the per-session object which will track the memory usage
- * @param argument The argument from the user. A pointer to an struct mali_dd_get_big_block in user space
- * @return Zero if successful, a standard Linux error value value on error (a negative value)
- */
-_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args );
-
-/**
- * Buddy block memory subsystem's handler for MALI_IOC_MEM_FREE_BIG_BLOCK ioctl
- * Called by the generic ioctl handler when the MALI_IOC_MEM_FREE_BIG_BLOCK command is received.
- * Unmaps the memory from the process' address space and marks the block as free.
- * @param session_data Pointer to the per-session object which tracks the memory usage
- * @param argument The argument from the user. A pointer to an struct mali_dd_get_big_block in user space
- * @return Zero if successful, a standard Linux error value value on error (a negative value)
- */
-
-/* this static version allows us to make use of it while holding the memory_session lock.
- * This is required for the session_end code */
-static _mali_osk_errcode_t _mali_ukk_free_big_block_internal( struct mali_session_data * mali_session_data, memory_session * session_data, _mali_uk_free_big_block_s *args);
-
-_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args );
-
-/**
- * Buddy block memory subsystem's memory bank registration routine
- * Called when a MEMORY resource has been found.
- * The memory region has already been reserved for use by this driver.
- * Create a bank object to represent this region and initialize its slots.
- * @note Can only be called in an module atomic scope, i.e. during module init since no locking is performed
- * @param phys_base Physical base address of this bank
- * @param cpu_usage_adjust Adjustment factor for CPU seen address
- * @param size Size of the bank in bytes
- * @param flags Memory type bits
- * @param alloc_order Order in which the bank will be used for allocations
- * @param name descriptive name of the bank
- * @return Zero on success, negative on error
- */
-static int mali_memory_bank_register(u32 phys_base, u32 cpu_usage_adjust, u32 size, u32 flags, u32 alloc_order, const char *name);
-
-/**
- * Get a block of mali memory of at least the given size and of the given type
- * This is the backend for get_big_block.
- * @param type_id The type id of memory requested.
- * @param minimum_size The size requested
- * @return Pointer to a block on success, NULL on failure
- */
-static mali_memory_block * mali_memory_block_get(u32 type_id, u32 minimum_size);
-
-/**
- * Get the mali seen address of the memory described by the block
- * @param block The memory block to return the address of
- * @return The mali seen address of the memory block
- */
-MALI_STATIC_INLINE u32 block_mali_addr_get(mali_memory_block * block);
-
-/**
- * Get the cpu seen address of the memory described by the block
- * The cpu_usage_adjust will be used to change the mali seen phys address
- * @param block The memory block to return the address of
- * @return The mali seen address of the memory block
- */
-MALI_STATIC_INLINE u32 block_cpu_addr_get(mali_memory_block * block);
-
-/**
- * Get the size of the memory described by the given block
- * @param block The memory block to return the size of
- * @return The size of the memory block described by the object
- */
-MALI_STATIC_INLINE u32 block_size_get(mali_memory_block * block);
-
-/**
- * Get the user space accessible mapping the memory described by the given memory block
- * Returns a pointer in user space to the memory, if one has been created.
- * @param block The memory block to return the mapping of
- * @return User space pointer to cpu accessible memory or NULL if not mapped
- */
-MALI_STATIC_INLINE void __user * block_mapping_get(mali_memory_block * block);
-
-/**
- * Set the user space accessible mapping the memory described by the given memory block.
- * Sets the stored pointer to user space for the memory described by this block.
- * @param block The memory block to set mapping info for
- * @param ptr User space pointer to cpu accessible memory or NULL if not mapped
- */
-MALI_STATIC_INLINE void block_mapping_set(mali_memory_block * block, void __user * ptr);
-
-/**
- * Get the cookie for use with _mali_ukk_mem_munmap().
- * @param block The memory block to get the cookie from
- * @return the cookie. A return of 0 is still a valid cookie.
- */
-MALI_STATIC_INLINE u32 block_mmap_cookie_get(mali_memory_block * block);
-
-/**
- * Set the cookie returned via _mali_ukk_mem_mmap().
- * @param block The memory block to set the cookie for
- * @param cookie the cookie
- */
-MALI_STATIC_INLINE void block_mmap_cookie_set(mali_memory_block * block, u32 cookie);
-
-
-/**
- * Get a memory block's free status
- * @param block The block to get the state of
- */
-MALI_STATIC_INLINE u32 get_block_free(mali_memory_block * block);
-
-/**
- * Set a memory block's free status
- * @param block The block to set the state for
- * @param state The state to set
- */
-MALI_STATIC_INLINE void set_block_free(mali_memory_block * block, int state);
-
-/**
- * Set a memory block's order
- * @param block The block to set the order for
- * @param order The order to set
- */
-MALI_STATIC_INLINE void set_block_order(mali_memory_block * block, u32 order);
-
-/**
- * Get a memory block's order
- * @param block The block to get the order for
- * @return The order this block exists on
- */
-MALI_STATIC_INLINE u32 get_block_order(mali_memory_block * block);
-
-/**
- * Tag a block as being a toplevel block.
- * A toplevel block has no buddy and no parent
- * @param block The block to tag as being toplevel
- */
-MALI_STATIC_INLINE void set_block_toplevel(mali_memory_block * block, u32 level);
-
-/**
- * Check if a block is a toplevel block
- * @param block The block to check
- * @return 1 if toplevel, 0 else
- */
-MALI_STATIC_INLINE u32 get_block_toplevel(mali_memory_block * block);
-
-/**
- * Checks if the given block is a buddy at the given order and that it's free
- * @param block The block to check
- * @param order The order to check against
- * @return 0 if not valid, else 1
- */
-MALI_STATIC_INLINE int block_is_valid_buddy(mali_memory_block * block, int order);
-
-/*
- The buddy system uses the following rules to quickly find a blocks buddy
- and parent (block representing this block at a higher order level):
- - Given a block with index i the blocks buddy is at index i ^ ( 1 << order)
- - Given a block with index i the blocks parent is at i & ~(1 << order)
-*/
-
-/**
- * Get a blocks buddy
- * @param block The block to find the buddy for
- * @param order The order to operate on
- * @return Pointer to the buddy block
- */
-MALI_STATIC_INLINE mali_memory_block * block_get_buddy(mali_memory_block * block, u32 order);
-
-/**
- * Get a blocks parent
- * @param block The block to find the parent for
- * @param order The order to operate on
- * @return Pointer to the parent block
- */
-MALI_STATIC_INLINE mali_memory_block * block_get_parent(mali_memory_block * block, u32 order);
-
-/**
- * Release mali memory
- * Backend for free_big_block.
- * Will release the mali memory described by the given block struct.
- * @param block Memory block to free
- */
-static void block_release(mali_memory_block * block);
-
-/* end interface implementation */
-
-/**
- * List of all the memory banks registerd with the subsystem.
- * Access to this list is NOT synchronized since it's only
- * written to during module init and termination.
- */
-static _MALI_OSK_LIST_HEAD(memory_banks_list);
-
-/*
- The buddy memory system's mali subsystem interface implementation.
- We currently handle module and session life-time management.
-*/
-struct mali_kernel_subsystem mali_subsystem_memory =
-{
- mali_memory_core_initialize, /* startup */
- mali_memory_core_terminate, /* shutdown */
- mali_memory_core_load_complete, /* load_complete */
- mali_memory_core_system_info_fill, /* system_info_fill */
- mali_memory_core_session_begin, /* session_begin */
- mali_memory_core_session_end, /* session_end */
- NULL, /* broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-};
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_memory_id = -1;
-
-/* called during module init */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id)
-{
- _MALI_OSK_INIT_LIST_HEAD(&memory_banks_list);
-
- mali_subsystem_memory_id = id;
-
- /* register our handlers */
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MEMORY, mali_memory_core_resource_memory));
-
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MMU, mali_memory_core_resource_mmu));
-
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(FPGA_FRAMEWORK, mali_memory_core_resource_fpga));
-
- MALI_SUCCESS;
-}
-
-/* called if/when our module is unloaded */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id)
-{
- mali_memory_bank * bank, *temp;
-
- /* loop over all memory banks to free them */
- /* we use the safe version since we delete the current bank in the body */
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- MALI_DEBUG_CODE(int usage_count = _mali_osk_atomic_read(&bank->num_active_allocations));
- /*
- Report leaked memory
- */
- MALI_DEBUG_PRINT_IF(1, 0 != usage_count, ("%d allocation(s) from memory bank at 0x%X still in use\n", usage_count, bank->base_addr));
-
- _mali_osk_atomic_term(&bank->num_active_allocations);
-
- _mali_osk_lock_term(bank->lock);
-
- /* unlink from bank list */
- _mali_osk_list_del(&bank->list);
-
- /* release kernel resources used by the bank */
- _mali_osk_mem_unreqregion(bank->base_addr, bank->real_size);
-
- /* remove all resources used to represent this bank*/
- _mali_osk_free(bank->freelist);
- _mali_osk_free(bank->blocklist);
-
- /* destroy the bank object itself */
- _mali_osk_free(bank);
- }
-
- /* No need to de-initialize mali_subsystem_memory_id - it could only be
- * re-initialized to the same value */
-}
-
-/* load_complete handler */
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id)
-{
- mali_memory_bank * bank, *temp;
-
- MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest number first) :\n"));
-
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- if ( NULL != bank->name )
- {
- MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", bank->alloc_order, bank->name) );
- }
- else
- {
- MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", bank->alloc_order ) );
- }
- }
- MALI_SUCCESS;
-}
-
-MALI_STATIC_INLINE u32 order_needed_for_size(u32 size, struct mali_memory_bank * bank)
-{
- u32 order = 0;
-
- if (0 < size)
- {
- for ( order = sizeof(u32)*8 - 1; ((1UL<<order) & size) == 0; --order)
- /* nothing */;
-
- /* check if size is pow2, if not we need increment order by one */
- if (0 != (size & ((1UL<<order)-1))) ++order;
- }
-
- if ((NULL != bank) && (order < bank->min_order)) order = bank->min_order;
- /* Not capped to max order, that doesn't make sense */
-
- return order;
-}
-
-MALI_STATIC_INLINE u32 maximum_order_which_fits(u32 size)
-{
- u32 order = 0;
- u32 powsize = 1;
- while (powsize < size)
- {
- powsize <<= 1;
- if (powsize > size) break;
- order++;
- }
-
- return order;
-}
-
-/* called for new MEMORY resources */
-static _mali_osk_errcode_t mali_memory_bank_register(u32 phys_base, u32 cpu_usage_adjust, u32 size, u32 flags, u32 alloc_order, const char *name)
-{
- /* no locking performed due to function contract */
- int i;
- u32 left, offset;
- mali_memory_bank * bank;
- mali_memory_bank * bank_enum, *temp;
-
- _mali_osk_errcode_t err;
-
- /* Only a multiple of MIN_BLOCK_SIZE is usable */
- u32 usable_size = size & ~(MIN_BLOCK_SIZE - 1);
-
- /* handle zero sized banks and bank smaller than the fixed block size */
- if (0 == usable_size)
- {
- MALI_PRINT(("Usable size == 0\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- /* warn for banks not a muliple of the block size */
- MALI_DEBUG_PRINT_IF(1, usable_size != size, ("Memory bank @ 0x%X not a multiple of minimum block size. %d bytes wasted\n", phys_base, size - usable_size));
-
- /* check against previous registrations */
- MALI_DEBUG_CODE(
- {
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- /* duplicate ? */
- if (bank->base_addr == phys_base)
- {
- MALI_PRINT(("Duplicate registration of a memory bank at 0x%X detected\n", phys_base));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- /* overlapping ? */
- else if (
- ( (phys_base > bank->base_addr) && (phys_base < (bank->base_addr + bank->real_size)) ) ||
- ( (phys_base + size) > bank->base_addr && ((phys_base + size) < (bank->base_addr + bank->real_size)) )
- )
- {
- MALI_PRINT(("Overlapping memory blocks found. Memory at 0x%X overlaps with memory at 0x%X size 0x%X\n", bank->base_addr, phys_base, size));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- }
- }
- );
-
- /* create an object to represent this memory bank */
- MALI_CHECK_NON_NULL(bank = (mali_memory_bank*)_mali_osk_malloc(sizeof(mali_memory_bank)), _MALI_OSK_ERR_NOMEM);
-
- /* init the fields */
- _MALI_OSK_INIT_LIST_HEAD(&bank->list);
- bank->base_addr = phys_base;
- bank->cpu_usage_adjust = cpu_usage_adjust;
- bank->size = usable_size;
- bank->real_size = size;
- bank->alloc_order = alloc_order;
- bank->name = name;
-
- err = _mali_osk_atomic_init(&bank->num_active_allocations, 0);
- if (err != _MALI_OSK_ERR_OK)
- {
- _mali_osk_free(bank);
- MALI_ERROR(err);
- }
-
- bank->used_for_flags = flags;
- bank->min_order = order_needed_for_size(MIN_BLOCK_SIZE, NULL);
- bank->max_order = maximum_order_which_fits(usable_size);
- bank->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0);
- if (NULL == bank->lock)
- {
- _mali_osk_atomic_term(&bank->num_active_allocations);
- _mali_osk_free(bank);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- bank->blocklist = _mali_osk_calloc(1, sizeof(struct mali_memory_block) * (usable_size / MIN_BLOCK_SIZE));
- if (NULL == bank->blocklist)
- {
- _mali_osk_lock_term(bank->lock);
- _mali_osk_atomic_term(&bank->num_active_allocations);
- _mali_osk_free(bank);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- for (i = 0; i < (usable_size / MIN_BLOCK_SIZE); i++)
- {
- bank->blocklist[i].bank = bank;
- }
-
- bank->freelist = _mali_osk_calloc(1, sizeof(_mali_osk_list_t) * (bank->max_order - bank->min_order + 1));
- if (NULL == bank->freelist)
- {
- _mali_osk_lock_term(bank->lock);
- _mali_osk_free(bank->blocklist);
- _mali_osk_atomic_term(&bank->num_active_allocations);
- _mali_osk_free(bank);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- for (i = 0; i < (bank->max_order - bank->min_order + 1); i++) _MALI_OSK_INIT_LIST_HEAD(&bank->freelist[i]);
-
- /* init slot info */
- for (offset = 0, left = usable_size; offset < (usable_size / MIN_BLOCK_SIZE); /* updated inside the body */)
- {
- u32 block_order;
- mali_memory_block * block;
-
- /* the maximum order which fits in the remaining area */
- block_order = maximum_order_which_fits(left);
-
- /* find the block pointer */
- block = &bank->blocklist[offset];
-
- /* tag the block as being toplevel */
- set_block_toplevel(block, block_order);
-
- /* tag it as being free */
- set_block_free(block, 1);
-
- /* set the order */
- set_block_order(block, block_order);
-
- _mali_osk_list_addtail(&block->link, bank->freelist + (block_order - bank->min_order));
-
- left -= (1 << block_order);
- offset += ((1 << block_order) / MIN_BLOCK_SIZE);
- }
-
- /* add bank to list of banks on the system */
- _MALI_OSK_LIST_FOREACHENTRY( bank_enum, temp, &memory_banks_list, mali_memory_bank, list )
- {
- if ( bank_enum->alloc_order >= alloc_order )
- {
- /* Found insertion point - our item must go before this one */
- break;
- }
- }
- _mali_osk_list_addtail(&bank->list, &bank_enum->list);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_memory_mmu_register(u32 type, u32 phys_base)
-{
- /* not supported */
- return _MALI_OSK_ERR_INVALID_FUNC;
-}
-
-void mali_memory_mmu_unregister(u32 phys_base)
-{
- /* not supported */
- return;
-}
-
-static mali_memory_block * mali_memory_block_get(u32 type_id, u32 minimum_size)
-{
- mali_memory_bank * bank;
- mali_memory_block * block = NULL;
- u32 requested_order, current_order;
-
- /* input validation */
- if (0 == minimum_size)
- {
- /* bad size */
- MALI_DEBUG_PRINT(2, ("Zero size block requested by mali_memory_block_get\n"));
- return NULL;
- }
-
- bank = (mali_memory_bank*)type_id;
-
- requested_order = order_needed_for_size(minimum_size, bank);
-
- MALI_DEBUG_PRINT(4, ("For size %d we need order %d (%d)\n", minimum_size, requested_order, 1 << requested_order));
-
- _mali_osk_lock_wait(bank->lock, _MALI_OSK_LOCKMODE_RW);
- /* ! critical section begin */
-
- MALI_DEBUG_PRINT(7, ("Bank 0x%x locked\n", bank));
-
- for (current_order = requested_order; current_order <= bank->max_order; ++current_order)
- {
- _mali_osk_list_t * list = bank->freelist + (current_order - bank->min_order);
- MALI_DEBUG_PRINT(7, ("Checking freelist 0x%x for order %d\n", list, current_order));
- if (0 != _mali_osk_list_empty(list)) continue; /* empty list */
-
- MALI_DEBUG_PRINT(7, ("Found an entry on the freelist for order %d\n", current_order));
-
-
- block = _MALI_OSK_LIST_ENTRY(list->next, mali_memory_block, link);
- _mali_osk_list_delinit(&block->link);
-
- while (current_order > requested_order)
- {
- mali_memory_block * buddy_block;
- MALI_DEBUG_PRINT(7, ("Splitting block 0x%x\n", block));
- current_order--;
- list--;
- buddy_block = block_get_buddy(block, current_order - bank->min_order);
- set_block_order(buddy_block, current_order);
- set_block_free(buddy_block, 1);
- _mali_osk_list_add(&buddy_block->link, list);
- }
-
- set_block_order(block, current_order);
- set_block_free(block, 0);
-
- /* update usage count */
- _mali_osk_atomic_inc(&bank->num_active_allocations);
-
- break;
- }
-
- /* ! critical section end */
- _mali_osk_lock_signal(bank->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_DEBUG_PRINT(7, ("Lock released for bank 0x%x\n", bank));
-
- MALI_DEBUG_PRINT_IF(7, NULL != block, ("Block 0x%x allocated\n", block));
-
- return block;
-}
-
-
-static void block_release(mali_memory_block * block)
-{
- mali_memory_bank * bank;
- u32 current_order;
-
- if (NULL == block) return;
-
- bank = block->bank;
-
- /* we're manipulating the free list, so we need to lock it */
- _mali_osk_lock_wait(bank->lock, _MALI_OSK_LOCKMODE_RW);
- /* ! critical section begin */
-
- set_block_free(block, 1);
- current_order = get_block_order(block);
-
- while (current_order <= bank->max_order)
- {
- mali_memory_block * buddy_block;
- buddy_block = block_get_buddy(block, current_order - bank->min_order);
- if (!block_is_valid_buddy(buddy_block, current_order)) break;
- _mali_osk_list_delinit(&buddy_block->link); /* remove from free list */
- /* clear tracked data in both blocks */
- set_block_order(block, 0);
- set_block_free(block, 0);
- set_block_order(buddy_block, 0);
- set_block_free(buddy_block, 0);
- /* make the parent control the new state */
- block = block_get_parent(block, current_order - bank->min_order);
- set_block_order(block, current_order + 1); /* merged has a higher order */
- set_block_free(block, 1); /* mark it as free */
- current_order++;
- if (get_block_toplevel(block) == current_order) break; /* stop the merge if we've arrived at a toplevel block */
- }
-
- _mali_osk_list_add(&block->link, &bank->freelist[current_order - bank->min_order]);
-
- /* update bank usage statistics */
- _mali_osk_atomic_dec(&block->bank->num_active_allocations);
-
- /* !critical section end */
- _mali_osk_lock_signal(bank->lock, _MALI_OSK_LOCKMODE_RW);
-
- return;
-}
-
-MALI_STATIC_INLINE u32 block_get_offset(mali_memory_block * block)
-{
- return block - block->bank->blocklist;
-}
-
-MALI_STATIC_INLINE u32 block_mali_addr_get(mali_memory_block * block)
-{
- if (NULL != block) return block->bank->base_addr + MIN_BLOCK_SIZE * block_get_offset(block);
- else return 0;
-}
-
-MALI_STATIC_INLINE u32 block_cpu_addr_get(mali_memory_block * block)
-{
- if (NULL != block) return (block->bank->base_addr + MIN_BLOCK_SIZE * block_get_offset(block)) + block->bank->cpu_usage_adjust;
- else return 0;
-}
-
-MALI_STATIC_INLINE u32 block_size_get(mali_memory_block * block)
-{
- if (NULL != block) return 1 << get_block_order(block);
- else return 0;
-}
-
-MALI_STATIC_INLINE void __user * block_mapping_get(mali_memory_block * block)
-{
- if (NULL != block) return block->mapping;
- else return NULL;
-}
-
-MALI_STATIC_INLINE void block_mapping_set(mali_memory_block * block, void __user * ptr)
-{
- if (NULL != block) block->mapping = ptr;
-}
-
-MALI_STATIC_INLINE u32 block_mmap_cookie_get(mali_memory_block * block)
-{
- if (NULL != block) return block->mmap_cookie;
- else return 0;
-}
-
-/**
- * Set the cookie returned via _mali_ukk_mem_mmap().
- * @param block The memory block to set the cookie for
- * @param cookie the cookie
- */
-MALI_STATIC_INLINE void block_mmap_cookie_set(mali_memory_block * block, u32 cookie)
-{
- if (NULL != block) block->mmap_cookie = cookie;
-}
-
-
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- memory_session * session_data;
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- if (NULL != *slot)
- {
- MALI_DEBUG_PRINT(1, ("The slot given to memory session begin already contains data"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- /* create the session data object */
- MALI_CHECK_NON_NULL(session_data = _mali_osk_malloc(sizeof(memory_session)), _MALI_OSK_ERR_NOMEM);
-
- /* create descriptor mapping table */
- session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX);
-
- if (NULL == session_data->descriptor_mapping)
- {
- _mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- _MALI_OSK_INIT_LIST_HEAD(&session_data->memory_head); /* no memory in use */
- session_data->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0);
- if (NULL == session_data->lock)
- {
- _mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- *slot = session_data; /* slot will point to our data object */
-
- MALI_SUCCESS;
-}
-
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- memory_session * session_data;
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- return;
- }
-
- if (NULL == *slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL memory_session found in current session object"));
- return;
- }
-
- _mali_osk_lock_wait(((memory_session*)*slot)->lock, _MALI_OSK_LOCKMODE_RW);
- session_data = (memory_session *)*slot;
- /* clear our slot */
- *slot = NULL;
-
- /* First free all memory still being used. This can happen if the
- * caller has leaked memory or the application has crashed forcing an
- * auto-session end. */
- if (0 == _mali_osk_list_empty(&session_data->memory_head))
- {
- mali_memory_block * block, * temp;
- MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n"));
-
- /* use the _safe version since fre_big_block removes the active block from the list we're iterating */
- _MALI_OSK_LIST_FOREACHENTRY(block, temp, &session_data->memory_head, mali_memory_block, link)
- {
- _mali_osk_errcode_t err;
- _mali_uk_free_big_block_s uk_args;
-
- MALI_DEBUG_PRINT(4, ("Freeing block 0x%x with mali address 0x%x size %d mapped in user space at 0x%x\n",
- block,
- (void*)block_mali_addr_get(block),
- block_size_get(block),
- block_mapping_get(block))
- );
-
- /* free the block */
- /** @note manual type safety check-point */
- uk_args.ctx = mali_session_data;
- uk_args.cookie = (u32)block->descriptor;
- err = _mali_ukk_free_big_block_internal( mali_session_data, session_data, &uk_args );
-
- if ( _MALI_OSK_ERR_OK != err )
- {
- MALI_DEBUG_PRINT_ERROR(("_mali_ukk_free_big_block_internal() failed during session termination on block with cookie==0x%X\n",
- uk_args.cookie)
- );
- }
- }
- }
-
- if (NULL != session_data->descriptor_mapping)
- {
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
- session_data->descriptor_mapping = NULL;
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_lock_term(session_data->lock);
-
- /* free the session data object */
- _mali_osk_free(session_data);
-
- return;
-}
-
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info)
-{
- mali_memory_bank * bank, *temp;
- _mali_mem_info **mem_info_tail;
-
- /* check input */
- MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS);
-
- /* Make sure we won't leak any memory. It could also be that it's an
- * uninitialized variable, but the caller should have zeroed the
- * variable. */
- MALI_DEBUG_ASSERT(NULL == info->mem_info);
-
- mem_info_tail = &info->mem_info;
-
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- _mali_mem_info * mem_info;
-
- mem_info = (_mali_mem_info *)_mali_osk_calloc(1, sizeof(_mali_mem_info));
- if (NULL == mem_info) return _MALI_OSK_ERR_NOMEM; /* memory already allocated will be freed by the caller */
-
- /* set info */
- mem_info->size = bank->size;
- mem_info->flags = (_mali_bus_usage)bank->used_for_flags;
- mem_info->maximum_order_supported = bank->max_order;
- mem_info->identifier = (u32)bank;
-
- /* add to system info linked list */
- (*mem_info_tail) = mem_info;
- mem_info_tail = &mem_info->next;
- }
-
- /* all OK */
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_memory(_mali_osk_resource_t * resource)
-{
- _mali_osk_errcode_t err;
-
- /* Request ownership of the memory */
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description))
- {
- MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1));
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* call backend */
- err = mali_memory_bank_register(resource->base, resource->cpu_usage_adjust, resource->size, resource->flags, resource->alloc_order, resource->description);
- if (_MALI_OSK_ERR_OK != err)
- {
- /* if backend refused the memory we have to release the region again */
- MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
- _mali_osk_mem_unreqregion(resource->base, resource->size);
- MALI_ERROR(err);
- }
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource)
-{
- /* Not supported by the fixed block memory system */
- MALI_DEBUG_PRINT(1, ("MMU resource not supported by non-MMU driver!\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_FUNC);
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource)
-{
- mali_io_address mapping;
-
- MALI_DEBUG_PRINT(5, ("FPGA framework '%s' @ (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + sizeof(u32) * 2 - 1
- ));
-
- mapping = _mali_osk_mem_mapioregion(resource->base + 0x1000, sizeof(u32) * 2, "fpga framework");
- if (mapping)
- {
- u32 data;
- data = _mali_osk_mem_ioread32(mapping, 0);
- MALI_DEBUG_PRINT(2, ("FPGA framwork '%s' @ 0x%08X:\n", resource->description, resource->base));
- MALI_DEBUG_PRINT(2, ("\tBitfile date: %d%02d%02d_%02d%02d\n",
- (data >> 20),
- (data >> 16) & 0xF,
- (data >> 11) & 0x1F,
- (data >> 6) & 0x1F,
- (data >> 0) & 0x3F));
- data = _mali_osk_mem_ioread32(mapping, sizeof(u32));
- MALI_DEBUG_PRINT(2, ("\tBitfile SCCS rev: %d\n", data));
-
- _mali_osk_mem_unmapioregion(resource->base + 0x1000, sizeof(u32) *2, mapping);
- }
- else MALI_DEBUG_PRINT(1, ("Failed to access FPGA framwork '%s' @ 0x%08X\n", resource->description, resource->base));
-
- MALI_SUCCESS;
-}
-
-/* static _mali_osk_errcode_t get_big_block(void * ukk_private, struct mali_session_data * mali_session_data, void __user * argument) */
-_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args )
-{
- _mali_uk_mem_mmap_s args_mmap = {0, };
- int md;
- mali_memory_block * block;
- _mali_osk_errcode_t err;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER( args );
-
- MALI_DEBUG_ASSERT_POINTER( args->ctx );
-
- /** @note manual type safety check-point */
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
-
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- if (!args->type_id)
- {
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* at least min block size */
- if (MIN_BLOCK_SIZE > args->minimum_size_requested) args->minimum_size_requested = MIN_BLOCK_SIZE;
-
- /* perform the actual allocation */
- block = mali_memory_block_get(args->type_id, args->minimum_size_requested);
- if ( NULL == block )
- {
- /* no memory available with requested type_id */
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, block, &md))
- {
- block_release(block);
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
- block->descriptor = md;
-
-
- /* fill in response */
- args->mali_address = block_mali_addr_get(block);
- args->block_size = block_size_get(block);
- args->cookie = (u32)md;
- args->flags = block->bank->used_for_flags;
-
- /* map the block into the process' address space */
-
- /** @note manual type safety check-point */
- args_mmap.ukk_private = (void *)args->ukk_private;
- args_mmap.ctx = args->ctx;
- args_mmap.size = args->block_size;
- args_mmap.phys_addr = block_cpu_addr_get(block);
-
-#ifndef _MALI_OSK_SPECIFIC_INDIRECT_MMAP
- err = _mali_ukk_mem_mmap( &args_mmap );
-#else
- err = _mali_osk_specific_indirect_mmap( &args_mmap );
-#endif
-
- /* check if the mapping failed */
- if ( _MALI_OSK_ERR_OK != err )
- {
- MALI_DEBUG_PRINT(1, ("Memory mapping failed 0x%x\n", args->cpuptr));
- /* mapping failed */
-
- /* remove descriptor entry */
- mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
-
- /* free the mali memory */
- block_release(block);
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- return err;
- }
-
- args->cpuptr = args_mmap.mapping;
- block_mmap_cookie_set(block, args_mmap.cookie);
- block_mapping_set(block, args->cpuptr);
-
- MALI_DEBUG_PRINT(2, ("Mali memory 0x%x (size %d) mapped in process memory space at 0x%x\n", (void*)args->mali_address, args->block_size, args->cpuptr));
-
- /* track memory in use for the session */
- _mali_osk_list_addtail(&block->link, &session_data->memory_head);
-
- /* memory assigned to the session, memory mapped into the process' view */
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_SUCCESS;
-}
-
-/* Internal code that assumes the memory session lock is held */
-static _mali_osk_errcode_t _mali_ukk_free_big_block_internal( struct mali_session_data * mali_session_data, memory_session * session_data, _mali_uk_free_big_block_s *args)
-{
- mali_memory_block * block = NULL;
- _mali_osk_errcode_t err;
- _mali_uk_mem_munmap_s args_munmap = {0,};
-
- MALI_DEBUG_ASSERT_POINTER( mali_session_data );
- MALI_DEBUG_ASSERT_POINTER( session_data );
- MALI_DEBUG_ASSERT_POINTER( args );
-
- err = mali_descriptor_mapping_get(session_data->descriptor_mapping, (int)args->cookie, (void**)&block);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release memory pages\n", (int)args->cookie));
- MALI_ERROR(err);
- }
-
- MALI_DEBUG_ASSERT_POINTER(block);
-
- MALI_DEBUG_PRINT(4, ("Asked to free block 0x%x with mali address 0x%x size %d mapped in user space at 0x%x\n",
- block,
- (void*)block_mali_addr_get(block),
- block_size_get(block),
- block_mapping_get(block))
- );
-
- /** @note manual type safety check-point */
- args_munmap.ctx = (void*)mali_session_data;
- args_munmap.mapping = block_mapping_get( block );
- args_munmap.size = block_size_get( block );
- args_munmap.cookie = block_mmap_cookie_get( block );
-
-#ifndef _MALI_OSK_SPECIFIC_INDIRECT_MMAP
- _mali_ukk_mem_munmap( &args_munmap );
-#else
- _mali_osk_specific_indirect_munmap( &args_munmap );
-#endif
-
- MALI_DEBUG_PRINT(6, ("Session data 0x%x, lock 0x%x\n", session_data, &session_data->lock));
-
- /* unlink from session usage list */
- MALI_DEBUG_PRINT(5, ("unlink from session usage list\n"));
- _mali_osk_list_delinit(&block->link);
-
- /* remove descriptor entry */
- mali_descriptor_mapping_free(session_data->descriptor_mapping, (int)args->cookie);
-
- /* free the mali memory */
- block_release(block);
- MALI_DEBUG_PRINT(5, ("Block freed\n"));
-
- MALI_SUCCESS;
-}
-
-/* static _mali_osk_errcode_t free_big_block( struct mali_session_data * mali_session_data, void __user * argument) */
-_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args )
-{
- _mali_osk_errcode_t err;
- struct mali_session_data * mali_session_data;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER( args );
-
- MALI_DEBUG_ASSERT_POINTER( args->ctx );
-
- /** @note manual type safety check-point */
- mali_session_data = (struct mali_session_data *)args->ctx;
-
- /* Must always verify this, since these are provided by the user */
- MALI_CHECK_NON_NULL(mali_session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
-
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- /** @note this has been separated out so that the session_end handler can call this while it has the memory_session lock held */
- err = _mali_ukk_free_big_block_internal( mali_session_data, session_data, args );
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- return err;
-}
-
-MALI_STATIC_INLINE u32 get_block_free(mali_memory_block * block)
-{
- return (block->misc >> MISC_SHIFT_FREE) & MISC_MASK_FREE;
-}
-
-MALI_STATIC_INLINE void set_block_free(mali_memory_block * block, int state)
-{
- if (state) block->misc |= (MISC_MASK_FREE << MISC_SHIFT_FREE);
- else block->misc &= ~(MISC_MASK_FREE << MISC_SHIFT_FREE);
-}
-
-MALI_STATIC_INLINE void set_block_order(mali_memory_block * block, u32 order)
-{
- block->misc &= ~(MISC_MASK_ORDER << MISC_SHIFT_ORDER);
- block->misc |= ((order & MISC_MASK_ORDER) << MISC_SHIFT_ORDER);
-}
-
-MALI_STATIC_INLINE u32 get_block_order(mali_memory_block * block)
-{
- return (block->misc >> MISC_SHIFT_ORDER) & MISC_MASK_ORDER;
-}
-
-MALI_STATIC_INLINE void set_block_toplevel(mali_memory_block * block, u32 level)
-{
- block->misc |= ((level & MISC_MASK_TOPLEVEL) << MISC_SHIFT_TOPLEVEL);
-}
-
-MALI_STATIC_INLINE u32 get_block_toplevel(mali_memory_block * block)
-{
- return (block->misc >> MISC_SHIFT_TOPLEVEL) & MISC_MASK_TOPLEVEL;
-}
-
-MALI_STATIC_INLINE int block_is_valid_buddy(mali_memory_block * block, int order)
-{
- if (get_block_free(block) && (get_block_order(block) == order)) return 1;
- else return 0;
-}
-
-MALI_STATIC_INLINE mali_memory_block * block_get_buddy(mali_memory_block * block, u32 order)
-{
- return block + ( (block_get_offset(block) ^ (1 << order)) - block_get_offset(block));
-}
-
-MALI_STATIC_INLINE mali_memory_block * block_get_parent(mali_memory_block * block, u32 order)
-{
- return block + ((block_get_offset(block) & ~(1 << order)) - block_get_offset(block));
-}
-
-/* This handler registered to mali_mmap for non-MMU builds */
-_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
-{
- _mali_osk_errcode_t ret;
- struct mali_session_data * mali_session_data;
- mali_memory_allocation * descriptor;
- memory_session * session_data;
-
- /* validate input */
- if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
-
- /* Unpack arguments */
- mali_session_data = (struct mali_session_data *)args->ctx;
-
- if (NULL == mali_session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: mali_session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
-
- MALI_DEBUG_ASSERT( mali_subsystem_memory_id >= 0 );
-
- session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
- /* validate input */
- if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); }
-
- descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) );
- if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); }
-
- descriptor->size = args->size;
- descriptor->mali_address = args->phys_addr;
- descriptor->mali_addr_mapping_info = (void*)session_data;
- descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */
- descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE;
-
- ret = _mali_osk_mem_mapregion_init( descriptor );
- if ( _MALI_OSK_ERR_OK != ret )
- {
- MALI_DEBUG_PRINT(3, ("_mali_osk_mem_mapregion_init() failed\n"));
- _mali_osk_free(descriptor);
- MALI_ERROR(ret);
- }
-
- ret = _mali_osk_mem_mapregion_map( descriptor, 0, &descriptor->mali_address, descriptor->size );
- if ( _MALI_OSK_ERR_OK != ret )
- {
- MALI_DEBUG_PRINT(3, ("_mali_osk_mem_mapregion_map() failed\n"));
- _mali_osk_mem_mapregion_term( descriptor );
- _mali_osk_free(descriptor);
- MALI_ERROR(ret);
- }
-
- args->mapping = descriptor->mapping;
-
- /**
- * @note we do not require use of mali_descriptor_mapping here:
- * the cookie gets stored in the mali_memory_block struct, which itself is
- * protected by mali_descriptor_mapping, and so this cookie never leaves
- * kernel space (on any OS).
- *
- * In the MMU case, we must use a mali_descriptor_mapping, since on _some_
- * OSs, the cookie leaves kernel space.
- */
- args->cookie = (u32)descriptor;
- MALI_SUCCESS;
-}
-
-/* This handler registered to mali_munmap for non-MMU builds */
-_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
-{
- mali_memory_allocation * descriptor;
-
- /** see note in _mali_ukk_mem_mmap() - no need to use descriptor mapping */
- descriptor = (mali_memory_allocation *)args->cookie;
- MALI_DEBUG_ASSERT_POINTER(descriptor);
-
- /* args->mapping and args->size are also discarded. They are only necessary for certain do_munmap implementations. However, they could be used to check the descriptor at this point. */
- _mali_osk_mem_mapregion_unmap( descriptor, 0, descriptor->size, (_mali_osk_mem_mapregion_flags_t)0 );
-
- _mali_osk_mem_mapregion_term( descriptor );
-
- _mali_osk_free(descriptor);
-
- return _MALI_OSK_ERR_OK;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c b/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c
deleted file mode 100644
index be0cc67..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.c
+++ /dev/null
@@ -1,3158 +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_subsystem.h"
-#include "mali_kernel_mem.h"
-#include "mali_kernel_ioctl.h"
-#include "mali_kernel_descriptor_mapping.h"
-#include "mali_kernel_mem_mmu.h"
-#include "mali_kernel_memory_engine.h"
-#include "mali_block_allocator.h"
-#include "mali_kernel_mem_os.h"
-#include "mali_kernel_session_manager.h"
-#include "mali_kernel_core.h"
-#include "mali_kernel_rendercore.h"
-
-#if defined USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
-#endif
-
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-#include "ump_kernel_interface.h"
-#endif
-
-/* kernel side OS functions and user-kernel interface */
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_ukk.h"
-#include "mali_osk_bitops.h"
-#include "mali_osk_list.h"
-
-/**
- * Size of the MMU registers in bytes
- */
-#define MALI_MMU_REGISTERS_SIZE 0x24
-
-/**
- * Size of an MMU page in bytes
- */
-#define MALI_MMU_PAGE_SIZE 0x1000
-
-/**
- * Page directory index from address
- * Calculates the page directory index from the given address
- */
-#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF)
-
-/**
- * Page table index from address
- * Calculates the page table index from the given address
- */
-#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF)
-
-/**
- * Extract the memory address from an PDE/PTE entry
- */
-#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00)
-
-/**
- * Calculate memory address from PDE and PTE
- */
-#define MALI_MMU_ADDRESS(pde, pte) (((pde)<<22) | ((pte)<<12))
-
-/**
- * Linux kernel version has marked SA_SHIRQ as deprecated, IRQF_SHARED should be used.
- * This is to handle older kernels which haven't done this swap.
- */
-#ifndef IRQF_SHARED
-#define IRQF_SHARED SA_SHIRQ
-#endif /* IRQF_SHARED */
-
-/**
- * Per-session memory descriptor mapping table sizes
- */
-#define MALI_MEM_DESCRIPTORS_INIT 64
-#define MALI_MEM_DESCRIPTORS_MAX 65536
-
-/**
- * Used to disallow more than one core to run a MMU at the same time
- *
- * @note This value is hardwired into some systems' configuration files,
- * which \em might not be a header file (e.g. some external data configuration
- * file). Therefore, if this value is modified, its occurance must be
- * \b manually checked for in the entire driver source tree.
- */
-#define MALI_MMU_DISALLOW_PARALLELL_WORK_OF_MALI_CORES 1
-
-#define MALI_INVALID_PAGE ((u32)(~0))
-
-/**
- *
- */
-typedef enum mali_mmu_entry_flags
-{
- MALI_MMU_FLAGS_PRESENT = 0x01,
- MALI_MMU_FLAGS_READ_PERMISSION = 0x02,
- MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04,
- MALI_MMU_FLAGS_MASK = 0x07
-} mali_mmu_entry_flags;
-
-/**
- * MMU register numbers
- * Used in the register read/write routines.
- * See the hardware documentation for more information about each register
- */
-typedef enum mali_mmu_register {
- MALI_MMU_REGISTER_DTE_ADDR = 0x0000, /**< Current Page Directory Pointer */
- MALI_MMU_REGISTER_STATUS = 0x0001, /**< Status of the MMU */
- MALI_MMU_REGISTER_COMMAND = 0x0002, /**< Command register, used to control the MMU */
- MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x0003, /**< Logical address of the last page fault */
- MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x004, /**< Used to invalidate the mapping of a single page from the MMU */
- MALI_MMU_REGISTER_INT_RAWSTAT = 0x0005, /**< Raw interrupt status, all interrupts visible */
- MALI_MMU_REGISTER_INT_CLEAR = 0x0006, /**< Indicate to the MMU that the interrupt has been received */
- MALI_MMU_REGISTER_INT_MASK = 0x0007, /**< Enable/disable types of interrupts */
- MALI_MMU_REGISTER_INT_STATUS = 0x0008 /**< Interrupt status based on the mask */
-} mali_mmu_register;
-
-/**
- * MMU interrupt register bits
- * Each cause of the interrupt is reported
- * through the (raw) interrupt status registers.
- * Multiple interrupts can be pending, so multiple bits
- * can be set at once.
- */
-typedef enum mali_mmu_interrupt
-{
- MALI_MMU_INTERRUPT_PAGE_FAULT = 0x01, /**< A page fault occured */
- MALI_MMU_INTERRUPT_READ_BUS_ERROR = 0x02 /**< A bus read error occured */
-} mali_mmu_interrupt;
-
-/**
- * MMU commands
- * These are the commands that can be sent
- * to the MMU unit.
- */
-typedef enum mali_mmu_command
-{
- MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */
- MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */
- MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**< Enable stall on page fault */
- MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */
- MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */
- MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */
- MALI_MMU_COMMAND_SOFT_RESET = 0x06 /**< Reset the MMU back to power-on settings */
-} mali_mmu_command;
-
-typedef enum mali_mmu_status_bits
-{
- MALI_MMU_STATUS_BIT_PAGING_ENABLED = 1 << 0,
- MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE = 1 << 1,
- MALI_MMU_STATUS_BIT_STALL_ACTIVE = 1 << 2,
- MALI_MMU_STATUS_BIT_IDLE = 1 << 3,
- MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY = 1 << 4,
- MALI_MMU_STATUS_BIT_PAGE_FAULT_IS_WRITE = 1 << 5,
-} mali_mmu_status_bits;
-
-/**
- * Defintion of the type used to represent memory used by a session.
- * Containts the pointer to the huge user space virtual memory area
- * used to access the Mali memory.
- */
-typedef struct memory_session
-{
- _mali_osk_lock_t *lock; /**< Lock protecting the vm manipulation */
-
- u32 mali_base_address; /**< Mali virtual memory area used by this session */
- mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
-
- u32 page_directory; /**< Physical address of the memory session's page directory */
-
- mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */
- mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */
- u32 page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */
-
- _mali_osk_list_t active_mmus; /**< The MMUs in this session, in increasing order of ID (so we can lock them in the correct order when necessary) */
- _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */
-} memory_session;
-
-typedef struct mali_kernel_memory_mmu_idle_callback
-{
- _mali_osk_list_t link;
- void (*callback)(void*);
- void * callback_argument;
-} mali_kernel_memory_mmu_idle_callback;
-
-/**
- * Definition of the MMU struct
- * Used to track a MMU unit in the system.
- * Contains information about the mapping of the registers
- */
-typedef struct mali_kernel_memory_mmu
-{
- int id; /**< ID of the MMU, no duplicate IDs may exist on the system */
- const char * description; /**< Description text received from the resource manager to help identify the resource for people */
- int irq_nr; /**< IRQ number */
- u32 base; /**< Physical address of the registers */
- mali_io_address mapped_registers; /**< Virtual mapping of the registers */
- u32 mapping_size; /**< Size of registers in bytes */
- _mali_osk_list_t list; /**< Used to link multiple MMU's into a list */
- _mali_osk_irq_t *irq;
- u32 flags; /**< Used to store if there is something special with this mmu. */
-
- _mali_osk_lock_t *lock; /**< Lock protecting access to the usage fields */
- /* usage fields */
- memory_session * active_session; /**< Active session, NULL if no session is active */
- u32 usage_count; /**< Number of nested activations of the active session */
- _mali_osk_list_t callbacks; /**< Callback registered for MMU idle notification */
- void *core;
-
- int in_page_fault_handler;
-
- _mali_osk_list_t session_link;
-} mali_kernel_memory_mmu;
-
-typedef struct dedicated_memory_info
-{
- u32 base;
- u32 size;
- struct dedicated_memory_info * next;
-} dedicated_memory_info;
-
-/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-typedef struct ump_mem_allocation
-{
- mali_allocation_engine * engine;
- mali_memory_allocation * descriptor;
- u32 initial_offset;
- u32 size_allocated;
- ump_dd_handle ump_mem;
-} ump_mem_allocation ;
-#endif
-
-typedef struct external_mem_allocation
-{
- mali_allocation_engine * engine;
- mali_memory_allocation * descriptor;
- u32 initial_offset;
- u32 size;
-} external_mem_allocation;
-
-/*
- Subsystem interface implementation
-*/
-/**
- * Fixed block memory subsystem startup function.
- * Called by the driver core when the driver is loaded.
- * Registers the memory systems ioctl handler, resource handlers and memory map function with the core.
- *
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id);
-
-/**
- * Fixed block memory subsystem shutdown function.
- * Called by the driver core when the driver is unloaded.
- * Cleans up
- * @param id Identifier assigned by the core to the memory subsystem
- */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id);
-
-/**
- * MMU Memory load complete notification function.
- * Called by the driver core when all drivers have loaded and all resources has been registered
- * Builds the memory overall memory list
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id);
-
-/**
- * Fixed block memory subsystem session begin notification
- * Called by the core when a new session to the driver is started.
- * Creates a memory session object and sets it as the subsystem slot data for this session
- * @param slot Pointer to the slot to use for storing per-session data
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-
-/**
- * Fixed block memory subsystem session end notification
- * Called by the core when a session to the driver has ended.
- * Cleans up per session data, which includes checking and fixing memory leaks
- *
- * @param slot Pointer to the slot to use for storing per-session data
- */
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-
-/**
- * Fixed block memory subsystem system info filler
- * Called by the core when a system info update is needed
- * We fill in info about all the memory types we have
- * @param info Pointer to system info struct to update
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info);
-
-/* our registered resource handlers */
-
-/**
- * Fixed block memory subsystem's notification handler for MMU resource instances.
- * Registered with the core during startup.
- * Called by the core for each mmu described in the active architecture's config.h file.
- * @param resource The resource to handle (type MMU)
- * @return 0 if the MMU was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource);
-
-/**
- * Fixed block memory subsystem's notification handler for FPGA_FRAMEWORK resource instances.
- * Registered with the core during startup.
- * Called by the core for each fpga framework described in the active architecture's config.h file.
- * @param resource The resource to handle (type FPGA_FRAMEWORK)
- * @return 0 if the FPGA framework was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource);
-
-
-static _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource);
-static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource);
-
-/**
- * @brief Internal function for unmapping memory
- *
- * Worker function for unmapping memory from a user-process. We assume that the
- * session/descriptor's lock was obtained before entry. For example, the
- * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this
- * function to do the actual unmapping. mali_memory_core_session_end() could
- * also call this directly (depending on compilation options), having locked
- * the descriptor.
- *
- * This function will fail if it is unable to put the MMU in stall mode (which
- * might be the case if a page fault is also being processed).
- *
- * @param args see _mali_uk_mem_munmap_s in "mali_uk_types.h"
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args );
-
-/**
- * The MMU interrupt handler
- * Upper half of the MMU interrupt processing.
- * Called by the kernel when the MMU has triggered an interrupt.
- * The interrupt function supports IRQ sharing. So it'll probe the MMU in question
- * @param irq The irq number (not used)
- * @param dev_id Points to the MMU object being handled
- * @param regs Registers of interrupted process (not used)
- * @return Standard Linux interrupt result.
- * Subset used by the driver is IRQ_HANDLED processed
- * IRQ_NONE Not processed
- */
-static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(void * data);
-
-/**
- * The MMU reset hander
- * Bottom half of the MMU interrupt processing for page faults and bus errors
- * @param work The item to operate on, NULL in our case
- */
-static void mali_kernel_memory_mmu_interrupt_handler_bottom_half ( void *data );
-
-/**
- * Read MMU register value
- * Reads the contents of the specified register.
- * @param unit The MMU to read from
- * @param reg The register to read
- * @return The contents of the register
- */
-static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_register reg);
-
-/**
- * Write to a MMU register
- * Writes the given value to the specified register
- * @param unit The MMU to write to
- * @param reg The register to write to
- * @param val The value to write to the register
- */
-static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val);
-
-/**
- * Issues the reset command to the MMU and waits for HW to be ready again
- * @param mmu The MMU to reset
- */
-static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu);
-
-/**
- * Issues the enable paging command to the MMU and waits for HW to complete the request
- * @param mmu The MMU to enable paging for
- */
-static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu);
-
-/**
- * Issues the enable stall command to the MMU and waits for HW to complete the request
- * @param mmu The MMU to enable paging for
- * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out)
- */
-static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu);
-
-/**
- * Issues the disable stall command to the MMU and waits for HW to complete the request
- * @param mmu The MMU to enable paging for
- */
-static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu);
-
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-static void ump_memory_release(void * ctx, void * handle);
-static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/
-
-
-static void external_memory_release(void * ctx, void * handle);
-static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
-
-
-
-
-/* nop functions */
-
-/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */
-static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */
-static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);
-static void mali_address_manager_release(mali_memory_allocation * descriptor);
-
-static void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory);
-
-_mali_osk_errcode_t mali_mmu_page_table_cache_create(void);
-void mali_mmu_page_table_cache_destroy(void);
-
-_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping);
-void mali_mmu_release_table_page(u32 pa);
-
-static _mali_osk_errcode_t mali_allocate_empty_page_directory(void);
-
-static void mali_free_empty_page_directory(void);
-
-static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data);
-
-static _mali_osk_errcode_t mali_allocate_fault_flush_pages(void);
-
-static void mali_free_fault_flush_pages(void);
-
-static void mali_mmu_probe_irq_trigger(mali_kernel_memory_mmu * mmu);
-static _mali_osk_errcode_t mali_mmu_probe_irq_acknowledge(mali_kernel_memory_mmu * mmu);
-
-/* MMU variables */
-
-typedef struct mali_mmu_page_table_allocation
-{
- _mali_osk_list_t list;
- u32 * usage_map;
- u32 usage_count;
- u32 num_pages;
- mali_page_table_block pages;
-} mali_mmu_page_table_allocation;
-
-typedef struct mali_mmu_page_table_allocations
-{
- _mali_osk_lock_t *lock;
- _mali_osk_list_t partial;
- _mali_osk_list_t full;
- /* we never hold on to a empty allocation */
-} mali_mmu_page_table_allocations;
-
-/* Head of the list of MMUs */
-static _MALI_OSK_LIST_HEAD(mmu_head);
-
-/* the mmu page table cache */
-static struct mali_mmu_page_table_allocations page_table_cache;
-
-/* page fault queue flush helper pages
- * note that the mapping pointers are currently unused outside of the initialization functions */
-static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE;
-static mali_io_address mali_page_fault_flush_page_directory_mapping = NULL;
-static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
-static mali_io_address mali_page_fault_flush_page_table_mapping = NULL;
-static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
-static mali_io_address mali_page_fault_flush_data_page_mapping = NULL;
-
-/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */
-static u32 mali_empty_page_directory = MALI_INVALID_PAGE;
-
-/*
- The fixed memory system's mali subsystem interface implementation.
- We currently handle module and session life-time management.
-*/
-struct mali_kernel_subsystem mali_subsystem_memory =
-{
- mali_memory_core_initialize, /* startup */
- mali_memory_core_terminate, /* shutdown */
- mali_memory_core_load_complete, /* load_complete */
- mali_memory_core_system_info_fill, /* system_info_fill */
- mali_memory_core_session_begin, /* session_begin */
- mali_memory_core_session_end, /* session_end */
- NULL, /* broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-};
-
-static mali_kernel_mem_address_manager mali_address_manager =
-{
- mali_address_manager_allocate, /* allocate */
- mali_address_manager_release, /* release */
- mali_address_manager_map, /* map_physical */
- NULL /* unmap_physical not present*/
-};
-
-static mali_kernel_mem_address_manager process_address_manager =
-{
- _mali_osk_mem_mapregion_init, /* allocate */
- _mali_osk_mem_mapregion_term, /* release */
- _mali_osk_mem_mapregion_map, /* map_physical */
- _mali_osk_mem_mapregion_unmap /* unmap_physical */
-};
-
-static mali_allocation_engine memory_engine = NULL;
-static mali_physical_memory_allocator * physical_memory_allocators = NULL;
-
-static dedicated_memory_info * mem_region_registrations = NULL;
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_memory_id = (mali_kernel_subsystem_identifier)-1;
-
-/* called during module init */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id)
-{
- MALI_DEBUG_PRINT(2, ("MMU memory system initializing\n"));
-
- /* save our subsystem id for later for use in slot lookup during session activation */
- mali_subsystem_memory_id = id;
-
- _MALI_OSK_INIT_LIST_HEAD(&mmu_head);
-
- MALI_CHECK_NO_ERROR( mali_mmu_page_table_cache_create() );
-
- /* register our handlers */
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(MMU, mali_memory_core_resource_mmu) );
-
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(FPGA_FRAMEWORK, mali_memory_core_resource_fpga) );
-
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(MEMORY, mali_memory_core_resource_dedicated_memory) );
-
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(OS_MEMORY, mali_memory_core_resource_os_memory) );
-
- memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager);
- MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT);
-
- MALI_SUCCESS;
-}
-
-/* called if/when our module is unloaded */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_memory_mmu * mmu, *temp_mmu;
-
- MALI_DEBUG_PRINT(2, ("MMU memory system terminating\n"));
-
- /* loop over all MMU units and shut them down */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
- {
- /* reset to defaults */
- mali_mmu_raw_reset(mmu);
-
- /* unregister the irq */
- _mali_osk_irq_term(mmu->irq);
-
- /* remove from the list of MMU's on the system */
- _mali_osk_list_del(&mmu->list);
-
- /* release resources */
- _mali_osk_mem_unmapioregion(mmu->base, mmu->mapping_size, mmu->mapped_registers);
- _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size);
- _mali_osk_lock_term(mmu->lock);
- _mali_osk_free(mmu);
- }
-
- /* free global helper pages */
- mali_free_empty_page_directory();
- mali_free_fault_flush_pages();
-
- /* destroy the page table cache before shutting down backends in case we have a page table leak to report */
- mali_mmu_page_table_cache_destroy();
-
- while ( NULL != mem_region_registrations)
- {
- dedicated_memory_info * m;
- m = mem_region_registrations;
- mem_region_registrations = m->next;
- _mali_osk_mem_unreqregion(m->base, m->size);
- _mali_osk_free(m);
- }
-
- while ( NULL != physical_memory_allocators)
- {
- mali_physical_memory_allocator * m;
- m = physical_memory_allocators;
- physical_memory_allocators = m->next;
- m->destroy(m);
- }
-
- if (NULL != memory_engine)
- {
- mali_allocation_engine_destroy(memory_engine);
- memory_engine = NULL;
- }
-
-}
-
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- memory_session * session_data;
- _mali_osk_errcode_t err;
- int i;
- mali_io_address pd_mapped;
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- if (NULL != *slot)
- {
- MALI_DEBUG_PRINT(1, ("The slot given to memory session begin already contains data"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- MALI_DEBUG_PRINT(2, ("MMU session begin\n"));
-
- /* create the session data object */
- session_data = _mali_osk_calloc(1, sizeof(memory_session));
- MALI_CHECK_NON_NULL( session_data, _MALI_OSK_ERR_NOMEM );
-
- /* create descriptor mapping table */
- session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX);
-
- if (NULL == session_data->descriptor_mapping)
- {
- _mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- err = mali_mmu_get_table_page(&session_data->page_directory, &pd_mapped);
-
- session_data->page_directory_mapped = pd_mapped;
- if (_MALI_OSK_ERR_OK != err)
- {
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
- _mali_osk_free(session_data);
- MALI_ERROR(err);
- }
- MALI_DEBUG_ASSERT_POINTER( session_data->page_directory_mapped );
-
- MALI_DEBUG_PRINT(2, ("Page directory for session 0x%x placed at physical address 0x%08X\n", mali_session_data, session_data->page_directory));
-
- for (i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
- {
- /* mark each page table as not present */
- _mali_osk_mem_iowrite32_relaxed(session_data->page_directory_mapped, sizeof(u32) * i, 0);
- }
- _mali_osk_write_mem_barrier();
-
- /* page_table_mapped[] is already set to NULL by _mali_osk_calloc call */
-
- _MALI_OSK_INIT_LIST_HEAD(&session_data->active_mmus);
- session_data->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 128);
- if (NULL == session_data->lock)
- {
- mali_mmu_release_table_page(session_data->page_directory);
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
- _mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Init the session's memory allocation list */
- _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head );
-
- *slot = session_data; /* slot will point to our data object */
- MALI_DEBUG_PRINT(2, ("MMU session begin: success\n"));
- MALI_SUCCESS;
-}
-
-static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target)
-{
- mali_memory_allocation * descriptor;
-
- descriptor = (mali_memory_allocation*)map_target;
-
- MALI_DEBUG_PRINT(1, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target));
- MALI_DEBUG_ASSERT(descriptor);
-
- mali_allocation_engine_release_memory(memory_engine, descriptor);
- _mali_osk_free(descriptor);
-}
-
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- memory_session * session_data;
- int i;
- const int num_page_table_entries = sizeof(session_data->page_entries_mapped) / sizeof(session_data->page_entries_mapped[0]);
-
- MALI_DEBUG_PRINT(2, ("MMU session end\n"));
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- return;
- }
-
- session_data = (memory_session *)*slot;
-
- if (NULL == session_data)
- {
- MALI_DEBUG_PRINT(1, ("No session data found during session end\n"));
- return;
- }
- /* Lock the session so we can modify the memory list */
- _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
- /* Noninterruptable spinlock type, so must always have locked. Checking should've been done in OSK function. */
-
-#ifndef MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
-#if _MALI_OSK_SPECIFIC_INDIRECT_MMAP
-#error Indirect MMAP specified, but UKK does not have implicit MMAP cleanup. Current implementation does not handle this.
-#else
-
- /* Free all memory engine allocations */
- if (0 == _mali_osk_list_empty(&session_data->memory_head))
- {
- mali_memory_allocation *descriptor;
- mali_memory_allocation *temp;
- _mali_uk_mem_munmap_s unmap_args;
-
- MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n"));
-
- unmap_args.ctx = mali_session_data;
-
- /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */
- _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list)
- {
- MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n",
- descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping)
- );
- /* ASSERT that the descriptor's lock references the correct thing */
- MALI_DEBUG_ASSERT( descriptor->lock == session_data->lock );
- /* Therefore, we have already locked the descriptor */
-
- unmap_args.size = descriptor->size;
- unmap_args.mapping = descriptor->mapping;
- unmap_args.cookie = (u32)descriptor;
-
- /*
- * This removes the descriptor from the list, and frees the descriptor
- *
- * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since
- * the only OS we are aware of that requires indirect MMAP also has
- * implicit mmap cleanup.
- */
- _mali_ukk_mem_munmap_internal( &unmap_args );
- }
- }
-
- /* Assert that we really did free everything */
- MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) );
-#endif /* _MALI_OSK_SPECIFIC_INDIRECT_MMAP */
-#endif /* MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP */
-
- if (NULL != session_data->descriptor_mapping)
- {
- mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback);
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
- session_data->descriptor_mapping = NULL;
- }
-
- for (i = 0; i < num_page_table_entries; i++)
- {
- /* free PTE memory */
- if (session_data->page_directory_mapped && (_mali_osk_mem_ioread32(session_data->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT))
- {
- mali_mmu_release_table_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0);
- }
- }
-
- if (MALI_INVALID_PAGE != session_data->page_directory)
- {
- mali_mmu_release_table_page(session_data->page_directory);
- session_data->page_directory = MALI_INVALID_PAGE;
- }
-
- _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- /**
- * @note Could the VMA close handler mean that we use the session data after it was freed?
- * In which case, would need to refcount the session data, and free on VMA close
- */
-
- /* Free the lock */
- _mali_osk_lock_term( session_data->lock );
- /* free the session data object */
- _mali_osk_free(session_data);
-
- /* clear our slot */
- *slot = NULL;
-
- return;
-}
-
-static _mali_osk_errcode_t mali_allocate_empty_page_directory(void)
-{
- _mali_osk_errcode_t err;
- mali_io_address mapping;
-
- MALI_CHECK_NO_ERROR(mali_mmu_get_table_page(&mali_empty_page_directory, &mapping));
-
- MALI_DEBUG_ASSERT_POINTER( mapping );
-
- err = fill_page(mapping, 0);
- if (_MALI_OSK_ERR_OK != err)
- {
- mali_mmu_release_table_page(mali_empty_page_directory);
- mali_empty_page_directory = MALI_INVALID_PAGE;
- }
- return err;
-}
-
-static void mali_free_empty_page_directory(void)
-{
- if (MALI_INVALID_PAGE != mali_empty_page_directory)
- {
- mali_mmu_release_table_page(mali_empty_page_directory);
- mali_empty_page_directory = MALI_INVALID_PAGE;
- }
-}
-
-static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data)
-{
- int i;
- MALI_DEBUG_ASSERT_POINTER( mapping );
-
- for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
- {
- _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data);
- }
- _mali_osk_mem_barrier();
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_allocate_fault_flush_pages(void)
-{
- _mali_osk_errcode_t err;
-
- err = mali_mmu_get_table_page(&mali_page_fault_flush_data_page, &mali_page_fault_flush_data_page_mapping);
- if (_MALI_OSK_ERR_OK == err)
- {
- err = mali_mmu_get_table_page(&mali_page_fault_flush_page_table, &mali_page_fault_flush_page_table_mapping);
- if (_MALI_OSK_ERR_OK == err)
- {
- err = mali_mmu_get_table_page(&mali_page_fault_flush_page_directory, &mali_page_fault_flush_page_directory_mapping);
- if (_MALI_OSK_ERR_OK == err)
- {
- fill_page(mali_page_fault_flush_data_page_mapping, 0);
- fill_page(mali_page_fault_flush_page_table_mapping, mali_page_fault_flush_data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
- fill_page(mali_page_fault_flush_page_directory_mapping, mali_page_fault_flush_page_table | MALI_MMU_FLAGS_PRESENT);
- MALI_SUCCESS;
- }
- mali_mmu_release_table_page(mali_page_fault_flush_page_table);
- mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
- mali_page_fault_flush_page_table_mapping = NULL;
- }
- mali_mmu_release_table_page(mali_page_fault_flush_data_page);
- mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
- mali_page_fault_flush_data_page_mapping = NULL;
- }
- MALI_ERROR(err);
-}
-
-static void mali_free_fault_flush_pages(void)
-{
- if (MALI_INVALID_PAGE != mali_page_fault_flush_page_directory)
- {
- mali_mmu_release_table_page(mali_page_fault_flush_page_directory);
- mali_page_fault_flush_page_directory = MALI_INVALID_PAGE;
- }
-
- if (MALI_INVALID_PAGE != mali_page_fault_flush_page_table)
- {
- mali_mmu_release_table_page(mali_page_fault_flush_page_table);
- mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
- }
-
- if (MALI_INVALID_PAGE != mali_page_fault_flush_data_page)
- {
- mali_mmu_release_table_page(mali_page_fault_flush_data_page);
- mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
- }
-}
-
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_memory_mmu * mmu, * temp_mmu;
-
- /* Report the allocators */
- mali_allocation_engine_report_allocators( physical_memory_allocators );
-
- /* allocate the helper pages */
- MALI_CHECK_NO_ERROR( mali_allocate_empty_page_directory() );
- if (_MALI_OSK_ERR_OK != mali_allocate_fault_flush_pages())
- {
- mali_free_empty_page_directory();
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* activate the empty page directory on all MMU's */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
- {
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory);
- mali_mmu_enable_paging(mmu);
- }
-
- MALI_DEBUG_PRINT(4, ("MMUs activated\n"));
- /* the MMU system is now active */
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info)
-{
- _mali_mem_info * mem_info;
-
- /* Make sure we won't leak any memory. It could also be that it's an
- * uninitialized variable, but the caller should have zeroed the
- * variable. */
- MALI_DEBUG_ASSERT(NULL == info->mem_info);
-
- info->has_mmu = 1;
-
- mem_info = _mali_osk_calloc(1,sizeof(_mali_mem_info));
- MALI_CHECK_NON_NULL( mem_info, _MALI_OSK_ERR_NOMEM );
-
- mem_info->size = 2048UL * 1024UL * 1024UL;
- mem_info->maximum_order_supported = 30;
- mem_info->flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE;
- mem_info->identifier = 0;
-
- info->mem_info = mem_info;
-
- /* all OK */
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource)
-{
- mali_kernel_memory_mmu * mmu;
-
- MALI_DEBUG_PRINT(4, ("MMU '%s' @ (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1
- ));
-
- if (NULL != mali_memory_core_mmu_lookup(resource->mmu_id))
- {
- MALI_DEBUG_PRINT(1, ("Duplicate MMU ids found. The id %d is already in use\n", resource->mmu_id));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, MALI_MMU_REGISTERS_SIZE, resource->description))
- {
- /* specified addresses are already in used by another driver / the kernel */
- MALI_DEBUG_PRINT(
- 1, ("Failed to request MMU '%s' register address space at (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1
- ));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- mmu = _mali_osk_calloc(1, sizeof(mali_kernel_memory_mmu));
-
- if (NULL == mmu)
- {
- MALI_DEBUG_PRINT(1, ("Failed to allocate memory for handling a MMU unit"));
- _mali_osk_mem_unreqregion(resource->base, MALI_MMU_REGISTERS_SIZE);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* basic setup */
- _MALI_OSK_INIT_LIST_HEAD(&mmu->list);
-
- mmu->id = resource->mmu_id;
- mmu->irq_nr = resource->irq;
- mmu->flags = resource->flags;
- mmu->base = resource->base;
- mmu->mapping_size = MALI_MMU_REGISTERS_SIZE;
- mmu->description = resource->description; /* no need to copy */
- _MALI_OSK_INIT_LIST_HEAD(&mmu->callbacks);
- _MALI_OSK_INIT_LIST_HEAD(&mmu->session_link);
- mmu->in_page_fault_handler = 0;
-
- mmu->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 127-mmu->id);
- if (NULL == mmu->lock)
- {
- MALI_DEBUG_PRINT(1, ("Failed to create mmu lock\n"));
- _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size);
- _mali_osk_free(mmu);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* map the registers */
- mmu->mapped_registers = _mali_osk_mem_mapioregion( mmu->base, mmu->mapping_size, mmu->description );
- if (NULL == mmu->mapped_registers)
- {
- /* failed to map the registers */
- MALI_DEBUG_PRINT(1, ("Failed to map MMU registers at 0x%08X\n", mmu->base));
- _mali_osk_lock_term(mmu->lock);
- _mali_osk_mem_unreqregion(mmu->base, MALI_MMU_REGISTERS_SIZE);
- _mali_osk_free(mmu);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_DEBUG_PRINT(4, ("MMU '%s' @ (0x%08X - 0x%08X) mapped to 0x%08X\n",
- resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1, mmu->mapped_registers
- ));
-
- /* setup MMU interrupt mask */
- /* set all values to known defaults */
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- /* setup MMU page directory pointer */
- /* The mali_page_directory pointer is guaranteed to be 4kb aligned because we've used get_zeroed_page to accquire it */
- /* convert the kernel virtual address into a physical address and set */
-
- /* add to our list of MMU's */
- _mali_osk_list_addtail(&mmu->list, &mmu_head);
-
- mmu->irq = _mali_osk_irq_init(
- mmu->irq_nr,
- mali_kernel_memory_mmu_interrupt_handler_upper_half,
- mali_kernel_memory_mmu_interrupt_handler_bottom_half,
- (_mali_osk_irq_trigger_t)mali_mmu_probe_irq_trigger,
- (_mali_osk_irq_ack_t)mali_mmu_probe_irq_acknowledge,
- mmu,
- "mali_mmu_irq_handlers"
- );
- if (NULL == mmu->irq)
- {
- _mali_osk_list_del(&mmu->list);
- _mali_osk_lock_term(mmu->lock);
- _mali_osk_mem_unmapioregion( mmu->base, mmu->mapping_size, mmu->mapped_registers );
- _mali_osk_mem_unreqregion(resource->base, MALI_MMU_REGISTERS_SIZE);
- _mali_osk_free(mmu);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* set to a known state */
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
-
- MALI_DEBUG_PRINT(2, ("MMU registered\n"));
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource)
-{
- mali_io_address mapping;
-
- MALI_DEBUG_PRINT(5, ("FPGA framework '%s' @ (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + sizeof(u32) * 2 - 1
- ));
-
- mapping = _mali_osk_mem_mapioregion(resource->base + 0x1000, sizeof(u32) * 2, "fpga framework");
- if (mapping)
- {
- MALI_DEBUG_CODE(u32 data = )
- _mali_osk_mem_ioread32(mapping, 0);
- MALI_DEBUG_PRINT(2, ("FPGA framwork '%s' @ 0x%08X:\n", resource->description, resource->base));
- MALI_DEBUG_PRINT(2, ("\tBitfile date: %d%02d%02d_%02d%02d\n",
- (data >> 20),
- (data >> 16) & 0xF,
- (data >> 11) & 0x1F,
- (data >> 6) & 0x1F,
- (data >> 0) & 0x3F));
- MALI_DEBUG_CODE(data = )
- _mali_osk_mem_ioread32(mapping, sizeof(u32));
- MALI_DEBUG_PRINT(2, ("\tBitfile SCCS rev: %d\n", data));
-
- _mali_osk_mem_unmapioregion(resource->base + 0x1000, sizeof(u32) *2, mapping);
- }
- else MALI_DEBUG_PRINT(1, ("Failed to access FPGA framwork '%s' @ 0x%08X\n", resource->description, resource->base));
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource)
-{
- mali_physical_memory_allocator * allocator;
- mali_physical_memory_allocator ** next_allocator_list;
-
- u32 alloc_order = resource->alloc_order;
-
- allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description);
- if (NULL == allocator)
- {
- MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n"));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- allocator->alloc_order = alloc_order;
-
- /* link in the allocator: insertion into ordered list
- * resources of the same alloc_order will be Last-in-first */
- next_allocator_list = &physical_memory_allocators;
-
- while ( NULL != *next_allocator_list &&
- (*next_allocator_list)->alloc_order < alloc_order )
- {
- next_allocator_list = &((*next_allocator_list)->next);
- }
-
- allocator->next = (*next_allocator_list);
- (*next_allocator_list) = allocator;
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource)
-{
- mali_physical_memory_allocator * allocator;
- mali_physical_memory_allocator ** next_allocator_list;
- dedicated_memory_info * cleanup_data;
-
- u32 alloc_order = resource->alloc_order;
-
- /* do the lowlevel linux operation first */
-
- /* Request ownership of the memory */
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description))
- {
- MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* create generic block allocator object to handle it */
- allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description );
-
- if (NULL == allocator)
- {
- MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
- _mali_osk_mem_unreqregion(resource->base, resource->size);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* save lowlevel cleanup info */
- allocator->alloc_order = alloc_order;
-
- cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info));
-
- if (NULL == cleanup_data)
- {
- _mali_osk_mem_unreqregion(resource->base, resource->size);
- allocator->destroy(allocator);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- cleanup_data->base = resource->base;
- cleanup_data->size = resource->size;
-
- cleanup_data->next = mem_region_registrations;
- mem_region_registrations = cleanup_data;
-
- /* link in the allocator: insertion into ordered list
- * resources of the same alloc_order will be Last-in-first */
- next_allocator_list = &physical_memory_allocators;
-
- while ( NULL != *next_allocator_list &&
- (*next_allocator_list)->alloc_order < alloc_order )
- {
- next_allocator_list = &((*next_allocator_list)->next);
- }
-
- allocator->next = (*next_allocator_list);
- (*next_allocator_list) = allocator;
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(void * data)
-{
- mali_kernel_memory_mmu * mmu;
- u32 int_stat;
- mali_core_renderunit *core;
-
- if (mali_benchmark) MALI_SUCCESS;
-
- mmu = (mali_kernel_memory_mmu *)data;
-
- MALI_DEBUG_ASSERT_POINTER(mmu);
-
- /* Pointer to core holding this MMU */
- core = (mali_core_renderunit *)mmu->core;
-
- if(CORE_OFF == core->state)
- {
- MALI_SUCCESS;
- }
-
-
- /* check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
- int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS);
- if (0 == int_stat)
- {
- MALI_ERROR(_MALI_OSK_ERR_FAULT); /* no bits set, we are sharing the IRQ line and someone else caused the interrupt */
- }
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0);
-
- mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
-
- if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
- {
- _mali_osk_irq_schedulework(mmu->irq);
- }
- if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
- {
- /* clear interrupt flag */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- /* reenable it */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- }
-
- MALI_SUCCESS;
-}
-
-
-static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu)
-{
-
-#if defined(USING_MALI200)
- int i;
- const int replay_buffer_check_interval = 10; /* must be below 1000 */
- const int replay_buffer_max_number_of_checks = 100;
-#endif
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- /* add an extra reference while handling the page fault */
- mmu->usage_count++;
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_DEBUG_PRINT(4, ("Sending stop bus request to cores\n"));
- /* request to stop the bus, but don't wait for it to actually stop */
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES, (u32)mmu);
-
-#if defined(USING_MALI200)
- /* no new request will come from any of the connected cores from now
- * we must now flush the playback buffer for any requests queued already
- */
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_DEBUG_PRINT(4, ("Switching to the special page fault flush page directory\n"));
- /* don't use the mali_mmu_activate_address_space function here as we can't stall the MMU */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_page_fault_flush_page_directory);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- /* resume the MMU */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE);
- /* the MMU will now play back all the requests, all going to our special page fault flush data page */
-
- /* just to be safe, check that the playback buffer is empty before continuing */
- if (!mali_benchmark) {
- for (i = 0; i < replay_buffer_max_number_of_checks; i++)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY) break;
- _mali_osk_time_ubusydelay(replay_buffer_check_interval);
- }
-
- MALI_DEBUG_PRINT_IF(1, i == replay_buffer_max_number_of_checks, ("MMU: %s: Failed to flush replay buffer on page fault\n", mmu->description));
- MALI_DEBUG_PRINT(1, ("Replay playback took %ld usec\n", i * replay_buffer_check_interval));
- }
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
-#endif
- /* notify all subsystems that the core should be reset once the bus is actually stopped */
- MALI_DEBUG_PRINT(4,("Sending job abort command to subsystems\n"));
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, (u32)mmu);
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* reprogram the MMU */
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */
- mali_mmu_enable_paging(mmu);
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* release the extra address space reference, will schedule */
- mali_memory_core_mmu_release_address_space_reference(mmu);
-
- /* resume normal operation */
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP3_CONTINUE_JOB_HANDLING, (u32)mmu);
- MALI_DEBUG_PRINT(4, ("Page fault handling complete\n"));
-}
-
-static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
-
- if (!mali_benchmark)
- {
- int i;
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_DTE_ADDR) == 0)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Reset request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- }
-}
-
-static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
-
- if (!mali_benchmark)
- {
- int i;
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable paging request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- }
-}
-
-static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 999;
- int i;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
-
- if (!mali_benchmark)
- {
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- if (max_loop_count == i)
- {
- return MALI_FALSE;
- }
- }
-
- return MALI_TRUE;
-}
-
-static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
- int i;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
-
- if (!mali_benchmark)
- {
- for (i = 0; i < max_loop_count; ++i)
- {
- if ((mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Disable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- }
-}
-
-void mali_kernel_mmu_reset(void * input_mmu)
-{
- mali_kernel_memory_mmu * mmu;
- MALI_DEBUG_ASSERT_POINTER(input_mmu);
- mmu = (mali_kernel_memory_mmu *)input_mmu;
-
- MALI_DEBUG_PRINT(4, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->description));
-
- if ( 0 != mmu->in_page_fault_handler)
- {
- /* This is possible if the bus can never be stopped for some reason */
- MALI_PRINT_ERROR(("Stopping the Memory bus not possible. Mali reset could not be performed."));
- return;
- }
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */
- mali_mmu_enable_paging(mmu);
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
-}
-
-void mali_kernel_mmu_force_bus_reset(void * input_mmu)
-{
- mali_kernel_memory_mmu * mmu;
- MALI_DEBUG_ASSERT_POINTER(input_mmu);
- mmu = (mali_kernel_memory_mmu *)input_mmu;
- if ( 0 != mmu->in_page_fault_handler)
- {
- /* This is possible if the bus can never be stopped for some reason */
- MALI_PRINT_ERROR(("Stopping the Memory bus not possible. Mali reset could not be performed."));
- return;
- }
- MALI_DEBUG_PRINT(1, ("Mali MMU: Force_bus_reset.\n"));
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0);
- mali_kernel_mmu_bus_reset(mmu);
-}
-
-
-static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data)
-{
- mali_kernel_memory_mmu *mmu;
- u32 raw, fault_address, status;
- mali_core_renderunit *core;
-
- MALI_DEBUG_PRINT(1, ("mali_kernel_memory_mmu_interrupt_handler_bottom_half\n"));
- if (NULL == data)
- {
- MALI_PRINT_ERROR(("MMU IRQ work queue: NULL argument"));
- return; /* Error */
- }
- mmu = (mali_kernel_memory_mmu*)data;
-
-
- MALI_DEBUG_PRINT(4, ("Locking subsystems\n"));
- /* lock all subsystems */
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP0_LOCK_SUBSYSTEM, (u32)mmu);
-
- /* Pointer to core holding this MMU */
- core = (mali_core_renderunit *)mmu->core;
-
- if(CORE_OFF == core->state)
- {
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
- return;
- }
-
- raw = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_RAWSTAT);
- status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
-
- if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) )
- {
- MALI_DEBUG_PRINT(1, ("MMU: Page fault bottom half: No Irq found.\n"));
- MALI_DEBUG_PRINT(4, ("Unlocking subsystems"));
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
- return;
- }
-
- mmu->in_page_fault_handler = 1;
-
- fault_address = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
- MALI_PRINT(("Page fault detected at 0x%x from bus id %d of type %s on %s\n",
- (void*)fault_address,
- (status >> 6) & 0x1F,
- (status & 32) ? "write" : "read",
- mmu->description)
- );
-
- if (NULL == mmu->active_session)
- {
- MALI_PRINT(("Spurious memory access detected from MMU %s\n", mmu->description));
- }
- else
- {
- MALI_PRINT(("Active page directory at 0x%08X\n", mmu->active_session->page_directory));
- MALI_PRINT(("Info from page table for VA 0x%x:\n", (void*)fault_address));
- MALI_PRINT(("DTE entry: PTE at 0x%x marked as %s\n",
- (void*)(_mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped,
- MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK),
- _mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped,
- MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT ? "present" : "not present"
- ));
-
- if (_mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped, MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)
- {
- mali_io_address pte;
- u32 data;
- pte = mmu->active_session->page_entries_mapped[MALI_MMU_PDE_ENTRY(fault_address)];
- data = _mali_osk_mem_ioread32(pte, MALI_MMU_PTE_ENTRY(fault_address) * sizeof(u32));
- MALI_PRINT(("PTE entry: Page at 0x%x, %s %s %s\n",
- (void*)(data & ~MALI_MMU_FLAGS_MASK),
- data & MALI_MMU_FLAGS_PRESENT ? "present" : "not present",
- data & MALI_MMU_FLAGS_READ_PERMISSION ? "readable" : "",
- data & MALI_MMU_FLAGS_WRITE_PERMISSION ? "writable" : ""
- ));
- }
- else
- {
- MALI_PRINT(("PTE entry: Not present\n"));
- }
- }
-
-
- mali_kernel_mmu_bus_reset(mmu);
-
- mmu->in_page_fault_handler = 0;
-
- /* unlock all subsystems */
- MALI_DEBUG_PRINT(4, ("Unlocking subsystems"));
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
-
-}
-
-
-static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_register reg)
-{
- u32 val;
-
- if (mali_benchmark) return 0;
-
- val = _mali_osk_mem_ioread32(unit->mapped_registers, (u32)reg * sizeof(u32));
-
- MALI_DEBUG_PRINT(6, ("mali_mmu_register_read addr:0x%04X val:0x%08x\n", (u32)reg * sizeof(u32),val));
-
- return val;
-}
-
-static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val)
-{
- if (mali_benchmark) return;
-
- MALI_DEBUG_PRINT(6, ("mali_mmu_register_write addr:0x%04X val:0x%08x\n", (u32)reg * sizeof(u32), val));
-
- _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val);
-}
-
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
-{
- ump_dd_handle ump_mem;
- u32 nr_blocks;
- u32 i;
- ump_dd_physical_block * ump_blocks;
- ump_mem_allocation *ret_allocation;
-
- MALI_DEBUG_ASSERT_POINTER(ctx);
- MALI_DEBUG_ASSERT_POINTER(engine);
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT_POINTER(alloc_info);
-
- ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) );
- if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
-
- ump_mem = (ump_dd_handle)ctx;
-
- MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n"));
-
- nr_blocks = ump_dd_phys_block_count_get(ump_mem);
-
- MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks));
-
- if (nr_blocks == 0)
- {
- MALI_DEBUG_PRINT(1, ("No block count\n"));
- _mali_osk_free( ret_allocation );
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
-
- ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks );
- if ( NULL==ump_blocks )
- {
- _mali_osk_free( ret_allocation );
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
-
- if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks))
- {
- _mali_osk_free(ump_blocks);
- _mali_osk_free( ret_allocation );
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
-
- /* Store away the initial offset for unmapping purposes */
- ret_allocation->initial_offset = *offset;
-
- for(i=0; i<nr_blocks; ++i)
- {
- MALI_DEBUG_PRINT(4, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size));
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[i].addr , 0, ump_blocks[i].size ))
- {
- u32 size_allocated = *offset - ret_allocation->initial_offset;
- MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n"));
-
- /* unmap all previous blocks (if any) */
- mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
-
- _mali_osk_free(ump_blocks);
- _mali_osk_free(ret_allocation);
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
- *offset += ump_blocks[i].size;
- }
-
- if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
- {
- /* Map in an extra virtual guard page at the end of the VMA */
- MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n"));
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE ))
- {
- u32 size_allocated = *offset - ret_allocation->initial_offset;
- MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n"));
-
- /* unmap all previous blocks (if any) */
- mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
-
- _mali_osk_free(ump_blocks);
- _mali_osk_free(ret_allocation);
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
- *offset += _MALI_OSK_MALI_PAGE_SIZE;
- }
-
- _mali_osk_free( ump_blocks );
-
- ret_allocation->engine = engine;
- ret_allocation->descriptor = descriptor;
- ret_allocation->ump_mem = ump_mem;
- ret_allocation->size_allocated = *offset - ret_allocation->initial_offset;
-
- alloc_info->ctx = NULL;
- alloc_info->handle = ret_allocation;
- alloc_info->next = NULL;
- alloc_info->release = ump_memory_release;
-
- return MALI_MEM_ALLOC_FINISHED;
-}
-
-static void ump_memory_release(void * ctx, void * handle)
-{
- ump_dd_handle ump_mem;
- ump_mem_allocation *allocation;
-
- allocation = (ump_mem_allocation *)handle;
-
- MALI_DEBUG_ASSERT_POINTER( allocation );
-
- ump_mem = allocation->ump_mem;
-
- MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem);
-
- /* At present, this is a no-op. But, it allows the mali_address_manager to
- * do unmapping of a subrange in future. */
- mali_allocation_engine_unmap_physical( allocation->engine,
- allocation->descriptor,
- allocation->initial_offset,
- allocation->size_allocated,
- (_mali_osk_mem_mapregion_flags_t)0
- );
- _mali_osk_free( allocation );
-
-
- ump_dd_reference_release(ump_mem) ;
- return;
-}
-
-_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args )
-{
- ump_dd_handle ump_mem;
- mali_physical_memory_allocator external_memory_allocator;
- memory_session * session_data;
- mali_memory_allocation * descriptor;
- int md;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- /* check arguments */
- /* NULL might be a valid Mali address */
- if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
-
- /* size must be a multiple of the system page size */
- if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
-
- MALI_DEBUG_PRINT(3,
- ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n",
- args->secure_id, args->mali_address, args->size));
-
- ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ;
-
- if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT);
-
- descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
- if (NULL == descriptor)
- {
- ump_dd_reference_release(ump_mem);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- descriptor->size = args->size;
- descriptor->mapping = NULL;
- descriptor->mali_address = args->mali_address;
- descriptor->mali_addr_mapping_info = (void*)session_data;
- descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
- descriptor->lock = session_data->lock;
- if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
- {
- descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
- }
- _mali_osk_list_init( &descriptor->list );
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md))
- {
- ump_dd_reference_release(ump_mem);
- _mali_osk_free(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- external_memory_allocator.allocate = ump_memory_commit;
- external_memory_allocator.allocate_page_table_block = NULL;
- external_memory_allocator.ctx = ump_mem;
- external_memory_allocator.name = "UMP Memory";
- external_memory_allocator.next = NULL;
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
- {
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
- ump_dd_reference_release(ump_mem);
- _mali_osk_free(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- args->cookie = md;
-
- MALI_DEBUG_PRINT(5,("Returning from UMP attach\n"));
-
- /* All OK */
- MALI_SUCCESS;
-}
-
-
-_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args )
-{
- mali_memory_allocation * descriptor;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor))
- {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
-
- _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- mali_allocation_engine_release_memory(memory_engine, descriptor);
-
- _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- _mali_osk_free(descriptor);
-
- MALI_SUCCESS;
-
-}
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */
-
-
-static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
-{
- u32 * data;
- external_mem_allocation * ret_allocation;
-
- MALI_DEBUG_ASSERT_POINTER(ctx);
- MALI_DEBUG_ASSERT_POINTER(engine);
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT_POINTER(alloc_info);
-
- ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) );
-
- if ( NULL == ret_allocation )
- {
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
-
- data = (u32*)ctx;
-
- ret_allocation->engine = engine;
- ret_allocation->descriptor = descriptor;
- ret_allocation->initial_offset = *offset;
-
- alloc_info->ctx = NULL;
- alloc_info->handle = ret_allocation;
- alloc_info->next = NULL;
- alloc_info->release = external_memory_release;
-
- MALI_DEBUG_PRINT(3, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1]));
-
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1]))
- {
- MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n"));
- _mali_osk_free(ret_allocation);
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
- *offset += data[1];
-
- if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
- {
- /* Map in an extra virtual guard page at the end of the VMA */
- MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n"));
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE))
- {
- u32 size_allocated = *offset - ret_allocation->initial_offset;
- MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n"));
-
- /* unmap what we previously mapped */
- mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
- _mali_osk_free(ret_allocation);
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
- *offset += _MALI_OSK_MALI_PAGE_SIZE;
- }
-
- ret_allocation->size = *offset - ret_allocation->initial_offset;
-
- return MALI_MEM_ALLOC_FINISHED;
-}
-
-static void external_memory_release(void * ctx, void * handle)
-{
- external_mem_allocation * allocation;
-
- allocation = (external_mem_allocation *) handle;
- MALI_DEBUG_ASSERT_POINTER( allocation );
-
- /* At present, this is a no-op. But, it allows the mali_address_manager to
- * do unmapping of a subrange in future. */
-
- mali_allocation_engine_unmap_physical( allocation->engine,
- allocation->descriptor,
- allocation->initial_offset,
- allocation->size,
- (_mali_osk_mem_mapregion_flags_t)0
- );
-
- _mali_osk_free( allocation );
-
- return;
-}
-
-_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args )
-{
- mali_physical_memory_allocator external_memory_allocator;
- memory_session * session_data;
- u32 info[2];
- mali_memory_allocation * descriptor;
- int md;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- external_memory_allocator.allocate = external_memory_commit;
- external_memory_allocator.allocate_page_table_block = NULL;
- external_memory_allocator.ctx = &info[0];
- external_memory_allocator.name = "External Memory";
- external_memory_allocator.next = NULL;
-
- /* check arguments */
- /* NULL might be a valid Mali address */
- if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
-
- /* size must be a multiple of the system page size */
- if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
-
- MALI_DEBUG_PRINT(3,
- ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n",
- (void*)args->phys_addr,
- (void*)(args->phys_addr + args->size -1),
- (void*)args->mali_address)
- );
-
- /* Validate the mali physical range */
- MALI_CHECK_NO_ERROR( mali_kernel_core_validate_mali_phys_range( args->phys_addr, args->size ) );
-
- info[0] = args->phys_addr;
- info[1] = args->size;
-
- descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
- if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
-
- descriptor->size = args->size;
- descriptor->mapping = NULL;
- descriptor->mali_address = args->mali_address;
- descriptor->mali_addr_mapping_info = (void*)session_data;
- descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
- descriptor->lock = session_data->lock;
- if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
- {
- descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
- }
- _mali_osk_list_init( &descriptor->list );
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md))
- {
- _mali_osk_free(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
- {
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
- _mali_osk_free(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- args->cookie = md;
-
- MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n"));
-
- /* All OK */
- MALI_SUCCESS;
-}
-
-
-_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args )
-{
- mali_memory_allocation * descriptor;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor))
- {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
-
- _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- mali_allocation_engine_release_memory(memory_engine, descriptor);
-
- _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- _mali_osk_free(descriptor);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args )
-{
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */
- args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args )
-{
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_mmu_page_table_cache_create(void)
-{
- page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 110);
- MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT );
- _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial);
- _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full);
- MALI_SUCCESS;
-}
-
-void mali_mmu_page_table_cache_destroy(void)
-{
- mali_mmu_page_table_allocation * alloc, *temp;
-
- _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list)
- {
- MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count));
- _mali_osk_list_del(&alloc->list);
- alloc->pages.release(&alloc->pages);
- _mali_osk_free(alloc->usage_map);
- _mali_osk_free(alloc);
- }
-
- MALI_DEBUG_PRINT_IF(1, 0 == _mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n"));
-
- _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list)
- {
- MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count));
- _mali_osk_list_del(&alloc->list);
- alloc->pages.release(&alloc->pages);
- _mali_osk_free(alloc->usage_map);
- _mali_osk_free(alloc);
- }
-
- _mali_osk_lock_term(page_table_cache.lock);
-}
-
-_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping)
-{
- _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
-
- if (0 == _mali_osk_list_empty(&page_table_cache.partial))
- {
- mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list);
- int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages);
- MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number));
- _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map);
- alloc->usage_count++;
- if (alloc->num_pages == alloc->usage_count)
- {
- /* full, move alloc to full list*/
- _mali_osk_list_move(&alloc->list, &page_table_cache.full);
- }
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
-
- *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base;
- *mapping = (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping);
- MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page ));
- MALI_SUCCESS;
- }
- else
- {
- mali_mmu_page_table_allocation * alloc;
- /* no free pages, allocate a new one */
-
- alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation));
- if (NULL == alloc)
- {
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- *table_page = MALI_INVALID_PAGE;
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- _MALI_OSK_INIT_LIST_HEAD(&alloc->list);
-
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators))
- {
- MALI_DEBUG_PRINT(1, ("No more memory for page tables\n"));
- _mali_osk_free(alloc);
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- *table_page = MALI_INVALID_PAGE;
- *mapping = NULL;
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* create the usage map */
- alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE;
- alloc->usage_count = 1;
- MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages));
- alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long));
- if (NULL == alloc->usage_map)
- {
- MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n"));
- alloc->pages.release(&alloc->pages);
- _mali_osk_free(alloc);
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- *table_page = MALI_INVALID_PAGE;
- *mapping = NULL;
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* clear memory allocation */
- fill_page(alloc->pages.mapping, 0);
-
- _mali_osk_set_nonatomic_bit(0, alloc->usage_map);
-
- if (alloc->num_pages > 1)
- {
- _mali_osk_list_add(&alloc->list, &page_table_cache.partial);
- }
- else
- {
- _mali_osk_list_add(&alloc->list, &page_table_cache.full);
- }
-
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- *table_page = alloc->pages.phys_base; /* return the first page */
- *mapping = alloc->pages.mapping; /* Mapping for first page */
- MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page ));
- MALI_SUCCESS;
- }
-}
-
-void mali_mmu_release_table_page(u32 pa)
-{
- mali_mmu_page_table_allocation * alloc, * temp_alloc;
-
- MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa));
-
- MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa));
-
- _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
-
- /* find the entry this address belongs to */
- /* first check the partial list */
- _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list)
- {
- u32 start = alloc->pages.phys_base;
- u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE;
- if (pa >= start && pa <= last)
- {
- MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map));
- _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map);
- alloc->usage_count--;
-
- _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
-
- if (0 == alloc->usage_count)
- {
- /* empty, release whole page alloc */
- _mali_osk_list_del(&alloc->list);
- alloc->pages.release(&alloc->pages);
- _mali_osk_free(alloc->usage_map);
- _mali_osk_free(alloc);
- }
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa));
- return;
- }
- }
-
- /* the check the full list */
- _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list)
- {
- u32 start = alloc->pages.phys_base;
- u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE;
- if (pa >= start && pa <= last)
- {
- _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map);
- alloc->usage_count--;
-
- _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
-
-
- if (0 == alloc->usage_count)
- {
- /* empty, release whole page alloc */
- _mali_osk_list_del(&alloc->list);
- alloc->pages.release(&alloc->pages);
- _mali_osk_free(alloc->usage_map);
- _mali_osk_free(alloc);
- }
- else
- {
- /* transfer to partial list */
- _mali_osk_list_move(&alloc->list, &page_table_cache.partial);
- }
-
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa));
- return;
- }
- }
-
- MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa));
-
- _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
-}
-
-void* mali_memory_core_mmu_lookup(u32 id)
-{
- mali_kernel_memory_mmu * mmu, * temp_mmu;
-
- /* find an MMU with a matching id */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
- {
- if (id == mmu->id) return mmu;
- }
-
- /* not found */
- return NULL;
-}
-
-void mali_memory_core_mmu_owner(void *core, void *mmu_ptr)
-{
- mali_kernel_memory_mmu *mmu;
-
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
- MALI_DEBUG_ASSERT_POINTER(core);
-
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
- mmu->core = core;
-}
-
-void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory)
-{
- mali_mmu_enable_stall(mmu); /* this might fail, but changing the DTE address and ZAP should work anyway... */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, page_directory);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_disable_stall(mmu);
-}
-
-_mali_osk_errcode_t mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument)
-{
- memory_session * requested_memory_session;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
- mali_kernel_memory_mmu * mmu;
-
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
- MALI_DEBUG_ASSERT_POINTER(mali_session_data);
-
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
-
- MALI_DEBUG_PRINT(4, ("Asked to activate page table for session 0x%x on MMU %s\n", mali_session_data, mmu->description));
- requested_memory_session = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
- MALI_DEBUG_PRINT(5, ("Session 0x%x looked up as using memory session 0x%x\n", mali_session_data, requested_memory_session));
-
- MALI_DEBUG_ASSERT_POINTER(requested_memory_session);
-
- MALI_DEBUG_PRINT(7, ("Taking locks\n"));
-
- _mali_osk_lock_wait(requested_memory_session->lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- if (0 == mmu->usage_count)
- {
- /* no session currently active, activate the requested session */
- MALI_DEBUG_ASSERT(NULL == mmu->active_session);
- mmu->active_session = requested_memory_session;
- mmu->usage_count = 1;
- MALI_DEBUG_PRINT(4, ("MMU idle, activating page directory 0x%08X on MMU %s\n", requested_memory_session->page_directory, mmu->description));
- mali_mmu_activate_address_space(mmu, requested_memory_session->page_directory);
- {
- /* Insert mmu into the right place in the active_mmus list so that
- * it is still sorted. The list must be sorted by ID so we can get
- * the mutexes in the right order in
- * _mali_ukk_mem_munmap_internal().
- */
- _mali_osk_list_t *entry;
- for (entry = requested_memory_session->active_mmus.next;
- entry != &requested_memory_session->active_mmus;
- entry = entry->next)
- {
- mali_kernel_memory_mmu *temp = _MALI_OSK_LIST_ENTRY(entry, mali_kernel_memory_mmu, session_link);
- if (mmu->id < temp->id)
- break;
- }
- /* If we broke out, then 'entry' points to the list node of the
- * first mmu with a greater ID; otherwise, it points to
- * active_mmus. We want to add *before* this node.
- */
- _mali_osk_list_addtail(&mmu->session_link, entry);
- }
- err = _MALI_OSK_ERR_OK;
- }
-
- /* Allow two cores to run in parallel if they come from the same session */
- else if (
- (mmu->in_page_fault_handler == 0) &&
- (requested_memory_session == mmu->active_session ) &&
- (0==(MALI_MMU_DISALLOW_PARALLELL_WORK_OF_MALI_CORES & mmu->flags))
- )
- {
- /* nested activation detected, just update the reference count */
- MALI_DEBUG_PRINT(4, ("Nested activation detected, %d previous activations found\n", mmu->usage_count));
- mmu->usage_count++;
- err = _MALI_OSK_ERR_OK;
- }
-
- else if (NULL != callback)
- {
- /* can't activate right now, notify caller on idle via callback */
- mali_kernel_memory_mmu_idle_callback * callback_object, * temp_callback_object;
- int found = 0;
-
- MALI_DEBUG_PRINT(3, ("The MMU is busy and is using a different address space, callback given\n"));
- /* check for existing registration */
- _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp_callback_object, &mmu->callbacks, mali_kernel_memory_mmu_idle_callback, link)
- {
- if (callback_object->callback == callback)
- {
- found = 1;
- break;
- }
- }
-
- if (found)
- {
- MALI_DEBUG_PRINT(5, ("Duplicate callback registration found, ignoring\n"));
- /* callback already registered */
- err = _MALI_OSK_ERR_BUSY;
- }
- else
- {
- MALI_DEBUG_PRINT(5,("New callback, registering\n"));
- /* register the new callback */
- callback_object = _mali_osk_malloc(sizeof(mali_kernel_memory_mmu_idle_callback));
- if (NULL != callback_object)
- {
- MALI_DEBUG_PRINT(7,("Callback struct setup\n"));
- callback_object->callback = callback;
- callback_object->callback_argument = callback_argument;
- _mali_osk_list_addtail(&callback_object->link, &mmu->callbacks);
- err = _MALI_OSK_ERR_BUSY;
- }
- }
- }
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_lock_signal(requested_memory_session->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_ERROR(err);
-}
-
-void mali_memory_core_mmu_release_address_space_reference(void* mmu_ptr)
-{
- mali_kernel_memory_mmu_idle_callback * callback_object, * temp;
- mali_kernel_memory_mmu * mmu;
- memory_session * session;
-
- _MALI_OSK_LIST_HEAD(callbacks);
-
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
-
- session = mmu->active_session;
-
- /* support that we handle spurious page faults */
- if (NULL != session)
- {
- _mali_osk_lock_wait(session->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_DEBUG_PRINT(4, ("Deactivation of address space on MMU %s, %d references exists\n", mmu->description, mmu->usage_count));
- MALI_DEBUG_ASSERT(0 != mmu->usage_count);
- mmu->usage_count--;
- if (0 != mmu->usage_count)
- {
- MALI_DEBUG_PRINT(4, ("MMU still in use by this address space, %d references still exists\n", mmu->usage_count));
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- /* support that we handle spurious page faults */
- if (NULL != session)
- {
- _mali_osk_lock_signal(session->lock, _MALI_OSK_LOCKMODE_RW);
- }
- return;
- }
-
- MALI_DEBUG_PRINT(4, ("Activating the empty page directory on %s\n", mmu->description));
-
- /* last reference gone, deactivate current address space */
- mali_mmu_activate_address_space(mmu, mali_empty_page_directory);
-
- /* unlink from session */
- _mali_osk_list_delinit(&mmu->session_link);
- /* remove the active session pointer */
- mmu->active_session = NULL;
-
- /* Notify all registered callbacks.
- * We have to be clever here:
- * We must call the callbacks with the spinlock unlocked and
- * the callback list emptied to allow them to re-register.
- * So we make a copy of the list, clears the list and then later call the callbacks on the local copy
- */
- /* copy list */
- _MALI_OSK_INIT_LIST_HEAD(&callbacks);
- _mali_osk_list_splice(&mmu->callbacks, &callbacks);
- /* clear the original, allowing new registrations during the callback */
- _MALI_OSK_INIT_LIST_HEAD(&mmu->callbacks);
-
- /* end of mmu manipulation, so safe to unlock */
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* then finally remove the (possible) session lock, supporting that no session was active (spurious page fault handling) */
- if (NULL != session)
- {
- _mali_osk_lock_signal(session->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp, &callbacks, mali_kernel_memory_mmu_idle_callback, link)
- {
- MALI_DEBUG_ASSERT_POINTER(callback_object->callback);
- (callback_object->callback)(callback_object->callback_argument);
- _mali_osk_list_del(&callback_object->link);
- _mali_osk_free(callback_object);
- }
-}
-
-void mali_memory_core_mmu_unregister_callback(void* mmu_ptr, void(*callback)(void*))
-{
- mali_kernel_memory_mmu_idle_callback * callback_object, * temp_callback_object;
- mali_kernel_memory_mmu * mmu;
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
-
- MALI_DEBUG_ASSERT_POINTER(callback);
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
-
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp_callback_object, &mmu->callbacks, mali_kernel_memory_mmu_idle_callback, link)
- {
- MALI_DEBUG_ASSERT_POINTER(callback_object->callback);
- if (callback_object->callback == callback)
- {
- _mali_osk_list_del(&callback_object->link);
- _mali_osk_free(callback_object);
- break;
- }
- }
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-}
-
-static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor)
-{
- /* allocate page tables, if needed */
- int i;
- const int first_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address);
- int last_pde_idx;
- memory_session * session_data;
-#if defined USING_MALI400_L2_CACHE
- int has_active_mmus = 0;
- int page_dir_updated = 0;
-#endif
-
-
- if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
- {
- last_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address + _MALI_OSK_MALI_PAGE_SIZE + descriptor->size - 1);
- }
- else
- {
- last_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address + descriptor->size - 1);
- }
-
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
-
- MALI_DEBUG_PRINT(4, ("allocating page tables for Mali virtual address space 0x%08X to 0x%08X\n", descriptor->mali_address, descriptor->mali_address + descriptor->size - 1));
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == _mali_osk_list_empty(&session_data->active_mmus))
- {
- /*
- * We have active MMUs, so we are probably in the process of alocating more memory for a suspended GP job (PLBU heap)
- * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page directory
- * from the L2 cache if we add new page directory entries (PDEs) to the page directory.
- * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start
- */
- has_active_mmus = 1;
- }
-#endif
-
- for (i = first_pde_idx; i <= last_pde_idx; i++)
- {
- if ( 0 == (_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT) )
- {
- u32 pte_phys;
- mali_io_address pte_mapped;
- _mali_osk_errcode_t err;
-
- /* allocate a new page table */
- MALI_DEBUG_ASSERT(0 == session_data->page_entries_usage_count[i]);
- MALI_DEBUG_ASSERT(NULL == session_data->page_entries_mapped[i]);
-
- err = mali_mmu_get_table_page(&pte_phys, &pte_mapped);
- if (_MALI_OSK_ERR_OK == err)
- {
- session_data->page_entries_mapped[i] = pte_mapped;
- MALI_DEBUG_ASSERT_POINTER( session_data->page_entries_mapped[i] );
-
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), pte_phys | MALI_MMU_FLAGS_PRESENT); /* mark page table as present */
-
- /* update usage count */
- session_data->page_entries_usage_count[i]++;
-#if defined USING_MALI400_L2_CACHE
- page_dir_updated = 1;
-#endif
- continue; /* continue loop */
- }
-
- MALI_DEBUG_PRINT(1, ("Page table alloc failed\n"));
- break; /* abort loop, failed to allocate one or more page tables */
- }
- else
- {
- session_data->page_entries_usage_count[i]++;
- }
- }
-
- if (i <= last_pde_idx)
- {
- /* one or more pages could not be allocated, release reference count for the ones we added one for */
- /* adjust for the one which caused the for loop to be aborted */
- i--;
-
- while (i >= first_pde_idx)
- {
- MALI_DEBUG_ASSERT(0 != session_data->page_entries_usage_count[i]);
- session_data->page_entries_usage_count[i]--;
- if (0 == session_data->page_entries_usage_count[i])
- {
- /* last reference removed */
- mali_mmu_release_table_page(MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32))));
- session_data->page_entries_mapped[i] = NULL;
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); /* mark as not present in the page directory */
- }
- i--;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
-#if defined USING_MALI400_L2_CACHE
- if (1 == has_active_mmus && 1 == page_dir_updated)
- {
- /*
- * We have updated the page directory and have an active MMU using it, so invalidate it in the Mali L2 cache.
- */
- mali_kernel_l2_cache_invalidate_page(session_data->page_directory);
- }
-#endif
-
- /* all OK */
- MALI_SUCCESS;
-}
-
-static void mali_address_manager_release(mali_memory_allocation * descriptor)
-{
- int first_pde_idx;
- int last_pde_idx;
- memory_session * session_data;
- u32 mali_address;
- u32 mali_address_end;
- u32 left;
- int i;
-#if defined USING_MALI400_L2_CACHE
- int has_active_mmus = 0;
- int page_dir_updated = 0;
-#endif
-
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
- MALI_DEBUG_ASSERT_POINTER(session_data->page_directory_mapped);
-
- mali_address = descriptor->mali_address;
- mali_address_end = descriptor->mali_address + descriptor->size;
- left = descriptor->size;
-
- first_pde_idx = MALI_MMU_PDE_ENTRY(mali_address);
- last_pde_idx = MALI_MMU_PDE_ENTRY(mali_address_end - 1);
-
- MALI_DEBUG_PRINT(3, ("Zapping Mali MMU table for address 0x%08X size 0x%08X\n", mali_address, left));
- MALI_DEBUG_PRINT(4, ("Zapping PDE %d through %d\n", first_pde_idx, last_pde_idx));
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == _mali_osk_list_empty(&session_data->active_mmus))
- {
- /*
- * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page tables
- * from the L2 cache to ensure that the memory is unmapped.
- * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start
- */
- has_active_mmus = 1;
- }
-#endif
-
-
- for (i = first_pde_idx; i <= last_pde_idx; i++)
- {
- int size_inside_pte = left < 0x400000 ? left : 0x400000;
- const int first_pte_idx = MALI_MMU_PTE_ENTRY(mali_address);
- int last_pte_idx = MALI_MMU_PTE_ENTRY(mali_address + size_inside_pte - 1);
-
- if (last_pte_idx < first_pte_idx)
- {
- /* The last_pte_idx is into the next PTE, crop it to fit into this */
- last_pte_idx = 1023; /* 1024 PTE entries, so 1023 is the last one */
- size_inside_pte = MALI_MMU_ADDRESS(i + 1, 0) - mali_address;
- }
-
- MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[i]);
- MALI_DEBUG_ASSERT(0 != session_data->page_entries_usage_count[i]);
- MALI_DEBUG_PRINT(4, ("PDE %d: zapping entries %d through %d, address 0x%08X, size 0x%08X, left 0x%08X (page table at 0x%08X)\n",
- i, first_pte_idx, last_pte_idx, mali_address, size_inside_pte, left,
- MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)))));
-
- session_data->page_entries_usage_count[i]--;
-
- if (0 == session_data->page_entries_usage_count[i])
- {
- MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n"));
- /* last reference removed, no need to zero out each PTE */
- mali_mmu_release_table_page(MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32))));
- session_data->page_entries_mapped[i] = NULL;
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); /* mark as not present in the page directory */
-#if defined USING_MALI400_L2_CACHE
- page_dir_updated = 1;
-#endif
- }
- else
- {
- int j;
-
- for (j = first_pte_idx; j <= last_pte_idx; j++)
- {
- _mali_osk_mem_iowrite32(session_data->page_entries_mapped[i], j * sizeof(u32), 0);
- }
-
-#if defined USING_MALI400_L2_CACHE
- if (1 == has_active_mmus)
- {
- /* Invalidate the page we've just modified */
- mali_kernel_l2_cache_invalidate_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
- }
-#endif
- }
- left -= size_inside_pte;
- mali_address += size_inside_pte;
- }
-
-#if defined USING_MALI400_L2_CACHE
- if ((1 == page_dir_updated) && (1== has_active_mmus))
- {
- /* The page directory was also updated */
- mali_kernel_l2_cache_invalidate_page(session_data->page_directory);
- }
-#endif
-}
-
-static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size)
-{
- memory_session * session_data;
- u32 mali_address;
- u32 mali_address_end;
- u32 current_phys_addr;
-#if defined USING_MALI400_L2_CACHE
- int has_active_mmus = 0;
-#endif
-
- MALI_DEBUG_ASSERT_POINTER(descriptor);
-
- MALI_DEBUG_ASSERT_POINTER( phys_addr );
-
- current_phys_addr = *phys_addr;
-
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
-
- mali_address = descriptor->mali_address + offset;
- mali_address_end = descriptor->mali_address + offset + size;
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == _mali_osk_list_empty(&session_data->active_mmus))
- {
- /*
- * We have active MMUs, so we are probably in the process of alocating more memory for a suspended GP job (PLBU heap)
- * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page tables
- * from the L2 cache when we have allocated more heap memory.
- * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start
- */
- has_active_mmus = 1;
- }
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", current_phys_addr, mali_address, size));
-
- MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped);
-
- for ( ; mali_address < mali_address_end; mali_address += MALI_MMU_PAGE_SIZE, current_phys_addr += MALI_MMU_PAGE_SIZE)
- {
- MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]);
- _mali_osk_mem_iowrite32_relaxed(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
- }
- _mali_osk_write_mem_barrier();
-
-#if defined USING_MALI400_L2_CACHE
- if (1 == has_active_mmus)
- {
- int i;
- const int first_pde_idx = MALI_MMU_PDE_ENTRY(mali_address);
- const int last_pde_idx = MALI_MMU_PDE_ENTRY(mali_address_end - 1);
-
- /*
- * Invalidate the updated page table(s), incase they have been used for something
- * else since last job start (invalidation of entire Mali L2 cache)
- */
- for (i = first_pde_idx; i <= last_pde_idx; i++)
- {
- mali_kernel_l2_cache_invalidate_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
- }
- }
-#endif
-
- MALI_SUCCESS;
-}
-
-/* This handler registered to mali_mmap for MMU builds */
-_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
-{
- struct mali_session_data * mali_session_data;
- mali_memory_allocation * descriptor;
- memory_session * session_data;
-
- /* validate input */
- if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
-
- /* Unpack arguments */
- mali_session_data = (struct mali_session_data *)args->ctx;
-
- if (NULL == mali_session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: mali_session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
-
- MALI_DEBUG_ASSERT( mali_subsystem_memory_id >= 0 );
-
- session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
- /* validate input */
- if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); }
-
- descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) );
- if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); }
-
- descriptor->size = args->size;
- descriptor->mali_address = args->phys_addr;
- descriptor->mali_addr_mapping_info = (void*)session_data;
-
- descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */
- descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE;
- descriptor->lock = session_data->lock;
- _mali_osk_list_init( &descriptor->list );
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head))
- {
- mali_kernel_memory_mmu * mmu, * temp_mmu;
-
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- /* no need to lock the MMU as we own it already */
- MALI_DEBUG_PRINT(5, ("Zapping the cache of mmu %s as it's using the page table we have updated\n", mmu->description));
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- mali_mmu_enable_stall(mmu); /* this might fail, but ZAP should work anyway... */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_disable_stall(mmu);
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* All ok, write out any information generated from this call */
- args->mapping = descriptor->mapping;
- args->cookie = (u32)descriptor;
-
- MALI_DEBUG_PRINT(7, ("MMAP OK\n"));
- /* All done */
- MALI_SUCCESS;
- }
- else
- {
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- /* OOM, but not a fatal error */
- MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n"));
- _mali_osk_free(descriptor);
- /* Linux will free the CPU address allocation, userspace client the Mali address allocation */
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-}
-
-static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
-{
- memory_session * session_data;
- mali_kernel_memory_mmu * mmu, * temp_mmu;
- mali_memory_allocation * descriptor;
-
- descriptor = (mali_memory_allocation *)args->cookie;
- MALI_DEBUG_ASSERT_POINTER(descriptor);
-
- /** @note args->context unused; we use the memory_session from the cookie */
- /* args->mapping and args->size are also discarded. They are only necessary
- for certain do_munmap implementations. However, they could be used to check the
- descriptor at this point. */
-
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
-
- /* Stall the MMU(s) which is using the address space we're operating on.
- * Note that active_mmus must be sorted in order of ID to avoid a mutex
- * ordering violation.
- */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- u32 status;
- status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
- if ( MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE == (status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) {
- MALI_DEBUG_PRINT(2, ("Stopped stall attempt for mmu with id %d since it is in page fault mode.\n", mmu->id));
- continue;
- }
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /*
- * If we're unable to stall, then make sure we tell our caller that,
- * the caller should then release the session lock for a while,
- * then this function again.
- * This function will fail if we're in page fault mode, and to get
- * out of page fault mode, the page fault handler must be able to
- * take the session lock.
- */
- if (!mali_mmu_enable_stall(mmu))
- {
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_BUSY;
- }
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- /* This function also removes the memory from the session's memory list */
- mali_allocation_engine_release_memory(memory_engine, descriptor);
- _mali_osk_free(descriptor);
-
- /* any L2 maintenance was done during mali_allocation_engine_release_memory */
- /* the session is locked, so the active mmu list should be the same */
- /* zap the TLB and resume operation */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_disable_stall(mmu);
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-/* Handler for unmapping memory for MMU builds */
-_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
-{
- mali_memory_allocation * descriptor;
- _mali_osk_lock_t *descriptor_lock;
- _mali_osk_errcode_t err;
-
- descriptor = (mali_memory_allocation *)args->cookie;
- MALI_DEBUG_ASSERT_POINTER(descriptor);
-
- /** @note args->context unused; we use the memory_session from the cookie */
- /* args->mapping and args->size are also discarded. They are only necessary
- for certain do_munmap implementations. However, they could be used to check the
- descriptor at this point. */
-
- MALI_DEBUG_ASSERT_POINTER((memory_session*)descriptor->mali_addr_mapping_info);
-
- descriptor_lock = descriptor->lock; /* should point to the session data lock... */
-
- err = _MALI_OSK_ERR_BUSY;
- while (err == _MALI_OSK_ERR_BUSY)
- {
- if (descriptor_lock)
- {
- _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
- }
-
- err = _mali_ukk_mem_munmap_internal( args );
-
- if (descriptor_lock)
- {
- _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
- }
-
- if (err == _MALI_OSK_ERR_BUSY)
- {
- /*
- * Reason for this;
- * We where unable to stall the MMU, probably because we are in page fault handling.
- * Sleep for a while with the session lock released, then try again.
- * Abnormal termination of programs with running Mali jobs is a normal reason for this.
- */
- _mali_osk_time_ubusydelay(10);
- }
- }
-
- return err;
-}
-
-/* Is called when the rendercore wants the mmu to give an interrupt */
-static void mali_mmu_probe_irq_trigger(mali_kernel_memory_mmu * mmu)
-{
- MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_trigger\n"));
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR);
-}
-
-/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */
-static _mali_osk_errcode_t mali_mmu_probe_irq_acknowledge(mali_kernel_memory_mmu * mmu)
-{
- u32 int_stat;
-
- int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS);
-
- MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat));
- if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
- {
- MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n"));
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT);
- }
- else MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n"));
-
- if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
- {
- MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n"));
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- }
- else MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n"));
-
- if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) ==
- (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR))
- {
- MALI_SUCCESS;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-struct dump_info
-{
- u32 buffer_left;
- u32 register_writes_size;
- u32 page_table_dump_size;
- u32 *buffer;
-};
-
-static _mali_osk_errcode_t writereg(u32 where, u32 what, const char * comment, struct dump_info * info, int dump_to_serial)
-{
- if (dump_to_serial) MALI_DEBUG_PRINT(1, ("writereg %08X %08X # %s\n", where, what, comment));
-
- if (NULL != info)
- {
- info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */
-
- if (NULL != info->buffer)
- {
- /* check that we have enough space */
- if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
-
- *info->buffer = where;
- info->buffer++;
-
- *info->buffer = what;
- info->buffer++;
-
- info->buffer_left -= sizeof(u32)*2;
- }
- }
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info, int dump_to_serial)
-{
- if (dump_to_serial)
- {
- int i;
- for (i = 0; i < 256; i++)
- {
- MALI_DEBUG_PRINT(1, ("%08X: %08X %08X %08X %08X\n", phys_addr + 16*i, _mali_osk_mem_ioread32(page, (i*4 + 0) * sizeof(u32)),
- _mali_osk_mem_ioread32(page, (i*4 + 1) * sizeof(u32)),
- _mali_osk_mem_ioread32(page, (i*4 + 2) * sizeof(u32)),
- _mali_osk_mem_ioread32(page, (i*4 + 3) * sizeof(u32))));
-
- }
- }
-
- if (NULL != info)
- {
- /* 4096 for the page and 4 bytes for the address */
- const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4;
- const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE;
- const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4;
-
- info->page_table_dump_size += dump_size_in_bytes;
-
- if (NULL != info->buffer)
- {
- if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
-
- *info->buffer = phys_addr;
- info->buffer++;
-
- _mali_osk_memcpy(info->buffer, page, page_size_in_bytes);
- info->buffer += page_size_in_elements;
-
- info->buffer_left -= dump_size_in_bytes;
- }
- }
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t dump_mmu_page_table(memory_session * session_data, struct dump_info * info)
-{
- MALI_DEBUG_ASSERT_POINTER(session_data);
- MALI_DEBUG_ASSERT_POINTER(info);
-
- if (NULL != session_data->page_directory_mapped)
- {
- int i;
-
- MALI_CHECK_NO_ERROR(
- dump_page(session_data->page_directory_mapped, session_data->page_directory, info, 0)
- );
-
- for (i = 0; i < 1024; i++)
- {
- if (NULL != session_data->page_entries_mapped[i])
- {
- MALI_CHECK_NO_ERROR(
- dump_page(session_data->page_entries_mapped[i], _mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info, 0)
- );
- }
- }
- }
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t dump_mmu_registers(memory_session * session_data, struct dump_info * info)
-{
- MALI_CHECK_NO_ERROR(writereg(0x00000000, session_data->page_directory, "set the page directory address", info, 0));
- MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info, 0));
- MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info, 0));
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args )
-{
- struct dump_info info = { 0, 0, 0, NULL };
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
-
- MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data, &info));
- MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data, &info));
- args->size = info.register_writes_size + info.page_table_dump_size;
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args )
-{
- struct dump_info info = { 0, 0, 0, NULL };
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
-
- info.buffer_left = args->size;
- info.buffer = args->buffer;
-
- args->register_writes = info.buffer;
- MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data, &info));
-
- args->page_table_dump = info.buffer;
- MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data, &info));
-
- args->register_writes_size = info.register_writes_size;
- args->page_table_dump_size = info.page_table_dump_size;
-
- MALI_SUCCESS;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-u32 _mali_ukk_report_memory_usage(void)
-{
- return mali_allocation_engine_memory_usage(physical_memory_allocators);
-}
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h b/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h
deleted file mode 100644
index 0462f66..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_mem_mmu.h
+++ /dev/null
@@ -1,75 +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.
- */
-
-#ifndef __MALI_KERNEL_MEM_MMU_H__
-#define __MALI_KERNEL_MEM_MMU_H__
-
-#include "mali_kernel_session_manager.h"
-
-/**
- * Lookup a MMU core by ID.
- * @param id ID of the MMU to find
- * @return NULL if ID not found or valid, non-NULL if a core was found.
- */
-void* mali_memory_core_mmu_lookup(u32 id);
-
-/**
- * Set the core pointer of MMU to core owner of MMU
- *
- * @param core Core holding this MMU
- * @param mmu_ptr The MMU whose core pointer needs set to core holding the MMU
- *
- */
-void mali_memory_core_mmu_owner(void *core, void *mmu_ptr);
-
-/**
- * Activate a user session with its address space on the given MMU.
- * If the session can't be activated due to that the MMU is busy and
- * a callback pointer is given, the callback will be called once the MMU becomes idle.
- * If the same callback pointer is registered multiple time it will only be called once.
- * Nested activations are supported.
- * Each call must be matched by a call to @see mali_memory_core_mmu_release_address_space_reference
- *
- * @param mmu The MMU to activate the address space on
- * @param mali_session_data The user session object which address space to activate
- * @param callback Pointer to the function to call when the MMU becomes idle
- * @param callback_arg Argument given to the callback
- * @return 0 if the address space was activated, -EBUSY if the MMU was busy, -EFAULT in all other cases.
- */
-int mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument);
-
-/**
- * Release a reference to the current active address space.
- * Once the last reference is released any callback(s) registered will be called before the function returns
- *
- * @note Caution must be shown calling this function with locks held due to that callback can be called
- * @param mmu The mmu to release a reference to the active address space of
- */
-void mali_memory_core_mmu_release_address_space_reference(void* mmu);
-
-/**
- * Soft reset of MMU - needed after power up
- *
- * @param mmu_ptr The MMU pointer registered with the relevant core
- */
-void mali_kernel_mmu_reset(void * mmu_ptr);
-
-void mali_kernel_mmu_force_bus_reset(void * mmu_ptr);
-
-/**
- * Unregister a previously registered callback.
- * @param mmu The MMU to unregister the callback on
- * @param callback The function to unregister
- */
-void mali_memory_core_mmu_unregister_callback(void* mmu, void(*callback)(void*));
-
-
-
-#endif /* __MALI_KERNEL_MEM_MMU_H__ */
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c b/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c
index 9ac122d..167b01f 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c
+++ b/driver/src/devicedrv/mali/common/mali_kernel_mem_os.c
@@ -65,7 +65,7 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3
info->num_pages_allocated = 0;
info->cpu_usage_adjust = cpu_usage_adjust;
- info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, 106);
+ info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
if (NULL != info->mutex)
{
allocator->allocate = os_allocator_allocate;
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h b/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h
index 59e6494..0946169 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h
+++ b/driver/src/devicedrv/mali/common/mali_kernel_mem_os.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c b/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c
index 8bb80e6..1377560 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c
+++ b/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.c
@@ -161,13 +161,28 @@ _mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engin
void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
{
+ mali_allocation_engine_release_pt1_mali_pagetables_unmap(mem_engine, descriptor);
+ mali_allocation_engine_release_pt2_physical_memory_free(mem_engine, descriptor);
+}
+
+void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
+{
memory_engine * engine = (memory_engine*)mem_engine;
- mali_physical_memory_allocation * active_allocation_tracker;
MALI_DEBUG_ASSERT_POINTER(engine);
MALI_DEBUG_ASSERT_POINTER(descriptor);
- /* Determine whether we need to remove this from a tracking list */
+ /* Calling: mali_address_manager_release() */
+ /* This function is allowed to be called several times, and it only does the release on the first call. */
+ engine->mali_address->release(descriptor);
+}
+
+void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
+{
+ memory_engine * engine = (memory_engine*)mem_engine;
+ mali_physical_memory_allocation * active_allocation_tracker;
+
+ /* Remove this from a tracking list in session_data->memory_head */
if ( ! _mali_osk_list_empty( &descriptor->list ) )
{
_mali_osk_list_del( &descriptor->list );
@@ -175,8 +190,6 @@ void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, ma
MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; )
}
- engine->mali_address->release(descriptor);
-
active_allocation_tracker = &descriptor->physical_allocation;
while (NULL != active_allocation_tracker)
{
@@ -199,7 +212,6 @@ void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, ma
}
}
-
_mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size)
{
_mali_osk_errcode_t err;
@@ -244,7 +256,7 @@ _mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine m
}
}
- MALI_DEBUG_PRINT(4, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset));
+ MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset));
/* Mali address manager must use the physical address - no point in asking
* it to allocate another one for us */
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h b/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h
index 367219f..cda74c3 100644
--- a/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h
+++ b/driver/src/devicedrv/mali/common/mali_kernel_memory_engine.h
@@ -136,6 +136,9 @@ void mali_allocation_engine_destroy(mali_allocation_engine engine);
int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list );
void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor);
+void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor);
+void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor);
+
int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size);
void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags);
diff --git a/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c b/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c
deleted file mode 100644
index c050771..0000000
--- a/driver/src/devicedrv/mali/common/mali_kernel_rendercore.c
+++ /dev/null
@@ -1,2021 +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_kernel_core.h"
-#include "mali_osk.h"
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_rendercore.h"
-#include "mali_osk_list.h"
-#if MALI_GPU_UTILIZATION
-#include "mali_kernel_utilization.h"
-#endif
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-#if USING_MMU
-#include "mali_kernel_mem_mmu.h"
-#endif /* USING_MMU */
-#if defined USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
-#endif /* USING_MALI400_L2_CACHE */
-
-#define HANG_CHECK_MSECS_MIN 100
-#define HANG_CHECK_MSECS_MAX 2000 /* 2 secs */
-#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */
-
-#define WATCHDOG_MSECS_MIN (2*HANG_CHECK_MSECS_MIN)
-#define WATCHDOG_MSECS_MAX 3600000 /* 1 hour */
-#define WATCHDOG_MSECS_DEFAULT 900000 /* 15 mins */
-
-/* max value that will be converted from jiffies to micro seconds and written to job->render_time_usecs */
-#define JOB_MAX_JIFFIES 100000
-
-int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
-int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
-int mali_boot_profiling = 0;
-#endif
-
-/* Subsystem entrypoints: */
-static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id);
-static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id);
-#if USING_MMU
-static void rendercore_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
-#endif
-
-
-static void mali_core_subsystem_cleanup_all_renderunits(struct mali_core_subsystem* subsys);
-static void mali_core_subsystem_move_core_set_idle(struct mali_core_renderunit *core);
-
-static mali_core_session * mali_core_subsystem_get_waiting_session(mali_core_subsystem *subsystem);
-static mali_core_job * mali_core_subsystem_release_session_get_job(mali_core_subsystem *subsystem, mali_core_session * session);
-
-static void find_and_abort(mali_core_session* session, u32 abort_id);
-
-static void mali_core_job_start_on_core(mali_core_job *job, mali_core_renderunit *core);
-#if USING_MMU
-static void mali_core_subsystem_callback_schedule_wrapper(void* sub);
-#endif
-static void mali_core_subsystem_schedule(mali_core_subsystem*subsystem);
-static void mali_core_renderunit_detach_job_from_core(mali_core_renderunit* core, mali_subsystem_reschedule_option reschedule, mali_subsystem_job_end_code end_status);
-
-static void mali_core_renderunit_irq_handler_remove(struct mali_core_renderunit *core);
-
-static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data);
-static void mali_core_irq_handler_bottom_half ( void *data );
-
-#if USING_MMU
-static void lock_subsystem(struct mali_core_subsystem * subsys);
-static void unlock_subsystem(struct mali_core_subsystem * subsys);
-#endif
-
-
-/**
- * This will be one of the subsystems in the array of subsystems:
- * static struct mali_kernel_subsystem * subsystems[];
- * found in file: mali_kernel_core.c
- *
- * This subsystem is necessary for operations common to all rendercore
- * subsystems. For example, mali_subsystem_mali200 and mali_subsystem_gp2 may
- * share a mutex when RENDERCORES_USE_GLOBAL_MUTEX is non-zero.
- */
-struct mali_kernel_subsystem mali_subsystem_rendercore=
-{
- rendercore_subsystem_startup, /* startup */
- rendercore_subsystem_terminate, /* shutdown */
- NULL, /* load_complete */
- NULL, /* system_info_fill */
- NULL, /* session_begin */
- NULL, /* session_end */
-#if USING_MMU
- rendercore_subsystem_broadcast_notification, /* broadcast_notification */
-#else
- NULL,
-#endif
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-} ;
-
-static _mali_osk_lock_t *rendercores_global_mutex = NULL;
-static u32 rendercores_global_mutex_is_held = 0;
-static u32 rendercores_global_mutex_owner = 0;
-
-/** The 'dummy' rendercore subsystem to allow global subsystem mutex to be
- * locked for all subsystems that extend the ''rendercore'' */
-static mali_core_subsystem rendercore_dummy_subsystem = {0,};
-
-/*
- * Rendercore Subsystem functions.
- *
- * These are exposed by mali_subsystem_rendercore
- */
-
-/**
- * @brief Initialize the Rendercore subsystem.
- *
- * This must be called before any other subsystem that extends the
- * ''rendercore'' may be initialized. For example, this must be called before
- * the following functions:
- * - mali200_subsystem_startup(), from mali_subsystem_mali200
- * - maligp_subsystem_startup(), from mali_subsystem_gp2
- *
- * @note This function is separate from mali_core_subsystem_init(). They
- * are related, in that mali_core_subsystem_init() may use the structures
- * initialized by rendercore_subsystem_startup()
- */
-static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id)
-{
- rendercores_global_mutex_is_held = 0;
- rendercores_global_mutex = _mali_osk_lock_init(
- (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED),
- 0, 129);
-
- if (NULL == rendercores_global_mutex)
- {
- MALI_PRINT_ERROR(("Failed: _mali_osk_lock_init\n")) ;
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- rendercore_dummy_subsystem.name = "Rendercore Global Subsystem"; /* On the constant pool, do not free */
- rendercore_dummy_subsystem.magic_nr = SUBSYSTEM_MAGIC_NR; /* To please the Subsystem Mutex code */
-
-#if MALI_GPU_UTILIZATION
- if (mali_utilization_init() != _MALI_OSK_ERR_OK)
- {
- _mali_osk_lock_term(rendercores_global_mutex);
- rendercores_global_mutex = NULL;
- MALI_PRINT_ERROR(("Failed: mali_utilization_init\n")) ;
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- if (_mali_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE) != _MALI_OSK_ERR_OK)
- {
- /* No biggie if we wheren't able to initialize the profiling */
- MALI_PRINT_ERROR(("Rendercore: Failed to initialize profiling, feature will be unavailable\n")) ;
- }
-#endif
-
- MALI_DEBUG_PRINT(2, ("Rendercore: subsystem global mutex initialized\n")) ;
- MALI_SUCCESS;
-}
-
-/**
- * @brief Terminate the Rendercore subsystem.
- *
- * This must only be called \b after any other subsystem that extends the
- * ''rendercore'' has been terminated. For example, this must be called \b after
- * the following functions:
- * - mali200_subsystem_terminate(), from mali_subsystem_mali200
- * - maligp_subsystem_terminate(), from mali_subsystem_gp2
- *
- * @note This function is separate from mali_core_subsystem_cleanup(), though,
- * the subsystems that extend ''rendercore'' must still call
- * mali_core_subsystem_cleanup() when they terminate.
- */
-static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id)
-{
- /* Catch double-terminate */
- MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex );
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_term();
-#endif
-
-#if MALI_GPU_UTILIZATION
- mali_utilization_term();
-#endif
-
- rendercore_dummy_subsystem.name = NULL; /* The original string was on the constant pool, do not free */
- rendercore_dummy_subsystem.magic_nr = 0;
-
- /* ASSERT that no-one's holding this */
- MALI_DEBUG_PRINT_ASSERT( 0 == rendercores_global_mutex_is_held,
- ("Rendercores' Global Mutex was held at termination time. Have the subsystems that extend ''rendercore'' been terminated?\n") );
-
- _mali_osk_lock_term( rendercores_global_mutex );
- rendercores_global_mutex = NULL;
-
- MALI_DEBUG_PRINT(2, ("Rendercore: subsystem global mutex terminated\n")) ;
-}
-
-
-#if USING_MMU
-/**
- * @brief Handle certain Rendercore subsystem broadcast notifications
- *
- * When RENDERCORES_USE_GLOBAL_MUTEX is non-zero, this handles the following messages:
- * - MMU_KILL_STEP0_LOCK_SUBSYSTEM
- * - MMU_KILL_STEP4_UNLOCK_SUBSYSTEM
- *
- * The purpose is to manage the Rendercode Global Mutex, which cannot be
- * managed by any system that extends the ''rendercore''.
- *
- * All other messages must be handled by mali_core_subsystem_broadcast_notification()
- *
- *
- * When RENDERCORES_USE_GLOBAL_MUTEX is 0, this function does nothing.
- * Instead, the subsystem that extends the ''rendercore' \b must handle its
- * own mutexes - refer to mali_core_subsystem_broadcast_notification().
- *
- * Used currently only for signalling when MMU has a pagefault
- */
-static void rendercore_subsystem_broadcast_notification(mali_core_notification_message message, u32 data)
-{
- switch(message)
- {
- case MMU_KILL_STEP0_LOCK_SUBSYSTEM:
- lock_subsystem( &rendercore_dummy_subsystem );
- break;
- case MMU_KILL_STEP4_UNLOCK_SUBSYSTEM:
- unlock_subsystem( &rendercore_dummy_subsystem );
- break;
-
- case MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES:
- /** FALLTHROUGH */
- case MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS:
- /** FALLTHROUGH */
- case MMU_KILL_STEP3_CONTINUE_JOB_HANDLING:
- break;
-
- default:
- MALI_PRINT_ERROR(("Illegal message: 0x%x, data: 0x%x\n", (u32)message, data));
- break;
- }
-
-}
-#endif
-
-/*
- * Functions inherited by the subsystems that extend the ''rendercore''.
- */
-
-void mali_core_renderunit_timeout_function_hang_detection(void *arg)
-{
- mali_bool action = MALI_FALSE;
- mali_core_renderunit * core;
-
- core = (mali_core_renderunit *) arg;
- if( !core ) return;
-
- /* if NOT idle OR NOT powered off OR has TIMED_OUT */
- if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state) || (CORE_OFF == core->state)) )
- {
- core->state = CORE_HANG_CHECK_TIMEOUT;
- action = MALI_TRUE;
- }
-
- if(action) _mali_osk_irq_schedulework(core->irq);
-}
-
-
-void mali_core_renderunit_timeout_function(void *arg)
-{
- mali_core_renderunit * core;
- mali_bool is_watchdog;
-
- core = (mali_core_renderunit *)arg;
- if( !core ) return;
-
- is_watchdog = MALI_TRUE;
- if (mali_benchmark)
- {
- /* poll based core */
- mali_core_job *job;
- job = core->current_job;
- if ( (NULL != job) &&
- (0 != _mali_osk_time_after(job->watchdog_jiffies,_mali_osk_time_tickcount()))
- )
- {
- core->state = CORE_POLL;
- is_watchdog = MALI_FALSE;
- }
- }
-
- if (is_watchdog)
- {
- MALI_DEBUG_PRINT(3, ("SW-Watchdog timeout: Core:%s\n", core->description));
- core->state = CORE_WATCHDOG_TIMEOUT;
- }
-
- _mali_osk_irq_schedulework(core->irq);
-}
-
-/* Used by external renderunit_create<> function */
-_mali_osk_errcode_t mali_core_renderunit_init(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Core: renderunit_init: Core:%s\n", core->description));
-
- _MALI_OSK_INIT_LIST_HEAD(&core->list) ;
- core->timer = _mali_osk_timer_init();
- if (NULL == core->timer)
- {
- MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot init timer\n", core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- _mali_osk_timer_setcallback(core->timer, mali_core_renderunit_timeout_function, (void *)core);
-
- core->timer_hang_detection = _mali_osk_timer_init();
- if (NULL == core->timer_hang_detection)
- {
- _mali_osk_timer_term(core->timer);
- MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot init hang detection timer\n", core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- _mali_osk_timer_setcallback(core->timer_hang_detection, mali_core_renderunit_timeout_function_hang_detection, (void *)core);
-
-#if USING_MALI_PMM
- /* Init no pending power downs */
- core->pend_power_down = MALI_FALSE;
-
- /* Register the core with the PMM - which powers it up */
- if (_MALI_OSK_ERR_OK != malipmm_core_register( core->pmm_id ))
- {
- _mali_osk_timer_term(core->timer);
- _mali_osk_timer_term(core->timer_hang_detection);
- MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot register with PMM\n", core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif /* USING_MALI_PMM */
-
- core->error_recovery = MALI_FALSE;
- core->in_detach_function = MALI_FALSE;
- core->state = CORE_IDLE;
- core->current_job = NULL;
- core->magic_nr = CORE_MAGIC_NR;
-#if USING_MMU
- core->mmu = NULL;
-#endif /* USING_MMU */
-
- MALI_SUCCESS;
-}
-
-void mali_core_renderunit_term(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Core: renderunit_term: Core:%s\n", core->description));
-
- if (NULL != core->timer)
- {
- _mali_osk_timer_term(core->timer);
- core->timer = NULL;
- }
- if (NULL != core->timer_hang_detection)
- {
- _mali_osk_timer_term(core->timer_hang_detection);
- core->timer_hang_detection = NULL;
- }
-
-#if USING_MALI_PMM
- /* Unregister the core with the PMM */
- malipmm_core_unregister( core->pmm_id );
-#endif
-}
-
-/* Used by external renderunit_create<> function */
-_mali_osk_errcode_t mali_core_renderunit_map_registers(mali_core_renderunit *core)
-{
- MALI_DEBUG_PRINT(3, ("Core: renderunit_map_registers: Core:%s\n", core->description)) ;
- if( (0 == core->registers_base_addr) ||
- (0 == core->size) ||
- (NULL == core->description)
- )
- {
- MALI_PRINT_ERROR(("Missing fields in the core structure %u %u 0x%x;\n", core->registers_base_addr, core->size, core->description));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(core->registers_base_addr, core->size, core->description))
- {
- MALI_PRINT_ERROR(("Could not request register region (0x%08X - 0x%08X) to core: %s\n",
- core->registers_base_addr, core->registers_base_addr + core->size - 1, core->description));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
- else
- {
- MALI_DEBUG_PRINT(6, ("Success: request_mem_region: (0x%08X - 0x%08X) Core:%s\n",
- core->registers_base_addr, core->registers_base_addr + core->size - 1, core->description));
- }
-
- core->registers_mapped = _mali_osk_mem_mapioregion( core->registers_base_addr, core->size, core->description );
-
- if ( 0 == core->registers_mapped )
- {
- MALI_PRINT_ERROR(("Could not ioremap registers for %s .\n", core->description));
- _mali_osk_mem_unreqregion(core->registers_base_addr, core->size);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
- else
- {
- MALI_DEBUG_PRINT(6, ("Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) Core:%s\n",
- (u32) core->registers_mapped,
- ((u32)core->registers_mapped)+ core->size - 1,
- core->description));
- }
-
- MALI_DEBUG_PRINT(4, ("Success: Mapping registers to core: %s\n",core->description));
-
- MALI_SUCCESS;
-}
-
-/* Used by external renderunit_create<> function + other places */
-void mali_core_renderunit_unmap_registers(mali_core_renderunit *core)
-{
- MALI_DEBUG_PRINT(3, ("Core: renderunit_unmap_registers: Core:%s\n", core->description));
- if (0 == core->registers_mapped)
- {
- MALI_PRINT_ERROR(("Trying to unmap register-mapping with NULL from core: %s\n", core->description));
- return;
- }
- _mali_osk_mem_unmapioregion(core->registers_base_addr, core->size, core->registers_mapped);
- core->registers_mapped = 0;
- _mali_osk_mem_unreqregion(core->registers_base_addr, core->size);
-}
-
-static void mali_core_renderunit_irq_handler_remove(mali_core_renderunit *core)
-{
- MALI_DEBUG_PRINT(3, ("Core: renderunit_irq_handler_remove: Core:%s\n", core->description));
- _mali_osk_irq_term(core->irq);
-}
-
-mali_core_renderunit * mali_core_renderunit_get_mali_core_nr(mali_core_subsystem *subsys, u32 mali_core_nr)
-{
- mali_core_renderunit * core;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- if (subsys->number_of_cores <= mali_core_nr)
- {
- MALI_PRINT_ERROR(("Trying to get illegal mali_core_nr: 0x%x for %s", mali_core_nr, subsys->name));
- return NULL;
- }
- core = (subsys->mali_core_array)[mali_core_nr];
- MALI_DEBUG_PRINT(6, ("Core: renderunit_get_mali_core_nr: Core:%s\n", core->description));
- MALI_CHECK_CORE(core);
- return core;
-}
-
-/* Is used by external function:
- subsystem_startup<> */
-_mali_osk_errcode_t mali_core_subsystem_init(mali_core_subsystem* new_subsys)
-{
- int i;
-
- /* These function pointers must have been set on before calling this function */
- if (
- ( NULL == new_subsys->name ) ||
- ( NULL == new_subsys->start_job ) ||
- ( NULL == new_subsys->irq_handler_upper_half ) ||
- ( NULL == new_subsys->irq_handler_bottom_half ) ||
- ( NULL == new_subsys->get_new_job_from_user ) ||
- ( NULL == new_subsys->return_job_to_user )
- )
- {
- MALI_PRINT_ERROR(("Missing functions in subsystem."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_DEBUG_PRINT(2, ("Core: subsystem_init: %s\n", new_subsys->name)) ;
-
- /* Catch use-before-initialize/use-after-terminate */
- MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex );
-
- new_subsys->magic_nr = SUBSYSTEM_MAGIC_NR;
-
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->renderunit_idle_head); /* Idle cores of this type */
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->renderunit_off_head); /* Powered off cores of this type */
-
- /* Linked list for each priority of sessions with a job ready for scheduleing */
- for(i=0; i<PRIORITY_LEVELS; ++i)
- {
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->awaiting_sessions_head[i]);
- }
-
- /* Linked list of all sessions connected to this coretype */
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->all_sessions_head);
-
- MALI_SUCCESS;
-}
-
-#if USING_MMU
-void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys)
-{
- u32 i;
- mali_core_renderunit * core;
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
- if ( NULL==core ) break;
- core->mmu = mali_memory_core_mmu_lookup(core->mmu_id);
- mali_memory_core_mmu_owner(core,core->mmu);
- MALI_DEBUG_PRINT(2, ("Attach mmu: 0x%x to core: %s in subsystem: %s\n", core->mmu, core->description, subsys->name));
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-}
-#endif
-
-/* This will register an IRQ handler, and add the core to the list of available cores for this subsystem. */
-_mali_osk_errcode_t mali_core_subsystem_register_renderunit(mali_core_subsystem* subsys, mali_core_renderunit * core)
-{
- mali_core_renderunit ** mali_core_array;
- u32 previous_nr;
- u32 previous_size;
- u32 new_nr;
- u32 new_size;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
-
- /* If any of these are 0 there is an error */
- if(0 == core->subsystem ||
- 0 == core->registers_base_addr ||
- 0 == core->size ||
- 0 == core->description)
- {
- MALI_PRINT_ERROR(("Missing fields in the core structure 0x%x 0x%x 0x%x;\n",
- core->registers_base_addr, core->size, core->description));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- MALI_DEBUG_PRINT(3, ("Core: subsystem_register_renderunit: %s\n", core->description));
-
- MALI_CHECK_NON_NULL(
- core->irq = _mali_osk_irq_init(
- core->irq_nr,
- mali_core_irq_handler_upper_half,
- mali_core_irq_handler_bottom_half,
- (_mali_osk_irq_trigger_t)subsys->probe_core_irq_trigger,
- (_mali_osk_irq_ack_t)subsys->probe_core_irq_acknowledge,
- core,
- "mali_core_irq_handlers"
- ),
- _MALI_OSK_ERR_FAULT
- );
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- /* Update which core number this is */
- core->core_number = subsys->number_of_cores;
-
- /* Update the array of cores in the subsystem. */
- previous_nr = subsys->number_of_cores;
- previous_size = sizeof(mali_core_renderunit*)*previous_nr;
- new_nr = previous_nr + 1;
- new_size = sizeof(mali_core_renderunit*)*new_nr;
-
- if (0 != previous_nr)
- {
- if (NULL == subsys->mali_core_array)
- {
- MALI_PRINT_ERROR(("Internal error"));
- goto exit_function;
- }
-
- mali_core_array = (mali_core_renderunit **) _mali_osk_malloc( new_size );
- if (NULL == mali_core_array )
- {
- MALI_PRINT_ERROR(("Out of mem"));
- err = _MALI_OSK_ERR_NOMEM;
- goto exit_function;
- }
- _mali_osk_memcpy(mali_core_array, subsys->mali_core_array, previous_size);
- _mali_osk_free( subsys->mali_core_array);
- MALI_DEBUG_PRINT(5, ("Success: adding a new core to subsystem array %s\n", core->description) ) ;
- }
- else
- {
- mali_core_array = (mali_core_renderunit **) _mali_osk_malloc( new_size );
- if (NULL == mali_core_array )
- {
- MALI_PRINT_ERROR(("Out of mem"));
- err = _MALI_OSK_ERR_NOMEM;
- goto exit_function;
- }
- MALI_DEBUG_PRINT(6, ("Success: adding first core to subsystem array %s\n", core->description) ) ;
- }
- subsys->mali_core_array = mali_core_array;
- mali_core_array[previous_nr] = core;
-
- /* Add the core to the list of available cores on the system */
- _mali_osk_list_add(&(core->list), &(subsys->renderunit_idle_head));
-
- /* Update total number of cores */
- subsys->number_of_cores = new_nr;
- MALI_DEBUG_PRINT(6, ("Success: mali_core_subsystem_register_renderunit %s\n", core->description));
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_SUCCESS;
-
-exit_function:
- mali_core_renderunit_irq_handler_remove(core);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_ERROR(err);
-}
-
-
-/**
- * Called by the core when a system info update is needed
- * We fill in info about all the core types available
- * @param subsys Pointer to the core's @a mali_core_subsystem data structure
- * @param info Pointer to system info struct to update
- * @return _MALI_OSK_ERR_OK on success, or another _mali_osk_errcode_t error code on failure
- */
-_mali_osk_errcode_t mali_core_subsystem_system_info_fill(mali_core_subsystem* subsys, _mali_system_info* info)
-{
- u32 i;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; /* OK if no cores to update info for */
- mali_core_renderunit * core;
- _mali_core_info **core_info_nextp;
- _mali_core_info * cinfo;
-
- MALI_DEBUG_PRINT(4, ("mali_core_subsystem_system_info_fill: %s\n", subsys->name) ) ;
-
- /* check input */
- MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS);
-
- core_info_nextp = &(info->core_info);
- cinfo = info->core_info;
-
- while(NULL!=cinfo)
- {
- core_info_nextp = &(cinfo->next);
- cinfo = cinfo->next;
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
- if ( NULL==core )
- {
- err = _MALI_OSK_ERR_FAULT;
- goto early_exit;
- }
- cinfo = (_mali_core_info *)_mali_osk_calloc(1, sizeof(_mali_core_info));
- if ( NULL==cinfo )
- {
- err = _MALI_OSK_ERR_NOMEM;
- goto early_exit;
- }
- cinfo->version = core->core_version;
- cinfo->type =subsys->core_type;
- cinfo->reg_address = core->registers_base_addr;
- cinfo->core_nr = i;
- cinfo->next = NULL;
- /* Writing this address to the previous' *(&next) ptr */
- *core_info_nextp = cinfo;
- /* Setting the next_ptr to point to &this->next_ptr */
- core_info_nextp = &(cinfo->next);
- }
-early_exit:
- if ( _MALI_OSK_ERR_OK != err) MALI_PRINT_ERROR(("Error: In mali_core_subsystem_system_info_fill %d\n", err));
- MALI_DEBUG_CODE(
- cinfo = info->core_info;
-
- MALI_DEBUG_PRINT(3, ("Current list of cores\n"));
- while( NULL != cinfo )
- {
- MALI_DEBUG_PRINT(3, ("Type: 0x%x\n", cinfo->type));
- MALI_DEBUG_PRINT(3, ("Version: 0x%x\n", cinfo->version));
- MALI_DEBUG_PRINT(3, ("Reg_addr: 0x%x\n", cinfo->reg_address));
- MALI_DEBUG_PRINT(3, ("Core_nr: 0x%x\n", cinfo->core_nr));
- MALI_DEBUG_PRINT(3, ("Flags: 0x%x\n", cinfo->flags));
- MALI_DEBUG_PRINT(3, ("*****\n"));
- cinfo = cinfo->next;
- }
- );
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_ERROR(err);
-}
-
-
-/* Is used by external function:
- subsystem_terminate<> */
-void mali_core_subsystem_cleanup(mali_core_subsystem* subsys)
-{
- u32 i;
- mali_core_renderunit * core;
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
- MALI_DEBUG_PRINT(2, ("Core: subsystem_cleanup: %s\n", subsys->name )) ;
-
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
-
-#if USING_MMU
- if (NULL != core->mmu)
- {
- /* the MMU is attached in the load_complete callback, which will never be called if the module fails to load, handle that case */
- mali_memory_core_mmu_unregister_callback(core->mmu, mali_core_subsystem_callback_schedule_wrapper);
- }
-#endif
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-
- mali_core_renderunit_irq_handler_remove(core);
-
- /* When a process terminates, all cores running jobs from that process is reset and put to idle.
- That means that when the module is unloading (this code) we are guaranteed that all cores are idle.
- However: if something (we can't think of) is really wrong, a core may give an interrupt during this
- unloading, and we may now in the code have a bottom-half-processing pending from the interrupts
- we deregistered above. To be sure that the bottom halves do not access the structures after they
- are deallocated we flush the bottom-halves processing here, before the deallocation. */
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
-#if USING_MALI_PMM
- /* Only reset when we are using PMM and the core is not off */
-#if MALI_PMM_NO_PMU
- /* We need to reset when there is no PMU - but this will
- * cause the register read/write functions to report an
- * error (hence the if to check for CORE_OFF below) we
- * change state to allow the reset to happen.
- */
- core->state = CORE_IDLE;
-#endif
- if( core->state != CORE_OFF )
- {
- subsys->reset_core( core, MALI_CORE_RESET_STYLE_DISABLE );
- }
-#else
- /* Always reset the core */
- subsys->reset_core( core, MALI_CORE_RESET_STYLE_DISABLE );
-#endif
-
- mali_core_renderunit_unmap_registers(core);
-
- _mali_osk_list_delinit(&core->list);
-
- mali_core_renderunit_term(core);
-
- subsys->renderunit_delete(core);
- }
-
- mali_core_subsystem_cleanup_all_renderunits(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT(6, ("SUCCESS: mali_core_subsystem_cleanup: %s\n", subsys->name )) ;
-}
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_session * session, u32 *number_of_cores)
-{
- mali_core_subsystem * subsystem;
-
- subsystem = session->subsystem;
- if ( NULL != number_of_cores )
- {
- *number_of_cores = subsystem->number_of_cores;
-
- MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ;
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data)
-{
- mali_core_subsystem * subsystem;
- _mali_osk_errcode_t err;
-
- /* need the subsystem to run callback function */
- subsystem = session->subsystem;
- MALI_CHECK_NON_NULL(subsystem, _MALI_OSK_ERR_FAULT);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
- err = subsystem->get_new_job_from_user(session, job_data);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- MALI_ERROR(err);
-}
-
-
-/* We return the version number to the first core in this subsystem */
-_mali_osk_errcode_t mali_core_subsystem_ioctl_core_version_get(mali_core_session * session, _mali_core_version *version)
-{
- mali_core_subsystem * subsystem;
- mali_core_renderunit * core0;
- u32 nr_return;
-
- subsystem = session->subsystem;
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
-
- core0 = mali_core_renderunit_get_mali_core_nr(subsystem, 0);
-
- if( NULL == core0 )
- {
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- nr_return = core0->core_version;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- MALI_DEBUG_PRINT(4, ("Core: ioctl_core_version_get: %s: %u\n", subsystem->name, nr_return )) ;
-
- *version = nr_return;
-
- MALI_SUCCESS;
-}
-
-void mali_core_subsystem_ioctl_abort_job(mali_core_session * session, u32 id)
-{
- find_and_abort(session, id);
-}
-
-static mali_bool job_should_be_aborted(mali_core_job *job, u32 abort_id)
-{
- if ( job->abort_id == abort_id ) return MALI_TRUE;
- else return MALI_FALSE;
-}
-
-static void find_and_abort(mali_core_session* session, u32 abort_id)
-{
- mali_core_subsystem * subsystem;
- mali_core_renderunit *core;
- mali_core_renderunit *tmp;
- mali_core_job *job;
-
- subsystem = session->subsystem;
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
-
- job = mali_job_queue_abort_job(session, abort_id);
- if (NULL != job)
- {
- MALI_DEBUG_PRINT(3, ("Core: Aborting %s job, with id nr: %u, from the waiting_to_run slot.\n", subsystem->name, abort_id ));
- if (mali_job_queue_empty(session))
- {
- _mali_osk_list_delinit(&(session->awaiting_sessions_list));
- }
- subsystem->awaiting_sessions_sum_all_priorities--;
- subsystem->return_job_to_user(job , JOB_STATUS_END_ABORT);
- }
-
- _MALI_OSK_LIST_FOREACHENTRY( core, tmp, &session->renderunits_working_head, mali_core_renderunit, list )
- {
- job = core->current_job;
- if ( (job!=NULL) && (job_should_be_aborted (job, abort_id) ) )
- {
- MALI_DEBUG_PRINT(3, ("Core: Aborting %s job, with id nr: %u, which is currently running on mali.\n", subsystem->name, abort_id ));
- if ( core->state==CORE_IDLE )
- {
- MALI_PRINT_ERROR(("Aborting core with running job which is idle. Must be something very wrong."));
- goto end_bug;
- }
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_ABORT);
- }
- }
-end_bug:
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem );
-}
-
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_suspend_response(mali_core_session * session, void *argument)
-{
- mali_core_subsystem * subsystem;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
-
- /* need the subsystem to run callback function */
- subsystem = session->subsystem;
- MALI_CHECK_NON_NULL(subsystem, _MALI_OSK_ERR_FAULT);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
- if ( NULL != subsystem->suspend_response)
- {
- MALI_DEBUG_PRINT(4, ("MALI_IOC_CORE_CMD_SUSPEND_RESPONSE start\n"));
- err = subsystem->suspend_response(session, argument);
- MALI_DEBUG_PRINT(4, ("MALI_IOC_CORE_CMD_SUSPEND_RESPONSE end\n"));
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- return err;
-}
-
-
-/* Is used by internal function:
- mali_core_subsystem_cleanup<>s */
-/* All cores should be removed before calling this function
-Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_cleanup_all_renderunits(mali_core_subsystem* subsys)
-{
- int i;
- _mali_osk_free(subsys->mali_core_array);
- subsys->number_of_cores = 0;
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_cleanup_all_renderunits: %s\n", subsys->name) ) ;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-
- if ( ! _mali_osk_list_empty(&(subsys->renderunit_idle_head)))
- {
- MALI_PRINT_ERROR(("List renderunit_list_idle should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->renderunit_idle_head)) ;
- }
-
- if ( ! _mali_osk_list_empty(&(subsys->renderunit_off_head)))
- {
- MALI_PRINT_ERROR(("List renderunit_list_off should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->renderunit_off_head)) ;
- }
-
- for(i=0; i<PRIORITY_LEVELS; ++i)
- {
- if ( ! _mali_osk_list_empty(&(subsys->awaiting_sessions_head[i])))
- {
- MALI_PRINT_ERROR(("List awaiting_sessions_linkedlist should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->awaiting_sessions_head[i])) ;
- subsys->awaiting_sessions_sum_all_priorities = 0;
- }
- }
-
- if ( ! _mali_osk_list_empty(&(subsys->all_sessions_head)))
- {
- MALI_PRINT_ERROR(("List all_sessions_linkedlist should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->all_sessions_head)) ;
- }
-}
-
-/* Is used by internal functions:
- mali_core_irq_handler_bottom_half<>;
- mali_core_subsystem_schedule<>; */
-/* Will release the core.*/
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core)
-{
- mali_core_subsystem *subsystem;
-#if USING_MALI_PMM
- mali_core_status oldstatus;
-#endif
- subsystem = core->subsystem;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
- MALI_CHECK_CORE(core);
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- _mali_osk_timer_del(core->timer);
- _mali_osk_timer_del(core->timer_hang_detection);
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_move_core_set_idle: %s\n", core->description) ) ;
-
- core->current_job = NULL ;
-
-#if USING_MALI_PMM
-
- oldstatus = core->state;
-
- if ( !core->pend_power_down )
- {
- core->state = CORE_IDLE ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head );
- }
-
- if( CORE_OFF != oldstatus )
- {
- /* Message that this core is now idle or in fact off */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_JOB_FINISHED,
- 0 };
- event.data = core->pmm_id;
- _mali_ukk_pmm_event_message( &event );
-#if USING_MMU
- /* Only free the reference when entering idle state from
- * anything other than power off
- */
- mali_memory_core_mmu_release_address_space_reference(core->mmu);
-#endif /* USING_MMU */
- }
-
- if( core->pend_power_down )
- {
- core->state = CORE_OFF ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head );
-
- /* Done the move from the active queues, so the pending power down can be done */
- core->pend_power_down = MALI_FALSE;
- malipmm_core_power_down_okay( core->pmm_id );
- }
-
-#else /* !USING_MALI_PMM */
-
- core->state = CORE_IDLE ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head );
-
-#if USING_MMU
- mali_memory_core_mmu_release_address_space_reference(core->mmu);
-#endif
-
-#endif /* USING_MALI_PMM */
-}
-
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_move_set_working(mali_core_renderunit *core, mali_core_job *job)
-{
- mali_core_subsystem *subsystem;
- mali_core_session *session;
- u64 time_now;
-
- session = job->session;
- subsystem = core->subsystem;
-
- MALI_CHECK_CORE(core);
- MALI_CHECK_JOB(job);
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_move_set_working: %s\n", core->description) ) ;
-
- time_now = _mali_osk_time_get_ns();
- job->start_time = time_now;
-#if MALI_GPU_UTILIZATION
- mali_utilization_core_start(time_now);
-#endif
-
- core->current_job = job ;
- core->state = CORE_WORKING ;
- _mali_osk_list_move( &core->list, &session->renderunits_working_head );
-
-}
-
-#if USING_MALI_PMM
-
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_move_core_set_off(mali_core_renderunit *core)
-{
- mali_core_subsystem *subsystem;
- subsystem = core->subsystem;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
- MALI_CHECK_CORE(core);
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- /* Cores must be idle before powering off */
- MALI_DEBUG_ASSERT(core->state == CORE_IDLE);
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_move_core_set_off: %s\n", core->description) ) ;
-
- core->current_job = NULL ;
- core->state = CORE_OFF ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head );
-}
-
-#endif /* USING_MALI_PMM */
-
-/* Is used by internal function:
- mali_core_subsystem_schedule<>; */
-/* Returns the job with the highest priority for the subsystem. NULL if none*/
-/* Must hold subsystem_mutex before entering this function */
-static mali_core_session * mali_core_subsystem_get_waiting_session(mali_core_subsystem *subsystem)
-{
- int i;
-
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- if ( 0 == subsystem->awaiting_sessions_sum_all_priorities )
- {
- MALI_DEBUG_PRINT(5, ("Core: subsystem_get_waiting_job: No awaiting session found\n"));
- return NULL;
- }
-
- for( i=0; i<PRIORITY_LEVELS ; ++i)
- {
- if (!_mali_osk_list_empty(&subsystem->awaiting_sessions_head[i]))
- {
- return _MALI_OSK_LIST_ENTRY(subsystem->awaiting_sessions_head[i].next, mali_core_session, awaiting_sessions_list);
- }
- }
-
- return NULL;
-}
-
-static mali_core_job * mali_core_subsystem_release_session_get_job(mali_core_subsystem *subsystem, mali_core_session * session)
-{
- mali_core_job *job;
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- job = mali_job_queue_get_job(session);
- subsystem->awaiting_sessions_sum_all_priorities--;
-
- if(mali_job_queue_empty(session))
- {
- /* This is the last job, so remove it from the list */
- _mali_osk_list_delinit(&session->awaiting_sessions_list);
- }
- else
- {
- if (0 == (job->flags & MALI_UK_START_JOB_FLAG_MORE_JOBS_FOLLOW))
- {
- /* There are more jobs, but the follow flag is not set, so let other sessions run their jobs first */
- _mali_osk_list_del(&(session->awaiting_sessions_list));
- _mali_osk_list_addtail(&(session->awaiting_sessions_list), &(subsystem->awaiting_sessions_head[
- session->queue[session->queue_head]->priority]));
- }
- /* else; keep on list, follow flag is set and there are more jobs in queue for this session */
- }
-
- MALI_CHECK_JOB(job);
- return job;
-}
-
-/* Is used by internal functions:
- mali_core_subsystem_schedule<> */
-/* This will start the job on the core. It will also release the core if it did not start.*/
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_job_start_on_core(mali_core_job *job, mali_core_renderunit *core)
-{
- mali_core_session *session;
- mali_core_subsystem *subsystem;
- _mali_osk_errcode_t err;
- session = job->session;
- subsystem = core->subsystem;
-
- MALI_CHECK_CORE(core);
- MALI_CHECK_JOB(job);
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_CHECK_SESSION(session);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- MALI_DEBUG_PRINT(4, ("Core: job_start_on_core: job=0x%x, session=0x%x, core=%s\n", job, session, core->description));
-
- MALI_DEBUG_ASSERT(NULL == core->current_job) ;
- MALI_DEBUG_ASSERT(CORE_IDLE == core->state );
-
- mali_core_subsystem_move_set_working(core, job);
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == (job->flags & MALI_UK_START_JOB_FLAG_NO_FLUSH))
- {
- /* Invalidate the L2 cache */
- if (_MALI_OSK_ERR_OK != mali_kernel_l2_cache_invalidate_all() )
- {
- MALI_DEBUG_PRINT(4, ("Core: Clear of L2 failed, return job. System may not be usable for some reason.\n"));
- mali_core_subsystem_move_core_set_idle(core);
- subsystem->return_job_to_user(job,JOB_STATUS_END_SYSTEM_UNUSABLE );
- return;
- }
- }
-#endif
-
- /* Tries to start job on the core. Returns MALI_FALSE if the job could not be started */
- err = subsystem->start_job(job, core);
-
- if ( _MALI_OSK_ERR_OK != err )
- {
- /* This will happen only if there is something in the job object
- which make it inpossible to start. Like if it require illegal memory.*/
- MALI_DEBUG_PRINT(4, ("Core: start_job failed, return job and putting core back into idle list\n"));
- mali_core_subsystem_move_core_set_idle(core);
- subsystem->return_job_to_user(job,JOB_STATUS_END_ILLEGAL_JOB );
- }
- else
- {
- u32 delay = _mali_osk_time_mstoticks(job->watchdog_msecs)+1;
- job->watchdog_jiffies = _mali_osk_time_tickcount() + delay;
- if (mali_benchmark)
- {
- _mali_osk_timer_add(core->timer, 1);
- }
- else
- {
- _mali_osk_timer_add(core->timer, delay);
- }
- }
-}
-
-#if USING_MMU
-static void mali_core_subsystem_callback_schedule_wrapper(void* sub)
-{
- mali_core_subsystem * subsystem;
- subsystem = (mali_core_subsystem *)sub;
- MALI_DEBUG_PRINT(3, ("MMU: Is schedulling subsystem: %s\n", subsystem->name));
- mali_core_subsystem_schedule(subsystem);
-}
-#endif
-
-/* Is used by internal function:
- mali_core_irq_handler_bottom_half
- mali_core_session_add_job
-*/
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_schedule(mali_core_subsystem * subsystem)
-{
- mali_core_renderunit *core, *tmp;
- mali_core_session *session;
- mali_core_job *job;
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_schedule: %s\n", subsystem->name )) ;
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- /* First check that there are sessions with jobs waiting to run */
- if ( 0 == subsystem->awaiting_sessions_sum_all_priorities)
- {
- MALI_DEBUG_PRINT(6, ("Core: No jobs available for %s\n", subsystem->name) ) ;
- return;
- }
-
- /* Returns the session with the highest priority job for the subsystem. NULL if none*/
- session = mali_core_subsystem_get_waiting_session(subsystem);
-
- if (NULL == session)
- {
- MALI_DEBUG_PRINT(6, ("Core: Schedule: No runnable job found\n"));
- return;
- }
-
- _MALI_OSK_LIST_FOREACHENTRY(core, tmp, &subsystem->renderunit_idle_head, mali_core_renderunit, list)
- {
-#if USING_MMU
- int err = mali_memory_core_mmu_activate_page_table(core->mmu, session->mmu_session, mali_core_subsystem_callback_schedule_wrapper, subsystem);
- if (0 == err)
- {
- /* core points to a core where the MMU page table activation succeeded */
-#endif
- /* This will remove the job from queue system */
- job = mali_core_subsystem_release_session_get_job(subsystem, session);
- MALI_DEBUG_ASSERT_POINTER(job);
-
- MALI_DEBUG_PRINT(6, ("Core: Schedule: Got a job 0x%x\n", job));
-
-#if USING_MALI_PMM
- {
- /* Message that there is a job scheduled to run
- * NOTE: mali_core_job_start_on_core() can fail to start
- * the job for several reasons, but it will move the core
- * back to idle which will create the FINISHED message
- * so we can still say that the job is SCHEDULED
- */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_JOB_SCHEDULED,
- 0 };
- event.data = core->pmm_id;
- _mali_ukk_pmm_event_message( &event );
- }
-#endif
- /* This will {remove core from freelist AND start the job on the core}*/
- mali_core_job_start_on_core(job, core);
-
- MALI_DEBUG_PRINT(6, ("Core: Schedule: Job started, done\n"));
- return;
-#if USING_MMU
- }
-#endif
- }
- MALI_DEBUG_PRINT(6, ("Core: Schedule: Could not activate MMU. Scheduelling postponed to MMU, checking next.\n"));
-
-#if USING_MALI_PMM
- {
- /* Message that there are jobs to run */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_JOB_QUEUED,
- 0 };
- if( subsystem->core_type == _MALI_GP2 || subsystem->core_type == _MALI_400_GP )
- {
- event.data = MALI_PMM_CORE_GP;
- }
- else
- {
- /* Check the PP is supported by the PMM */
- MALI_DEBUG_ASSERT( subsystem->core_type == _MALI_200 || subsystem->core_type == _MALI_400_PP );
- /* We state that all PP cores are scheduled to inform the PMM
- * that it may need to power something up!
- */
- event.data = MALI_PMM_CORE_PP_ALL;
- }
- _mali_ukk_pmm_event_message( &event );
- }
-#endif /* USING_MALI_PMM */
-
-}
-
-/* Is used by external function:
- session_begin<> */
-void mali_core_session_begin(mali_core_session * session)
-{
- mali_core_subsystem * subsystem;
- int i;
-
- subsystem = session->subsystem;
- if ( NULL == subsystem )
- {
- MALI_PRINT_ERROR(("Missing data in struct\n"));
- return;
- }
- MALI_DEBUG_PRINT(2, ("Core: session_begin: for %s\n", session->subsystem->name )) ;
-
- session->magic_nr = SESSION_MAGIC_NR;
-
- _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head);
-
- for (i = 0; i < MALI_JOB_QUEUE_SIZE; i++)
- {
- session->queue[i] = NULL;
- }
- session->queue_head = 0;
- session->queue_tail = 0;
- _MALI_OSK_INIT_LIST_HEAD(&session->awaiting_sessions_list);
- _MALI_OSK_INIT_LIST_HEAD(&session->all_sessions_list);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
- _mali_osk_list_add(&session->all_sessions_list, &session->subsystem->all_sessions_head);
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_init(&session->jobs_received, 0);
- _mali_osk_atomic_init(&session->jobs_returned, 0);
- session->pid = _mali_osk_get_pid();
-#endif
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- MALI_DEBUG_PRINT(5, ("Core: session_begin: for %s DONE\n", session->subsystem->name) ) ;
-}
-
-#if USING_MMU
-static void mali_core_renderunit_stop_bus(mali_core_renderunit* core)
-{
- core->subsystem->stop_bus(core);
-}
-#endif
-
-void mali_core_session_close(mali_core_session * session)
-{
- mali_core_subsystem * subsystem;
- mali_core_renderunit *core;
-
- subsystem = session->subsystem;
- MALI_DEBUG_ASSERT_POINTER(subsystem);
-
- MALI_DEBUG_PRINT(2, ("Core: session_close: for %s\n", session->subsystem->name) ) ;
-
- /* We must grab subsystem mutex since the list this session belongs to
- is owned by the subsystem */
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
-
- /* Remove this session from the global sessionlist */
- _mali_osk_list_delinit(&session->all_sessions_list);
-
- _mali_osk_list_delinit(&(session->awaiting_sessions_list));
-
- /* Return the potensial waiting job to user */
- while ( !mali_job_queue_empty(session) )
- {
- /* Queue not empty */
- mali_core_job *job = mali_job_queue_get_job(session);
- subsystem->return_job_to_user( job, JOB_STATUS_END_SHUTDOWN );
- subsystem->awaiting_sessions_sum_all_priorities--;
- }
-
- /* Kill active cores working for this session - freeing their jobs
- Since the handling of one core also could stop jobs from another core, there is a while loop */
- while ( ! _mali_osk_list_empty(&session->renderunits_working_head) )
- {
- core = _MALI_OSK_LIST_ENTRY(session->renderunits_working_head.next, mali_core_renderunit, list);
- MALI_DEBUG_PRINT(3, ("Core: session_close: Core was working: %s\n", core->description )) ;
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_SHUTDOWN );
- }
- _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head); /* Not necessary - we will _mali_osk_free session*/
-
- MALI_DEBUG_PRINT(5, ("Core: session_close: for %s FINISHED\n", session->subsystem->name )) ;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem );
-}
-
-/* Must hold subsystem_mutex before entering this function */
-_mali_osk_errcode_t mali_core_session_add_job(mali_core_session * session, mali_core_job *job, mali_core_job **job_return)
-{
- mali_core_subsystem * subsystem;
-
- job->magic_nr = JOB_MAGIC_NR;
- MALI_CHECK_SESSION(session);
-
- subsystem = session->subsystem;
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- MALI_DEBUG_PRINT(5, ("Core: session_add_job: for %s\n", subsystem->name )) ;
-
- /* Setting the default value; No job to return */
- MALI_DEBUG_ASSERT_POINTER(job_return);
- *job_return = NULL;
-
- if (mali_job_queue_empty(session))
- {
- /* Add session to the wait list only if it didn't already have a job waiting. */
- _mali_osk_list_addtail( &(session->awaiting_sessions_list), &(subsystem->awaiting_sessions_head[job->priority]));
- }
-
-
- if (_MALI_OSK_ERR_OK != mali_job_queue_add_job(session, job))
- {
- if (mali_job_queue_empty(session))
- {
- _mali_osk_list_delinit(&(session->awaiting_sessions_list));
- }
- MALI_DEBUG_PRINT(4, ("Core: session_add_job: %s queue is full\n", subsystem->name));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Continue to add the new job as the next job from this session */
- MALI_DEBUG_PRINT(6, ("Core: session_add_job job=0x%x\n", job));
-
- subsystem->awaiting_sessions_sum_all_priorities++;
-
- mali_core_subsystem_schedule(subsystem);
-
- MALI_DEBUG_PRINT(6, ("Core: session_add_job: for %s FINISHED\n", session->subsystem->name )) ;
-
- MALI_SUCCESS;
-}
-
-static void mali_core_job_set_run_time(mali_core_job * job, u64 end_time)
- {
- u32 time_used_nano_seconds;
-
- time_used_nano_seconds = end_time - job->start_time;
- job->render_time_usecs = time_used_nano_seconds / 1000;
-}
-
-static void mali_core_renderunit_detach_job_from_core(mali_core_renderunit* core, mali_subsystem_reschedule_option reschedule, mali_subsystem_job_end_code end_status)
-{
- mali_core_job * job;
- mali_core_subsystem * subsystem;
- mali_bool already_in_detach_function;
- u64 time_now;
-
- MALI_DEBUG_ASSERT(CORE_IDLE != core->state);
- time_now = _mali_osk_time_get_ns();
- job = core->current_job;
- subsystem = core->subsystem;
-
- /* The reset_core() called some lines below might call this detach
- * funtion again. To protect the core object from being modified by
- * recursive calls, the in_detach_function would track if it is an recursive call
- */
- already_in_detach_function = core->in_detach_function;
-
-
- if ( MALI_FALSE == already_in_detach_function )
- {
- core->in_detach_function = MALI_TRUE;
- if ( NULL != job )
- {
- mali_core_job_set_run_time(job, time_now);
- core->current_job = NULL;
- }
- }
-
- if (JOB_STATUS_END_SEG_FAULT == end_status)
- {
- subsystem->reset_core( core, MALI_CORE_RESET_STYLE_HARD );
- }
- else
- {
- subsystem->reset_core( core, MALI_CORE_RESET_STYLE_RUNABLE );
- }
-
- if ( MALI_FALSE == already_in_detach_function )
- {
- if ( CORE_IDLE != core->state )
- {
- #if MALI_GPU_UTILIZATION
- mali_utilization_core_end(time_now);
- #endif
- mali_core_subsystem_move_core_set_idle(core);
- }
-
- core->in_detach_function = MALI_FALSE;
-
- if ( SUBSYSTEM_RESCHEDULE == reschedule )
- {
- mali_core_subsystem_schedule(subsystem);
- }
- if ( NULL != job )
- {
- core->subsystem->return_job_to_user(job, end_status);
- }
- }
-}
-
-#if USING_MMU
-/* This function intentionally does not release the semaphore. You must run
- stop_bus_for_all_cores(), reset_all_cores_on_mmu() and continue_job_handling()
- after calling this function, and then call unlock_subsystem() to release the
- semaphore. */
-
-static void lock_subsystem(struct mali_core_subsystem * subsys)
-{
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* You must run lock_subsystem() before entering this function, to ensure that
- the subsystem mutex is held.
- Later, unlock_subsystem() can be called to release the mutex.
-
- This function only stops cores behind the given MMU, unless "mmu" is NULL, in
- which case all cores are stopped.
-*/
-static void stop_bus_for_all_cores_on_mmu(struct mali_core_subsystem * subsys, void* mmu)
-{
- u32 i;
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- MALI_DEBUG_PRINT(2,("Handling: bus stop %s\n", subsys->name ));
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- mali_core_renderunit * core;
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
-
- /* We stop only cores behind the given MMU, unless MMU is NULL */
- if ( (NULL!=mmu) && (core->mmu != mmu) ) continue;
-
- if ( CORE_IDLE != core->state )
- {
- MALI_DEBUG_PRINT(4, ("Stopping bus on core %s\n", core->description));
- mali_core_renderunit_stop_bus(core);
- core->error_recovery = MALI_TRUE;
- }
- else
- {
- MALI_DEBUG_PRINT(4,("Core: not active %s\n", core->description ));
- }
- }
- /* Mutex is still being held, to prevent things to happen while we do cleanup */
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* You must run lock_subsystem() before entering this function, to ensure that
- the subsystem mutex is held.
- Later, unlock_subsystem() can be called to release the mutex.
-
- This function only resets cores behind the given MMU, unless "mmu" is NULL, in
- which case all cores are reset.
-*/
-static void reset_all_cores_on_mmu(struct mali_core_subsystem * subsys, void* mmu)
-{
- u32 i;
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- MALI_DEBUG_PRINT(3, ("Handling: reset cores from mmu: 0x%x on %s\n", mmu, subsys->name ));
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- mali_core_renderunit * core;
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
-
- /* We reset only cores behind the given MMU, unless MMU is NULL */
- if ( (NULL!=mmu) && (core->mmu != mmu) ) continue;
-
- if ( CORE_IDLE != core->state )
- {
- MALI_DEBUG_PRINT(4, ("Abort and reset core: %s\n", core->description ));
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_WAIT, JOB_STATUS_END_SEG_FAULT);
- }
- else
- {
- MALI_DEBUG_PRINT(4, ("Core: not active %s\n", core->description ));
- }
- }
- MALI_DEBUG_PRINT(4, ("Handling: done %s\n", subsys->name ));
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* You must run lock_subsystem() before entering this function, to ensure that
- the subsystem mutex is held.
- Later, unlock_subsystem() can be called to release the mutex. */
-static void continue_job_handling(struct mali_core_subsystem * subsys)
-{
- u32 i, j;
-
- MALI_DEBUG_PRINT(3, ("Handling: Continue: %s\n", subsys->name ));
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-
-
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- mali_core_renderunit * core;
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
- core->error_recovery = MALI_FALSE;
- }
-
- i = subsys->number_of_cores;
- j = subsys->awaiting_sessions_sum_all_priorities;
-
- /* Schedule MIN(nr_waiting_jobs , number of cores) times */
- while( i-- && j--)
- {
- mali_core_subsystem_schedule(subsys);
- }
- MALI_DEBUG_PRINT(4, ("Handling: done %s\n", subsys->name ));
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* Unlock the subsystem. */
-static void unlock_subsystem(struct mali_core_subsystem * subsys)
-{
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-}
-
-void mali_core_subsystem_broadcast_notification(struct mali_core_subsystem * subsys, mali_core_notification_message message, u32 data)
-{
- void * mmu;
- mmu = (void*) data;
-
- switch(message)
- {
- case MMU_KILL_STEP0_LOCK_SUBSYSTEM:
- break;
- case MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES:
- stop_bus_for_all_cores_on_mmu(subsys, mmu);
- break;
- case MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS:
- reset_all_cores_on_mmu(subsys, mmu );
- break;
- case MMU_KILL_STEP3_CONTINUE_JOB_HANDLING:
- continue_job_handling(subsys);
- break;
- case MMU_KILL_STEP4_UNLOCK_SUBSYSTEM:
- break;
-
- default:
- MALI_PRINT_ERROR(("Illegal message: 0x%x, data: 0x%x\n", (u32)message, data));
- break;
- }
-}
-#endif /* USING_MMU */
-
-void job_watchdog_set(mali_core_job * job, u32 watchdog_msecs)
-{
- if (watchdog_msecs == 0) job->watchdog_msecs = mali_max_job_runtime; /* use the default */
- else if (watchdog_msecs > WATCHDOG_MSECS_MAX) job->watchdog_msecs = WATCHDOG_MSECS_MAX; /* no larger than max */
- else if (watchdog_msecs < WATCHDOG_MSECS_MIN) job->watchdog_msecs = WATCHDOG_MSECS_MIN; /* not below min */
- else job->watchdog_msecs = watchdog_msecs;
-}
-
-u32 mali_core_hang_check_timeout_get(void)
-{
- /* check the value. The user might have set the value outside the allowed range */
- if (mali_hang_check_interval > HANG_CHECK_MSECS_MAX) mali_hang_check_interval = HANG_CHECK_MSECS_MAX; /* cap to max */
- else if (mali_hang_check_interval < HANG_CHECK_MSECS_MIN) mali_hang_check_interval = HANG_CHECK_MSECS_MIN; /* cap to min */
-
- /* return the active value */
- return mali_hang_check_interval;
-}
-
-static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data)
-{
- mali_core_renderunit *core;
- u32 has_pending_irq;
-
- core = (mali_core_renderunit * )data;
-
- if(core && (CORE_OFF == core->state))
- {
- MALI_SUCCESS;
- }
-
- if ( (NULL == core) ||
- (NULL == core->subsystem) ||
- (NULL == core->subsystem->irq_handler_upper_half) )
- {
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
- MALI_CHECK_CORE(core);
- MALI_CHECK_SUBSYSTEM(core->subsystem);
-
- has_pending_irq = core->subsystem->irq_handler_upper_half(core);
-
- if ( has_pending_irq )
- {
- _mali_osk_irq_schedulework( core->irq ) ;
- MALI_SUCCESS;
- }
-
- if (mali_benchmark) MALI_SUCCESS;
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-static void mali_core_irq_handler_bottom_half ( void *data )
-{
- mali_core_renderunit *core;
- mali_core_subsystem* subsystem;
-
- mali_subsystem_job_end_code job_status;
-
- core = (mali_core_renderunit * )data;
-
- MALI_CHECK_CORE(core);
- subsystem = core->subsystem;
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
- if ( CORE_IDLE == core->state || CORE_OFF == core->state ) goto end_function;
-
- MALI_DEBUG_PRINT(5, ("IRQ: handling irq from core %s\n", core->description )) ;
-
- _mali_osk_cache_flushall();
-
- /* This function must also update the job status flag */
- job_status = subsystem->irq_handler_bottom_half( core );
-
- /* Retval is nonzero if the job is finished. */
- if ( JOB_STATUS_CONTINUE_RUN != job_status )
- {
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, job_status);
- }
- else
- {
- switch ( core->state )
- {
- case CORE_WATCHDOG_TIMEOUT:
- MALI_DEBUG_PRINT(2, ("Watchdog SW Timeout of job from core: %s\n", core->description ));
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_TIMEOUT_SW );
- break;
-
- case CORE_POLL:
- MALI_DEBUG_PRINT(5, ("Poll core: %s\n", core->description )) ;
- core->state = CORE_WORKING;
- _mali_osk_timer_add( core->timer, 1);
- break;
-
- default:
- MALI_DEBUG_PRINT(4, ("IRQ: The job on the core continue to run: %s\n", core->description )) ;
- break;
- }
- }
-end_function:
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-}
-
-void subsystem_flush_mapped_mem_cache(void)
-{
- _mali_osk_cache_flushall();
- _mali_osk_mem_barrier();
-}
-
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool immediate_only)
-{
- mali_core_renderunit * core = NULL;
-
- MALI_CHECK_SUBSYSTEM(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- /* It is possible that this signal funciton can be called during a driver exit,
- * and so the requested core may now be destroyed. (This is due to us not having
- * the subsys lock before signalling power down).
- * mali_core_renderunit_get_mali_core_nr() will report a Mali ERR because
- * the core number is out of range (which is a valid error in other cases).
- * So instead we check here (now that we have the subsys lock) and let the
- * caller cope with the core get failure and check that the core has
- * been unregistered in the PMM as part of its destruction.
- */
- if ( subsys->number_of_cores > mali_core_nr )
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys, mali_core_nr);
- }
-
- if ( NULL == core )
- {
- /* Couldn't find the core */
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power down\n") );
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- else if ( core->state != CORE_IDLE )
- {
- /* When powering down we either set a pending power down flag here so we
- * can power down cleanly after the job completes or we don't set the
- * flag if we have been asked to only do a power down right now
- * In either case, return that the core is busy
- */
- if ( !immediate_only ) core->pend_power_down = MALI_TRUE;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 5, ("Core: No idle core to power down\n") );
- MALI_ERROR(_MALI_OSK_ERR_BUSY);
- }
-
- /* Shouldn't have a pending power down flag set */
- MALI_DEBUG_ASSERT( !core->pend_power_down );
-
- /* Move core to off queue */
- mali_core_subsystem_move_core_set_off(core);
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool queue_only)
-{
- mali_core_renderunit * core;
-
- MALI_CHECK_SUBSYSTEM(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- core = mali_core_renderunit_get_mali_core_nr(subsys, mali_core_nr);
-
- if( core == NULL )
- {
- /* Couldn't find the core */
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power up\n") );
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- else if( core->state != CORE_OFF )
- {
- /* This will usually happen because we are trying to cancel a pending power down */
- core->pend_power_down = MALI_FALSE;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 1, ("Core: No powered off core to power up (cancelled power down?)\n") );
- MALI_ERROR(_MALI_OSK_ERR_BUSY);
- }
-
- /* Shouldn't have a pending power down set */
- MALI_DEBUG_ASSERT( !core->pend_power_down );
-
- /* Move core to idle queue */
- mali_core_subsystem_move_core_set_idle(core);
-
- if( !queue_only )
- {
- /* Reset MMU & core - core must be idle to allow this */
-#if USING_MMU
- if ( NULL!=core->mmu )
- {
-#if defined(USING_MALI200)
- if (core->pmm_id != MALI_PMM_CORE_PP0)
- {
-#endif
- mali_kernel_mmu_reset(core->mmu);
-#if defined(USING_MALI200)
- }
-#endif
-
- }
-#endif /* USING_MMU */
- subsys->reset_core( core, MALI_CORE_RESET_STYLE_RUNABLE );
- }
-
- /* Need to schedule work to start on this core */
- mali_core_subsystem_schedule(subsys);
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-
- MALI_SUCCESS;
-}
-
-#endif /* USING_MALI_PMM */
-
-#if MALI_STATE_TRACKING
-u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size)
-{
- u32 i, len = 0;
- mali_core_renderunit *core;
- mali_core_renderunit *tmp_core;
-
- mali_core_session* session;
- mali_core_session* tmp_session;
-
- if (0 >= size)
- {
- return 0;
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
-
- len += _mali_osk_snprintf(buf + len, size - len, "Subsystem:\n");
- len += _mali_osk_snprintf(buf + len, size - len, " Name: %s\n", subsystem->name);
-
- for (i = 0; i < subsystem->number_of_cores; i++)
- {
- len += _mali_osk_snprintf(buf + len, size - len, " Core: #%u\n",
- subsystem->mali_core_array[i]->core_number);
- len += _mali_osk_snprintf(buf + len, size - len, " Description: %s\n",
- subsystem->mali_core_array[i]->description);
- switch(subsystem->mali_core_array[i]->state)
- {
- case CORE_IDLE:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_IDLE\n");
- break;
- case CORE_WORKING:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WORKING\n");
- break;
- case CORE_WATCHDOG_TIMEOUT:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WATCHDOG_TIMEOUT\n");
- break;
- case CORE_POLL:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_POLL\n");
- break;
- case CORE_HANG_CHECK_TIMEOUT:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_HANG_CHECK_TIMEOUT\n");
- break;
- case CORE_OFF:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_OFF\n");
- break;
- default:
- len += _mali_osk_snprintf(buf + len, size - len, " State: Unknown (0x%X)\n",
- subsystem->mali_core_array[i]->state);
- break;
- }
- len += _mali_osk_snprintf(buf + len, size - len, " Current job: 0x%X\n",
- (u32)(subsystem->mali_core_array[i]->current_job));
- if (subsystem->mali_core_array[i]->current_job)
- {
- u64 time_used_nano_seconds;
- u32 time_used_micro_seconds;
- u64 time_now = _mali_osk_time_get_ns();
-
- time_used_nano_seconds = time_now - subsystem->mali_core_array[i]->current_job->start_time;
- time_used_micro_seconds = ((u32)(time_used_nano_seconds)) / 1000;
-
- len += _mali_osk_snpr