aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authormcampbellsmith <mcampbellsmith@gmail.com>2013-11-20 22:34:44 +1100
committersbrissen <sbrissen@hotmail.com>2013-12-10 14:54:28 -0500
commit74bcc029c6ab942f252477a74102877f7d093388 (patch)
tree044bd97b98693c073841663c62f57e1520509109 /drivers
parent2a6649bf6aa50c44a05fc02e1efb8b788c58e82b (diff)
downloadkernel_samsung_smdk4412-74bcc029c6ab942f252477a74102877f7d093388.zip
kernel_samsung_smdk4412-74bcc029c6ab942f252477a74102877f7d093388.tar.gz
kernel_samsung_smdk4412-74bcc029c6ab942f252477a74102877f7d093388.tar.bz2
mali: bulk import of r3p2-01rel3 drivers from i9300-update12
Courtesy of a similar commit from OMNI ROM. Requires updated mali blobs Change-Id: I9ee55b653b57b7c390f8e0e8cd4fc068f1c751c3
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/base/sync.c321
-rw-r--r--drivers/gpu/Makefile6
-rw-r--r--drivers/gpu/mali400/Kconfig26
-rw-r--r--drivers/gpu/mali400/r3p2/mali/Kbuild220
-rw-r--r--drivers/gpu/mali400/r3p2/mali/Kconfig67
-rw-r--r--drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION24
-rw-r--r--drivers/gpu/mali400/r3p2/mali/Makefile (renamed from drivers/media/video/samsung/mali/Makefile_module)85
-rw-r--r--drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c1
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c (renamed from drivers/media/video/samsung/mali/common/mali_block_allocator.c)3
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.h (renamed from drivers/media/video/samsung/mali/common/mali_block_allocator.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c129
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h52
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c (renamed from drivers/media/video/samsung/mali/common/mali_dlbu.c)166
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h (renamed from drivers/media/video/samsung/mali/common/mali_dlbu.h)29
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp.c364
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp.h96
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c116
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h (renamed from drivers/media/video/samsung/mali/common/mali_gp_job.h)59
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c571
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h (renamed from drivers/media/video/samsung/mali/common/mali_gp_scheduler.h)21
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_group.c2046
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_group.h283
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c (renamed from drivers/media/video/samsung/mali/common/mali_hw_core.c)1
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h (renamed from drivers/media/video/samsung/mali/common/mali_hw_core.h)37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_common.h)3
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c1293
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_core.h)18
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c (renamed from drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c (renamed from drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c)11
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c (renamed from drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c)1
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c420
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_utilization.h)36
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c (renamed from drivers/media/video/samsung/mali/common/mali_kernel_vsync.c)4
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c (renamed from drivers/media/video/samsung/mali/common/mali_l2_cache.c)181
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h (renamed from drivers/media/video/samsung/mali/common/mali_l2_cache.h)42
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c (renamed from drivers/media/video/samsung/mali/common/mali_mem_validation.c)46
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h (renamed from drivers/media/video/samsung/mali/common/mali_mem_validation.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_memory.c (renamed from drivers/media/video/samsung/mali/common/mali_memory.c)98
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_memory.h (renamed from drivers/media/video/samsung/mali/common/mali_memory.h)14
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c (renamed from drivers/media/video/samsung/mali/common/mali_mmu.c)293
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h130
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c (renamed from drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c)50
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h (renamed from drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk.h (renamed from drivers/media/video/samsung/mali/common/mali_osk.h)393
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.h (renamed from drivers/media/video/samsung/mali/common/mali_osk_bitops.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h (renamed from drivers/media/video/samsung/mali/common/mali_osk_list.h)37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h (renamed from drivers/media/video/samsung/mali/common/mali_osk_mali.h)83
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h (renamed from drivers/media/video/samsung/mali/common/mali_osk_profiling.h)24
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm.c144
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm.h (renamed from drivers/media/video/samsung/mali/common/mali_pm.h)34
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c240
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h73
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c405
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h (renamed from drivers/media/video/samsung/mali/common/mali_pmu.h)53
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp.c521
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp.h127
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c169
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h (renamed from drivers/media/video/samsung/mali/common/mali_pp_job.h)179
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c1890
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h80
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c (renamed from drivers/media/video/samsung/mali/common/mali_scheduler.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h (renamed from drivers/media/video/samsung/mali/common/mali_scheduler.h)26
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_session.c (renamed from drivers/media/video/samsung/mali/common/mali_session.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_session.h (renamed from drivers/media/video/samsung/mali/common/mali_session.h)7
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h (renamed from drivers/media/video/samsung/mali/common/mali_ukk.h)28
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c (renamed from drivers/media/video/samsung/mali/common/mali_user_settings_db.c)11
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h (renamed from drivers/media/video/samsung/mali/common/mali_user_settings_db.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h390
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h (renamed from drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h (renamed from drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h)4
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h (renamed from drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h)51
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h202
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h (renamed from drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h)76
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.h (renamed from drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c (renamed from drivers/media/video/samsung/mali/common/mali_device_pause_resume.c)23
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c480
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h (renamed from drivers/media/video/samsung/mali/linux/mali_dma_buf.h)11
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c (renamed from drivers/media/video/samsung/mali/linux/mali_kernel_linux.c)496
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h (renamed from drivers/media/video/samsung/mali/linux/mali_kernel_linux.h)8
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c (renamed from drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c)857
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h (renamed from drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h)9
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h (renamed from drivers/media/video/samsung/mali/linux/mali_linux_trace.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_atomics.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c139
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_locks.c)59
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c)77
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c140
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_math.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_memory.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_misc.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_notification.c)100
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c110
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c)144
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_time.c)6
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_timers.c)18
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c (renamed from drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c124
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c (renamed from drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c)14
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h (renamed from drivers/media/video/samsung/mali/linux/mali_profiling_events.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h (renamed from drivers/media/video/samsung/ump/arch-pb-virtex5/config.h)11
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c300
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h36
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c273
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h102
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c183
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h (renamed from drivers/media/video/samsung/mali/linux/mali_uk_types.h)3
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_core.c)70
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_gp.c)37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_mem.c)48
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_pp.c)45
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h (renamed from drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h)10
-rw-r--r--drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c405
-rw-r--r--drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c1373
-rw-r--r--drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h121
-rw-r--r--drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h (renamed from drivers/media/video/samsung/mali/regs/mali_200_regs.h)54
-rw-r--r--drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h (renamed from drivers/media/video/samsung/mali/regs/mali_gp_regs.h)49
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c (renamed from drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.h (renamed from drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c (renamed from drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.h (renamed from drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Kbuild78
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Kconfig7
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Makefile67
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Makefile.common (renamed from drivers/media/video/samsung/ump/Makefile.common)8
-rw-r--r--drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h (renamed from drivers/media/video/samsung/ump/arch-orion-m400/config.h)0
l---------drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m4001
-rw-r--r--drivers/gpu/mali400/r3p2/ump/arch/config.h (renamed from drivers/media/video/samsung/ump/arch-pegasus-m400/config.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c (renamed from drivers/media/video/samsung/ump/common/ump_kernel_api.c)11
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c (renamed from drivers/media/video/samsung/ump/common/ump_kernel_common.c)3
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h (renamed from drivers/media/video/samsung/ump/common/ump_kernel_common.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c (renamed from drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c)35
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.h (renamed from drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h (renamed from drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h)8
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c (renamed from drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c)3
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h (renamed from drivers/media/video/samsung/ump/common/ump_kernel_types.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_osk.h (renamed from drivers/media/video/samsung/ump/common/ump_osk.h)5
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h (renamed from drivers/media/video/samsung/ump/common/ump_ukk.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h (renamed from drivers/media/video/samsung/ump/include/ump_kernel_interface.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h (renamed from drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h)4
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h (renamed from drivers/media/video/samsung/ump/include/ump_kernel_platform.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h (renamed from drivers/media/video/samsung/ump/common/ump_uk_types.h)8
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h (renamed from drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h (renamed from drivers/media/video/samsung/ump/linux/ump_ioctl.h)6
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c (renamed from drivers/media/video/samsung/ump/linux/ump_kernel_linux.c)22
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h (renamed from drivers/media/video/samsung/ump/linux/ump_kernel_linux.h)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c (renamed from drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c)7
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.h (renamed from drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c (renamed from drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c)13
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.h (renamed from drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h)2
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c (renamed from drivers/media/video/samsung/ump/linux/ump_memory_backend.c)3
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c (renamed from drivers/media/video/samsung/ump/linux/ump_osk_atomics.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c (renamed from drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c)24
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c (renamed from drivers/media/video/samsung/ump/linux/ump_osk_misc.c)2
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c (renamed from drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c)15
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.h (renamed from drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h)5
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c (renamed from drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c)0
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h (renamed from drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h)0
-rw-r--r--drivers/media/video/samsung/Kconfig2
-rw-r--r--drivers/media/video/samsung/Makefile2
-rw-r--r--drivers/media/video/samsung/mali/Kbuild_module295
-rw-r--r--drivers/media/video/samsung/mali/Kconfig63
-rw-r--r--drivers/media/video/samsung/mali/Kconfig_module30
-rw-r--r--drivers/media/video/samsung/mali/Makefile337
l---------drivers/media/video/samsung/mali/arch1
l---------drivers/media/video/samsung/mali/arch-debug1
-rw-r--r--drivers/media/video/samsung/mali/arch-orion-m400/config.h154
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h85
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h92
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h85
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h77
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h91
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h105
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h119
-rw-r--r--drivers/media/video/samsung/mali/arch-pegasus-m400/config.h154
l---------drivers/media/video/samsung/mali/arch-release1
-rw-r--r--drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h174
-rw-r--r--drivers/media/video/samsung/mali/common/mali_cluster.c218
-rw-r--r--drivers/media/video/samsung/mali/common/mali_cluster.h44
-rw-r--r--drivers/media/video/samsung/mali/common/mali_device_pause_resume.h31
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp.c746
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp.h46
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_job.c49
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_scheduler.c443
-rw-r--r--drivers/media/video/samsung/mali/common/mali_group.c841
-rw-r--r--drivers/media/video/samsung/mali/common/mali_group.h146
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_core.c980
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_utilization.c218
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mmu.h55
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pm.c552
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pmu.c199
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp.c710
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp.h47
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_job.c95
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.c594
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.h38
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h28
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_dma_buf.c392
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_pm.c268
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_pm.h17
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_linux_pm.h50
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h32
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_irq.c266
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_mali.c34
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_pm.c83
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c324
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_specific.h130
-rw-r--r--drivers/media/video/samsung/mali/platform/default/mali_platform.c43
-rw-r--r--drivers/media/video/samsung/mali/platform/mali_platform.h153
-rw-r--r--drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c66
-rw-r--r--drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c656
-rw-r--r--drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c448
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c801
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c847
-rw-r--r--drivers/media/video/samsung/ump/Kconfig58
-rw-r--r--drivers/media/video/samsung/ump/Kconfig_module16
-rw-r--r--drivers/media/video/samsung/ump/Makefile93
l---------drivers/media/video/samsung/ump/arch1
l---------drivers/media/video/samsung/ump/arch-debug1
l---------drivers/media/video/samsung/ump/arch-release1
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c290
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h22
228 files changed, 17080 insertions, 14913 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index eb24286..b16fa42 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -1,5 +1,7 @@
menu "Device Drivers"
+source "drivers/gpu/mali400/Kconfig"
+
source "drivers/base/Kconfig"
source "drivers/connector/Kconfig"
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index d6913f8..06a5eac 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -15,6 +15,7 @@
*/
#include <linux/debugfs.h>
+#include <linux/export.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/kernel.h>
@@ -27,8 +28,13 @@
#include <linux/anon_inodes.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/sync.h>
+
static void sync_fence_signal_pt(struct sync_pt *pt);
static int _sync_pt_has_signaled(struct sync_pt *pt);
+static void sync_fence_free(struct kref *kref);
+static void sync_dump(void);
static LIST_HEAD(sync_timeline_list_head);
static DEFINE_SPINLOCK(sync_timeline_list_lock);
@@ -49,6 +55,7 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
if (obj == NULL)
return NULL;
+ kref_init(&obj->kref);
obj->ops = ops;
strlcpy(obj->name, name, sizeof(obj->name));
@@ -64,9 +71,12 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
return obj;
}
+EXPORT_SYMBOL(sync_timeline_create);
-static void sync_timeline_free(struct sync_timeline *obj)
+static void sync_timeline_free(struct kref *kref)
{
+ struct sync_timeline *obj =
+ container_of(kref, struct sync_timeline, kref);
unsigned long flags;
if (obj->ops->release_obj)
@@ -81,19 +91,17 @@ static void sync_timeline_free(struct sync_timeline *obj)
void sync_timeline_destroy(struct sync_timeline *obj)
{
- unsigned long flags;
- bool needs_freeing;
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
obj->destroyed = true;
- needs_freeing = list_empty(&obj->child_list_head);
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
- if (needs_freeing)
- sync_timeline_free(obj);
- else
+ /*
+ * If this is not the last reference, signal any children
+ * that their parent is going away.
+ */
+
+ if (!kref_put(&obj->kref, sync_timeline_free))
sync_timeline_signal(obj);
}
+EXPORT_SYMBOL(sync_timeline_destroy);
static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt)
{
@@ -110,7 +118,6 @@ static void sync_timeline_remove_pt(struct sync_pt *pt)
{
struct sync_timeline *obj = pt->parent;
unsigned long flags;
- bool needs_freeing;
spin_lock_irqsave(&obj->active_list_lock, flags);
if (!list_empty(&pt->active_list))
@@ -118,12 +125,10 @@ static void sync_timeline_remove_pt(struct sync_pt *pt)
spin_unlock_irqrestore(&obj->active_list_lock, flags);
spin_lock_irqsave(&obj->child_list_lock, flags);
- list_del(&pt->child_list);
- needs_freeing = obj->destroyed && list_empty(&obj->child_list_head);
+ if (!list_empty(&pt->child_list)) {
+ list_del_init(&pt->child_list);
+ }
spin_unlock_irqrestore(&obj->child_list_lock, flags);
-
- if (needs_freeing)
- sync_timeline_free(obj);
}
void sync_timeline_signal(struct sync_timeline *obj)
@@ -132,26 +137,33 @@ void sync_timeline_signal(struct sync_timeline *obj)
LIST_HEAD(signaled_pts);
struct list_head *pos, *n;
+ trace_sync_timeline(obj);
+
spin_lock_irqsave(&obj->active_list_lock, flags);
list_for_each_safe(pos, n, &obj->active_list_head) {
struct sync_pt *pt =
container_of(pos, struct sync_pt, active_list);
- if (_sync_pt_has_signaled(pt))
- list_move(pos, &signaled_pts);
+ if (_sync_pt_has_signaled(pt)) {
+ list_del_init(pos);
+ list_add(&pt->signaled_list, &signaled_pts);
+ kref_get(&pt->fence->kref);
+ }
}
spin_unlock_irqrestore(&obj->active_list_lock, flags);
list_for_each_safe(pos, n, &signaled_pts) {
struct sync_pt *pt =
- container_of(pos, struct sync_pt, active_list);
+ container_of(pos, struct sync_pt, signaled_list);
list_del_init(pos);
sync_fence_signal_pt(pt);
+ kref_put(&pt->fence->kref, sync_fence_free);
}
}
+EXPORT_SYMBOL(sync_timeline_signal);
struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
{
@@ -165,10 +177,12 @@ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
return NULL;
INIT_LIST_HEAD(&pt->active_list);
+ kref_get(&parent->kref);
sync_timeline_add_pt(parent, pt);
return pt;
}
+EXPORT_SYMBOL(sync_pt_create);
void sync_pt_free(struct sync_pt *pt)
{
@@ -177,8 +191,11 @@ void sync_pt_free(struct sync_pt *pt)
sync_timeline_remove_pt(pt);
+ kref_put(&pt->parent->kref, sync_timeline_free);
+
kfree(pt);
}
+EXPORT_SYMBOL(sync_pt_free);
/* call with pt->parent->active_list_lock held */
static int _sync_pt_has_signaled(struct sync_pt *pt)
@@ -247,6 +264,7 @@ static struct sync_fence *sync_fence_alloc(const char *name)
if (fence->file == NULL)
goto err;
+ kref_init(&fence->kref);
strlcpy(fence->name, name, sizeof(fence->name));
INIT_LIST_HEAD(&fence->pt_list_head);
@@ -282,29 +300,67 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
list_add(&pt->pt_list, &fence->pt_list_head);
sync_pt_activate(pt);
+ /*
+ * signal the fence in case pt was activated before
+ * sync_pt_activate(pt) was called
+ */
+ sync_fence_signal_pt(pt);
+
return fence;
}
+EXPORT_SYMBOL(sync_fence_create);
static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src)
{
- struct list_head *pos;
+ struct list_head *pos, *test_pos;
list_for_each(pos, &src->pt_list_head) {
struct sync_pt *orig_pt =
container_of(pos, struct sync_pt, pt_list);
- struct sync_pt *new_pt = sync_pt_dup(orig_pt);
+ struct sync_pt *new_pt;
+
+ /* Skip already signaled points */
+ if (1 == orig_pt->status)
+ continue;
+
+ list_for_each(test_pos, &src->pt_list_head) {
+ struct sync_pt *test_pt =
+ container_of(pos, struct sync_pt, pt_list);
+ if (orig_pt->parent == test_pt->parent) {
+ int diff;
+ diff = orig_pt->parent->ops->compare(orig_pt,
+ test_pt);
+ if (diff == -1) {
+ /* Skip orig_pt; another point will
+ * signal after it */
+ continue;
+ }
+ break;
+ }
+ }
+
+ new_pt = sync_pt_dup(orig_pt);
if (new_pt == NULL)
return -ENOMEM;
new_pt->fence = dst;
list_add(&new_pt->pt_list, &dst->pt_list_head);
- sync_pt_activate(new_pt);
}
return 0;
}
+static void sync_fence_detach_pts(struct sync_fence *fence)
+{
+ struct list_head *pos, *n;
+
+ list_for_each_safe(pos, n, &fence->pt_list_head) {
+ struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+ sync_timeline_remove_pt(pt);
+ }
+}
+
static void sync_fence_free_pts(struct sync_fence *fence)
{
struct list_head *pos, *n;
@@ -331,16 +387,19 @@ err:
fput(file);
return NULL;
}
+EXPORT_SYMBOL(sync_fence_fdget);
void sync_fence_put(struct sync_fence *fence)
{
fput(fence->file);
}
+EXPORT_SYMBOL(sync_fence_put);
void sync_fence_install(struct sync_fence *fence, int fd)
{
fd_install(fd, fence->file);
}
+EXPORT_SYMBOL(sync_fence_install);
static int sync_fence_get_status(struct sync_fence *fence)
{
@@ -349,7 +408,13 @@ static int sync_fence_get_status(struct sync_fence *fence)
list_for_each(pos, &fence->pt_list_head) {
struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
- int pt_status = pt->status;
+ int pt_status;
+
+ if (pt == NULL) {
+ printk(KERN_ERR"[sync driver] sync_fence_get_status : sync_pt is NULL\n");
+ break;
+ }
+ pt_status = pt->status;
if (pt_status < 0) {
status = pt_status;
@@ -365,6 +430,7 @@ static int sync_fence_get_status(struct sync_fence *fence)
struct sync_fence *sync_fence_merge(const char *name,
struct sync_fence *a, struct sync_fence *b)
{
+ struct list_head *pos;
struct sync_fence *fence;
int err;
@@ -380,7 +446,29 @@ struct sync_fence *sync_fence_merge(const char *name,
if (err < 0)
goto err;
- fence->status = sync_fence_get_status(fence);
+ /* Make sure there is at least one point in the fence */
+ if (list_empty(&fence->pt_list_head)) {
+ struct sync_pt *orig_pt = list_first_entry(&a->pt_list_head,
+ struct sync_pt, pt_list);
+ struct sync_pt *new_pt = sync_pt_dup(orig_pt);
+
+ new_pt->fence = fence;
+ list_add(&new_pt->pt_list, &fence->pt_list_head);
+ }
+
+ list_for_each(pos, &fence->pt_list_head) {
+ struct sync_pt *pt =
+ container_of(pos, struct sync_pt, pt_list);
+ sync_pt_activate(pt);
+ }
+
+ /*
+ * signal the fence in case one of it's pts were activated before
+ * they were activated
+ */
+ sync_fence_signal_pt(list_first_entry(&fence->pt_list_head,
+ struct sync_pt,
+ pt_list));
return fence;
err:
@@ -388,6 +476,7 @@ err:
kfree(fence);
return NULL;
}
+EXPORT_SYMBOL(sync_fence_merge);
static void sync_fence_signal_pt(struct sync_pt *pt)
{
@@ -421,33 +510,22 @@ static void sync_fence_signal_pt(struct sync_pt *pt)
container_of(pos, struct sync_fence_waiter,
waiter_list);
- waiter->callback(fence, waiter->callback_data);
list_del(pos);
- kfree(waiter);
+ waiter->callback(fence, waiter);
}
wake_up(&fence->wq);
}
}
int sync_fence_wait_async(struct sync_fence *fence,
- void (*callback)(struct sync_fence *, void *data),
- void *callback_data)
+ struct sync_fence_waiter *waiter)
{
- struct sync_fence_waiter *waiter;
unsigned long flags;
int err = 0;
- waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL);
- if (waiter == NULL)
- return -ENOMEM;
-
- waiter->callback = callback;
- waiter->callback_data = callback_data;
-
spin_lock_irqsave(&fence->waiter_list_lock, flags);
if (fence->status) {
- kfree(waiter);
err = fence->status;
goto out;
}
@@ -458,44 +536,120 @@ out:
return err;
}
+EXPORT_SYMBOL(sync_fence_wait_async);
+
+int sync_fence_cancel_async(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter)
+{
+ struct list_head *pos;
+ struct list_head *n;
+ unsigned long flags;
+ int ret = -ENOENT;
+
+ spin_lock_irqsave(&fence->waiter_list_lock, flags);
+ /*
+ * Make sure waiter is still in waiter_list because it is possible for
+ * the waiter to be removed from the list while the callback is still
+ * pending.
+ */
+ list_for_each_safe(pos, n, &fence->waiter_list_head) {
+ struct sync_fence_waiter *list_waiter =
+ container_of(pos, struct sync_fence_waiter,
+ waiter_list);
+ if (list_waiter == waiter) {
+ list_del(pos);
+ ret = 0;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(sync_fence_cancel_async);
+
+static bool sync_fence_check(struct sync_fence *fence)
+{
+ /*
+ * Make sure that reads to fence->status are ordered with the
+ * wait queue event triggering
+ */
+ smp_rmb();
+ return fence->status != 0;
+}
int sync_fence_wait(struct sync_fence *fence, long timeout)
{
- int err;
+ int err = 0;
+ struct sync_pt *pt;
- if (timeout) {
+ trace_sync_wait(fence, 1);
+ list_for_each_entry(pt, &fence->pt_list_head, pt_list)
+ trace_sync_pt(pt);
+
+ if (timeout > 0) {
timeout = msecs_to_jiffies(timeout);
err = wait_event_interruptible_timeout(fence->wq,
- fence->status != 0,
+ sync_fence_check(fence),
timeout);
- } else {
- err = wait_event_interruptible(fence->wq, fence->status != 0);
+ } else if (timeout < 0) {
+ err = wait_event_interruptible(fence->wq,
+ sync_fence_check(fence));
}
+ trace_sync_wait(fence, 0);
if (err < 0)
return err;
- if (fence->status < 0)
+ if (fence->status < 0) {
+ pr_info("fence error %d on [%p]\n", fence->status, fence);
+ sync_dump();
return fence->status;
+ }
- if (fence->status == 0)
+ if (fence->status == 0) {
+ if (timeout > 0) {
+ pr_info("fence timeout on [%p] after %dms\n", fence,
+ jiffies_to_msecs(timeout));
+ sync_dump();
+ }
return -ETIME;
+ }
return 0;
}
+EXPORT_SYMBOL(sync_fence_wait);
+
+static void sync_fence_free(struct kref *kref)
+{
+ struct sync_fence *fence = container_of(kref, struct sync_fence, kref);
+
+ sync_fence_free_pts(fence);
+
+ kfree(fence);
+}
static int sync_fence_release(struct inode *inode, struct file *file)
{
struct sync_fence *fence = file->private_data;
unsigned long flags;
- sync_fence_free_pts(fence);
-
+ /*
+ * We need to remove all ways to access this fence before droping
+ * our ref.
+ *
+ * start with its membership in the global fence list
+ */
spin_lock_irqsave(&sync_fence_list_lock, flags);
list_del(&fence->sync_fence_list);
spin_unlock_irqrestore(&sync_fence_list_lock, flags);
- kfree(fence);
+ /*
+ * remove its pts from their parents so that sync_timeline_signal()
+ * can't reference the fence.
+ */
+ sync_fence_detach_pts(fence);
+
+ kref_put(&fence->kref, sync_fence_free);
return 0;
}
@@ -506,6 +660,12 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
poll_wait(file, &fence->wq, wait);
+ /*
+ * Make sure that reads to fence->status are ordered with the
+ * wait queue event triggering
+ */
+ smp_rmb();
+
if (fence->status == 1)
return POLLIN;
else if (fence->status < 0)
@@ -516,7 +676,7 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg)
{
- __u32 value;
+ __s32 value;
if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
return -EFAULT;
@@ -531,8 +691,13 @@ static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg)
struct sync_fence *fence2, *fence3;
struct sync_merge_data data;
- if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
- return -EFAULT;
+ if (fd < 0)
+ return fd;
+
+ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
+ err = -EFAULT;
+ goto err_put_fd;
+ }
fence2 = sync_fence_fdget(data.fd2);
if (fence2 == NULL) {
@@ -568,7 +733,7 @@ err_put_fd:
return err;
}
-int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
+static int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
{
struct sync_pt_info *info = data;
int ret;
@@ -596,7 +761,6 @@ int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
return info->len;
}
-
static long sync_fence_ioctl_fence_info(struct sync_fence *fence,
unsigned long arg)
{
@@ -690,7 +854,17 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
}
- if (pt->parent->ops->print_pt) {
+ if (pt->parent->ops->timeline_value_str &&
+ pt->parent->ops->pt_value_str) {
+ char value[64];
+ pt->parent->ops->pt_value_str(pt, value, sizeof(value));
+ seq_printf(s, ": %s", value);
+ if (fence) {
+ pt->parent->ops->timeline_value_str(pt->parent, value,
+ sizeof(value));
+ seq_printf(s, " / %s", value);
+ }
+ } else if (pt->parent->ops->print_pt) {
seq_printf(s, ": ");
pt->parent->ops->print_pt(s, pt);
}
@@ -705,7 +879,11 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
- if (obj->ops->print_obj) {
+ if (obj->ops->timeline_value_str) {
+ char value[64];
+ obj->ops->timeline_value_str(obj, value, sizeof(value));
+ seq_printf(s, ": %s", value);
+ } else if (obj->ops->print_obj) {
seq_printf(s, ": ");
obj->ops->print_obj(s, obj);
}
@@ -726,7 +904,8 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
struct list_head *pos;
unsigned long flags;
- seq_printf(s, "%s: %s\n", fence->name, sync_status_str(fence->status));
+ seq_printf(s, "[%p] %s: %s\n", fence, fence->name,
+ sync_status_str(fence->status));
list_for_each(pos, &fence->pt_list_head) {
struct sync_pt *pt =
@@ -740,8 +919,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
container_of(pos, struct sync_fence_waiter,
waiter_list);
- seq_printf(s, "waiter %pF %p\n", waiter->callback,
- waiter->callback_data);
+ seq_printf(s, "waiter %pF\n", waiter->callback);
}
spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
}
@@ -795,7 +973,34 @@ static __init int sync_debugfs_init(void)
debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops);
return 0;
}
-
late_initcall(sync_debugfs_init);
+#define DUMP_CHUNK 256
+static char sync_dump_buf[64 * 1024];
+void sync_dump(void)
+{
+ struct seq_file s = {
+ .buf = sync_dump_buf,
+ .size = sizeof(sync_dump_buf) - 1,
+ };
+ int i;
+
+ sync_debugfs_show(&s, NULL);
+
+ for (i = 0; i < s.count; i += DUMP_CHUNK) {
+ if ((s.count - i) > DUMP_CHUNK) {
+ char c = s.buf[i + DUMP_CHUNK];
+ s.buf[i + DUMP_CHUNK] = 0;
+ pr_cont("%s", s.buf + i);
+ s.buf[i + DUMP_CHUNK] = c;
+ } else {
+ s.buf[s.count] = 0;
+ pr_cont("%s", s.buf + i);
+ }
+ }
+}
+#else
+static void sync_dump(void)
+{
+}
#endif
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 00efbf6..8a0ed22 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -4,3 +4,9 @@ else
obj-y += drm/ vga/ stub/ ion/
endif
+ifeq ($(CONFIG_MALI400),y)
+ifeq ($(CONFIG_MALI_VER_R3P2),y)
+obj-y += mali400/r3p2/mali/
+obj-y += mali400/r3p2/ump/
+endif
+endif
diff --git a/drivers/gpu/mali400/Kconfig b/drivers/gpu/mali400/Kconfig
new file mode 100644
index 0000000..8ec13b3
--- /dev/null
+++ b/drivers/gpu/mali400/Kconfig
@@ -0,0 +1,26 @@
+menuconfig MALI400
+ tristate "Mali-300/400/450 support"
+ depends on ARM
+ default y
+ ---help---
+ This enables support for the ARM Mali-300, Mali-400, and Mali-450
+ GPUs.
+
+ To compile this driver as a module, choose M here: the module will be
+ called mali.
+
+choice
+depends on MALI400
+prompt "Select MALI VER"
+default MALI_VER_R3P2
+config MALI_VER_R3P2
+ bool "Mali400 Version R3P2"
+ help
+ Choose this option to select DDK version.
+
+if MALI_VER_R3P2
+source "drivers/gpu/mali400/r3p2/mali/Kconfig"
+source "drivers/gpu/mali400/r3p2/ump/Kconfig"
+endif
+
+endchoice
diff --git a/drivers/gpu/mali400/r3p2/mali/Kbuild b/drivers/gpu/mali400/r3p2/mali/Kbuild
new file mode 100644
index 0000000..81acbb8
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/Kbuild
@@ -0,0 +1,220 @@
+#
+# Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# This file is called by the Linux build system.
+
+# set up defaults if not defined by the user
+TIMESTAMP ?= default
+OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
+USING_GPU_UTILIZATION ?= 1
+PROFILING_SKIP_PP_JOBS ?= 0
+PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
+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
+MALI_UPPER_HALF_SCHEDULING ?= 1
+# MALI_SEC
+# Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
+ifeq ($(CONFIG_CPU_EXYNOS4210),y)
+ TARGET_PLATFORM=pegasus-m400
+endif
+ifeq ($(CONFIG_CPU_EXYNOS4212),y)
+ TARGET_PLATFORM=pegasus-m400
+endif
+ifeq ($(CONFIG_CPU_EXYNOS4412),y)
+ TARGET_PLATFORM=pegasus-m400
+endif
+ifeq ($(CONFIG_SOC_EXYNOS3470),y)
+ TARGET_PLATFORM=exynos4270
+endif
+
+include $(srctree)/$(src)/MALI_CONFIGURATION
+MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM))
+EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+MALI_PLATFORM_FILES = $(subst $(srctree)/$(src)/,,$(wildcard $(srctree)/$(src)/platform/$(MALI_PLATFORM)/*.c))
+# End of MALI_SEC
+
+# 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
+$(warning Current directory is $(srctree)/$(src) from $(shell pwd))
+ifeq ($(wildcard $(srctree)/$(src)/linux/license/gpl/*),)
+ ccflags-y += -I$(srctree)/$(src)/linux/license/proprietary
+ ifeq ($(CONFIG_MALI400_PROFILING),y)
+ $(error Profiling is incompatible with non-GPL license)
+ endif
+ ifeq ($(CONFIG_PM_RUNTIME),y)
+ $(error Runtime PM is incompatible with non-GPL license)
+ endif
+ ifeq ($(CONFIG_DMA_SHARED_BUFFER),y)
+ $(error DMA-BUF is incompatible with non-GPL license)
+ endif
+ $(error Linux Device integration is incompatible with non-GPL license)
+else
+ ccflags-y += -I$(srctree)/$(src)/linux/license/gpl
+endif
+
+mali-y += \
+ linux/mali_osk_atomics.o \
+ linux/mali_osk_irq.o \
+ linux/mali_osk_wq.o \
+ linux/mali_osk_locks.o \
+ linux/mali_osk_wait_queue.o \
+ linux/mali_osk_low_level_mem.o \
+ linux/mali_osk_math.o \
+ linux/mali_osk_memory.o \
+ linux/mali_osk_misc.o \
+ linux/mali_osk_mali.o \
+ linux/mali_osk_notification.o \
+ linux/mali_osk_time.o \
+ linux/mali_osk_timers.o
+
+mali-y += \
+ linux/mali_ukk_mem.o \
+ linux/mali_ukk_gp.o \
+ linux/mali_ukk_pp.o \
+ linux/mali_ukk_core.o
+
+# Source files which always are included in a build
+mali-y += \
+ common/mali_kernel_core.o \
+ linux/mali_kernel_linux.o \
+ common/mali_kernel_descriptor_mapping.o \
+ common/mali_session.o \
+ linux/mali_device_pause_resume.o \
+ common/mali_kernel_vsync.o \
+ linux/mali_ukk_vsync.o \
+ linux/mali_kernel_sysfs.o \
+ common/mali_mmu.o \
+ common/mali_mmu_page_directory.o \
+ common/mali_memory.o \
+ common/mali_kernel_memory_engine.o \
+ common/mali_block_allocator.o \
+ common/mali_kernel_mem_os.o \
+ common/mali_mem_validation.o \
+ common/mali_hw_core.o \
+ common/mali_gp.o \
+ common/mali_pp.o \
+ common/mali_pp_job.o \
+ common/mali_gp_job.o \
+ common/mali_scheduler.o \
+ common/mali_gp_scheduler.o \
+ common/mali_pp_scheduler.o \
+ common/mali_group.o \
+ common/mali_dlbu.o \
+ common/mali_broadcast.o \
+ common/mali_pm.o \
+ common/mali_pmu.o \
+ common/mali_user_settings_db.o \
+ common/mali_kernel_utilization.o \
+ common/mali_l2_cache.o \
+ common/mali_pm_domain.o \
+ linux/mali_osk_pm.o \
+ linux/mali_pmu_power_up_down.o \
+ __malidrv_build_info.o
+
+ifneq ($(MALI_PLATFORM_FILES),)
+ mali-y += $(MALI_PLATFORM_FILES:.c=.o)
+endif
+
+mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o
+mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o
+
+mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o
+ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(srctree)/$(src)/timestamp-$(TIMESTAMP)
+
+mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o
+mali-$(CONFIG_SYNC) += linux/mali_sync.o linux/mali_sync_user.o
+
+# Tell the Linux build system from which .o file to create the kernel module
+obj-$(CONFIG_MALI400) := mali.o
+
+ccflags-y += $(EXTRA_DEFINES)
+
+# Set up our defines, which will be passed to gcc
+ccflags-y += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
+ccflags-y += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
+
+ccflags-y += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
+ccflags-y += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
+ccflags-y += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
+ccflags-y += -DMALI_STATE_TRACKING=1
+ccflags-y += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
+ccflags-y += -DUSING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
+
+ifeq ($(MALI_UPPER_HALF_SCHEDULING),1)
+ ccflags-y += -DMALI_UPPER_HALF_SCHEDULING
+endif
+
+ccflags-$(CONFIG_MALI400_UMP) += -I$(srctree)/$(src)/../../ump/include/ump
+ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG
+
+# Use our defines when compiling
+ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/include -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/platform
+# MALI_SEC
+ccflags-y += -I$(srctree)/$(src)/../ump/include -I$(srctree)/$(src)/include/linux/mali
+
+# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
+MALI_RELEASE_NAME=$(shell cat $(srctree)/$(src)/.version 2> /dev/null)
+
+SVN_INFO = (cd $(srctree)/$(src); svn info 2>/dev/null)
+
+ifneq ($(shell $(SVN_INFO) 2>/dev/null),)
+# SVN detected
+SVN_REV := $(shell $(SVN_INFO) | grep '^Revision: '| sed -e 's/^Revision: //' 2>/dev/null)
+DRIVER_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
+CHANGE_DATE := $(shell $(SVN_INFO) | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
+CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
+REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-)
+
+else # SVN
+GIT_REV := $(shell cd $(srctree)/$(src); git describe --always 2>/dev/null)
+ifneq ($(GIT_REV),)
+# Git detected
+DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV)
+CHANGE_DATE := $(shell cd $(srctree)/$(src); git log -1 --format="%ci")
+CHANGED_REVISION := $(GIT_REV)
+REPO_URL := $(shell cd $(srctree)/$(src); git describe --all --always 2>/dev/null)
+
+else # Git
+# No Git or SVN detected
+DRIVER_REV := $(MALI_RELEASE_NAME)
+CHANGE_DATE := $(MALI_RELEASE_NAME)
+CHANGED_REVISION := $(MALI_RELEASE_NAME)
+endif
+endif
+
+ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\"
+
+VERSION_STRINGS :=
+VERSION_STRINGS += API_VERSION=$(shell cd $(srctree)/$(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 )
+VERSION_STRINGS += REPO_URL=$(REPO_URL)
+VERSION_STRINGS += REVISION=$(DRIVER_REV)
+VERSION_STRINGS += CHANGED_REVISION=$(CHANGED_REVISION)
+VERSION_STRINGS += CHANGE_DATE=$(CHANGE_DATE)
+VERSION_STRINGS += BUILD_DATE=$(shell date)
+ifdef CONFIG_MALI400_DEBUG
+VERSION_STRINGS += BUILD=debug
+else
+VERSION_STRINGS += BUILD=release
+endif
+VERSION_STRINGS += TARGET_PLATFORM=$(TARGET_PLATFORM)
+VERSION_STRINGS += MALI_PLATFORM=$(MALI_PLATFORM)
+VERSION_STRINGS += KDIR=$(KDIR)
+VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
+VERSION_STRINGS += USING_UMP=$(CONFIG_MALI400_UMP)
+VERSION_STRINGS += USING_PROFILING=$(CONFIG_MALI400_PROFILING)
+VERSION_STRINGS += USING_INTERNAL_PROFILING=$(CONFIG_MALI400_INTERNAL_PROFILING)
+VERSION_STRINGS += USING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
+VERSION_STRINGS += MALI_UPPER_HALF_SCHEDULING=$(MALI_UPPER_HALF_SCHEDULING)
+
+# Create file with Mali driver configuration
+$(srctree)/$(src)/__malidrv_build_info.c:
+ @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(srctree)/$(src)/__malidrv_build_info.c
diff --git a/drivers/gpu/mali400/r3p2/mali/Kconfig b/drivers/gpu/mali400/r3p2/mali/Kconfig
new file mode 100644
index 0000000..14af54a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/Kconfig
@@ -0,0 +1,67 @@
+config MALI400_DEBUG
+ bool "Enable debug in Mali driver"
+ depends on MALI400
+ ---help---
+ This enabled extra debug checks and messages in the Mali driver.
+
+config MALI400_PROFILING
+ bool "Enable Mali profiling"
+ depends on MALI400
+ select TRACEPOINTS
+ default n
+ ---help---
+ This enables gator profiling of Mali GPU events.
+
+config MALI400_INTERNAL_PROFILING
+ bool "Enable internal Mali profiling API"
+ depends on MALI400_PROFILING
+ default n
+ ---help---
+ This enables the internal legacy Mali profiling API.
+
+if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
+config MALI_DVFS
+ bool "Enable mali DVFS"
+ depends on MALI400 && PM
+ default y
+ ---help---
+ This enables Mali driver DVFS.
+endif
+
+if SOC_EXYNOS3470
+config MALI_DVFS
+ bool "Enable mali DVFS"
+ depends on MALI400 && PM_DEVFREQ
+ default y
+ ---help---
+ This enables Mali driver DVFS.
+endif
+
+if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
+config MALI400_UMP
+ bool "Enable UMP support"
+ depends on MALI400
+ default y
+ ---help---
+ This enables support for the UMP memory sharing API in the Mali driver.
+endif
+
+config MALI_DMA_BUF_MAP_ON_ATTACH
+ bool "Map dma-buf attachments on attach"
+ depends on MALI400 && DMA_SHARED_BUFFER
+ default y
+ ---help---
+ This makes the Mali driver map dma-buf attachments after doing
+ attach. If this is not set the dma-buf attachments will be mapped for
+ every time the GPU need to access the buffer.
+
+ Mapping for each access can cause lower performance.
+
+config MALI_SHARED_INTERRUPTS
+ bool "Support for shared interrupts"
+ depends on MALI400
+ default n
+ ---help---
+ Adds functionality required to properly support shared interrupts. Without this support,
+ the device driver will fail during insmod if it detects shared interrupts. Works even if
+ the GPU is not using shared interrupts, but can cause lower performance.
diff --git a/drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION b/drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION
new file mode 100644
index 0000000..4b099b7
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION
@@ -0,0 +1,24 @@
+# Location of default kernels
+KDIR-odroida:=/projects/pr297/linux/odroid-a/current/linux
+KDIR-odroidpc:=/projects/pr297/linux/odroid-pc/current/linux
+KDIR-odroidq:=/projects/pr297/linux/odroid-q/current/linux
+KDIR-orion:=/projects/pr297/linux/orion/current/linux
+KDIR-pegasus:=/projects/pr297/linux/pegasus-smdk/current/linux
+KDIR-tcc8900:=/projects/pr297/linux/tcc8900/current/linux
+KDIR-pb11mp:=/projects/pr297/linux/pb11mp/current/linux
+KDIR-vea9:=/projects/pr297/linux/vea9/current/linux
+KDIR-snowball:=/no/default/kernel/yet
+
+# Name of platform directory with platform specific code (should be built into kernel on a real system)
+MALI_PLATFORM-odroida=exynos4
+MALI_PLATFORM-odroidpc=exynos4
+MALI_PLATFORM-odroidq=exynos4
+MALI_PLATFORM-orion=exynos4
+MALI_PLATFORM-pegasus=exynos4
+# MALI_SEC
+MALI_PLATFORM-pegasus-m400=pegasus-m400
+MALI_PLATFORM-exynos4270=exynos4270
+MALI_PLATFORM-tcc8900=tcc8900
+MALI_PLATFORM-pb11mp=arm
+MALI_PLATFORM-vea9=arm
+MALI_PLATFORM-snowball=ux500
diff --git a/drivers/media/video/samsung/mali/Makefile_module b/drivers/gpu/mali400/r3p2/mali/Makefile
index 361ce08..b487011 100644
--- a/drivers/media/video/samsung/mali/Makefile_module
+++ b/drivers/gpu/mali400/r3p2/mali/Makefile
@@ -9,6 +9,9 @@
#
USE_UMPV2=0
+USING_PROFILING ?= 1
+USING_INTERNAL_PROFILING ?= 0
+MALI_DMA_BUF_MAP_ON_ATTACH ?= 1
# The Makefile sets up "arch" based on the CONFIG, creates the version info
# string and the __malidrv_build_info.c file, and then call the Linux build
@@ -32,15 +35,35 @@ check_cc2 = \
# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak
-include ../../../arm_internal.mak
-# Check that required parameters are supplied.
-ifeq ($(CONFIG),)
-$(error "CONFIG must be specified.")
+# Give warning of old config parameters are used
+ifneq ($(CONFIG),)
+$(warning "You have specified the CONFIG variable which is no longer in used. Use TARGET_PLATFORM instead.")
endif
-ifeq ($(CPU)$(KDIR),)
-$(error "KDIR or CPU must be specified.")
+
+ifneq ($(CPU),)
+$(warning "You have specified the CPU variable which is no longer in used. Use TARGET_PLATFORM instead.")
+endif
+
+# Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
+-include MALI_CONFIGURATION
+export KDIR ?= $(KDIR-$(TARGET_PLATFORM))
+export MALI_PLATFORM ?= $(MALI_PLATFORM-$(TARGET_PLATFORM))
+
+ifneq ($(TARGET_PLATFORM),)
+ifeq ($(MALI_PLATFORM),)
+$(error "Invalid TARGET_PLATFORM: $(TARGET_PLATFORM)")
+endif
+endif
+
+# validate lookup result
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(TARGET_PLATFORM))
endif
+
ifeq ($(USING_UMP),1)
+export CONFIG_MALI400_UMP=y
+export EXTRA_DEFINES += -DCONFIG_MALI400_UMP=1
ifeq ($(USE_UMPV2),1)
UMP_SYMVERS_FILE ?= ../umpv2/Module.symvers
else
@@ -50,38 +73,56 @@ KBUILD_EXTRA_SYMBOLS = $(realpath $(UMP_SYMVERS_FILE))
$(warning $(KBUILD_EXTRA_SYMBOLS))
endif
-# Get any user defined KDIR-<names> or maybe even a hardcoded KDIR
--include KDIR_CONFIGURATION
-
# Define host system directory
KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
+include $(KDIR)/.config
+
ifeq ($(ARCH), arm)
# when compiling for ARM we're cross compiling
export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
endif
-# look up KDIR based om CPU selection
-KDIR ?= $(KDIR-$(CPU))
-
-# validate lookup result
-ifeq ($(KDIR),)
-$(error No KDIR found for platform $(CPU))
-endif
-
# report detected/selected settings
ifdef ARM_INTERNAL_BUILD
-$(warning Config $(CONFIG))
-$(warning Host CPU $(CPU))
-$(warning OS_MEMORY $(USING_OS_MEMORY))
+$(warning TARGET_PLATFORM $(TARGET_PLATFORM))
+$(warning KDIR $(KDIR))
+$(warning MALI_PLATFORM $(MALI_PLATFORM))
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
+ifneq ($(MALI_PLATFORM),)
+export EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+export MALI_PLATFORM_FILES = $(wildcard platform/$(MALI_PLATFORM)/*.c)
+endif
+
+ifeq ($(USING_PROFILING),1)
+ifeq ($(CONFIG_TRACEPOINTS),)
+$(warning CONFIG_TRACEPOINTS reqired for profiling)
+else
+export CONFIG_MALI400_PROFILING=y
+export EXTRA_DEFINES += -DCONFIG_MALI400_PROFILING=1
+ifeq ($(USING_INTERNAL_PROFILING),1)
+export CONFIG_MALI400_INTERNAL_PROFILING=y
+export EXTRA_DEFINES += -DCONFIG_MALI400_INTERNAL_PROFILING=1
+endif
+endif
+endif
+
+ifeq ($(MALI_DMA_BUF_MAP_ON_ATTACH),1)
+export CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH=y
+export EXTRA_DEFINES += -DCONFIG_MALI_DMA_BUF_MAP_ON_ATTACH
+endif
+
+ifeq ($(MALI_SHARED_INTERRUPTS),1)
+export CONFIG_MALI_SHARED_INTERRUPTS=y
+export EXTRA_DEFINES += -DCONFIG_MALI_SHARED_INTERRUPTS
+endif
+
+ifneq ($(BUILD),release)
+export CONFIG_MALI400_DEBUG=y
endif
all: $(UMP_SYMVERS_FILE)
diff --git a/drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c b/drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c
new file mode 100644
index 0000000..af5e808
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c
@@ -0,0 +1 @@
+const char *__malidrv_build_info(void) { return "malidrv: API_VERSION=23 REPO_URL=heads/master REVISION=r3p2-01rel3-137c649 CHANGED_REVISION=137c649 CHANGE_DATE=2013-08-22 17:45:49 +0900 BUILD_DATE=Fri Aug 23 20:48:48 KST 2013 BUILD=release TARGET_PLATFORM=pegasus-m400 MALI_PLATFORM=pegasus-m400 KDIR= OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=16 USING_UMP=y USING_PROFILING= USING_INTERNAL_PROFILING= USING_GPU_UTILIZATION=1 MALI_UPPER_HALF_SCHEDULING=1";}
diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.c b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c
index 269e662..3651ce5 100644
--- a/drivers/media/video/samsung/mali/common/mali_block_allocator.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c
@@ -8,7 +8,6 @@
* 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_memory_engine.h"
#include "mali_block_allocator.h"
#include "mali_osk.h"
@@ -320,6 +319,8 @@ static mali_physical_memory_allocation_result block_allocator_allocate_page_tabl
alloc->next = NULL; /* Could potentially link many blocks together instead */
+ _mali_osk_memset(block->mapping, 0, size);
+
result = MALI_MEM_ALLOC_FINISHED;
}
}
diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.h b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.h
index 6c6f13e..d3f0f9b 100644
--- a/drivers/media/video/samsung/mali/common/mali_block_allocator.h
+++ b/drivers/gpu/mali400/r3p2/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/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c
new file mode 100644
index 0000000..8b05496
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c
@@ -0,0 +1,129 @@
+/*
+ * 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_broadcast.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+
+static const int bcast_unit_reg_size = 0x1000;
+static const int bcast_unit_addr_broadcast_mask = 0x0;
+static const int bcast_unit_addr_irq_override_mask = 0x4;
+
+struct mali_bcast_unit
+{
+ struct mali_hw_core hw_core;
+ u32 current_mask;
+};
+
+struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource)
+{
+ struct mali_bcast_unit *bcast_unit = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(resource);
+ MALI_DEBUG_PRINT(2, ("Mali Broadcast unit: Creating Mali Broadcast unit: %s\n", resource->description));
+
+ bcast_unit = _mali_osk_malloc(sizeof(struct mali_bcast_unit));
+ if (NULL == bcast_unit)
+ {
+ MALI_PRINT_ERROR(("Mali Broadcast unit: Failed to allocate memory for Broadcast unit\n"));
+ return NULL;
+ }
+
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&bcast_unit->hw_core, resource, bcast_unit_reg_size))
+ {
+ bcast_unit->current_mask = 0;
+ mali_bcast_reset(bcast_unit);
+
+ return bcast_unit;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali Broadcast unit: Failed map broadcast unit\n"));
+ }
+
+ _mali_osk_free(bcast_unit);
+
+ return NULL;
+}
+
+void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit)
+{
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+
+ mali_hw_core_delete(&bcast_unit->hw_core);
+ _mali_osk_free(bcast_unit);
+}
+
+void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group)
+{
+ u32 bcast_id;
+ u32 broadcast_mask;
+
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ bcast_id = mali_pp_core_get_bcast_id(mali_group_get_pp_core(group));
+
+ broadcast_mask = bcast_unit->current_mask;
+
+ broadcast_mask |= (bcast_id); /* add PP core to broadcast */
+ broadcast_mask |= (bcast_id << 16); /* add MMU to broadcast */
+
+ /* store mask so we can restore on reset */
+ bcast_unit->current_mask = broadcast_mask;
+}
+
+void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group)
+{
+ u32 bcast_id;
+ u32 broadcast_mask;
+
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ bcast_id = mali_pp_core_get_bcast_id(mali_group_get_pp_core(group));
+
+ broadcast_mask = bcast_unit->current_mask;
+
+ broadcast_mask &= ~((bcast_id << 16) | bcast_id);
+
+ /* store mask so we can restore on reset */
+ bcast_unit->current_mask = broadcast_mask;
+}
+
+void mali_bcast_reset(struct mali_bcast_unit *bcast_unit)
+{
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+
+ /* set broadcast mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_broadcast_mask,
+ bcast_unit->current_mask);
+
+ /* set IRQ override mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_irq_override_mask,
+ bcast_unit->current_mask & 0xFF);
+}
+
+void mali_bcast_disable(struct mali_bcast_unit *bcast_unit)
+{
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+
+ /* set broadcast mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_broadcast_mask,
+ 0x0);
+
+ /* set IRQ override mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_irq_override_mask,
+ 0x0);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h
new file mode 100644
index 0000000..df5f2f9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/*
+ * Interface for the broadcast unit on Mali-450.
+ *
+ * - Represents up to 8 × (MMU + PP) pairs.
+ * - Supports dynamically changing which (MMU + PP) pairs receive the broadcast by
+ * setting a mask.
+ */
+
+#include "mali_hw_core.h"
+#include "mali_group.h"
+
+struct mali_bcast_unit;
+
+struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource);
+void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit);
+
+/* Add a group to the list of (MMU + PP) pairs broadcasts go out to. */
+void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group);
+
+/* Remove a group to the list of (MMU + PP) pairs broadcasts go out to. */
+void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group);
+
+/* Re-set cached mask. This needs to be called after having been suspended. */
+void mali_bcast_reset(struct mali_bcast_unit *bcast_unit);
+
+/**
+ * Disable broadcast unit
+ *
+ * mali_bcast_enable must be called to re-enable the unit. Cores may not be
+ * added or removed when the unit is disabled.
+ */
+void mali_bcast_disable(struct mali_bcast_unit *bcast_unit);
+
+/**
+ * Re-enable broadcast unit
+ *
+ * This resets the masks to include the cores present when mali_bcast_disable was called.
+ */
+MALI_STATIC_INLINE void mali_bcast_enable(struct mali_bcast_unit *bcast_unit)
+{
+ mali_bcast_reset(bcast_unit);
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.c b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c
index fcc51fa..0181663 100644
--- a/drivers/media/video/samsung/mali/common/mali_dlbu.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c
@@ -23,8 +23,6 @@
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.
@@ -86,7 +84,7 @@ struct mali_dlbu_core
_mali_osk_errcode_t mali_dlbu_initialize(void)
{
- MALI_DEBUG_PRINT(2, ("Dynamic Load Balancing Unit initializing\n"));
+ MALI_DEBUG_PRINT(2, ("Mali DLBU: Initializing\n"));
if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr))
{
@@ -114,10 +112,9 @@ struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource)
{
if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE))
{
+ core->pp_cores_mask = 0;
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));
@@ -136,150 +133,85 @@ struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource)
void mali_dlbu_delete(struct mali_dlbu_core *dlbu)
{
+ MALI_DEBUG_ASSERT_POINTER(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)
{
+ u32 dlbu_registers[7];
_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);
+ dlbu_registers[0] = mali_dlbu_phys_addr | 1; /* bit 0 enables the whole core */
+ dlbu_registers[1] = MALI_DLBU_VIRT_ADDR;
+ dlbu_registers[2] = 0;
+ dlbu_registers[3] = 0;
+ dlbu_registers[4] = 0;
+ dlbu_registers[5] = 0;
+ dlbu_registers[6] = dlbu->pp_cores_mask;
- mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
+ /* write reset values to core registers */
+ mali_hw_core_register_write_array_relaxed(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, dlbu_registers, 7);
err = _MALI_OSK_ERR_OK;
return err;
}
-_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
+void mali_dlbu_update_mask(struct mali_dlbu_core *dlbu)
{
- _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;
- }
+ MALI_DEBUG_ASSERT_POINTER(dlbu);
- return err;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
}
-void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val)
+void mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
{
- mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, val);
+ struct mali_pp_core *pp_core;
+ u32 bcast_id;
+
+ MALI_DEBUG_ASSERT_POINTER( dlbu );
+ MALI_DEBUG_ASSERT_POINTER( group );
+
+ pp_core = mali_group_get_pp_core(group);
+ bcast_id = mali_pp_core_get_bcast_id(pp_core);
+
+ dlbu->pp_cores_mask |= bcast_id;
+ MALI_DEBUG_PRINT(3, ("Mali DLBU: Adding core[%d] New mask= 0x%02x\n", bcast_id , dlbu->pp_cores_mask));
}
-void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu)
+/* Remove a group from the DLBU */
+void mali_dlbu_remove_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
{
- /* 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!!! */
+ struct mali_pp_core *pp_core;
+ u32 bcast_id;
+
+ MALI_DEBUG_ASSERT_POINTER( dlbu );
+ MALI_DEBUG_ASSERT_POINTER( group );
- /* 1) */
- mali_dlbu_disable_all_pp_cores(dlbu);
+ pp_core = mali_group_get_pp_core(group);
+ bcast_id = mali_pp_core_get_bcast_id(pp_core);
- /* 3) */
- mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS);
+ dlbu->pp_cores_mask &= ~bcast_id;
+ MALI_DEBUG_PRINT(3, ("Mali DLBU: Removing core[%d] New mask= 0x%02x\n", bcast_id, dlbu->pp_cores_mask));
}
-void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu)
+/* Configure the DLBU for \a job. This needs to be done before the job is started on the groups in the DLBU. */
+void mali_dlbu_config_job(struct mali_dlbu_core *dlbu, struct mali_pp_job *job)
{
- /* 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 */
+ u32 *registers;
+ MALI_DEBUG_ASSERT(job);
+ registers = mali_pp_job_get_dlbu_registers(job);
+ MALI_DEBUG_PRINT(4, ("Mali DLBU: Starting job\n"));
- /* 1) */
- mali_dlbu_reset(dlbu);
- /* ++ setup the needed values - see this */
+ /* Writing 4 registers:
+ * DLBU registers except the first two (written once at DLBU initialisation / reset) and the PP_ENABLE_MASK register */
+ mali_hw_core_register_write_array_relaxed(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, registers, 4);
- /* 2) */
- mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, mali_dlbu_tile_position);
}
diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.h b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h
index e3c3b9d..b1a59d6 100644
--- a/drivers/media/video/samsung/mali/common/mali_dlbu.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h
@@ -11,10 +11,12 @@
#ifndef __MALI_DLBU_H__
#define __MALI_DLBU_H__
+#define MALI_DLBU_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */
+
#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 */
+struct mali_pp_job;
+struct mali_group;
extern u32 mali_dlbu_phys_addr;
@@ -26,20 +28,19 @@ 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_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
+void mali_dlbu_remove_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
+
+/** @brief Called to update HW after DLBU state changed
+ *
+ * This function must be called after \a mali_dlbu_add_group or \a
+ * mali_dlbu_remove_group to write the updated mask to hardware, unless the
+ * same is accomplished by calling \a mali_dlbu_reset.
+ */
+void mali_dlbu_update_mask(struct mali_dlbu_core *dlbu);
-void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu);
-void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu);
+void mali_dlbu_config_job(struct mali_dlbu_core *dlbu, struct mali_pp_job *job);
#endif /* __MALI_DLBU_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp.c b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.c
new file mode 100644
index 0000000..c2b01f9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.c
@@ -0,0 +1,364 @@
+/*
+ * 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 defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+static struct mali_gp_core *mali_global_gp_core = NULL;
+
+/* Interrupt handlers */
+static void mali_gp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_gp_irq_probe_ack(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->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;
+
+ ret = mali_gp_reset(core);
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ ret = mali_group_add_gp_core(group, core);
+ 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_group_upper_half_gp,
+ group,
+ mali_gp_irq_probe_trigger,
+ mali_gp_irq_probe_ack,
+ core,
+ "mali_gp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ 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(("Mali GP: Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
+ }
+ mali_group_remove_gp_core(group);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to add core %s to group\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_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;
+
+ 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 < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == 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 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_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 < MALI_REG_POLL_COUNT_FAST; 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 (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ 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);
+
+}
+
+void mali_gp_reset_async(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description));
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
+ 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);
+
+}
+
+_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core)
+{
+ int i;
+ u32 rawstat = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ rawstat = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
+ if (rawstat & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ }
+
+ if (i == MALI_REG_POLL_COUNT_FAST)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, rawstat: 0x%08x\n",
+ core->hw_core.description, rawstat));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* 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;
+}
+
+_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core)
+{
+ mali_gp_reset_async(core);
+ return mali_gp_reset_wait(core);
+}
+
+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 = mali_gp_job_get_perf_counter_src0(job);
+ core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ 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);
+
+ 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);
+ }
+
+ 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();
+}
+
+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);
+
+ 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();
+ }
+ /*
+ * 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.
+ */
+}
+
+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);
+}
+
+struct mali_gp_core *mali_gp_get_global_gp_core(void)
+{
+ return mali_global_gp_core;
+}
+
+/* ------------- interrupt handling below ------------------ */
+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);
+ 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 --------- */
+#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
+
+void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job, mali_bool suspend)
+{
+ u32 val0 = 0;
+ u32 val1 = 0;
+
+ 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);
+ mali_gp_job_set_perf_counter_value0(job, val0);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_0_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);
+ mali_gp_job_set_perf_counter_value1(job, val1);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_0_C1, val1);
+#endif
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp.h b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.h
new file mode 100644
index 0000000..2750c75
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.h
@@ -0,0 +1,96 @@
+/*
+ * 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"
+#include "mali_hw_core.h"
+#include "regs/mali_gp_regs.h"
+
+struct mali_group;
+
+/**
+ * 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 */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ 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 */
+};
+
+_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_reset_async(struct mali_gp_core *core);
+_mali_osk_errcode_t mali_gp_reset_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);
+
+u32 mali_gp_core_get_version(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);
+
+void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job, mali_bool suspend);
+
+/*** Accessor functions ***/
+MALI_STATIC_INLINE const char *mali_gp_get_hw_core_desc(struct mali_gp_core *core)
+{
+ return core->hw_core.description;
+}
+
+/*** Register reading/writing functions ***/
+MALI_STATIC_INLINE u32 mali_gp_get_int_stat(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
+}
+
+MALI_STATIC_INLINE void mali_gp_mask_all_interrupts(struct mali_gp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
+}
+
+MALI_STATIC_INLINE u32 mali_gp_read_rawstat(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_read_core_status(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS);
+}
+
+MALI_STATIC_INLINE void mali_gp_enable_interrupts(struct mali_gp_core *core, u32 irq_exceptions)
+{
+ /* Enable all interrupts, except those specified in irq_exceptions */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK,
+ MALIGP2_REG_VAL_IRQ_MASK_USED & ~irq_exceptions);
+}
+
+MALI_STATIC_INLINE u32 mali_gp_read_plbu_alloc_start_addr(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR);
+}
+
+#endif /* __MALI_GP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c
new file mode 100644
index 0000000..dae68b1
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c
@@ -0,0 +1,116 @@
+/*
+ * 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"
+
+static u32 gp_counter_src0 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
+static u32 gp_counter_src1 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
+
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id)
+{
+ struct mali_gp_job *job;
+ u32 perf_counter_flag;
+
+ job = _mali_osk_malloc(sizeof(struct mali_gp_job));
+ if (NULL != job)
+ {
+ job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
+ if (NULL == job->finished_notification)
+ {
+ _mali_osk_free(job);
+ return NULL;
+ }
+
+ job->oom_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
+ if (NULL == job->oom_notification)
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ _mali_osk_free(job);
+ return NULL;
+ }
+
+ if (0 != copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_gp_start_job_s)))
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ _mali_osk_notification_delete(job->oom_notification);
+ _mali_osk_free(job);
+ return NULL;
+ }
+
+ perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
+
+ /* case when no counters came from user space
+ * so pass the debugfs / DS-5 provided global ones to the job object */
+ if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
+ (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)))
+ {
+ mali_gp_job_set_perf_counter_src0(job, mali_gp_job_get_gp_counter_src0());
+ mali_gp_job_set_perf_counter_src1(job, mali_gp_job_get_gp_counter_src1());
+ }
+
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ job->id = id;
+ job->heap_current_addr = job->uargs.frame_registers[4];
+ job->perf_counter_value0 = 0;
+ job->perf_counter_value1 = 0;
+ job->pid = _mali_osk_get_pid();
+ job->tid = _mali_osk_get_tid();
+
+ return job;
+ }
+
+ return NULL;
+}
+
+void mali_gp_job_delete(struct mali_gp_job *job)
+{
+
+ /* de-allocate the pre-allocated oom notifications */
+ if (NULL != job->oom_notification)
+ {
+ _mali_osk_notification_delete(job->oom_notification);
+ job->oom_notification = NULL;
+ }
+ if (NULL != job->finished_notification)
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ job->finished_notification = NULL;
+ }
+
+ _mali_osk_free(job);
+}
+
+u32 mali_gp_job_get_gp_counter_src0(void)
+{
+ return gp_counter_src0;
+}
+
+mali_bool mali_gp_job_set_gp_counter_src0(u32 counter)
+{
+ gp_counter_src0 = counter;
+
+ return MALI_TRUE;
+}
+
+u32 mali_gp_job_get_gp_counter_src1(void)
+{
+ return gp_counter_src1;
+}
+
+mali_bool mali_gp_job_set_gp_counter_src1(u32 counter)
+{
+ gp_counter_src1 = counter;
+
+ return MALI_TRUE;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.h b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h
index 9c29f1c..e021b9b 100644
--- a/drivers/media/video/samsung/mali/common/mali_gp_job.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h
@@ -17,32 +17,33 @@
#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_*
+ * The structure represents a GP job, including all sub-jobs
+ * (This struct unfortunately 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 */
+ _mali_uk_gp_start_job_s uargs; /**< Arguments from user space */
u32 id; /**< identifier for this job in kernel space (sequential numbering) */
- u32 user_id; /**< identifier for the job in user space */
- u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< core specific registers associated with this job, see ARM DDI0415A */
u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */
- u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
- u32 perf_counter_src0; /**< source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
- u32 perf_counter_src1; /**< source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
u32 perf_counter_value0; /**< Value of performance counter 0 (to be returned to user space) */
u32 perf_counter_value1; /**< Value of performance counter 1 (to be returned to user space) */
u32 pid; /**< Process ID of submitting process */
u32 tid; /**< Thread ID of submitting thread */
- u32 frame_builder_id; /**< id of the originating frame builder */
- u32 flush_id; /**< flush id within the originating frame builder */
+ _mali_osk_notification_t *finished_notification; /**< Notification sent back to userspace on job complete */
+ _mali_osk_notification_t *oom_notification; /**< Notification sent back to userspace on OOM */
};
-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 *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id);
void mali_gp_job_delete(struct mali_gp_job *job);
+u32 mali_gp_job_get_gp_counter_src0(void);
+mali_bool mali_gp_job_set_gp_counter_src0(u32 counter);
+u32 mali_gp_job_get_gp_counter_src1(void);
+mali_bool mali_gp_job_set_gp_counter_src1(u32 counter);
+
MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
{
return (NULL == job) ? 0 : job->id;
@@ -50,22 +51,32 @@ MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job)
{
- return job->user_id;
+ return job->uargs.user_job_ptr;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
{
- return job->frame_builder_id;
+ return job->uargs.frame_builder_id;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
{
- return job->flush_id;
+ return job->uargs.flush_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_pid(struct mali_gp_job *job)
+{
+ return job->pid;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_tid(struct mali_gp_job *job)
+{
+ return job->tid;
}
MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job)
{
- return job->frame_registers;
+ return job->uargs.frame_registers;
}
MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job)
@@ -75,12 +86,12 @@ MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali
MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job)
{
- return (job->frame_registers[0] != job->frame_registers[1]) ? MALI_TRUE : MALI_FALSE;
+ return (job->uargs.frame_registers[0] != job->uargs.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;
+ return (job->uargs.frame_registers[2] != job->uargs.frame_registers[3]) ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job)
@@ -95,17 +106,17 @@ MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *jo
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job)
{
- return job->perf_counter_flag;
+ return job->uargs.perf_counter_flag;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
{
- return job->perf_counter_src0;
+ return job->uargs.perf_counter_src0;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
{
- return job->perf_counter_src1;
+ return job->uargs.perf_counter_src1;
}
MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job)
@@ -118,6 +129,16 @@ MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *j
return job->perf_counter_value1;
}
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src0(struct mali_gp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src0 = src;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src1(struct mali_gp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src1 = src;
+}
+
MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value)
{
job->perf_counter_value0 = value;
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c
new file mode 100644
index 0000000..ebbc281
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c
@@ -0,0 +1,571 @@
+/*
+ * 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_pm.h"
+#include "mali_kernel_utilization.h"
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+#include <linux/sched.h>
+#include <trace/events/gpu.h>
+#endif
+
+enum mali_gp_slot_state
+{
+ MALI_GP_SLOT_STATE_IDLE,
+ MALI_GP_SLOT_STATE_WORKING,
+ MALI_GP_SLOT_STATE_DISABLED,
+};
+
+/* 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 void mali_gp_scheduler_job_queued(void);
+static void mali_gp_scheduler_job_completed(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 num_groups;
+ u32 i;
+
+ _MALI_OSK_INIT_LIST_HEAD(&job_queue);
+
+ gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ if (NULL == gp_scheduler_lock)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
+ 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 */
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
+ {
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ 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 is only one GP, no point in looking for more */
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_scheduler_terminate(void)
+{
+ MALI_DEBUG_ASSERT( MALI_GP_SLOT_STATE_IDLE == slot.state
+ || MALI_GP_SLOT_STATE_DISABLED == slot.state);
+ MALI_DEBUG_ASSERT_POINTER(slot.group);
+ mali_group_delete(slot.group);
+
+ _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_gp_scheduler_lock();
+
+ 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));
+ mali_gp_scheduler_unlock();
+ return; /* Nothing to do, so early out */
+ }
+
+ /* Get (and remove) next job in queue */
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
+ _mali_osk_list_del(&job->list);
+
+ /* Mark slot as busy */
+ slot.state = MALI_GP_SLOT_STATE_WORKING;
+
+ mali_gp_scheduler_unlock();
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
+
+ mali_group_lock(slot.group);
+ mali_group_start_gp_job(slot.group, job);
+ mali_group_unlock(slot.group);
+}
+
+static void mali_gp_scheduler_schedule_on_group(struct mali_group *group)
+{
+ struct mali_gp_job *job;
+
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);
+
+ if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue))
+ {
+ mali_gp_scheduler_unlock();
+ 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));
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_gp_get_hw_core_desc(group->gp_core), sched_clock(), 0, 0, 0);
+#endif
+ return; /* Nothing to do, so early out */
+ }
+
+ /* Get (and remove) next job in queue */
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
+ _mali_osk_list_del(&job->list);
+
+ /* Mark slot as busy */
+ slot.state = MALI_GP_SLOT_STATE_WORKING;
+
+ mali_gp_scheduler_unlock();
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
+
+ mali_group_start_gp_job(slot.group, job);
+}
+
+static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
+{
+ _mali_uk_gp_job_finished_s *jobres = job->finished_notification->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), job->finished_notification);
+ job->finished_notification = NULL;
+
+ mali_gp_job_delete(job);
+}
+
+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_return_job_to_user(job, success);
+
+ 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);
+ }
+
+ mali_gp_scheduler_schedule_on_group(group);
+
+ /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+ mali_gp_scheduler_job_completed();
+}
+
+void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
+{
+ _mali_uk_gp_job_suspended_s * jobres;
+ _mali_osk_notification_t * notification;
+
+ mali_gp_scheduler_lock();
+
+ notification = job->oom_notification;
+ job->oom_notification = NULL;
+ slot.returned_cookie = mali_gp_job_get_id(job);
+
+ jobres = (_mali_uk_gp_job_suspended_s *)notification->result_buffer;
+ jobres->user_job_ptr = mali_gp_job_get_user_id(job);
+ jobres->cookie = mali_gp_job_get_id(job);
+
+ mali_gp_scheduler_unlock();
+
+ jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
+
+ mali_session_send_notification(mali_gp_job_get_session(job), notification);
+
+ /*
+ * 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) */
+ mali_gp_scheduler_unlock();
+ if (0 == pause_count)
+ {
+ mali_gp_scheduler_schedule();
+ }
+}
+
+_mali_osk_errcode_t _mali_ukk_gp_start_job(void *ctx, _mali_uk_gp_start_job_s *uargs)
+{
+ struct mali_session_data *session;
+ struct mali_gp_job *job;
+
+ MALI_DEBUG_ASSERT_POINTER(uargs);
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+
+ session = (struct mali_session_data*)ctx;
+
+ job = mali_gp_job_create(session, uargs, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+#if PROFILING_SKIP_PP_AND_GP_JOBS
+#warning GP jobs will not be executed
+ mali_gp_scheduler_return_job_to_user(job, MALI_TRUE);
+ return _MALI_OSK_ERR_OK;
+#endif
+
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_job_enqueue(mali_gp_job_get_tid(job), mali_gp_job_get_id(job), "GP");
+#endif
+
+ mali_gp_scheduler_job_queued();
+
+ mali_gp_scheduler_lock();
+ _mali_osk_list_addtail(&job->list, &job_queue);
+ mali_gp_scheduler_unlock();
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job));
+
+ mali_gp_scheduler_schedule();
+
+ 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;
+ struct mali_gp_job *resumed_job;
+ _mali_osk_notification_t *new_notification = 0;
+
+ 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;
+ }
+
+ if (_MALIGP_JOB_RESUME_WITH_NEW_HEAP == args->code)
+ {
+ new_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
+
+ if (NULL == new_notification)
+ {
+ MALI_PRINT_ERROR(("Mali GP scheduler: Failed to allocate notification object. Will abort GP job.\n"));
+ mali_group_lock(slot.group);
+ mali_group_abort_gp_job(slot.group, args->cookie);
+ mali_group_unlock(slot.group);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ mali_group_lock(slot.group);
+
+ if (_MALIGP_JOB_RESUME_WITH_NEW_HEAP == args->code)
+ {
+ 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]));
+
+ resumed_job = mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]);
+ if (NULL != resumed_job)
+ {
+ resumed_job->oom_notification = new_notification;
+ mali_group_unlock(slot.group);
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ mali_group_unlock(slot.group);
+ _mali_osk_notification_delete(new_notification);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ 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);
+ mali_group_unlock(slot.group);
+ return _MALI_OSK_ERR_OK;
+}
+
+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_job_completed();
+ }
+ }
+
+ mali_gp_scheduler_unlock();
+
+ 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, "\n");
+
+ return n;
+}
+#endif
+
+void mali_gp_scheduler_reset_all_groups(void)
+{
+ if (NULL != slot.group)
+ {
+ mali_group_lock(slot.group);
+ mali_group_reset(slot.group);
+ mali_group_unlock(slot.group);
+ }
+}
+
+void mali_gp_scheduler_zap_all_active(struct mali_session_data *session)
+{
+ if (NULL != slot.group)
+ {
+ mali_group_zap_session(slot.group, session);
+ }
+}
+
+void mali_gp_scheduler_enable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(slot.group == group);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: enabling gp group %p\n", group));
+
+ mali_group_lock(group);
+
+ if (MALI_GROUP_STATE_DISABLED != group->state)
+ {
+ mali_group_unlock(group);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: gp group %p already enabled\n", group));
+ return;
+ }
+
+ mali_gp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+ MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_DISABLED == slot.state);
+ slot.state = MALI_GP_SLOT_STATE_IDLE;
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ mali_group_power_on_group(group);
+ mali_group_reset(group);
+
+ mali_gp_scheduler_unlock();
+ mali_group_unlock(group);
+
+ /* Pick up any jobs that might have been queued while the GP group was disabled. */
+ mali_gp_scheduler_schedule();
+}
+
+void mali_gp_scheduler_disable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(slot.group == group);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: disabling gp group %p\n", group));
+
+ mali_gp_scheduler_suspend();
+ mali_group_lock(group);
+ mali_gp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_DISABLED == slot.state);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: gp group %p already disabled\n", group));
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_IDLE == slot.state);
+ slot.state = MALI_GP_SLOT_STATE_DISABLED;
+ group->state = MALI_GROUP_STATE_DISABLED;
+
+ mali_group_power_off_group(group);
+ }
+
+ mali_gp_scheduler_unlock();
+ mali_group_unlock(group);
+ mali_gp_scheduler_resume();
+}
+
+static void mali_gp_scheduler_job_queued(void)
+{
+ /* We hold a PM reference for every job we hold queued (and running) */
+ _mali_osk_pm_dev_ref_add();
+
+ if (mali_utilization_enabled())
+ {
+ /*
+ * We cheat a little bit by counting the PP as busy from the time a GP job is queued.
+ * This will be fine because we only loose the tiny idle gap between jobs, but
+ * we will instead get less utilization work to do (less locks taken)
+ */
+ mali_utilization_gp_start();
+ }
+}
+
+static void mali_gp_scheduler_job_completed(void)
+{
+ /* Release the PM reference we got in the mali_gp_scheduler_job_queued() function */
+ _mali_osk_pm_dev_ref_dec();
+
+ if (mali_utilization_enabled())
+ {
+ mali_utilization_gp_end();
+ }
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h
index ef58509..7f61a78 100644
--- a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h
@@ -12,13 +12,12 @@
#define __MALI_GP_SCHEDULER_H__
#include "mali_osk.h"
-#include "mali_cluster.h"
#include "mali_gp_job.h"
+#include "mali_group.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);
@@ -27,4 +26,22 @@ u32 mali_gp_scheduler_dump_state(char *buf, u32 size);
void mali_gp_scheduler_suspend(void);
void mali_gp_scheduler_resume(void);
+/**
+ * @brief Reset all groups
+ *
+ * This function resets all groups known by the GP scheuduler. This must be
+ * called after the Mali HW has been powered on in order to reset the HW.
+ */
+void mali_gp_scheduler_reset_all_groups(void);
+
+/**
+ * @brief Zap TLB on all groups with \a session active
+ *
+ * The scheculer will zap the session on all groups it owns.
+ */
+void mali_gp_scheduler_zap_all_active(struct mali_session_data *session);
+
+void mali_gp_scheduler_enable_group(struct mali_group *group);
+void mali_gp_scheduler_disable_group(struct mali_group *group);
+
#endif /* __MALI_GP_SCHEDULER_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_group.c b/drivers/gpu/mali400/r3p2/mali/common/mali_group.c
new file mode 100644
index 0000000..070879e
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_group.c
@@ -0,0 +1,2046 @@
+/*
+ * 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_l2_cache.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_mmu.h"
+#include "mali_dlbu.h"
+#include "mali_broadcast.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_kernel_core.h"
+#include "mali_osk_profiling.h"
+#include "mali_pm_domain.h"
+#include "mali_pm.h"
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+#include <linux/sched.h>
+#include <trace/events/gpu.h>
+#endif
+
+
+static void mali_group_bottom_half_mmu(void *data);
+static void mali_group_bottom_half_gp(void *data);
+static void mali_group_bottom_half_pp(void *data);
+
+static void mali_group_timeout(void *data);
+static void mali_group_reset_pp(struct mali_group *group);
+static void mali_group_reset_mmu(struct mali_group *group);
+
+#if defined(CONFIG_MALI400_PROFILING)
+static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num);
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+
+/*
+ * 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).
+ */
+
+static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS] = { NULL, };
+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_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session);
+static void mali_group_recovery_reset(struct mali_group *group);
+static void mali_group_mmu_page_fault(struct mali_group *group);
+
+static void mali_group_post_process_job_pp(struct mali_group *group);
+static void mali_group_post_process_job_gp(struct mali_group *group, mali_bool suspend);
+
+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_l2_cache_core *core, struct mali_dlbu_core *dlbu, struct mali_bcast_unit *bcast)
+{
+ struct mali_group *group = NULL;
+ _mali_osk_lock_flags_t lock_flags;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#else
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#endif
+
+ 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_calloc(1, sizeof(struct mali_group));
+ if (NULL != group)
+ {
+ group->timeout_timer = _mali_osk_timer_init();
+
+ if (NULL != group->timeout_timer)
+ {
+ _mali_osk_lock_order_t order;
+ _mali_osk_timer_setcallback(group->timeout_timer, mali_group_timeout, (void *)group);
+
+ if (NULL != dlbu)
+ {
+ order = _MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL;
+ }
+ else
+ {
+ order = _MALI_OSK_LOCK_ORDER_GROUP;
+ }
+
+ group->lock = _mali_osk_lock_init(lock_flags, 0, order);
+ if (NULL != group->lock)
+ {
+ group->l2_cache_core[0] = core;
+ group->session = NULL;
+ group->page_dir_ref_count = 0;
+ group->power_is_on = MALI_TRUE;
+ group->state = MALI_GROUP_STATE_IDLE;
+ _mali_osk_list_init(&group->group_list);
+ _mali_osk_list_init(&group->pp_scheduler_list);
+ group->parent_group = NULL;
+ group->l2_cache_core_ref_count[0] = 0;
+ group->l2_cache_core_ref_count[1] = 0;
+ group->bcast_core = bcast;
+ group->dlbu_core = dlbu;
+
+ mali_global_groups[mali_global_num_groups] = group;
+ mali_global_num_groups++;
+
+ return group;
+ }
+ _mali_osk_timer_term(group->timeout_timer);
+ }
+ _mali_osk_free(group);
+ }
+
+ return NULL;
+}
+
+_mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core)
+{
+ /* This group object now owns the MMU core object */
+ group->mmu= mmu_core;
+ group->bottom_half_work_mmu = _mali_osk_wq_create_work(mali_group_bottom_half_mmu, group);
+ if (NULL == group->bottom_half_work_mmu)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_group_remove_mmu_core(struct mali_group *group)
+{
+ /* This group object no longer owns the MMU core object */
+ group->mmu = NULL;
+ if (NULL != group->bottom_half_work_mmu)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
+ }
+}
+
+_mali_osk_errcode_t 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;
+ group->bottom_half_work_gp = _mali_osk_wq_create_work(mali_group_bottom_half_gp, group);
+ if (NULL == group->bottom_half_work_gp)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_group_remove_gp_core(struct mali_group *group)
+{
+ /* This group object no longer owns the GP core object */
+ group->gp_core = NULL;
+ if (NULL != group->bottom_half_work_gp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_gp);
+ }
+}
+
+_mali_osk_errcode_t 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;
+ group->bottom_half_work_pp = _mali_osk_wq_create_work(mali_group_bottom_half_pp, group);
+ if (NULL == group->bottom_half_work_pp)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_group_remove_pp_core(struct mali_group *group)
+{
+ /* This group object no longer owns the PP core object */
+ group->pp_core = NULL;
+ if (NULL != group->bottom_half_work_pp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_pp);
+ }
+}
+
+void mali_group_set_pm_domain(struct mali_group *group, struct mali_pm_domain *domain)
+{
+ group->pm_domain = domain;
+}
+
+void mali_group_delete(struct mali_group *group)
+{
+ u32 i;
+
+ MALI_DEBUG_PRINT(4, ("Deleting group %p\n", group));
+
+ MALI_DEBUG_ASSERT(NULL == group->parent_group);
+
+ /* 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);
+ }
+
+ if (mali_group_is_virtual(group))
+ {
+ /* Remove all groups from virtual group */
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ child->parent_group = NULL;
+ mali_group_delete(child);
+ }
+
+ mali_dlbu_delete(group->dlbu_core);
+
+ if (NULL != group->bcast_core)
+ {
+ mali_bcast_unit_delete(group->bcast_core);
+ }
+ }
+
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ if (mali_global_groups[i] == group)
+ {
+ mali_global_groups[i] = NULL;
+ mali_global_num_groups--;
+
+ if (i != mali_global_num_groups)
+ {
+ /* We removed a group from the middle of the array -- move the last
+ * group to the current position to close the gap */
+ mali_global_groups[i] = mali_global_groups[mali_global_num_groups];
+ mali_global_groups[mali_global_num_groups] = NULL;
+ }
+
+ break;
+ }
+ }
+
+ if (NULL != group->timeout_timer)
+ {
+ _mali_osk_timer_del(group->timeout_timer);
+ _mali_osk_timer_term(group->timeout_timer);
+ }
+
+ if (NULL != group->bottom_half_work_mmu)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
+ }
+
+ if (NULL != group->bottom_half_work_gp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_gp);
+ }
+
+ if (NULL != group->bottom_half_work_pp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_pp);
+ }
+
+ _mali_osk_lock_term(group->lock);
+
+ _mali_osk_free(group);
+}
+
+MALI_DEBUG_CODE(static void mali_group_print_virtual(struct mali_group *vgroup)
+{
+ u32 i;
+ struct mali_group *group;
+ struct mali_group *temp;
+
+ MALI_DEBUG_PRINT(4, ("Virtual group %p\n", vgroup));
+ MALI_DEBUG_PRINT(4, ("l2_cache_core[0] = %p, ref = %d\n", vgroup->l2_cache_core[0], vgroup->l2_cache_core_ref_count[0]));
+ MALI_DEBUG_PRINT(4, ("l2_cache_core[1] = %p, ref = %d\n", vgroup->l2_cache_core[1], vgroup->l2_cache_core_ref_count[1]));
+
+ i = 0;
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &vgroup->group_list, struct mali_group, group_list)
+ {
+ MALI_DEBUG_PRINT(4, ("[%d] %p, l2_cache_core[0] = %p\n", i, group, group->l2_cache_core[0]));
+ i++;
+ }
+})
+
+/**
+ * @brief Add child group to virtual group parent
+ *
+ * Before calling this function, child must have it's state set to JOINING_VIRTUAL
+ * to ensure it's not touched during the transition period. When this function returns,
+ * child's state will be IN_VIRTUAL.
+ */
+void mali_group_add_group(struct mali_group *parent, struct mali_group *child, mali_bool update_hw)
+{
+ mali_bool found;
+ u32 i;
+ struct mali_session_data *child_session;
+
+ MALI_DEBUG_PRINT(3, ("Adding group %p to virtual group %p\n", child, parent));
+
+ MALI_ASSERT_GROUP_LOCKED(parent);
+
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
+ MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
+ MALI_DEBUG_ASSERT(NULL == child->parent_group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_JOINING_VIRTUAL == child->state);
+
+ _mali_osk_list_addtail(&child->group_list, &parent->group_list);
+
+ child->state = MALI_GROUP_STATE_IN_VIRTUAL;
+ child->parent_group = parent;
+
+ MALI_DEBUG_ASSERT_POINTER(child->l2_cache_core[0]);
+
+ MALI_DEBUG_PRINT(4, ("parent->l2_cache_core: [0] = %p, [1] = %p\n", parent->l2_cache_core[0], parent->l2_cache_core[1]));
+ MALI_DEBUG_PRINT(4, ("child->l2_cache_core: [0] = %p, [1] = %p\n", child->l2_cache_core[0], child->l2_cache_core[1]));
+
+ /* Keep track of the L2 cache cores of child groups */
+ found = MALI_FALSE;
+ for (i = 0; i < 2; i++)
+ {
+ if (parent->l2_cache_core[i] == child->l2_cache_core[0])
+ {
+ MALI_DEBUG_ASSERT(parent->l2_cache_core_ref_count[i] > 0);
+ parent->l2_cache_core_ref_count[i]++;
+ found = MALI_TRUE;
+ }
+ }
+
+ if (!found)
+ {
+ /* First time we see this L2 cache, add it to our list */
+ i = (NULL == parent->l2_cache_core[0]) ? 0 : 1;
+
+ MALI_DEBUG_PRINT(4, ("First time we see l2_cache %p. Adding to [%d] = %p\n", child->l2_cache_core[0], i, parent->l2_cache_core[i]));
+
+ MALI_DEBUG_ASSERT(NULL == parent->l2_cache_core[i]);
+
+ parent->l2_cache_core[i] = child->l2_cache_core[0];
+ parent->l2_cache_core_ref_count[i]++;
+ }
+
+ /* Update Broadcast Unit and DLBU */
+ mali_bcast_add_group(parent->bcast_core, child);
+ mali_dlbu_add_group(parent->dlbu_core, child);
+
+ child_session = child->session;
+ child->session = NULL;
+
+ /* Above this comment, only software state is updated and the HW is not
+ * touched. Now, check if Mali is powered and skip the rest if it isn't
+ * powered.
+ */
+
+ if (!update_hw)
+ {
+ MALI_DEBUG_CODE(mali_group_print_virtual(parent));
+ return;
+ }
+
+ /* Update MMU */
+ MALI_DEBUG_ASSERT(0 == child->page_dir_ref_count);
+ if (parent->session == child_session)
+ {
+ mali_mmu_zap_tlb(child->mmu);
+ }
+ else
+ {
+ if (NULL == parent->session)
+ {
+ mali_mmu_activate_empty_page_directory(child->mmu);
+ }
+ else
+ {
+
+ mali_bool activate_success = mali_mmu_activate_page_directory(child->mmu,
+ mali_session_get_page_directory(parent->session));
+ MALI_DEBUG_ASSERT(activate_success);
+ MALI_IGNORE(activate_success);
+ }
+ }
+
+ /* Update HW only if power is on */
+ mali_bcast_reset(parent->bcast_core);
+ mali_dlbu_update_mask(parent->dlbu_core);
+
+ /* Start job on child when parent is active */
+ if (NULL != parent->pp_running_job)
+ {
+ struct mali_pp_job *job = parent->pp_running_job;
+ MALI_DEBUG_PRINT(3, ("Group %x joining running job %d on virtual group %x\n",
+ child, mali_pp_job_get_id(job), parent));
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_WORKING == parent->state);
+ mali_pp_job_start(child->pp_core, job, mali_pp_core_get_id(child->pp_core), MALI_TRUE);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
+ mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+ }
+
+ MALI_DEBUG_CODE(mali_group_print_virtual(parent);)
+}
+
+/**
+ * @brief Remove child group from virtual group parent
+ *
+ * After the child is removed, it's state will be LEAVING_VIRTUAL and must be set
+ * to IDLE before it can be used.
+ */
+void mali_group_remove_group(struct mali_group *parent, struct mali_group *child)
+{
+ u32 i;
+
+ MALI_ASSERT_GROUP_LOCKED(parent);
+
+ MALI_DEBUG_PRINT(3, ("Removing group %p from virtual group %p\n", child, parent));
+
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
+ MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
+ MALI_DEBUG_ASSERT(parent == child->parent_group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IN_VIRTUAL == child->state);
+ /* Removing groups while running is not yet supported. */
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == parent->state);
+
+ mali_group_lock(child);
+
+ /* Update Broadcast Unit and DLBU */
+ mali_bcast_remove_group(parent->bcast_core, child);
+ mali_dlbu_remove_group(parent->dlbu_core, child);
+
+ /* Update HW only if power is on */
+ if (mali_pm_is_power_on())
+ {
+ mali_bcast_reset(parent->bcast_core);
+ mali_dlbu_update_mask(parent->dlbu_core);
+ }
+
+ _mali_osk_list_delinit(&child->group_list);
+
+ child->session = parent->session;
+ child->parent_group = NULL;
+ child->state = MALI_GROUP_STATE_LEAVING_VIRTUAL;
+
+ /* Keep track of the L2 cache cores of child groups */
+ i = (child->l2_cache_core[0] == parent->l2_cache_core[0]) ? 0 : 1;
+
+ MALI_DEBUG_ASSERT(child->l2_cache_core[0] == parent->l2_cache_core[i]);
+
+ parent->l2_cache_core_ref_count[i]--;
+
+ if (parent->l2_cache_core_ref_count[i] == 0)
+ {
+ parent->l2_cache_core[i] = NULL;
+ }
+
+ MALI_DEBUG_CODE(mali_group_print_virtual(parent));
+
+ mali_group_unlock(child);
+}
+
+struct mali_group *mali_group_acquire_group(struct mali_group *parent)
+{
+ struct mali_group *child;
+
+ MALI_ASSERT_GROUP_LOCKED(parent);
+
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
+ MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&parent->group_list));
+
+ child = _MALI_OSK_LIST_ENTRY(parent->group_list.prev, struct mali_group, group_list);
+
+ mali_group_remove_group(parent, child);
+
+ return child;
+}
+
+void mali_group_reset(struct mali_group *group)
+{
+ /*
+ * This function should not be used to abort jobs,
+ * currently only called during insmod and PM resume
+ */
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT(NULL == group->gp_running_job);
+ MALI_DEBUG_ASSERT(NULL == group->pp_running_job);
+
+ group->session = NULL;
+
+ if (NULL != group->dlbu_core)
+ {
+ mali_dlbu_reset(group->dlbu_core);
+ }
+
+ if (NULL != group->bcast_core)
+ {
+ mali_bcast_reset(group->bcast_core);
+ }
+
+ if (NULL != group->mmu)
+ {
+ mali_group_reset_mmu(group);
+ }
+
+ if (NULL != group->gp_core)
+ {
+ mali_gp_reset(group->gp_core);
+ }
+
+ if (NULL != group->pp_core)
+ {
+ mali_group_reset_pp(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;
+}
+
+void 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_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
+
+ session = mali_gp_job_get_session(job);
+
+ if (NULL != group->l2_cache_core[0])
+ {
+ mali_l2_cache_invalidate_conditional(group->l2_cache_core[0], 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);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) |
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job), 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
+ mali_gp_job_get_pid(job), mali_gp_job_get_tid(job), 0, 0, 0);
+#if defined(CONFIG_MALI400_PROFILING)
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ mali_group_report_l2_cache_counters_per_core(group, 0);
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_gp_get_hw_core_desc(group->gp_core), sched_clock(),
+ mali_gp_job_get_pid(job), 0, mali_gp_job_get_id(job));
+#endif
+ group->gp_running_job = job;
+ group->state = MALI_GROUP_STATE_WORKING;
+
+ }
+
+ /* Setup the timeout timer value and save the job id for the job running on the gp core */
+ _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+}
+
+void 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_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
+
+ session = mali_pp_job_get_session(job);
+
+ if (NULL != group->l2_cache_core[0])
+ {
+ mali_l2_cache_invalidate_conditional(group->l2_cache_core[0], mali_pp_job_get_id(job));
+ }
+
+ if (NULL != group->l2_cache_core[1])
+ {
+ mali_l2_cache_invalidate_conditional(group->l2_cache_core[1], 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);
+ }
+
+ if (mali_group_is_virtual(group))
+ {
+ struct mali_group *child;
+ struct mali_group *temp;
+ u32 core_num = 0;
+
+ /* Configure DLBU for the job */
+ mali_dlbu_config_job(group->dlbu_core, job);
+
+ /* Write stack address for each child group */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_write_addr_stack(child->pp_core, job);
+ core_num++;
+ }
+ }
+
+ mali_pp_job_start(group->pp_core, job, sub_job, MALI_FALSE);
+
+ /* if the group is virtual, loop through physical groups which belong to this group
+ * and call profiling events for its cores as virtual */
+ if (MALI_TRUE == mali_group_is_virtual(group))
+ {
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
+ mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+ }
+#if defined(CONFIG_MALI400_PROFILING)
+ if (0 != group->l2_cache_core_ref_count[0])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+ }
+ if (0 != group->l2_cache_core_ref_count[1])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
+ }
+ }
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+ }
+ else /* group is physical - call profiling events for physical cores */
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
+ mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+#if defined(CONFIG_MALI400_PROFILING)
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+ }
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_pp_get_hw_core_desc(group->pp_core), sched_clock(), mali_pp_job_get_tid(job), 0, mali_pp_job_get_id(job));
+#endif
+ group->pp_running_job = job;
+ group->pp_running_sub_job = sub_job;
+ group->state = MALI_GROUP_STATE_WORKING;
+
+ }
+
+ /* Setup the timeout timer value and save the job id for the job running on the pp core */
+ _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+}
+
+struct mali_gp_job *mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (group->state != MALI_GROUP_STATE_OOM ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ return NULL; /* Illegal request or job has already been aborted */
+ }
+
+ if (NULL != group->l2_cache_core[0])
+ {
+ mali_l2_cache_invalidate(group->l2_cache_core[0]);
+ }
+
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+
+ mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0);
+
+ group->state = MALI_GROUP_STATE_WORKING;
+
+ return group->gp_running_job;
+}
+
+static void mali_group_reset_mmu(struct mali_group *group)
+{
+ struct mali_group *child;
+ struct mali_group *temp;
+ _mali_osk_errcode_t err;
+
+ if (!mali_group_is_virtual(group))
+ {
+ /* This is a physical group or an idle virtual group -- simply wait for
+ * the reset to complete. */
+ err = mali_mmu_reset(group->mmu);
+ MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
+ }
+ else /* virtual group */
+ {
+ err = mali_mmu_reset(group->mmu);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ return;
+ }
+
+ /* Loop through all members of this virtual group and wait
+ * until they are done resetting.
+ */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ err = mali_mmu_reset(child->mmu);
+ MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
+ }
+ }
+}
+
+static void mali_group_reset_pp(struct mali_group *group)
+{
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ mali_pp_reset_async(group->pp_core);
+
+ if (!mali_group_is_virtual(group) || NULL == group->pp_running_job)
+ {
+ /* This is a physical group or an idle virtual group -- simply wait for
+ * the reset to complete. */
+ mali_pp_reset_wait(group->pp_core);
+ }
+ else /* virtual group */
+ {
+ /* Loop through all members of this virtual group and wait until they
+ * are done resetting.
+ */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_reset_wait(child->pp_core);
+ }
+ }
+}
+
+static void mali_group_complete_pp(struct mali_group *group, mali_bool success)
+{
+ struct mali_pp_job *pp_job_to_return;
+ u32 pp_sub_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->pp_core);
+ MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ mali_group_post_process_job_pp(group);
+
+ if (success)
+ {
+ /* Only do soft reset for successful jobs, a full recovery
+ * reset will be done for failed jobs. */
+ mali_pp_reset_async(group->pp_core);
+ }
+
+ pp_job_to_return = group->pp_running_job;
+ pp_sub_job_to_return = group->pp_running_sub_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->pp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ /* Do hard reset if the job failed, or if soft reset fails */
+ if (!success || _MALI_OSK_ERR_OK != mali_pp_reset_wait(group->pp_core))
+ {
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
+
+ mali_group_recovery_reset(group);
+ }
+
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, success);
+}
+
+static void mali_group_complete_gp(struct mali_group *group, mali_bool success)
+{
+ struct mali_gp_job *gp_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->gp_core);
+ MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ mali_group_post_process_job_gp(group, MALI_FALSE);
+
+ mali_gp_reset_async(group->gp_core);
+
+ gp_job_to_return = group->gp_running_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->gp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ if (_MALI_OSK_ERR_OK != mali_gp_reset_wait(group->gp_core))
+ {
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
+
+ mali_group_recovery_reset(group);
+ }
+
+ mali_gp_scheduler_job_done(group, gp_job_to_return, success);
+}
+
+void mali_group_abort_gp_job(struct mali_group *group, u32 job_id)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (MALI_GROUP_STATE_IDLE == group->state ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_gp(group, MALI_FALSE);
+}
+
+static void mali_group_abort_pp_job(struct mali_group *group, u32 job_id)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (MALI_GROUP_STATE_IDLE == group->state ||
+ mali_pp_job_get_id(group->pp_running_job) != job_id)
+ {
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_pp(group, MALI_FALSE);
+}
+
+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);
+
+ if (mali_group_is_in_virtual(group))
+ {
+ /* Group is member of a virtual group, don't touch it! */
+ mali_group_unlock(group);
+ return;
+ }
+
+ gp_job = group->gp_running_job;
+ pp_job = group->pp_running_job;
+
+ if ((NULL != 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 ((NULL != 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;
+ }
+
+ if (abort_gp)
+ {
+ mali_group_abort_gp_job(group, gp_job_id);
+ }
+ if (abort_pp)
+ {
+ mali_group_abort_pp_job(group, pp_job_id);
+ }
+
+ mali_group_remove_session_if_unused(group, session);
+
+ mali_group_unlock(group);
+}
+
+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;
+}
+
+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_GROUP_ACTIVATE_PD_STATUS_FAILED;
+ 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);
+}
+
+static 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_STATE_WORKING != group->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;
+ }
+ }
+}
+
+mali_bool mali_group_power_is_on(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ return group->power_is_on;
+}
+
+void mali_group_power_on_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_IN_VIRTUAL == group->state
+ || MALI_GROUP_STATE_JOINING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ MALI_DEBUG_PRINT(3, ("Group %p powered on\n", group));
+
+ group->power_is_on = MALI_TRUE;
+}
+
+void mali_group_power_off_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_IN_VIRTUAL == group->state
+ || MALI_GROUP_STATE_JOINING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ MALI_DEBUG_PRINT(3, ("Group %p powered off\n", group));
+
+ /* It is necessary to set group->session = NULL so that the powered off MMU is not written
+ * to on map/unmap. It is also necessary to set group->power_is_on = MALI_FALSE so that
+ * pending bottom_halves does not access powered off cores. */
+
+ group->session = NULL;
+ group->power_is_on = MALI_FALSE;
+}
+
+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);
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_ASSERT(MALI_FALSE == group->power_is_on);
+ }
+ else
+ {
+ mali_group_power_on_group(group);
+ }
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(4, ("Mali Group: power on\n"));
+}
+
+void mali_group_power_off(void)
+{
+ int i;
+
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ struct mali_group *group = mali_global_groups[i];
+
+ mali_group_lock(group);
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_ASSERT(MALI_FALSE == group->power_is_on);
+ }
+ else
+ {
+ mali_group_power_off_group(group);
+ }
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(4, ("Mali Group: power off\n"));
+}
+
+static void mali_group_recovery_reset(struct mali_group *group)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ /* Stop cores, bus stop */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_stop_bus(group->pp_core);
+ }
+ else
+ {
+ mali_gp_stop_bus(group->gp_core);
+ }
+
+ /* Flush MMU and clear page fault (if any) */
+ mali_mmu_activate_fault_flush_page_directory(group->mmu);
+ mali_mmu_page_fault_done(group->mmu);
+
+ /* Wait for cores to stop bus, then do a hard reset on them */
+ if (NULL != group->pp_core)
+ {
+ if (mali_group_is_virtual(group))
+ {
+ struct mali_group *child, *temp;
+
+ /* Disable the broadcast unit while we do reset directly on the member cores. */
+ mali_bcast_disable(group->bcast_core);
+
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_stop_bus_wait(child->pp_core);
+ mali_pp_hard_reset(child->pp_core);
+ }
+
+ mali_bcast_enable(group->bcast_core);
+ }
+ else
+ {
+ mali_pp_stop_bus_wait(group->pp_core);
+ mali_pp_hard_reset(group->pp_core);
+ }
+ }
+ else
+ {
+ mali_gp_stop_bus_wait(group->gp_core);
+ mali_gp_hard_reset(group->gp_core);
+ }
+
+ /* Reset MMU */
+ err = mali_mmu_reset(group->mmu);
+ MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
+ MALI_IGNORE(err);
+
+ group->session = NULL;
+}
+
+#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);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tstate: %d\n", group->state);
+ 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 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 job: %p, subjob %d \n",
+ group->pp_running_job, group->pp_running_sub_job);
+ }
+
+ return n;
+}
+#endif
+
+static void mali_group_mmu_page_fault(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (NULL != group->pp_core)
+ {
+ struct mali_pp_job *pp_job_to_return;
+ u32 pp_sub_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
+
+ mali_group_post_process_job_pp(group);
+
+ pp_job_to_return = group->pp_running_job;
+ pp_sub_job_to_return = group->pp_running_sub_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->pp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ mali_group_recovery_reset(group); /* This will also clear the page fault itself */
+
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, MALI_FALSE);
+ }
+ else
+ {
+ struct mali_gp_job *gp_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
+
+ mali_group_post_process_job_gp(group, MALI_FALSE);
+
+ gp_job_to_return = group->gp_running_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->gp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ mali_group_recovery_reset(group); /* This will also clear the page fault itself */
+
+ mali_gp_scheduler_job_done(group, gp_job_to_return, MALI_FALSE);
+ }
+}
+
+_mali_osk_errcode_t mali_group_upper_half_mmu(void * data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_mmu_core *mmu = group->mmu;
+ u32 int_stat;
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain))
+ {
+ goto out;
+ }
+#endif
+
+ /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
+ int_stat = mali_mmu_get_int_status(mmu);
+ if (0 != int_stat)
+ {
+ struct mali_group *parent = group->parent_group;
+
+ /* page fault or bus error, we thread them both in the same way */
+ mali_mmu_mask_all_interrupts(mmu);
+ if (NULL == parent)
+ {
+ _mali_osk_wq_schedule_work(group->bottom_half_work_mmu);
+ }
+ else
+ {
+ _mali_osk_wq_schedule_work(parent->bottom_half_work_mmu);
+ }
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+out:
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_pm_domain_unlock_state(group->pm_domain);
+#endif
+
+ return err;
+}
+
+static void mali_group_bottom_half_mmu(void * data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_mmu_core *mmu = group->mmu;
+ u32 rawstat;
+ MALI_DEBUG_CODE(u32 status);
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ mali_group_lock(group);
+
+ MALI_DEBUG_ASSERT(NULL == group->parent_group);
+
+ if ( MALI_FALSE == mali_group_power_is_on(group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", mmu->hw_core.description));
+ mali_group_unlock(group);
+ return;
+ }
+
+ rawstat = mali_mmu_get_rawstat(mmu);
+ MALI_DEBUG_CODE(status = mali_mmu_get_status(mmu));
+
+ MALI_DEBUG_PRINT(4, ("Mali MMU: Bottom half, interrupt 0x%08X, status 0x%08X\n", rawstat, status));
+
+ if (rawstat & (MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR))
+ {
+ /* An actual page fault has occurred. */
+ u32 fault_address = mali_mmu_get_page_fault_addr(mmu);
+ MALI_DEBUG_PRINT(2,("Mali MMU: 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->hw_core.description));
+ MALI_IGNORE(fault_address);
+
+ mali_group_mmu_page_fault(group);
+ }
+
+ mali_group_unlock(group);
+}
+
+_mali_osk_errcode_t mali_group_upper_half_gp(void *data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_gp_core *core = group->gp_core;
+ u32 irq_readout;
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain))
+ {
+ goto out;
+ }
+#endif
+
+ irq_readout = mali_gp_get_int_stat(core);
+
+ if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_gp_mask_all_interrupts(core);
+
+ _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);
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
+
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+out:
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_pm_domain_unlock_state(group->pm_domain);
+#endif
+
+ return err;
+}
+
+static void mali_group_bottom_half_gp(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+ u32 irq_readout;
+ u32 irq_errors;
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0), 0, 0);
+
+ mali_group_lock(group);
+
+ if ( MALI_FALSE == mali_group_power_is_on(group) )
+ {
+ MALI_PRINT_ERROR(("Mali group: Interrupt bottom half of %s when core is OFF.", mali_gp_get_hw_core_desc(group->gp_core)));
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ irq_readout = mali_gp_read_rawstat(group->gp_core);
+
+ MALI_DEBUG_PRINT(4, ("Mali group: GP bottom half IRQ 0x%08X from core %s\n", irq_readout, mali_gp_get_hw_core_desc(group->gp_core)));
+
+ if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST))
+ {
+ u32 core_status = mali_gp_read_core_status(group->gp_core);
+ if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: GP job completed, calling group handler\n"));
+ group->core_timed_out = MALI_FALSE;
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ mali_group_complete_gp(group, MALI_TRUE);
+ mali_group_unlock(group);
+ 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_PRINT_ERROR(("Mali group: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, mali_gp_get_hw_core_desc(group->gp_core)));
+ group->core_timed_out = MALI_FALSE;
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ mali_group_complete_gp(group, MALI_FALSE);
+ mali_group_unlock(group);
+ return;
+ }
+ else if (group->core_timed_out) /* SW timeout */
+ {
+ group->core_timed_out = MALI_FALSE;
+ if (!_mali_osk_timer_pending(group->timeout_timer) && NULL != group->gp_running_job)
+ {
+ MALI_PRINT(("Mali group: Job %d timed out\n", mali_gp_job_get_id(group->gp_running_job)));
+ mali_group_complete_gp(group, MALI_FALSE);
+ mali_group_unlock(group);
+ return;
+ }
+ }
+ else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
+ {
+ /* GP wants more memory in order to continue. */
+ MALI_DEBUG_PRINT(3, ("Mali group: PLBU needs more heap memory\n"));
+
+ group->state = MALI_GROUP_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);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ /*
+ * The only way to get here is if we only got one of two needed END_CMD_LST
+ * interrupts. Enable all but not the complete interrupt that has been
+ * received and continue to run.
+ */
+ mali_gp_enable_interrupts(group->gp_core, irq_readout & (MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST));
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+}
+
+static void mali_group_post_process_job_gp(struct mali_group *group, mali_bool suspend)
+{
+ /* Stop the timeout timer. */
+ _mali_osk_timer_del_async(group->timeout_timer);
+
+ if (NULL == group->gp_running_job)
+ {
+ /* Nothing to do */
+ return;
+ }
+
+ mali_gp_update_performance_counters(group->gp_core, group->gp_running_job, suspend);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ if (suspend)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
+ mali_gp_job_get_perf_counter_value0(group->gp_running_job),
+ mali_gp_job_get_perf_counter_value1(group->gp_running_job),
+ mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
+ 0, 0);
+ }
+ else
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
+ mali_gp_job_get_perf_counter_value0(group->gp_running_job),
+ mali_gp_job_get_perf_counter_value1(group->gp_running_job),
+ mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
+ 0, 0);
+
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ mali_group_report_l2_cache_counters_per_core(group, 0);
+ }
+#endif
+
+ mali_gp_job_set_current_heap_addr(group->gp_running_job,
+ mali_gp_read_plbu_alloc_start_addr(group->gp_core));
+}
+
+_mali_osk_errcode_t mali_group_upper_half_pp(void *data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_pp_core *core = group->pp_core;
+ u32 irq_readout;
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain))
+ {
+ goto out;
+ }
+#endif
+
+ /*
+ * For Mali-450 there is one particular case we need to watch out for:
+ *
+ * Criteria 1) this function call can be due to a shared interrupt,
+ * and not necessary because this core signaled an interrupt.
+ * Criteria 2) this core is a part of a virtual group, and thus it should
+ * not do any post processing.
+ * Criteria 3) this core has actually indicated that is has completed by
+ * having set raw_stat/int_stat registers to != 0
+ *
+ * If all this criteria is meet, then we could incorrectly start post
+ * processing on the wrong group object (this should only happen on the
+ * parent group)
+ */
+#if !defined(MALI_UPPER_HALF_SCHEDULING)
+ if (mali_group_is_in_virtual(group))
+ {
+ /*
+ * This check is done without the group lock held, which could lead to
+ * a potential race. This is however ok, since we will safely re-check
+ * this with the group lock held at a later stage. This is just an
+ * early out which will strongly benefit shared IRQ systems.
+ */
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+#endif
+
+ irq_readout = mali_pp_get_int_stat(core);
+ if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_pp_mask_all_interrupts(core);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ /* Currently no support for this interrupt event for the virtual PP core */
+ if (!mali_group_is_virtual(group))
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) |
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT,
+ irq_readout, 0, 0, 0, 0);
+ }
+#endif
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ /* Check if job is complete without errors */
+ if (MALI200_REG_VAL_IRQ_END_OF_FRAME == irq_readout)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler from upper half\n"));
+
+ mali_group_lock(group);
+
+ /* Check if job is complete without errors, again, after taking the group lock */
+ irq_readout = mali_pp_read_rawstat(core);
+ if (MALI200_REG_VAL_IRQ_END_OF_FRAME != irq_readout)
+ {
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+ if (mali_group_is_virtual(group))
+ {
+ u32 status_readout = mali_pp_read_status(group->pp_core);
+ if (status_readout & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)
+ {
+ MALI_DEBUG_PRINT(6, ("Mali PP: Not all cores in broadcast completed\n"));
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+ }
+
+ if (mali_group_is_in_virtual(group))
+ {
+ /* We're member of a virtual group, so interrupt should be handled by the virtual group */
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+ err = _MALI_OSK_ERR_FAULT;
+ goto out;
+ }
+
+ group->core_timed_out = MALI_FALSE;
+ mali_group_complete_pp(group, MALI_TRUE);
+ /* No need to enable interrupts again, since the core will be reset while completing the job */
+
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+#endif
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+out:
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_pm_domain_unlock_state(group->pm_domain);
+#endif
+
+ return err;
+}
+
+static void mali_group_bottom_half_pp(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_pp_core *core = group->pp_core;
+ u32 irq_readout;
+ u32 irq_errors;
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+
+ mali_group_lock(group);
+
+ if (mali_group_is_in_virtual(group))
+ {
+ /* We're member of a virtual group, so interrupt should be handled by the virtual group */
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ if ( MALI_FALSE == mali_group_power_is_on(group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", mali_pp_get_hw_core_desc(core)));
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ irq_readout = mali_pp_read_rawstat(group->pp_core);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, mali_pp_get_hw_core_desc(group->pp_core)));
+
+ /* Check if job is complete without errors */
+ if (MALI200_REG_VAL_IRQ_END_OF_FRAME == irq_readout)
+ {
+ if (mali_group_is_virtual(group))
+ {
+ u32 status_readout = mali_pp_read_status(group->pp_core);
+
+ if (status_readout & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)
+ {
+ MALI_DEBUG_PRINT(6, ("Mali PP: Not all cores in broadcast completed\n"));
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
+ group->core_timed_out = MALI_FALSE;
+ mali_group_complete_pp(group, MALI_TRUE);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ /*
+ * Now lets look at the possible error cases (IRQ indicating error or timeout)
+ * END_OF_FRAME and HANG interrupts are not considered error.
+ */
+ irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG);
+ if (0 != irq_errors)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Unexpected interrupt 0x%08X from core %s, aborting job\n",
+ irq_readout, mali_pp_get_hw_core_desc(group->pp_core)));
+ group->core_timed_out = MALI_FALSE;
+ mali_group_complete_pp(group, MALI_FALSE);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+ else if (group->core_timed_out) /* SW timeout */
+ {
+ group->core_timed_out = MALI_FALSE;
+ if (!_mali_osk_timer_pending(group->timeout_timer) && NULL != group->pp_running_job)
+ {
+ MALI_PRINT(("Mali PP: Job %d timed out on core %s\n",
+ mali_pp_job_get_id(group->pp_running_job), mali_pp_get_hw_core_desc(core)));
+ mali_group_complete_pp(group, MALI_FALSE);
+ mali_group_unlock(group);
+ }
+ else
+ {
+ mali_group_unlock(group);
+ }
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ /*
+ * We should never get here, re-enable interrupts and continue
+ */
+ if (0 == irq_readout)
+ {
+ MALI_DEBUG_PRINT(3, ("Mali group: No interrupt found on core %s\n",
+ mali_pp_get_hw_core_desc(group->pp_core)));
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali group: Unhandled PP interrupt 0x%08X on %s\n", irq_readout,
+ mali_pp_get_hw_core_desc(group->pp_core)));
+ }
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+}
+
+static void mali_group_post_process_job_pp(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ /* Stop the timeout timer. */
+ _mali_osk_timer_del_async(group->timeout_timer);
+
+ if (NULL != group->pp_running_job)
+ {
+ if (MALI_TRUE == mali_group_is_virtual(group))
+ {
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ /* update performance counters from each physical pp core within this virtual group */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_update_performance_counters(group->pp_core, child->pp_core, group->pp_running_job, mali_pp_core_get_id(child->pp_core));
+ }
+
+#if defined(CONFIG_MALI400_PROFILING)
+ /* send profiling data per physical core */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
+ mali_pp_job_get_perf_counter_value0(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
+ mali_pp_job_get_perf_counter_value1(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
+ mali_pp_job_get_perf_counter_src0(group->pp_running_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job) << 8),
+ 0, 0);
+ }
+ if (0 != group->l2_cache_core_ref_count[0])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+ }
+ if (0 != group->l2_cache_core_ref_count[1])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
+ }
+ }
+
+#endif
+ }
+ else
+ {
+ /* update performance counters for a physical group's pp core */
+ mali_pp_update_performance_counters(group->pp_core, group->pp_core, group->pp_running_job, group->pp_running_sub_job);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
+ mali_pp_job_get_perf_counter_value0(group->pp_running_job, group->pp_running_sub_job),
+ mali_pp_job_get_perf_counter_value1(group->pp_running_job, group->pp_running_sub_job),
+ mali_pp_job_get_perf_counter_src0(group->pp_running_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job) << 8),
+ 0, 0);
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+#endif
+ }
+ }
+}
+
+static void mali_group_timeout(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+
+ group->core_timed_out = MALI_TRUE;
+
+ if (NULL != group->gp_core)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali group: TIMEOUT on %s\n", mali_gp_get_hw_core_desc(group->gp_core)));
+ _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Mali group: TIMEOUT on %s\n", mali_pp_get_hw_core_desc(group->pp_core)));
+ _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
+ }
+}
+
+void mali_group_zap_session(struct mali_group *group, struct mali_session_data *session)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ /* Early out - safe even if mutex is not held */
+ if (group->session != session) return;
+
+ mali_group_lock(group);
+
+ mali_group_remove_session_if_unused(group, session);
+
+ if (group->session == session)
+ {
+ /* The Zap also does the stall and disable_stall */
+ mali_bool zap_success = mali_mmu_zap_tlb(group->mmu);
+ if (MALI_TRUE != zap_success)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n"));
+ mali_group_mmu_page_fault(group);
+ }
+ }
+
+ mali_group_unlock(group);
+}
+
+#if defined(CONFIG_MALI400_PROFILING)
+static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num)
+{
+ u32 source0 = 0;
+ u32 value0 = 0;
+ u32 source1 = 0;
+ u32 value1 = 0;
+ u32 profiling_channel = 0;
+
+ switch(core_num)
+ {
+ case 0: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
+ break;
+ case 1: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS;
+ break;
+ case 2: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS;
+ break;
+ default: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
+ break;
+ }
+
+ if (0 == core_num)
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
+ }
+ if (1 == core_num)
+ {
+ if (1 == mali_l2_cache_get_id(group->l2_cache_core[0]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
+ }
+ else if (1 == mali_l2_cache_get_id(group->l2_cache_core[1]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
+ }
+ }
+ if (2 == core_num)
+ {
+ if (2 == mali_l2_cache_get_id(group->l2_cache_core[0]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
+ }
+ else if (2 == mali_l2_cache_get_id(group->l2_cache_core[1]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
+ }
+ }
+
+ _mali_osk_profiling_add_event(profiling_channel, source1 << 8 | source0, value0, value1, 0, 0);
+}
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+
+mali_bool mali_group_is_enabled(struct mali_group *group)
+{
+ mali_bool enabled = MALI_TRUE;
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ mali_group_lock(group);
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ enabled = MALI_FALSE;
+ }
+ mali_group_unlock(group);
+
+ return enabled;
+}
+
+void mali_group_enable(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT( NULL != mali_group_get_pp_core(group)
+ || NULL != mali_group_get_gp_core(group));
+
+ if (NULL != mali_group_get_pp_core(group))
+ {
+ mali_pp_scheduler_enable_group(group);
+ }
+ else
+ {
+ mali_gp_scheduler_enable_group(group);
+ }
+}
+
+void mali_group_disable(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT( NULL != mali_group_get_pp_core(group)
+ || NULL != mali_group_get_gp_core(group));
+
+ if (NULL != mali_group_get_pp_core(group))
+ {
+ mali_pp_scheduler_disable_group(group);
+ }
+ else
+ {
+ mali_gp_scheduler_disable_group(group);
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_group.h b/drivers/gpu/mali400/r3p2/mali/common/mali_group.h
new file mode 100644
index 0000000..6a6a777
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_group.h
@@ -0,0 +1,283 @@
+/*
+ * 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_l2_cache.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 10
+
+enum mali_group_core_state
+{
+ MALI_GROUP_STATE_IDLE,
+ MALI_GROUP_STATE_WORKING,
+ MALI_GROUP_STATE_OOM,
+ MALI_GROUP_STATE_IN_VIRTUAL,
+ MALI_GROUP_STATE_JOINING_VIRTUAL,
+ MALI_GROUP_STATE_LEAVING_VIRTUAL,
+ MALI_GROUP_STATE_DISABLED,
+};
+
+/* Forward declaration from mali_pm_domain.h */
+struct mali_pm_domain;
+
+/**
+ * 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_mmu_core *mmu;
+ struct mali_session_data *session;
+ int page_dir_ref_count;
+
+ mali_bool power_is_on;
+ enum mali_group_core_state state;
+
+ struct mali_gp_core *gp_core;
+ struct mali_gp_job *gp_running_job;
+
+ struct mali_pp_core *pp_core;
+ struct mali_pp_job *pp_running_job;
+ u32 pp_running_sub_job;
+
+ struct mali_l2_cache_core *l2_cache_core[2];
+ u32 l2_cache_core_ref_count[2];
+
+ struct mali_dlbu_core *dlbu_core;
+ struct mali_bcast_unit *bcast_core;
+
+ _mali_osk_lock_t *lock;
+
+ _mali_osk_list_t pp_scheduler_list;
+
+ /* List used for virtual groups. For a virtual group, the list represents the
+ * head element. */
+ _mali_osk_list_t group_list;
+
+ struct mali_group *pm_domain_list;
+ struct mali_pm_domain *pm_domain;
+
+ /* Parent virtual group (if any) */
+ struct mali_group *parent_group;
+
+ _mali_osk_wq_work_t *bottom_half_work_mmu;
+ _mali_osk_wq_work_t *bottom_half_work_gp;
+ _mali_osk_wq_work_t *bottom_half_work_pp;
+
+ _mali_osk_timer_t *timeout_timer;
+ mali_bool core_timed_out;
+};
+
+/** @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_l2_cache_core *core,
+ struct mali_dlbu_core *dlbu,
+ struct mali_bcast_unit *bcast);
+
+_mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core);
+void mali_group_remove_mmu_core(struct mali_group *group);
+
+_mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core);
+void mali_group_remove_gp_core(struct mali_group *group);
+
+_mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core);
+void mali_group_remove_pp_core(struct mali_group *group);
+
+void mali_group_set_pm_domain(struct mali_group *group, struct mali_pm_domain *domain);
+
+void mali_group_delete(struct mali_group *group);
+
+/** @brief Virtual groups */
+void mali_group_add_group(struct mali_group *parent, struct mali_group *child, mali_bool update_hw);
+void mali_group_remove_group(struct mali_group *parent, struct mali_group *child);
+struct mali_group *mali_group_acquire_group(struct mali_group *parent);
+
+MALI_STATIC_INLINE mali_bool mali_group_is_virtual(struct mali_group *group)
+{
+ return (NULL != group->dlbu_core);
+}
+
+/** @brief Check if a group is considered as part of a virtual group
+ *
+ * @note A group is considered to be "part of" a virtual group also during the transition
+ * in to / out of the virtual group.
+ */
+MALI_STATIC_INLINE mali_bool mali_group_is_in_virtual(struct mali_group *group)
+{
+ return (MALI_GROUP_STATE_IN_VIRTUAL == group->state ||
+ MALI_GROUP_STATE_JOINING_VIRTUAL == group->state ||
+ MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state);
+}
+
+/** @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 Zap MMU TLB on all groups
+ *
+ * Zap TLB on group if \a session is active.
+ */
+void mali_group_zap_session(struct mali_group* group, struct mali_session_data *session);
+
+/** @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
+ */
+void mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
+/** @brief Start fragment of PP job
+ */
+void 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
+ */
+struct mali_gp_job *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);
+
+mali_bool mali_group_power_is_on(struct mali_group *group);
+void mali_group_power_on_group(struct mali_group *group);
+void mali_group_power_off_group(struct mali_group *group);
+void mali_group_power_on(void);
+void mali_group_power_off(void);
+
+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);
+
+/* MMU-related functions */
+_mali_osk_errcode_t mali_group_upper_half_mmu(void * data);
+
+/* GP-related functions */
+_mali_osk_errcode_t mali_group_upper_half_gp(void *data);
+
+/* PP-related functions */
+_mali_osk_errcode_t mali_group_upper_half_pp(void *data);
+
+/** @brief Check if group is enabled
+ *
+ * @param group group to check
+ * @return MALI_TRUE if enabled, MALI_FALSE if not
+ */
+mali_bool mali_group_is_enabled(struct mali_group *group);
+
+/** @brief Enable group
+ *
+ * An enabled job is put on the idle scheduler list and can be used to handle jobs. Does nothing if
+ * group is already enabled.
+ *
+ * @param group group to enable
+ */
+void mali_group_enable(struct mali_group *group);
+
+/** @brief Disable group
+ *
+ * A disabled group will no longer be used by the scheduler. If part of a virtual group, the group
+ * will be removed before being disabled. Cores part of a disabled group is safe to power down.
+ *
+ * @param group group to disable
+ */
+void mali_group_disable(struct mali_group *group);
+
+MALI_STATIC_INLINE mali_bool mali_group_virtual_disable_if_empty(struct mali_group *group)
+{
+ mali_bool empty = MALI_FALSE;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
+
+ if (_mali_osk_list_empty(&group->group_list))
+ {
+ group->state = MALI_GROUP_STATE_DISABLED;
+ group->session = NULL;
+
+ empty = MALI_TRUE;
+ }
+
+ return empty;
+}
+
+MALI_STATIC_INLINE mali_bool mali_group_virtual_enable_if_empty(struct mali_group *group)
+{
+ mali_bool empty = MALI_FALSE;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
+
+ if (_mali_osk_list_empty(&group->group_list))
+ {
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ empty = MALI_TRUE;
+ }
+
+ return empty;
+}
+
+#endif /* __MALI_GROUP_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.c b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c
index 0b08622..c3a9c8b 100644
--- a/drivers/media/video/samsung/mali/common/mali_hw_core.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c
@@ -17,6 +17,7 @@ _mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_o
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);
diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.h b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h
index c797804..e687f60 100644
--- a/drivers/media/video/samsung/mali/common/mali_hw_core.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h
@@ -26,8 +26,8 @@ struct mali_hw_core
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)
+#define MALI_REG_POLL_COUNT_FAST 1000
+#define MALI_REG_POLL_COUNT_SLOW 1000000
_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);
@@ -48,6 +48,20 @@ MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core
_mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
}
+/* Conditionally write a register.
+ * The register will only be written if the new value is different from the old_value.
+ * If the new value is different, the old value will also be updated */
+MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 new_val, const u32 old_val)
+{
+ MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n",
+ core->description, relative_address, new_val));
+ if(old_val != new_val)
+ {
+ _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
+ }
+}
+
+
MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val)
{
MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n",
@@ -68,4 +82,23 @@ MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw
}
}
+/* Conditionally write a set of registers.
+ * The register will only be written if the new value is different from the old_value.
+ * If the new value is different, the old value will also be updated */
+MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs, const u32* old_array)
+{
+ u32 i;
+ MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n",
+ core->description,relative_address, nr_of_regs));
+
+ /* Do not use burst writes against the registers */
+ for (i = 0; i< nr_of_regs; i++)
+ {
+ if(old_array[i] != write_array[i])
+ {
+ mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
+ }
+ }
+}
+
#endif /* __MALI_HW_CORE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_common.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h
index b354f92..3376a07 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_common.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h
@@ -11,6 +11,8 @@
#ifndef __MALI_KERNEL_COMMON_H__
#define __MALI_KERNEL_COMMON_H__
+#include "mali_osk.h"
+
/* Make sure debug is defined when it should be */
#ifndef DEBUG
#if defined(_DEBUG)
@@ -18,6 +20,7 @@
#endif
#endif
+/* MALI_SEC */
/* Macro for generating a kernel panic.
* Turned on off by compile-time Makefile settings
*/
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c
new file mode 100644
index 0000000..5680374
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c
@@ -0,0 +1,1293 @@
+/*
+ * 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_session.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+#include "mali_kernel_core.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_broadcast.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_pmu.h"
+#include "mali_scheduler.h"
+#include "mali_kernel_utilization.h"
+#include "mali_l2_cache.h"
+#include "mali_pm_domain.h"
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+#include "mali_profiling_internal.h"
+#endif
+
+
+/* Mali GPU memory. Real values come from module parameter or from device specific data */
+unsigned int mali_dedicated_mem_start = 0;
+unsigned int mali_dedicated_mem_size = 0;
+unsigned int mali_shared_mem_size = 0;
+
+/* Frame buffer memory to be accessible by Mali GPU */
+int mali_fb_start = 0;
+int mali_fb_size = 0;
+
+/** Start profiling from module load? */
+int mali_boot_profiling = 0;
+
+/** Limits for the number of PP cores behind each L2 cache. */
+int mali_max_pp_cores_group_1 = 0xFF;
+int mali_max_pp_cores_group_2 = 0xFF;
+
+int mali_inited_pp_cores_group_1 = 0;
+int mali_inited_pp_cores_group_2 = 0;
+
+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;
+
+#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
+
+/* timer related */
+int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
+
+static _mali_osk_errcode_t mali_set_global_gpu_base_address(void)
+{
+ global_gpu_base_address = _mali_osk_resource_base_address();
+ if (0 == global_gpu_base_address)
+ {
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static u32 mali_get_bcast_id(_mali_osk_resource_t *resource_pp)
+{
+ switch (resource_pp->base - global_gpu_base_address)
+ {
+ case 0x08000:
+ case 0x20000: /* fall-through for aliased mapping */
+ return 0x01;
+ case 0x0A000:
+ case 0x22000: /* fall-through for aliased mapping */
+ return 0x02;
+ case 0x0C000:
+ case 0x24000: /* fall-through for aliased mapping */
+ return 0x04;
+ case 0x0E000:
+ case 0x26000: /* fall-through for aliased mapping */
+ return 0x08;
+ case 0x28000:
+ return 0x10;
+ case 0x2A000:
+ return 0x20;
+ case 0x2C000:
+ return 0x40;
+ case 0x2E000:
+ return 0x80;
+ default:
+ return 0;
+ }
+}
+
+static _mali_osk_errcode_t mali_parse_product_info(void)
+{
+ /*
+ * Mali-200 has the PP core first, while Mali-300, Mali-400 and Mali-450 have the GP core first.
+ * Look at the version register for the first PP core in order to determine the GPU HW revision.
+ */
+
+ u32 first_pp_offset;
+ _mali_osk_resource_t first_pp_resource;
+
+ /* Find out where the first PP core is located */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x8000, NULL))
+ {
+ /* Mali-300/400/450 */
+ first_pp_offset = 0x8000;
+ }
+ else
+ {
+ /* Mali-200 */
+ first_pp_offset = 0x0000;
+ }
+
+ /* Find the first PP core resource (again) */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + first_pp_offset, &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, NULL);
+ if (NULL != group)
+ {
+ struct mali_pp_core *pp_core = mali_pp_create(&first_pp_resource, group, MALI_FALSE, mali_get_bcast_id(&first_pp_resource));
+ if (NULL != pp_core)
+ {
+ u32 pp_version = mali_pp_core_get_version(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));
+ MALI_PRINT_ERROR(("Mali-200 is not supported by this driver.\n"));
+ _mali_osk_abort();
+ 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 (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"));
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+
+void mali_resource_count(u32 *pp_count, u32 *l2_count)
+{
+ *pp_count = 0;
+ *l2_count = 0;
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x08000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0A000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0C000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0E000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x28000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2A000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2C000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2E000, NULL))
+ {
+ ++(*pp_count);
+ }
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x1000, NULL))
+ {
+ ++(*l2_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x10000, NULL))
+ {
+ ++(*l2_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x11000, NULL))
+ {
+ ++(*l2_count);
+ }
+}
+
+static void mali_delete_groups(void)
+{
+ while (0 < mali_group_get_glob_num_groups())
+ {
+ mali_group_delete(mali_group_get_glob_group(0));
+ }
+}
+
+static void mali_delete_l2_cache_cores(void)
+{
+ while (0 < mali_l2_cache_core_get_glob_num_l2_cores())
+ {
+ mali_l2_cache_delete(mali_l2_cache_core_get_glob_l2_core(0));
+ }
+}
+
+static struct mali_l2_cache_core *mali_create_l2_cache_core(_mali_osk_resource_t *resource)
+{
+ struct mali_l2_cache_core *l2_cache = NULL;
+
+ if (NULL != resource)
+ {
+
+ MALI_DEBUG_PRINT(3, ("Found L2 cache %s\n", resource->description));
+
+ l2_cache = mali_l2_cache_create(resource);
+ if (NULL == l2_cache)
+ {
+ MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
+ return NULL;
+ }
+ }
+ MALI_DEBUG_PRINT(3, ("Created L2 cache core object\n"));
+
+ return l2_cache;
+}
+
+static _mali_osk_errcode_t mali_parse_config_l2_cache(void)
+{
+ struct mali_l2_cache_core *l2_cache = NULL;
+
+ if (mali_is_mali400())
+ {
+ _mali_osk_resource_t l2_resource;
+ if (_MALI_OSK_ERR_OK != _mali_osk_resource_find(global_gpu_base_address + 0x1000, &l2_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ l2_cache = mali_create_l2_cache_core(&l2_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+ else if (mali_is_mali450())
+ {
+ /*
+ * 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 */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x10000, &l2_gp_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for GP\n"));
+ l2_cache = mali_create_l2_cache_core(&l2_gp_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Make cluster for first PP core group */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x1000, &l2_pp_grp0_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 0\n"));
+ l2_cache = mali_create_l2_cache_core(&l2_pp_grp0_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_pm_domain_add_l2(MALI_PMU_M450_DOM1, l2_cache);
+ }
+ else
+ {
+ 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 */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x11000, &l2_pp_grp1_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 1\n"));
+ l2_cache = mali_create_l2_cache_core(&l2_pp_grp1_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_pm_domain_add_l2(MALI_PMU_M450_DOM3, l2_cache);
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static struct mali_group *mali_create_group(struct mali_l2_cache_core *cache,
+ _mali_osk_resource_t *resource_mmu,
+ _mali_osk_resource_t *resource_gp,
+ _mali_osk_resource_t *resource_pp)
+{
+ struct mali_mmu_core *mmu;
+ struct mali_group *group;
+
+ MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
+
+ /* Create the group object */
+ group = mali_group_create(cache, NULL, NULL);
+ if (NULL == group)
+ {
+ MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
+ return NULL;
+ }
+
+ /* Create the MMU object inside group */
+ mmu = mali_mmu_create(resource_mmu, group, MALI_FALSE);
+ if (NULL == mmu)
+ {
+ MALI_PRINT_ERROR(("Failed to create MMU object\n"));
+ mali_group_delete(group);
+ return NULL;
+ }
+
+ if (NULL != resource_gp)
+ {
+ /* Create the GP core object inside this group */
+ struct mali_gp_core *gp_core = mali_gp_create(resource_gp, group);
+ if (NULL == gp_core)
+ {
+ /* 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"));
+ mali_group_delete(group);
+ return NULL;
+ }
+ }
+
+ if (NULL != resource_pp)
+ {
+ struct mali_pp_core *pp_core;
+
+ /* Create the PP core object inside this group */
+ pp_core = mali_pp_create(resource_pp, group, MALI_FALSE, mali_get_bcast_id(resource_pp));
+ if (NULL == pp_core)
+ {
+ /* 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"));
+ mali_group_delete(group);
+ return NULL;
+ }
+ }
+
+ /* Reset group */
+ mali_group_lock(group);
+ mali_group_reset(group);
+ mali_group_unlock(group);
+
+ return group;
+}
+
+static _mali_osk_errcode_t mali_create_virtual_group(_mali_osk_resource_t *resource_mmu_pp_bcast,
+ _mali_osk_resource_t *resource_pp_bcast,
+ _mali_osk_resource_t *resource_dlbu,
+ _mali_osk_resource_t *resource_bcast)
+{
+ struct mali_mmu_core *mmu_pp_bcast_core;
+ struct mali_pp_core *pp_bcast_core;
+ struct mali_dlbu_core *dlbu_core;
+ struct mali_bcast_unit *bcast_core;
+ struct mali_group *group;
+
+ MALI_DEBUG_PRINT(2, ("Starting new virtual group for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
+
+ /* Create the DLBU core object */
+ dlbu_core = mali_dlbu_create(resource_dlbu);
+ if (NULL == dlbu_core)
+ {
+ MALI_PRINT_ERROR(("Failed to create DLBU object \n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the Broadcast unit core */
+ bcast_core = mali_bcast_unit_create(resource_bcast);
+ if (NULL == bcast_core)
+ {
+ MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
+ mali_dlbu_delete(dlbu_core);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the group object */
+ group = mali_group_create(NULL, dlbu_core, bcast_core);
+ if (NULL == group)
+ {
+ MALI_PRINT_ERROR(("Failed to create group object for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
+ mali_bcast_unit_delete(bcast_core);
+ mali_dlbu_delete(dlbu_core);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the MMU object inside group */
+ mmu_pp_bcast_core = mali_mmu_create(resource_mmu_pp_bcast, group, MALI_TRUE);
+ if (NULL == mmu_pp_bcast_core)
+ {
+ MALI_PRINT_ERROR(("Failed to create MMU PP broadcast object\n"));
+ mali_group_delete(group);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the PP core object inside this group */
+ pp_bcast_core = mali_pp_create(resource_pp_bcast, group, MALI_TRUE, 0);
+ if (NULL == pp_bcast_core)
+ {
+ /* 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"));
+ mali_group_delete(group);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_groups(void)
+{
+ struct mali_group *group;
+ 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[8];
+ _mali_osk_resource_t resource_pp_mmu[8];
+ _mali_osk_resource_t resource_pp_mmu_bcast;
+ _mali_osk_resource_t resource_pp_bcast;
+ _mali_osk_resource_t resource_dlbu;
+ _mali_osk_resource_t resource_bcast;
+ _mali_osk_errcode_t resource_gp_found;
+ _mali_osk_errcode_t resource_gp_mmu_found;
+ _mali_osk_errcode_t resource_pp_found[8];
+ _mali_osk_errcode_t resource_pp_mmu_found[8];
+ _mali_osk_errcode_t resource_pp_mmu_bcast_found;
+ _mali_osk_errcode_t resource_pp_bcast_found;
+ _mali_osk_errcode_t resource_dlbu_found;
+ _mali_osk_errcode_t resource_bcast_found;
+
+ if (!(mali_is_mali400() || mali_is_mali450()))
+ {
+ /* No known HW core */
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ if (mali_is_mali450())
+ {
+ /* Mali-450 have separate L2s for GP, and PP core group(s) */
+ cluster_id_pp_grp0 = 1;
+ cluster_id_pp_grp1 = 2;
+ }
+
+ resource_gp_found = _mali_osk_resource_find(global_gpu_base_address + 0x00000, &resource_gp);
+ resource_gp_mmu_found = _mali_osk_resource_find(global_gpu_base_address + 0x03000, &resource_gp_mmu);
+ resource_pp_found[0] = _mali_osk_resource_find(global_gpu_base_address + 0x08000, &(resource_pp[0]));
+ resource_pp_found[1] = _mali_osk_resource_find(global_gpu_base_address + 0x0A000, &(resource_pp[1]));
+ resource_pp_found[2] = _mali_osk_resource_find(global_gpu_base_address + 0x0C000, &(resource_pp[2]));
+ resource_pp_found[3] = _mali_osk_resource_find(global_gpu_base_address + 0x0E000, &(resource_pp[3]));
+ resource_pp_found[4] = _mali_osk_resource_find(global_gpu_base_address + 0x28000, &(resource_pp[4]));
+ resource_pp_found[5] = _mali_osk_resource_find(global_gpu_base_address + 0x2A000, &(resource_pp[5]));
+ resource_pp_found[6] = _mali_osk_resource_find(global_gpu_base_address + 0x2C000, &(resource_pp[6]));
+ resource_pp_found[7] = _mali_osk_resource_find(global_gpu_base_address + 0x2E000, &(resource_pp[7]));
+ resource_pp_mmu_found[0] = _mali_osk_resource_find(global_gpu_base_address + 0x04000, &(resource_pp_mmu[0]));
+ resource_pp_mmu_found[1] = _mali_osk_resource_find(global_gpu_base_address + 0x05000, &(resource_pp_mmu[1]));
+ resource_pp_mmu_found[2] = _mali_osk_resource_find(global_gpu_base_address + 0x06000, &(resource_pp_mmu[2]));
+ resource_pp_mmu_found[3] = _mali_osk_resource_find(global_gpu_base_address + 0x07000, &(resource_pp_mmu[3]));
+ resource_pp_mmu_found[4] = _mali_osk_resource_find(global_gpu_base_address + 0x1C000, &(resource_pp_mmu[4]));
+ resource_pp_mmu_found[5] = _mali_osk_resource_find(global_gpu_base_address + 0x1D000, &(resource_pp_mmu[5]));
+ resource_pp_mmu_found[6] = _mali_osk_resource_find(global_gpu_base_address + 0x1E000, &(resource_pp_mmu[6]));
+ resource_pp_mmu_found[7] = _mali_osk_resource_find(global_gpu_base_address + 0x1F000, &(resource_pp_mmu[7]));
+
+
+ if (mali_is_mali450())
+ {
+ resource_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x13000, &resource_bcast);
+ resource_dlbu_found = _mali_osk_resource_find(global_gpu_base_address + 0x14000, &resource_dlbu);
+ resource_pp_mmu_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x15000, &resource_pp_mmu_bcast);
+ resource_pp_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x16000, &resource_pp_bcast);
+
+ if (_MALI_OSK_ERR_OK != resource_bcast_found ||
+ _MALI_OSK_ERR_OK != resource_dlbu_found ||
+ _MALI_OSK_ERR_OK != resource_pp_mmu_bcast_found ||
+ _MALI_OSK_ERR_OK != resource_pp_bcast_found)
+ {
+ /* Missing mandatory core(s) for Mali-450 */
+ MALI_DEBUG_PRINT(2, ("Missing mandatory resources, Mali-450 needs DLBU, Broadcast unit, virtual PP core and virtual MMU\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ if (_MALI_OSK_ERR_OK != resource_gp_found ||
+ _MALI_OSK_ERR_OK != resource_gp_mmu_found ||
+ _MALI_OSK_ERR_OK != resource_pp_found[0] ||
+ _MALI_OSK_ERR_OK != resource_pp_mmu_found[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\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ MALI_DEBUG_ASSERT(1 <= mali_l2_cache_core_get_glob_num_l2_cores());
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_gp), &resource_gp_mmu, &resource_gp, NULL);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create group for first (and mandatory) PP core */
+ MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[0], NULL, &resource_pp[0]);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ if (mali_is_mali450())
+ {
+ mali_pm_domain_add_group(MALI_PMU_M450_DOM1, group);
+ }
+ else
+ {
+ mali_pm_domain_add_group(MALI_PMU_M400_PP0, group);
+ }
+ mali_inited_pp_cores_group_1++;
+
+ /* 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 (mali_inited_pp_cores_group_1 < mali_max_pp_cores_group_1)
+ {
+ if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i])
+ {
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[i], NULL, &resource_pp[i]);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ if (mali_is_mali450())
+ {
+ mali_pm_domain_add_group(MALI_PMU_M450_DOM2, group);
+ }
+ else
+ {
+ mali_pm_domain_add_group(MALI_PMU_M400_PP0 + i, group);
+ }
+ mali_inited_pp_cores_group_1++;
+ }
+ }
+ }
+
+ /* Create groups for cores in the second PP core group */
+ for (i = 4; i < 8; i++) /* Second half of the PP cores belong to second core group */
+ {
+ if (mali_inited_pp_cores_group_2 < mali_max_pp_cores_group_2)
+ {
+ if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i])
+ {
+ MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= 2); /* Only Mali-450 have a second core group */
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp1), &resource_pp_mmu[i], NULL, &resource_pp[i]);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_pm_domain_add_group(MALI_PMU_M450_DOM3, group);
+ mali_inited_pp_cores_group_2++;
+ }
+ }
+ }
+
+ if(mali_is_mali450())
+ {
+ _mali_osk_errcode_t err = mali_create_virtual_group(&resource_pp_mmu_bcast, &resource_pp_bcast, &resource_dlbu, &resource_bcast);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return err;
+ }
+ }
+
+ mali_max_pp_cores_group_1 = mali_inited_pp_cores_group_1;
+ mali_max_pp_cores_group_2 = mali_inited_pp_cores_group_2;
+ MALI_DEBUG_PRINT(2, ("%d+%d PP cores initialized\n", mali_inited_pp_cores_group_1, mali_inited_pp_cores_group_2));
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_check_shared_interrupts(void)
+{
+#if !defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_TRUE == _mali_osk_shared_interrupts())
+ {
+ MALI_PRINT_ERROR(("Shared interrupts detected, but driver support is not enabled\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif /* !defined(CONFIG_MALI_SHARED_INTERRUPTS) */
+
+ /* It is OK to compile support for shared interrupts even if Mali is not using it. */
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_create_pm_domains(void)
+{
+ struct mali_pm_domain *domain;
+ u32 number_of_pp_cores = 0;
+ u32 number_of_l2_caches = 0;
+
+ mali_resource_count(&number_of_pp_cores, &number_of_l2_caches);
+
+ if (mali_is_mali450())
+ {
+ MALI_DEBUG_PRINT(2, ("Creating PM domains for Mali-450 MP%d\n", number_of_pp_cores));
+ switch (number_of_pp_cores)
+ {
+ case 8: /* Fall through */
+ case 6: /* Fall through */
+ domain = mali_pm_domain_create(MALI_PMU_M450_DOM3, MALI_PMU_M450_DOM3_MASK);
+ MALI_CHECK(NULL != domain, _MALI_OSK_ERR_NOMEM);
+ case 4: /* Fall through */
+ case 3: /* Fall through */
+ case 2: /* Fall through */
+ domain = mali_pm_domain_create(MALI_PMU_M450_DOM2, MALI_PMU_M450_DOM2_MASK);
+ MALI_CHECK(NULL != domain, _MALI_OSK_ERR_NOMEM);
+ domain = mali_pm_domain_create(MALI_PMU_M450_DOM1, MALI_PMU_M450_DOM1_MASK);
+ MALI_CHECK(NULL != domain, _MALI_OSK_ERR_NOMEM);
+
+ break;
+ default:
+ MALI_PRINT_ERROR(("Unsupported core configuration\n"));
+ MALI_DEBUG_ASSERT(0);
+ }
+ }
+ else
+ {
+ int i;
+ u32 mask = MALI_PMU_M400_PP0_MASK;
+
+ MALI_DEBUG_PRINT(2, ("Creating PM domains for Mali-400 MP%d\n", number_of_pp_cores));
+
+ MALI_DEBUG_ASSERT(mali_is_mali400());
+
+ for (i = 0; i < number_of_pp_cores; i++)
+ {
+ MALI_CHECK(NULL != mali_pm_domain_create(i, mask), _MALI_OSK_ERR_NOMEM);
+
+ /* Shift mask up, for next core */
+ mask = mask << 1;
+ }
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_pmu(void)
+{
+ _mali_osk_resource_t resource_pmu;
+
+ MALI_DEBUG_ASSERT(0 != global_gpu_base_address);
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x02000, &resource_pmu))
+ {
+ struct mali_pmu_core *pmu;
+ u32 number_of_pp_cores = 0;
+ u32 number_of_l2_caches = 0;
+
+ mali_resource_count(&number_of_pp_cores, &number_of_l2_caches);
+
+ pmu = mali_pmu_create(&resource_pmu, number_of_pp_cores, number_of_l2_caches);
+ if (NULL == pmu)
+ {
+ MALI_PRINT_ERROR(("Failed to create PMU\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ /* It's ok if the PMU doesn't exist */
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_memory(void)
+{
+ _mali_osk_errcode_t ret;
+
+ if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size && 0 == mali_shared_mem_size)
+ {
+ /* Memory settings are not overridden by module parameters, so use device settings */
+ struct _mali_osk_device_data data = { 0, };
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
+ {
+ /* Use device specific settings (if defined) */
+ mali_dedicated_mem_start = data.dedicated_mem_start;
+ mali_dedicated_mem_size = data.dedicated_mem_size;
+ mali_shared_mem_size = data.shared_mem_size;
+ }
+
+ if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size && 0 == mali_shared_mem_size)
+ {
+ /* No GPU memory specified */
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ MALI_DEBUG_PRINT(2, ("Using device defined memory settings (dedicated: 0x%08X@0x%08X, shared: 0x%08X)\n",
+ mali_dedicated_mem_size, mali_dedicated_mem_start, mali_shared_mem_size));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Using module defined memory settings (dedicated: 0x%08X@0x%08X, shared: 0x%08X)\n",
+ mali_dedicated_mem_size, mali_dedicated_mem_start, mali_shared_mem_size));
+ }
+
+ if (0 < mali_dedicated_mem_size && 0 != mali_dedicated_mem_start)
+ {
+ /* Dedicated memory */
+ ret = mali_memory_core_resource_dedicated_memory(mali_dedicated_mem_start, mali_dedicated_mem_size);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register dedicated memory\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ }
+
+ if (0 < mali_shared_mem_size)
+ {
+ /* Shared OS memory */
+ ret = mali_memory_core_resource_os_memory(mali_shared_mem_size);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register shared OS memory\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ }
+
+ if (0 == mali_fb_start && 0 == mali_fb_size)
+ {
+ /* Frame buffer settings are not overridden by module parameters, so use device settings */
+ struct _mali_osk_device_data data = { 0, };
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
+ {
+ /* Use device specific settings (if defined) */
+ mali_fb_start = data.fb_start;
+ mali_fb_size = data.fb_size;
+ }
+
+ MALI_DEBUG_PRINT(2, ("Using device defined frame buffer settings (0x%08X@0x%08X)\n",
+ mali_fb_size, mali_fb_start));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Using module defined frame buffer settings (0x%08X@0x%08X)\n",
+ mali_fb_size, mali_fb_start));
+ }
+
+ if (0 != mali_fb_size)
+ {
+ /* Register frame buffer */
+ ret = mali_mem_validation_add_range(mali_fb_start, mali_fb_size);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register frame buffer memory region\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_initialize_subsystems(void)
+{
+ _mali_osk_errcode_t err;
+ struct mali_pmu_core *pmu;
+
+ err = mali_session_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto session_init_failed;
+
+#if defined(CONFIG_MALI400_PROFILING)
+ err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ /* No biggie if we weren't able to initialize the profiling */
+ MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
+ }
+#endif
+
+ 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;
+
+ err = mali_set_global_gpu_base_address();
+ if (_MALI_OSK_ERR_OK != err) goto set_global_gpu_base_address_failed;
+
+ err = mali_check_shared_interrupts();
+ if (_MALI_OSK_ERR_OK != err) goto check_shared_interrupts_failed;
+
+ err = mali_pp_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed;
+
+ /* Initialize the power management module */
+ err = mali_pm_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pm_init_failed;
+
+ /* Initialize the MALI PMU */
+ err = mali_parse_config_pmu();
+ if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed;
+
+ /* Make sure the power stays on for the rest of this function */
+ err = _mali_osk_pm_dev_ref_add();
+ if (_MALI_OSK_ERR_OK != err) goto pm_always_on_failed;
+
+ /*
+ * If run-time PM is used, then the mali_pm module has now already been
+ * notified that the power now is on (through the resume callback functions).
+ * However, if run-time PM is not used, then there will probably not be any
+ * calls to the resume callback functions, so we need to explicitly tell it
+ * that the power is on.
+ */
+ mali_pm_set_power_is_on();
+
+ /* Reset PMU HW and ensure all Mali power domains are on */
+ pmu = mali_pmu_get_global_pmu_core();
+ if (NULL != pmu)
+ {
+ err = mali_pmu_reset(pmu);
+ if (_MALI_OSK_ERR_OK != err) goto pmu_reset_failed;
+ }
+
+ /* 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 */
+
+ /* Create PM domains only if PMU exists */
+ if (NULL != pmu)
+ {
+ err = mali_create_pm_domains();
+ if (_MALI_OSK_ERR_OK != err) goto pm_domain_failed;
+ }
+
+ /* Initialize MMU module */
+ err = mali_mmu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed;
+
+ if (mali_is_mali450())
+ {
+ err = mali_dlbu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed;
+ }
+
+ /* Start configuring the actual Mali hardware. */
+ err = mali_parse_config_l2_cache();
+ 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;
+
+ /* PP scheduler population can't fail */
+ mali_pp_scheduler_populate();
+
+ /* Initialize the GPU utilization tracking */
+ err = mali_utilization_init();
+ if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed;
+
+ /* Allowing the system to be turned off */
+ _mali_osk_pm_dev_ref_dec();
+
+ MALI_SUCCESS; /* all ok */
+
+ /* Error handling */
+
+utilization_init_failed:
+ mali_pp_scheduler_depopulate();
+ mali_gp_scheduler_terminate();
+gp_scheduler_init_failed:
+ mali_scheduler_terminate();
+scheduler_init_failed:
+config_parsing_failed:
+ mali_delete_groups(); /* Delete any groups not (yet) owned by a scheduler */
+ mali_delete_l2_cache_cores(); /* Delete L2 cache cores even if config parsing failed. */
+dlbu_init_failed:
+ mali_dlbu_terminate();
+mmu_init_failed:
+ mali_pm_domain_terminate();
+pm_domain_failed:
+ /* Nothing to roll back */
+product_info_parsing_failed:
+ /* Nothing to roll back */
+pmu_reset_failed:
+ /* Allowing the system to be turned off */
+ _mali_osk_pm_dev_ref_dec();
+pm_always_on_failed:
+ pmu = mali_pmu_get_global_pmu_core();
+ if (NULL != pmu)
+ {
+ mali_pmu_delete(pmu);
+ }
+parse_pmu_config_failed:
+ mali_pm_terminate();
+pm_init_failed:
+ mali_pp_scheduler_terminate();
+pp_scheduler_init_failed:
+check_shared_interrupts_failed:
+ global_gpu_base_address = 0;
+set_global_gpu_base_address_failed:
+ global_gpu_base_address = 0;
+parse_memory_config_failed:
+ mali_memory_terminate();
+memory_init_failed:
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_term();
+#endif
+ mali_session_terminate();
+session_init_failed:
+ return err;
+}
+
+void mali_terminate_subsystems(void)
+{
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
+
+ /* shut down subsystems in reverse order from startup */
+
+ /* We need the GPU to be powered up for the terminate sequence */
+ _mali_osk_pm_dev_ref_add();
+
+ mali_utilization_term();
+ mali_pp_scheduler_depopulate();
+ mali_gp_scheduler_terminate();
+ mali_scheduler_terminate();
+ mali_delete_l2_cache_cores();
+ if (mali_is_mali450())
+ {
+ mali_dlbu_terminate();
+ }
+ mali_mmu_terminate();
+ if (NULL != pmu)
+ {
+ mali_pmu_delete(pmu);
+ }
+ mali_pm_terminate();
+ mali_memory_terminate();
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_term();
+#endif
+
+ /* Allowing the system to be turned off */
+ _mali_osk_pm_dev_ref_dec();
+
+ mali_pp_scheduler_terminate();
+ mali_session_terminate();
+}
+
+_mali_product_id_t mali_kernel_core_get_product_id(void)
+{
+ return global_product_id;
+}
+
+u32 mali_kernel_core_get_gpu_major_version(void)
+{
+ return global_gpu_major_version;
+}
+
+u32 mali_kernel_core_get_gpu_minor_version(void)
+{
+ return global_gpu_minor_version;
+}
+
+_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);
+
+ /* check compatability */
+ if ( args->version == _MALI_UK_API_VERSION )
+ {
+ args->compatible = 1;
+ }
+ else
+ {
+ args->compatible = 0;
+ }
+
+ args->version = _MALI_UK_API_VERSION; /* report our version */
+
+ /* success regardless of being compatible or not */
+ MALI_SUCCESS;
+}
+
+_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;
+
+ /* check input */
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ 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;
+ MALI_SUCCESS;
+ }
+
+ /* 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 */
+ }
+
+ /* 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);
+
+ /* finished with the notification */
+ _mali_osk_notification_delete( notification );
+
+ 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;
+
+ /* check input */
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ 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"));
+ MALI_SUCCESS;
+ }
+
+ notification = _mali_osk_notification_create(args->type, 0);
+ if (NULL == notification)
+ {
+ 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 */
+}
+
+_mali_osk_errcode_t _mali_ukk_open(void **context)
+{
+ struct mali_session_data *session;
+
+ /* allocated struct to track this session */
+ session = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
+ MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_NOMEM);
+
+ MALI_DEBUG_PRINT(3, ("Session starting\n"));
+
+ /* create a response queue for this session */
+ session->ioctl_queue = _mali_osk_notification_queue_init();
+ if (NULL == session->ioctl_queue)
+ {
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ session->page_directory = mali_mmu_pagedir_alloc();
+ if (NULL == session->page_directory)
+ {
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE))
+ {
+ MALI_PRINT_ERROR(("Failed to map DLBU page into session\n"));
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ if (0 != mali_dlbu_phys_addr)
+ {
+ mali_mmu_pagedir_update(session->page_directory, MALI_DLBU_VIRT_ADDR, mali_dlbu_phys_addr,
+ _MALI_OSK_MALI_PAGE_SIZE, MALI_CACHE_STANDARD);
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session))
+ {
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+#ifdef CONFIG_SYNC
+ _mali_osk_list_init(&session->pending_jobs);
+ session->pending_jobs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK,
+ 0, _MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS);
+ if (NULL == session->pending_jobs_lock)
+ {
+ MALI_PRINT_ERROR(("Failed to create pending jobs lock\n"));
+ mali_memory_session_end(session);
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+#endif
+
+ *context = (void*)session;
+
+ /* Add session to the list of all sessions. */
+ mali_session_add(session);
+
+ /* Initialize list of jobs on this session */
+ _MALI_OSK_INIT_LIST_HEAD(&session->job_list);
+
+ MALI_DEBUG_PRINT(2, ("Session started\n"));
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_close(void **context)
+{
+ struct mali_session_data *session;
+ MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
+ session = (struct mali_session_data *)*context;
+
+ MALI_DEBUG_PRINT(3, ("Session ending\n"));
+
+ /* Remove session from list of all sessions. */
+ mali_session_remove(session);
+
+ /* Abort pending jobs */
+#ifdef CONFIG_SYNC
+ {
+ _mali_osk_list_t tmp_job_list;
+ struct mali_pp_job *job, *tmp;
+ _MALI_OSK_INIT_LIST_HEAD(&tmp_job_list);
+
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ /* Abort asynchronous wait on fence. */
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &session->pending_jobs, struct mali_pp_job, list)
+ {
+ MALI_DEBUG_PRINT(2, ("Sync: Aborting wait for session %x job %x\n", session, job));
+ if (sync_fence_cancel_async(job->pre_fence, &job->sync_waiter))
+ {
+ MALI_DEBUG_PRINT(2, ("Sync: Failed to abort job %x\n", job));
+ }
+ _mali_osk_list_add(&job->list, &tmp_job_list);
+ }
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_wq_flush();
+
+ _mali_osk_lock_term(session->pending_jobs_lock);
+
+ /* Delete jobs */
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &tmp_job_list, struct mali_pp_job, list)
+ {
+ mali_pp_job_delete(job);
+ }
+ }
+#endif
+
+ /* Abort queued and running jobs */
+ mali_gp_scheduler_abort_session(session);
+ mali_pp_scheduler_abort_session(session);
+
+ /* 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_wq_flush();
+
+ /* Free remaining memory allocated to this session */
+ mali_memory_session_end(session);
+
+ /* Free session data structures */
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+
+ *context = NULL;
+
+ MALI_DEBUG_PRINT(2, ("Session has ended\n"));
+
+ MALI_SUCCESS;
+}
+
+#if MALI_STATE_TRACKING
+u32 _mali_kernel_core_dump_state(char* buf, u32 size)
+{
+ 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/drivers/media/video/samsung/mali/common/mali_kernel_core.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h
index d424c48..bf56b5c 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_core.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h
@@ -13,7 +13,6 @@
#include "mali_osk.h"
-extern int mali_hang_check_interval;
extern int mali_max_job_runtime;
typedef enum
@@ -29,11 +28,24 @@ _mali_osk_errcode_t mali_initialize_subsystems(void);
void mali_terminate_subsystems(void);
-void mali_kernel_core_wakeup(void);
-
_mali_product_id_t mali_kernel_core_get_product_id(void);
+u32 mali_kernel_core_get_gpu_major_version(void);
+
+u32 mali_kernel_core_get_gpu_minor_version(void);
+
u32 _mali_kernel_core_dump_state(char* buf, u32 size);
+MALI_STATIC_INLINE mali_bool mali_is_mali450(void)
+{
+ return _MALI_PRODUCT_ID_MALI450 == mali_kernel_core_get_product_id();
+}
+
+MALI_STATIC_INLINE mali_bool mali_is_mali400(void)
+{
+ u32 id = mali_kernel_core_get_product_id();
+ return _MALI_PRODUCT_ID_MALI400 == id || _MALI_PRODUCT_ID_MALI300 == id;
+}
+
#endif /* __MALI_KERNEL_CORE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c
index b9f05ca..b9f05ca 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h
index 82ed94d..82ed94d 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c
index 8ff3d37..0ab3a80 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c
@@ -9,7 +9,6 @@
*/
#include "mali_kernel_common.h"
-#include "mali_kernel_core.h"
#include "mali_kernel_memory_engine.h"
#include "mali_osk.h"
@@ -127,11 +126,12 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m
allocation = _mali_osk_malloc(sizeof(os_allocation));
if (NULL != allocation)
{
- u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE;
+ /* MALI_SEC */
+ //u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE;
allocation->offset_start = *offset;
allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER;
MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*)));
-
+ /* MALI_SEC */
while (left > 0)
{
err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE);
@@ -243,15 +243,12 @@ static void os_allocator_release(void * ctx, void * handle)
static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
{
-#if defined(CONFIG_MACH_KONA)
+/* MALI_SEC 6->10 */
#ifndef CONFIG_FORCE_MAX_ZONEORDER
int allocation_order = 10;
#else
int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1;
#endif
-#else
- int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */
-#endif
void *virt = NULL;
u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
os_allocator * info;
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.h
index 59e6494..0946169 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.h
+++ b/drivers/gpu/mali400/r3p2/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/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c
index d770e3e..00257ec 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c
@@ -9,7 +9,6 @@
*/
#include "mali_kernel_common.h"
-#include "mali_kernel_core.h"
#include "mali_kernel_memory_engine.h"
#include "mali_osk.h"
#include "mali_osk_list.h"
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h
index 3b41cee..3b41cee 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c
new file mode 100644
index 0000000..9dae2e8
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c
@@ -0,0 +1,420 @@
+/*
+ * 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_utilization.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_kernel_common.h"
+
+/* Define how often to calculate and report GPU utilization, in milliseconds */
+static _mali_osk_lock_t *time_data_lock;
+
+static u32 num_running_gp_cores;
+static u32 num_running_pp_cores;
+
+static u64 work_start_time_gpu = 0;
+static u64 work_start_time_gp = 0;
+static u64 work_start_time_pp = 0;
+static u64 accumulated_work_time_gpu = 0;
+static u64 accumulated_work_time_gp = 0;
+static u64 accumulated_work_time_pp = 0;
+
+static u64 period_start_time = 0;
+
+#ifndef CONFIG_PM_DEVFREQ /* MALI_SEC */
+static _mali_osk_timer_t *utilization_timer = NULL;
+#endif
+static mali_bool timer_running = MALI_FALSE;
+
+static u32 last_utilization_gpu = 0 ;
+static u32 last_utilization_gp = 0 ;
+static u32 last_utilization_pp = 0 ;
+
+#ifndef CONFIG_PM_DEVFREQ /* MALI_SEC */
+static u32 mali_utilization_timeout = 100;
+#endif
+void (*mali_utilization_callback)(struct mali_gpu_utilization_data *data) = NULL;
+
+#ifndef CONFIG_PM_DEVFREQ
+static void calculate_gpu_utilization(void* arg)
+{
+#else
+void calculate_gpu_utilization(void *arg)
+{
+#endif
+ u64 time_now;
+ u64 time_period;
+ u32 leading_zeroes;
+ u32 shift_val;
+ u32 work_normalized_gpu;
+ u32 work_normalized_gp;
+ u32 work_normalized_pp;
+ u32 period_normalized;
+ u32 utilization_gpu;
+ u32 utilization_gp;
+ u32 utilization_pp;
+
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (accumulated_work_time_gpu == 0 && work_start_time_gpu == 0)
+ {
+ /*
+ * No work done for this period
+ * - No need to reschedule timer
+ * - Report zero usage
+ */
+ timer_running = MALI_FALSE;
+
+ last_utilization_gpu = 0;
+ last_utilization_gp = 0;
+ last_utilization_pp = 0;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (NULL != mali_utilization_callback)
+ {
+ struct mali_gpu_utilization_data data = { 0, };
+ mali_utilization_callback(&data);
+ }
+
+ return;
+ }
+
+ time_now = _mali_osk_time_get_ns();
+
+ time_period = time_now - period_start_time;
+
+ /* If we are currently busy, update working period up to now */
+ if (work_start_time_gpu != 0)
+ {
+ accumulated_work_time_gpu += (time_now - work_start_time_gpu);
+ work_start_time_gpu = time_now;
+
+ /* GP and/or PP will also be busy if the GPU is busy at this point */
+
+ if (work_start_time_gp != 0)
+ {
+ accumulated_work_time_gp += (time_now - work_start_time_gp);
+ work_start_time_gp = time_now;
+ }
+
+ if (work_start_time_pp != 0)
+ {
+ accumulated_work_time_pp += (time_now - work_start_time_pp);
+ work_start_time_pp = time_now;
+ }
+ }
+
+ /*
+ * We have two 64-bit values, a dividend and a divisor.
+ * To avoid dependencies to a 64-bit divider, we shift down the two values
+ * equally first.
+ * We shift the dividend up and possibly the divisor down, making the result X in 256.
+ */
+
+ /* Shift the 64-bit values down so they fit inside a 32-bit integer */
+ leading_zeroes = _mali_osk_clz((u32)(time_period >> 32));
+ shift_val = 32 - leading_zeroes;
+ work_normalized_gpu = (u32)(accumulated_work_time_gpu >> shift_val);
+ work_normalized_gp = (u32)(accumulated_work_time_gp >> shift_val);
+ work_normalized_pp = (u32)(accumulated_work_time_pp >> shift_val);
+ period_normalized = (u32)(time_period >> shift_val);
+
+ /*
+ * Now, we should report the usage in parts of 256
+ * this means we must shift up the dividend or down the divisor by 8
+ * (we could do a combination, but we just use one for simplicity,
+ * but the end result should be good enough anyway)
+ */
+ if (period_normalized > 0x00FFFFFF)
+ {
+ /* The divisor is so big that it is safe to shift it down */
+ period_normalized >>= 8;
+ }
+ else
+ {
+ /*
+ * The divisor is so small that we can shift up the dividend, without loosing any data.
+ * (dividend is always smaller than the divisor)
+ */
+ work_normalized_gpu <<= 8;
+ work_normalized_gp <<= 8;
+ work_normalized_pp <<= 8;
+ }
+
+ utilization_gpu = work_normalized_gpu / period_normalized;
+ utilization_gp = work_normalized_gp / period_normalized;
+ utilization_pp = work_normalized_pp / period_normalized;
+
+ last_utilization_gpu = utilization_gpu;
+ last_utilization_gp = utilization_gp;
+ last_utilization_pp = utilization_pp;
+
+ /* starting a new period */
+ accumulated_work_time_gpu = 0;
+ accumulated_work_time_gp = 0;
+ accumulated_work_time_pp = 0;
+ period_start_time = time_now;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+#ifndef CONFIG_PM_DEVFREQ
+ _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
+#endif
+
+ if (NULL != mali_utilization_callback)
+ {
+ struct mali_gpu_utilization_data data = { utilization_gpu, utilization_gp, utilization_pp };
+ mali_utilization_callback(&data);
+ }
+}
+
+_mali_osk_errcode_t mali_utilization_init(void)
+{
+#if USING_GPU_UTILIZATION
+ struct _mali_osk_device_data data;
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
+ {
+ /* Use device specific settings (if defined) */
+#ifndef CONFIG_PM_DEVFREQ
+ if (0 != data.utilization_interval)
+ {
+ mali_utilization_timeout = data.utilization_interval;
+ }
+#endif
+ if (NULL != data.utilization_callback)
+ {
+ mali_utilization_callback = data.utilization_callback;
+ }
+ }
+#endif
+
+ if (NULL != mali_utilization_callback)
+ {
+#ifndef CONFIG_PM_DEVFREQ
+ MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: Utilization handler installed with interval %u\n", mali_utilization_timeout));
+#endif
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: No utilization handler installed\n"));
+ }
+
+ time_data_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |
+ _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_UTILIZATION);
+
+ if (NULL == time_data_lock)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ num_running_gp_cores = 0;
+ num_running_pp_cores = 0;
+
+#ifndef CONFIG_PM_DEVFREQ
+ utilization_timer = _mali_osk_timer_init();
+ if (NULL == utilization_timer)
+ {
+ _mali_osk_lock_term(time_data_lock);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ _mali_osk_timer_setcallback(utilization_timer, calculate_gpu_utilization, NULL);
+#endif
+
+ return _MALI_OSK_ERR_OK;
+}
+
+#ifndef CONFIG_PM_DEVFREQ
+void mali_utilization_suspend(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (timer_running == MALI_TRUE)
+ {
+ timer_running = MALI_FALSE;
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_timer_del(utilization_timer);
+ return;
+ }
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+}
+#endif
+
+void mali_utilization_term(void)
+{
+#ifndef CONFIG_PM_DEVFREQ
+ if (NULL != utilization_timer)
+ {
+ _mali_osk_timer_del(utilization_timer);
+ timer_running = MALI_FALSE;
+ _mali_osk_timer_term(utilization_timer);
+ utilization_timer = NULL;
+ }
+#endif
+
+ _mali_osk_lock_term(time_data_lock);
+}
+
+void mali_utilization_gp_start(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ ++num_running_gp_cores;
+ if (1 == num_running_gp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* First GP core started, consider GP busy from now and onwards */
+ work_start_time_gp = time_now;
+
+ if (0 == num_running_pp_cores)
+ {
+ /*
+ * There are no PP cores running, so this is also the point
+ * at which we consider the GPU to be busy as well.
+ */
+ work_start_time_gpu = time_now;
+ }
+
+ /* Start a new period (and timer) if needed */
+ if (timer_running != MALI_TRUE)
+ {
+ timer_running = MALI_TRUE;
+ period_start_time = time_now;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
+ }
+ else
+ {
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+}
+
+void mali_utilization_pp_start(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ ++num_running_pp_cores;
+ if (1 == num_running_pp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* First PP core started, consider PP busy from now and onwards */
+ work_start_time_pp = time_now;
+
+ if (0 == num_running_gp_cores)
+ {
+ /*
+ * There are no GP cores running, so this is also the point
+ * at which we consider the GPU to be busy as well.
+ */
+ work_start_time_gpu = time_now;
+ }
+
+ /* Start a new period (and timer) if needed */
+ if (timer_running != MALI_TRUE)
+ {
+ timer_running = MALI_TRUE;
+ period_start_time = time_now;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+#ifndef CONFIG_PM_DEVFREQ
+ _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
+#endif
+ }
+ else
+ {
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+}
+
+void mali_utilization_gp_end(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ --num_running_gp_cores;
+ if (0 == num_running_gp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* Last GP core ended, consider GP idle from now and onwards */
+ accumulated_work_time_gp += (time_now - work_start_time_gp);
+ work_start_time_gp = 0;
+
+ if (0 == num_running_pp_cores)
+ {
+ /*
+ * There are no PP cores running, so this is also the point
+ * at which we consider the GPU to be idle as well.
+ */
+ accumulated_work_time_gpu += (time_now - work_start_time_gpu);
+ work_start_time_gpu = 0;
+ }
+ }
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+void mali_utilization_pp_end(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ --num_running_pp_cores;
+ if (0 == num_running_pp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* Last PP core ended, consider PP idle from now and onwards */
+ accumulated_work_time_pp += (time_now - work_start_time_pp);
+ work_start_time_pp = 0;
+
+ if (0 == num_running_gp_cores)
+ {
+ /*
+ * There are no GP cores running, so this is also the point
+ * at which we consider the GPU to be idle as well.
+ */
+ accumulated_work_time_gpu += (time_now - work_start_time_gpu);
+ work_start_time_gpu = 0;
+ }
+ }
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+u32 _mali_ukk_utilization_gp_pp(void)
+{
+ return last_utilization_gpu;
+}
+
+u32 _mali_ukk_utilization_gp(void)
+{
+ return last_utilization_gp;
+}
+
+u32 _mali_ukk_utilization_pp(void)
+{
+ return last_utilization_pp;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h
index 1f60517..6ee5101 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h
@@ -11,8 +11,14 @@
#ifndef __MALI_KERNEL_UTILIZATION_H__
#define __MALI_KERNEL_UTILIZATION_H__
+#include <linux/mali/mali_utgard.h>
#include "mali_osk.h"
+extern void (*mali_utilization_callback)(struct mali_gpu_utilization_data *data);
+
+#ifdef CONFIG_PM_DEVFREQ /* MALI_SEC */
+void calculate_gpu_utilization(void *arg);
+#endif
/**
* Initialize/start the Mali GPU utilization metrics reporting.
*
@@ -26,19 +32,37 @@ _mali_osk_errcode_t mali_utilization_init(void);
void mali_utilization_term(void);
/**
- * Should be called when a job is about to execute a job
+ * Check if Mali utilization is enabled
*/
-void mali_utilization_core_start(u64 time_now);
+MALI_STATIC_INLINE mali_bool mali_utilization_enabled(void)
+{
+ return (NULL != mali_utilization_callback);
+}
/**
- * Should be called to stop the utilization timer during system suspend
+ * Should be called when a job is about to execute a GP job
*/
-void mali_utilization_suspend(void);
+void mali_utilization_gp_start(void);
+
+/**
+ * Should be called when a job has completed executing a GP job
+ */
+void mali_utilization_gp_end(void);
+
+/**
+ * Should be called when a job is about to execute a PP job
+ */
+void mali_utilization_pp_start(void);
/**
- * Should be called when a job has completed executing a job
+ * Should be called when a job has completed executing a PP job
*/
-void mali_utilization_core_end(u64 time_now);
+void mali_utilization_pp_end(void);
+
+/**
+ * Should be called to stop the utilization timer during system suspend
+ */
+void mali_utilization_suspend(void);
#endif /* __MALI_KERNEL_UTILIZATION_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c
index 63c9f5b..a1fdf00 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c
@@ -12,7 +12,7 @@
#include "mali_osk.h"
#include "mali_ukk.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_PROFILING)
#include "mali_osk_profiling.h"
#endif
@@ -21,7 +21,7 @@ _mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *
_mali_uk_vsync_event event = (_mali_uk_vsync_event)args->event;
MALI_IGNORE(event); /* event is not used for release code, and that is OK */
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_PROFILING)
/*
* Manually generate user space events in kernel space.
* This saves user space from calling kernel space twice in this case.
diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.c b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c
index b7267f1..b5cfcb5 100644
--- a/drivers/media/video/samsung/mali/common/mali_l2_cache.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c
@@ -9,18 +9,16 @@
*/
#include "mali_kernel_common.h"
#include "mali_osk.h"
-
#include "mali_l2_cache.h"
#include "mali_hw_core.h"
-#include "mali_pm.h"
+#include "mali_scheduler.h"
+#include "mali_pm_domain.h"
/**
* Size of the Mali L2 cache registers in bytes
*/
#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30
-#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES 3
-
/**
* Mali L2 cache register numbers
* Used in the register read/write routines.
@@ -69,24 +67,9 @@ typedef enum mali_l2_cache_status
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
- */
-struct mali_l2_cache_core
-{
- struct mali_hw_core hw_core; /**< Common for all HW cores */
- u32 core_id; /**< Unique core ID */
- _mali_osk_lock_t *command_lock; /**< Serialize all L2 cache commands */
- _mali_osk_lock_t *counter_lock; /**< Synchronize L2 cache counter access */
- 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 */
-};
-
#define MALI400_L2_MAX_READS_DEFAULT 0x1C
-static struct mali_l2_cache_core *mali_global_l2_cache_cores[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
+static struct mali_l2_cache_core *mali_global_l2_cache_cores[MALI_MAX_NUMBER_OF_L2_CACHE_CORES] = { NULL, };
static u32 mali_global_num_l2_cache_cores = 0;
int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT;
@@ -98,6 +81,13 @@ static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core
struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource)
{
struct mali_l2_cache_core *cache = NULL;
+ _mali_osk_lock_flags_t lock_flags;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#else
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#endif
MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description));
@@ -113,29 +103,23 @@ struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource)
cache->core_id = mali_global_num_l2_cache_cores;
cache->counter_src0 = MALI_HW_CORE_NO_COUNTER;
cache->counter_src1 = MALI_HW_CORE_NO_COUNTER;
+ cache->pm_domain = NULL;
if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE))
{
- cache->command_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE,
- 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND);
+ cache->command_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND);
if (NULL != cache->command_lock)
{
- cache->counter_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE,
- 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER);
+ cache->counter_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER);
if (NULL != cache->counter_lock)
{
- if (_MALI_OSK_ERR_OK == mali_l2_cache_reset(cache))
- {
- mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache;
- mali_global_num_l2_cache_cores++;
-
- return cache;
- }
- else
- {
- MALI_PRINT_ERROR(("Mali L2 cache: Failed to reset L2 cache core %s\n", cache->hw_core.description));
- }
-
- _mali_osk_lock_term(cache->counter_lock);
+ mali_l2_cache_reset(cache);
+
+ cache->last_invalidated_id = 0;
+
+ mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache;
+ mali_global_num_l2_cache_cores++;
+
+ return cache;
}
else
{
@@ -180,6 +164,16 @@ void mali_l2_cache_delete(struct mali_l2_cache_core *cache)
{
mali_global_l2_cache_cores[i] = NULL;
mali_global_num_l2_cache_cores--;
+
+ if (i != mali_global_num_l2_cache_cores)
+ {
+ /* We removed a l2 cache from the middle of the array -- move the last
+ * l2 cache to the current position to close the gap */
+ mali_global_l2_cache_cores[i] = mali_global_l2_cache_cores[mali_global_num_l2_cache_cores];
+ mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = NULL;
+ }
+
+ break;
}
}
@@ -280,7 +274,7 @@ void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32
*value0 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
}
- if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER)
+ if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER)
{
*value1 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
}
@@ -290,7 +284,7 @@ void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32
struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index)
{
- if (MALI_MAX_NUMBER_OF_L2_CACHE_CORES > index)
+ if (mali_global_num_l2_cache_cores > index)
{
return mali_global_l2_cache_cores[index];
}
@@ -303,15 +297,10 @@ u32 mali_l2_cache_core_get_glob_num_l2_cores(void)
return mali_global_num_l2_cache_cores;
}
-u32 mali_l2_cache_core_get_max_num_l2_cores(void)
-{
- return MALI_MAX_NUMBER_OF_L2_CACHE_CORES;
-}
-
-_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache)
+void mali_l2_cache_reset(struct mali_l2_cache_core *cache)
{
/* Invalidate cache (just to keep it in a known state at startup) */
- mali_l2_cache_invalidate_all(cache);
+ mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
/* Enable cache */
mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);
@@ -331,47 +320,107 @@ _mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache)
}
_mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+void mali_l2_cache_reset_all(void)
+{
+ int i;
+ u32 num_cores = mali_l2_cache_core_get_glob_num_l2_cores();
- return _MALI_OSK_ERR_OK;
+ for (i = 0; i < num_cores; i++)
+ {
+ mali_l2_cache_reset(mali_l2_cache_core_get_glob_l2_core(i));
+ }
}
-_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache)
+void mali_l2_cache_invalidate(struct mali_l2_cache_core *cache)
{
- return mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+ MALI_DEBUG_ASSERT_POINTER(cache);
+
+ if (NULL != cache)
+ {
+ cache->last_invalidated_id = mali_scheduler_get_new_id();
+ mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+ }
}
-_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages)
+mali_bool mali_l2_cache_invalidate_conditional(struct mali_l2_cache_core *cache, u32 id)
{
- u32 i;
- _mali_osk_errcode_t ret1, ret = _MALI_OSK_ERR_OK;
+ MALI_DEBUG_ASSERT_POINTER(cache);
- for (i = 0; i < num_pages; i++)
+ if (NULL != cache)
{
- ret1 = mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[i]);
- if (_MALI_OSK_ERR_OK != ret1)
+ /* 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)cache->last_invalidated_id))
+ {
+ return MALI_FALSE;
+ }
+ else
{
- ret = ret1;
+ cache->last_invalidated_id = mali_scheduler_get_new_id();
}
+
+ mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
}
+ return MALI_TRUE;
+}
- return ret;
+void mali_l2_cache_invalidate_all(void)
+{
+ u32 i;
+ for (i = 0; i < mali_global_num_l2_cache_cores; i++)
+ {
+ /*additional check*/
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_l2_cache_cores[i]))
+ {
+ _mali_osk_errcode_t ret;
+ mali_global_l2_cache_cores[i]->last_invalidated_id = mali_scheduler_get_new_id();
+ ret = mali_l2_cache_send_command(mali_global_l2_cache_cores[i], MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to invalidate cache\n"));
+ }
+ }
+ mali_l2_cache_unlock_power_state(mali_global_l2_cache_cores[i]);
+ }
+}
+
+void mali_l2_cache_invalidate_all_pages(u32 *pages, u32 num_pages)
+{
+ u32 i;
+ for (i = 0; i < mali_global_num_l2_cache_cores; i++)
+ {
+ /*additional check*/
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_l2_cache_cores[i]))
+ {
+ u32 j;
+ for (j = 0; j < num_pages; j++)
+ {
+ _mali_osk_errcode_t ret;
+ ret = mali_l2_cache_send_command(mali_global_l2_cache_cores[i], MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[j]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to invalidate page cache\n"));
+ }
+ }
+ }
+ mali_l2_cache_unlock_power_state(mali_global_l2_cache_cores[i]);
+ }
}
mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache)
{
- /*
- * Take PM lock and check power state.
- * Returns MALI_TRUE if module is powered on.
- * Power state will not change until mali_l2_cache_unlock_power_state() is called.
- */
- mali_pm_lock();
- return mali_pm_is_powered_on();
+ return mali_pm_domain_lock_state(cache->pm_domain);
}
void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache)
{
- /* Release PM lock */
- mali_pm_unlock();
+ return mali_pm_domain_unlock_state(cache->pm_domain);
}
/* -------- local helper functions below -------- */
diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.h b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h
index 5a8e4da..cabed39 100644
--- a/drivers/media/video/samsung/mali/common/mali_l2_cache.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h
@@ -12,8 +12,31 @@
#define __MALI_KERNEL_L2_CACHE_H__
#include "mali_osk.h"
+#include "mali_hw_core.h"
+#include "mali_pm_domain.h"
-struct mali_l2_cache_core;
+#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES 3
+/* Maximum 1 GP and 4 PP for an L2 cache core (Mali-400 Quad-core) */
+#define MALI_MAX_NUMBER_OF_GROUPS_PER_L2_CACHE 5
+
+struct mali_group;
+
+/**
+ * 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
+ */
+struct mali_l2_cache_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ u32 core_id; /**< Unique core ID */
+ _mali_osk_lock_t *command_lock; /**< Serialize all L2 cache commands */
+ _mali_osk_lock_t *counter_lock; /**< Synchronize L2 cache counter access */
+ 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 last_invalidated_id;
+ struct mali_pm_domain *pm_domain;
+};
_mali_osk_errcode_t mali_l2_cache_initialize(void);
void mali_l2_cache_terminate(void);
@@ -21,6 +44,11 @@ void mali_l2_cache_terminate(void);
struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t * resource);
void mali_l2_cache_delete(struct mali_l2_cache_core *cache);
+MALI_STATIC_INLINE void mali_l2_cache_set_pm_domain(struct mali_l2_cache_core *cache, struct mali_pm_domain *domain)
+{
+ cache->pm_domain = domain;
+}
+
u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache);
mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter);
@@ -30,12 +58,16 @@ u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache);
void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1);
struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index);
u32 mali_l2_cache_core_get_glob_num_l2_cores(void);
-u32 mali_l2_cache_core_get_max_num_l2_cores(void);
-_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache);
+void mali_l2_cache_reset(struct mali_l2_cache_core *cache);
+void mali_l2_cache_reset_all(void);
+
+struct mali_group *mali_l2_cache_get_group(struct mali_l2_cache_core *cache, u32 index);
-_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache);
-_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages);
+void mali_l2_cache_invalidate(struct mali_l2_cache_core *cache);
+mali_bool mali_l2_cache_invalidate_conditional(struct mali_l2_cache_core *cache, u32 id);
+void mali_l2_cache_invalidate_all(void);
+void mali_l2_cache_invalidate_all_pages(u32 *pages, u32 num_pages);
mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache);
void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache);
diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.c b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c
index ea9c428..aaf9c73 100644
--- a/drivers/media/video/samsung/mali/common/mali_mem_validation.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c
@@ -11,6 +11,13 @@
#include "mali_mem_validation.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
+/* MALI_SEC */
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+//#define MALI_SEC_MEM_VALIDATION
+#include <linux/cma.h>
+#include <plat/pd.h>
+#include <linux/platform_device.h>
+#endif
#define MALI_INVALID_MEM_ADDR 0xFFFFFFFF
@@ -20,29 +27,50 @@ typedef struct
u32 size; /**< size in bytes of the memory, multiple of page size */
} _mali_mem_validation_t;
+/* MALI_SEC */
+#if defined(MALI_SEC_MEM_VALIDATION)
+extern struct platform_device exynos4_device_pd[];
+#endif
+
static _mali_mem_validation_t mali_mem_validator = { MALI_INVALID_MEM_ADDR, MALI_INVALID_MEM_ADDR };
-_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t *resource)
+_mali_osk_errcode_t mali_mem_validation_add_range(u32 start, u32 size)
{
+ /* MALI_SEC */
+#if defined(MALI_SEC_MEM_VALIDATION)
+ struct cma_info mem_info;
+#endif
+
/* Check that no other MEM_VALIDATION resources exist */
if (MALI_INVALID_MEM_ADDR != mali_mem_validator.phys_base)
{
- MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; another range is already specified\n", resource->description));
+ MALI_PRINT_ERROR(("Failed to add frame buffer memory; another range is already specified\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* MALI_SEC */
+#if defined(MALI_SEC_MEM_VALIDATION)
+ if (cma_info(&mem_info, &exynos4_device_pd[PD_G3D].dev, "fimd")) {
+ MALI_PRINT_ERROR(("Failed to get framebuffer information from CMA\n"));
return _MALI_OSK_ERR_FAULT;
+ } else {
+ start = mem_info.lower_bound;
+ size = mem_info.total_size - mem_info.free_size;
}
+#endif
/* Check restrictions on page alignment */
- if ((0 != (resource->base & (~_MALI_OSK_CPU_PAGE_MASK))) ||
- (0 != (resource->size & (~_MALI_OSK_CPU_PAGE_MASK))))
+ if ((0 != (start & (~_MALI_OSK_CPU_PAGE_MASK))) ||
+ (0 != (size & (~_MALI_OSK_CPU_PAGE_MASK))))
{
- MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; incorrect alignment\n", resource->description));
+ MALI_PRINT_ERROR(("Failed to add frame buffer memory; incorrect alignment\n"));
return _MALI_OSK_ERR_FAULT;
}
- mali_mem_validator.phys_base = resource->base;
- mali_mem_validator.size = resource->size;
- MALI_DEBUG_PRINT(2, ("Memory Validator '%s' installed for Mali physical address base=0x%08X, size=0x%08X\n",
- resource->description, mali_mem_validator.phys_base, mali_mem_validator.size));
+ mali_mem_validator.phys_base = start;
+ mali_mem_validator.size = size;
+ MALI_DEBUG_PRINT(2, ("Memory Validator installed for Mali physical address base=0x%08X, size=0x%08X\n",
+ mali_mem_validator.phys_base, mali_mem_validator.size));
return _MALI_OSK_ERR_OK;
}
diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.h b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h
index 2043b44..1eeab38 100644
--- a/drivers/media/video/samsung/mali/common/mali_mem_validation.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h
@@ -13,7 +13,7 @@
#include "mali_osk.h"
-_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t * resource);
+_mali_osk_errcode_t mali_mem_validation_add_range(u32 start, u32 size);
_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size);
#endif /* __MALI_MEM_VALIDATION_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_memory.c b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.c
index 75506ed..1654675 100644
--- a/drivers/media/video/samsung/mali/common/mali_memory.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.c
@@ -18,9 +18,8 @@
#include "mali_kernel_mem_os.h"
#include "mali_session.h"
#include "mali_l2_cache.h"
-#include "mali_cluster.h"
-#include "mali_group.h"
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#include "mali_scheduler.h"
+#if defined(CONFIG_MALI400_UMP)
#include "ump_kernel_interface.h"
#endif
@@ -45,7 +44,7 @@ typedef struct dedicated_memory_info
} 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
+#if defined(CONFIG_MALI400_UMP)
typedef struct ump_mem_allocation
{
mali_allocation_engine * engine;
@@ -82,10 +81,10 @@ typedef struct external_mem_allocation
*/
static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args );
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#if defined(CONFIG_MALI400_UMP)
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*/
+#endif /* CONFIG_MALI400_UMP */
static void external_memory_release(void * ctx, void * handle);
@@ -261,7 +260,7 @@ void mali_memory_session_end(struct mali_session_data *session_data)
err = _MALI_OSK_ERR_OK;
/* Free all memory engine allocations */
- if (0 == _mali_osk_list_empty(&session_data->memory_head))
+ if (!_mali_osk_list_empty(&session_data->memory_head))
{
mali_memory_allocation *descriptor;
mali_memory_allocation *temp;
@@ -332,14 +331,14 @@ void mali_memory_session_end(struct mali_session_data *session_data)
return;
}
-_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource)
+_mali_osk_errcode_t mali_memory_core_resource_os_memory(u32 size)
{
mali_physical_memory_allocator * allocator;
mali_physical_memory_allocator ** next_allocator_list;
- u32 alloc_order = resource->alloc_order;
+ u32 alloc_order = 1; /* OS memory has second priority */
- allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description);
+ allocator = mali_os_allocator_create(size, 0 /* cpu_usage_adjust */, "Shared Mali GPU memory");
if (NULL == allocator)
{
MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n"));
@@ -364,30 +363,30 @@ _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * r
MALI_SUCCESS;
}
-_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource)
+_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size)
{
mali_physical_memory_allocator * allocator;
mali_physical_memory_allocator ** next_allocator_list;
dedicated_memory_info * cleanup_data;
- u32 alloc_order = resource->alloc_order;
+ u32 alloc_order = 0; /* Dedicated range has first priority */
/* do the low level linux operation first */
/* Request ownership of the memory */
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description))
+ if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(start, size, "Dedicated Mali GPU memory"))
{
- 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_DEBUG_PRINT(1, ("Failed to request memory region for frame buffer (0x%08X - 0x%08X)\n", start, start + 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 );
+ allocator = mali_block_allocator_create(start, 0 /* cpu_usage_adjust */, size, "Dedicated Mali GPU memory");
if (NULL == allocator)
{
MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
- _mali_osk_mem_unreqregion(resource->base, resource->size);
+ _mali_osk_mem_unreqregion(start, size);
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
@@ -398,13 +397,13 @@ _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resourc
if (NULL == cleanup_data)
{
- _mali_osk_mem_unreqregion(resource->base, resource->size);
+ _mali_osk_mem_unreqregion(start, size);
allocator->destroy(allocator);
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
- cleanup_data->base = resource->base;
- cleanup_data->size = resource->size;
+ cleanup_data->base = start;
+ cleanup_data->size = size;
cleanup_data->next = mem_region_registrations;
mem_region_registrations = cleanup_data;
@@ -425,7 +424,7 @@ _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resourc
MALI_SUCCESS;
}
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#if defined(CONFIG_MALI400_UMP)
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;
@@ -672,7 +671,7 @@ _mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args
MALI_SUCCESS;
}
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */
+#endif /* CONFIG_MALI400_UMP */
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)
@@ -757,6 +756,20 @@ static void external_memory_release(void * ctx, void * handle)
return;
}
+_mali_osk_errcode_t _mali_ukk_mem_write_safe(_mali_uk_mem_write_safe_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ if (NULL == args->ctx)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ /* Return number of bytes actually copied */
+ args->size = _mali_osk_mem_write_safe(args->dest, args->src, args->size);
+ return _MALI_OSK_ERR_OK;
+}
+
_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args )
{
mali_physical_memory_allocator external_memory_allocator;
@@ -1006,10 +1019,6 @@ static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s
struct mali_session_data *session_data;
mali_memory_allocation * descriptor;
- u32 num_groups = mali_group_get_glob_num_groups();
- struct mali_group *group;
- u32 i;
-
descriptor = (mali_memory_allocation *)args->cookie;
MALI_DEBUG_ASSERT_POINTER(descriptor);
@@ -1025,40 +1034,7 @@ static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s
It is allowed to call this function severeal times, which might happen if zapping below fails. */
mali_allocation_engine_release_pt1_mali_pagetables_unmap(memory_engine, descriptor);
-#ifdef MALI_UNMAP_FLUSH_ALL_MALI_L2
- {
- u32 number_of_clusters = mali_cluster_get_glob_num_clusters();
- for (i = 0; i < number_of_clusters; i++)
- {
- struct mali_cluster *cluster;
- cluster = mali_cluster_get_global_cluster(i);
- if( mali_cluster_power_is_enabled_get(cluster) )
- {
- mali_cluster_l2_cache_invalidate_all_force(cluster);
- }
- }
- }
-#endif
-
- for (i = 0; i < num_groups; i++)
- {
- group = mali_group_get_glob_group(i);
- mali_group_lock(group);
- mali_group_remove_session_if_unused(group, session_data);
- if (mali_group_get_session(group) == session_data)
- {
- /* The Zap also does the stall and disable_stall */
- mali_bool zap_success = mali_mmu_zap_tlb(mali_group_get_mmu(group));
- if (MALI_TRUE != zap_success)
- {
- MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n"));
- mali_group_bottom_half(group, GROUP_EVENT_MMU_PAGE_FAULT);
- /* The bottom half will also do the unlock */
- continue;
- }
- }
- mali_group_unlock(group);
- }
+ mali_scheduler_zap_all_active(session_data);
/* Removes the descriptor from the session's memory list, releases physical memory, releases descriptor */
mali_allocation_engine_release_pt2_physical_memory_free(memory_engine, descriptor);
@@ -1126,7 +1102,7 @@ _mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *ma
{
_mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
- if (0 == _mali_osk_list_empty(&page_table_cache.partial))
+ if (!_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);
@@ -1304,7 +1280,7 @@ static void mali_mmu_page_table_cache_destroy(void)
_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_DEBUG_PRINT_IF(1, !_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)
{
diff --git a/drivers/media/video/samsung/mali/common/mali_memory.h b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.h
index 78e2945..537c346 100644
--- a/drivers/media/video/samsung/mali/common/mali_memory.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.h
@@ -14,9 +14,6 @@
#include "mali_osk.h"
#include "mali_session.h"
-struct mali_cluster;
-struct mali_group;
-
/** @brief Initialize Mali memory subsystem
*
* Allocate and initialize internal data structures. Must be called before
@@ -70,12 +67,19 @@ void mali_mmu_release_table_page(u32 pa);
/** @brief Parse resource and prepare the OS memory allocator
+ *
+ * @param size Maximum size to allocate for Mali GPU.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource);
+_mali_osk_errcode_t mali_memory_core_resource_os_memory(u32 size);
/** @brief Parse resource and prepare the dedicated memory allocator
+ *
+ * @param start Physical start address of dedicated Mali GPU memory.
+ * @param size Size of dedicated Mali GPU memory.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource);
+_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size);
mali_allocation_engine mali_mem_get_memory_engine(void);
diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.c b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c
index 2f2fa4d..158cccf 100644
--- a/drivers/media/video/samsung/mali/common/mali_mmu.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c
@@ -25,36 +25,6 @@
#define MALI_MMU_REGISTERS_SIZE 0x24
/**
- * 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 = 0x0004, /**< Status of the MMU */
- MALI_MMU_REGISTER_COMMAND = 0x0008, /**< Command register, used to control the MMU */
- MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x000C, /**< Logical address of the last page fault */
- MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x010, /**< Used to invalidate the mapping of a single page from the MMU */
- MALI_MMU_REGISTER_INT_RAWSTAT = 0x0014, /**< Raw interrupt status, all interrupts visible */
- MALI_MMU_REGISTER_INT_CLEAR = 0x0018, /**< Indicate to the MMU that the interrupt has been received */
- MALI_MMU_REGISTER_INT_MASK = 0x001C, /**< Enable/disable types of interrupts */
- MALI_MMU_REGISTER_INT_STATUS = 0x0020 /**< 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.
@@ -70,49 +40,6 @@ typedef enum mali_mmu_command
MALI_MMU_COMMAND_HARD_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;
-
-/**
- * Definition of the MMU struct
- * Used to track a MMU unit in the system.
- * Contains information about the mapping of the registers
- */
-struct mali_mmu_core
-{
- struct mali_hw_core hw_core; /**< Common for all HW cores */
- struct mali_group *group; /**< Parent core group */
- _mali_osk_irq_t *irq; /**< IRQ handler */
-};
-
-/**
- * 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_mmu_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_mmu_bottom_half(void *data);
-
static void mali_mmu_probe_trigger(void *data);
static _mali_osk_errcode_t mali_mmu_probe_ack(void *data);
@@ -159,7 +86,7 @@ void mali_mmu_terminate(void)
&mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page);
}
-struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource)
+struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual)
{
struct mali_mmu_core* mmu = NULL;
@@ -172,24 +99,38 @@ struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource)
{
if (_MALI_OSK_ERR_OK == mali_hw_core_create(&mmu->hw_core, resource, MALI_MMU_REGISTERS_SIZE))
{
- if (_MALI_OSK_ERR_OK == mali_mmu_reset(mmu))
+ if (_MALI_OSK_ERR_OK == mali_group_add_mmu_core(group, mmu))
{
- /* Setup IRQ handlers (which will do IRQ probing if needed) */
- mmu->irq = _mali_osk_irq_init(resource->irq,
- mali_mmu_upper_half,
- mali_mmu_bottom_half,
- mali_mmu_probe_trigger,
- mali_mmu_probe_ack,
- mmu,
- "mali_mmu_irq_handlers");
- if (NULL != mmu->irq)
+ if (is_virtual)
{
+ /* Skip reset and IRQ setup for virtual MMU */
return mmu;
}
- else
+
+ if (_MALI_OSK_ERR_OK == mali_mmu_reset(mmu))
{
- MALI_PRINT_ERROR(("Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description));
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ mmu->irq = _mali_osk_irq_init(resource->irq,
+ mali_group_upper_half_mmu,
+ group,
+ mali_mmu_probe_trigger,
+ mali_mmu_probe_ack,
+ mmu,
+ "mali_mmu_irq_handlers");
+ if (NULL != mmu->irq)
+ {
+ return mmu;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali MMU: Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description));
+ }
}
+ mali_group_remove_mmu_core(group);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali MMU: Failed to add core %s to group\n", mmu->hw_core.description));
}
mali_hw_core_delete(&mmu->hw_core);
}
@@ -206,33 +147,29 @@ struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource)
void mali_mmu_delete(struct mali_mmu_core *mmu)
{
- _mali_osk_irq_term(mmu->irq);
+ if (NULL != mmu->irq)
+ {
+ _mali_osk_irq_term(mmu->irq);
+ }
+
mali_hw_core_delete(&mmu->hw_core);
_mali_osk_free(mmu);
}
-void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group)
-{
- mmu->group = group;
-}
-
static void mali_mmu_enable_paging(struct mali_mmu_core *mmu)
{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
int i;
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
- for (i = 0; i < max_loop_count; ++i)
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
{
if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
{
break;
}
- _mali_osk_time_ubusydelay(delay_in_usecs);
}
- if (max_loop_count == i)
+ if (MALI_REG_POLL_COUNT_FAST == i)
{
MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
}
@@ -240,19 +177,12 @@ static void mali_mmu_enable_paging(struct mali_mmu_core *mmu)
mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu)
{
- const int max_loop_count = 100;
- const int delay_in_usecs = 999;
int i;
- u32 mmu_status;
-
- /* There are no group when it is called from mali_mmu_create */
- if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group);
-
- mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+ u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) )
{
- MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enebled.\n"));
+ MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enabled.\n"));
return MALI_TRUE;
}
@@ -264,28 +194,31 @@ mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu)
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
- for (i = 0; i < max_loop_count; ++i)
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
{
mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
- if ( mmu_status & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE))
+ if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)
{
break;
}
- if ( 0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED )))
+ if ((mmu_status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) && (0 == (mmu_status & MALI_MMU_STATUS_BIT_STALL_NOT_ACTIVE)))
+ {
+ break;
+ }
+ if (0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED )))
{
break;
}
- _mali_osk_time_ubusydelay(delay_in_usecs);
}
- if (max_loop_count == i)
+ if (MALI_REG_POLL_COUNT_FAST == i)
{
- MALI_PRINT_ERROR(("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
return MALI_FALSE;
}
if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
{
- MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it has a pagefault.\n"));
+ MALI_DEBUG_PRINT(2, ("Aborting MMU stall request since it has a pagefault.\n"));
return MALI_FALSE;
}
@@ -294,14 +227,8 @@ mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu)
void mali_mmu_disable_stall(struct mali_mmu_core *mmu)
{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
int i;
- u32 mmu_status;
- /* There are no group when it is called from mali_mmu_create */
- if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group);
-
- mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+ u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED ))
{
@@ -316,7 +243,7 @@ void mali_mmu_disable_stall(struct mali_mmu_core *mmu)
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
- for (i = 0; i < max_loop_count; ++i)
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
{
u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) )
@@ -331,38 +258,32 @@ void mali_mmu_disable_stall(struct mali_mmu_core *mmu)
{
break;
}
- _mali_osk_time_ubusydelay(delay_in_usecs);
}
- if (max_loop_count == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+ if (MALI_REG_POLL_COUNT_FAST == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
}
void mali_mmu_page_fault_done(struct mali_mmu_core *mmu)
{
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
MALI_DEBUG_PRINT(4, ("Mali MMU: %s: Leaving page fault mode\n", mmu->hw_core.description));
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE);
}
MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu)
{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
int i;
- /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */
- if (mmu->group)MALI_ASSERT_GROUP_LOCKED(mmu->group);
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
+ MALI_DEBUG_ASSERT(0xCAFEB000 == mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR));
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET);
- for (i = 0; i < max_loop_count; ++i)
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
{
if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0)
{
break;
}
- _mali_osk_time_ubusydelay(delay_in_usecs);
}
- if (max_loop_count == i)
+ if (MALI_REG_POLL_COUNT_FAST == i)
{
MALI_PRINT_ERROR(("Reset request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
return _MALI_OSK_ERR_FAULT;
@@ -376,16 +297,12 @@ _mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu)
_mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
mali_bool stall_success;
MALI_DEBUG_ASSERT_POINTER(mmu);
- /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */
- if (mmu->group)
- {
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
- }
stall_success = mali_mmu_enable_stall(mmu);
-
- /* The stall can not fail in current hw-state */
- MALI_DEBUG_ASSERT(stall_success);
+ if (!stall_success)
+ {
+ err = _MALI_OSK_ERR_BUSY;
+ }
MALI_DEBUG_PRINT(3, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->hw_core.description));
@@ -402,91 +319,9 @@ _mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu)
return err;
}
-
-/* ------------- interrupt handling below ------------------ */
-
-static _mali_osk_errcode_t mali_mmu_upper_half(void * data)
-{
- struct mali_mmu_core *mmu = (struct mali_mmu_core *)data;
- u32 int_stat;
-
- MALI_DEBUG_ASSERT_POINTER(mmu);
-
- /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
- int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
- if (0 != int_stat)
- {
- mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0);
- mali_hw_core_register_read(&mmu->hw_core, 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_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- /* reenable it */
- mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK,
- mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- MALI_PRINT_ERROR(("Mali MMU: Read bus error\n"));
- }
- return _MALI_OSK_ERR_OK;
- }
-
- return _MALI_OSK_ERR_FAULT;
-}
-
-static void mali_mmu_bottom_half(void * data)
-{
- struct mali_mmu_core *mmu = (struct mali_mmu_core*)data;
- u32 raw, status, fault_address;
-
- MALI_DEBUG_ASSERT_POINTER(mmu);
-
- MALI_DEBUG_PRINT(3, ("Mali MMU: Page fault bottom half: Locking subsystems\n"));
-
- mali_group_lock(mmu->group); /* Unlocked in mali_group_bottom_half */
-
- if ( MALI_FALSE == mali_group_power_is_on(mmu->group) )
- {
- MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.",mmu->hw_core.description));
- mali_group_unlock(mmu->group);
- return;
- }
-
- raw = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT);
- status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
-
- if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) )
- {
- MALI_DEBUG_PRINT(2, ("Mali MMU: Page fault bottom half: No Irq found.\n"));
- mali_group_unlock(mmu->group);
- /* MALI_DEBUG_ASSERT(0); */
- return;
- }
-
- /* An actual page fault has occurred. */
-
- fault_address = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
-
- MALI_DEBUG_PRINT(2,("Mali MMU: 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->hw_core.description));
-
- mali_group_bottom_half(mmu->group, GROUP_EVENT_MMU_PAGE_FAULT); /* Unlocks the group lock */
-}
-
mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu)
{
- mali_bool stall_success;
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
-
- stall_success = mali_mmu_enable_stall(mmu);
+ mali_bool stall_success = mali_mmu_enable_stall(mmu);
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
@@ -502,23 +337,20 @@ mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu)
void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu)
{
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
}
void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address)
{
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_ZAP_ONE_LINE, MALI_MMU_PDE_ENTRY(mali_address));
}
static void mali_mmu_activate_address_space(struct mali_mmu_core *mmu, u32 page_directory)
{
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
/* The MMU must be in stalled or page fault mode, for this writing to work */
MALI_DEBUG_ASSERT( 0 != ( mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)
- & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) );
+ & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) );
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, page_directory);
mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
@@ -528,7 +360,6 @@ mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mal
{
mali_bool stall_success;
MALI_DEBUG_ASSERT_POINTER(mmu);
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
MALI_DEBUG_PRINT(5, ("Asked to activate page directory 0x%x on MMU %s\n", pagedir, mmu->hw_core.description));
stall_success = mali_mmu_enable_stall(mmu);
@@ -542,13 +373,16 @@ mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mal
void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu)
{
mali_bool stall_success;
+
MALI_DEBUG_ASSERT_POINTER(mmu);
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
MALI_DEBUG_PRINT(3, ("Activating the empty page directory on MMU %s\n", mmu->hw_core.description));
stall_success = mali_mmu_enable_stall(mmu);
+
/* This function can only be called when the core is idle, so it could not fail. */
- MALI_DEBUG_ASSERT( stall_success );
+ MALI_DEBUG_ASSERT(stall_success);
+ MALI_IGNORE(stall_success);
+
mali_mmu_activate_address_space(mmu, mali_empty_page_directory);
mali_mmu_disable_stall(mmu);
}
@@ -557,7 +391,6 @@ void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu)
{
mali_bool stall_success;
MALI_DEBUG_ASSERT_POINTER(mmu);
- MALI_ASSERT_GROUP_LOCKED(mmu->group);
MALI_DEBUG_PRINT(3, ("Activating the page fault flush page directory on MMU %s\n", mmu->hw_core.description));
stall_success = mali_mmu_enable_stall(mmu);
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h
new file mode 100644
index 0000000..59b5399
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h
@@ -0,0 +1,130 @@
+/*
+ * 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_MMU_H__
+#define __MALI_MMU_H__
+
+#include "mali_osk.h"
+#include "mali_mmu_page_directory.h"
+#include "mali_hw_core.h"
+
+/* Forward declaration from mali_group.h */
+struct mali_group;
+
+/**
+ * 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 = 0x0004, /**< Status of the MMU */
+ MALI_MMU_REGISTER_COMMAND = 0x0008, /**< Command register, used to control the MMU */
+ MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x000C, /**< Logical address of the last page fault */
+ MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x010, /**< Used to invalidate the mapping of a single page from the MMU */
+ MALI_MMU_REGISTER_INT_RAWSTAT = 0x0014, /**< Raw interrupt status, all interrupts visible */
+ MALI_MMU_REGISTER_INT_CLEAR = 0x0018, /**< Indicate to the MMU that the interrupt has been received */
+ MALI_MMU_REGISTER_INT_MASK = 0x001C, /**< Enable/disable types of interrupts */
+ MALI_MMU_REGISTER_INT_STATUS = 0x0020 /**< 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;
+
+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_BIT_STALL_NOT_ACTIVE = 1 << 31,
+} mali_mmu_status_bits;
+
+/**
+ * Definition of the MMU struct
+ * Used to track a MMU unit in the system.
+ * Contains information about the mapping of the registers
+ */
+struct mali_mmu_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+};
+
+_mali_osk_errcode_t mali_mmu_initialize(void);
+
+void mali_mmu_terminate(void);
+
+struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual);
+void mali_mmu_delete(struct mali_mmu_core *mmu);
+
+_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu);
+mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu);
+void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu);
+void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address);
+
+mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core* mmu, struct mali_page_directory *pagedir);
+void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu);
+void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* 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)
+ */
+mali_bool mali_mmu_enable_stall(struct mali_mmu_core *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
+ */
+void mali_mmu_disable_stall(struct mali_mmu_core *mmu);
+
+void mali_mmu_page_fault_done(struct mali_mmu_core *mmu);
+
+/*** Register reading/writing functions ***/
+MALI_STATIC_INLINE u32 mali_mmu_get_int_status(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
+}
+
+MALI_STATIC_INLINE u32 mali_mmu_get_rawstat(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT);
+}
+
+MALI_STATIC_INLINE void mali_mmu_mask_all_interrupts(struct mali_mmu_core *mmu)
+{
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0);
+}
+
+MALI_STATIC_INLINE u32 mali_mmu_get_status(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+}
+
+MALI_STATIC_INLINE u32 mali_mmu_get_page_fault_addr(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
+}
+
+#endif /* __MALI_MMU_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c
index cc91ae9..258fc1b 100644
--- a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c
@@ -14,8 +14,7 @@
#include "mali_uk_types.h"
#include "mali_mmu_page_directory.h"
#include "mali_memory.h"
-
-#include "mali_cluster.h"
+#include "mali_l2_cache.h"
#include "mali_group.h"
static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data);
@@ -174,11 +173,10 @@ _mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir,
const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1);
u32 left = size;
int i;
-#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
mali_bool pd_changed = MALI_FALSE;
u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */
u32 num_pages_inv = 0;
-#endif
+ mali_bool invalidate_all = MALI_FALSE; /* safety mechanism in case page_entries_usage_count is unreliable */
/* For all page directory entries in range. */
for (i = first_pde; i <= last_pde; i++)
@@ -213,17 +211,20 @@ _mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir,
_mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), 0);
mali_mmu_release_table_page(page_address);
-#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
pd_changed = MALI_TRUE;
-#endif
}
else
{
-#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
- pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i);
- num_pages_inv++;
- MALI_DEBUG_ASSERT(num_pages_inv<3);
-#endif
+ MALI_DEBUG_ASSERT(num_pages_inv < 2);
+ if (num_pages_inv < 2)
+ {
+ pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i);
+ num_pages_inv++;
+ }
+ else
+ {
+ invalidate_all = MALI_TRUE;
+ }
/* If part of the page table is still in use, zero the relevant PTEs */
mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde);
@@ -234,20 +235,29 @@ _mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir,
}
_mali_osk_write_mem_barrier();
-#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
/* L2 pages invalidation */
if (MALI_TRUE == pd_changed)
{
- pages_to_invalidate[num_pages_inv] = pagedir->page_directory;
- num_pages_inv++;
- MALI_DEBUG_ASSERT(num_pages_inv<3);
+ MALI_DEBUG_ASSERT(num_pages_inv < 3);
+ if (num_pages_inv < 3)
+ {
+ pages_to_invalidate[num_pages_inv] = pagedir->page_directory;
+ num_pages_inv++;
+ }
+ else
+ {
+ invalidate_all = MALI_TRUE;
+ }
}
- if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id())
+ if (invalidate_all)
+ {
+ mali_l2_cache_invalidate_all();
+ }
+ else
{
- mali_cluster_invalidate_pages(pages_to_invalidate, num_pages_inv);
+ mali_l2_cache_invalidate_all_pages(pages_to_invalidate, num_pages_inv);
}
-#endif
MALI_SUCCESS;
}
@@ -305,12 +315,12 @@ void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_addre
switch ( cache_settings )
{
case MALI_CACHE_GP_READ_ALLOCATE:
- MALI_DEBUG_PRINT(3, ("Map L2 GP_Read_allocate\n"));
+ MALI_DEBUG_PRINT(5, ("Map L2 GP_Read_allocate\n"));
permission_bits = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE;
break;
case MALI_CACHE_STANDARD:
- MALI_DEBUG_PRINT(3, ("Map L2 Standard\n"));
+ MALI_DEBUG_PRINT(5, ("Map L2 Standard\n"));
/*falltrough */
default:
if ( MALI_CACHE_STANDARD != cache_settings) MALI_PRINT_ERROR(("Wrong cache settings\n"));
diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h
index 628833a..628833a 100644
--- a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h
diff --git a/drivers/media/video/samsung/mali/common/mali_osk.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk.h
index e32d15d..6217203 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk.h
@@ -63,6 +63,8 @@ extern "C"
#define MALI_FALSE ((mali_bool)0)
#endif
+#define MALI_HW_CORE_NO_COUNTER ((u32)-1)
+
/**
* @brief OSK Error codes
*
@@ -92,6 +94,25 @@ typedef enum
/** @} */ /* end group _mali_osk_miscellaneous */
+/** @defgroup _mali_osk_wq OSK work queues
+ * @{ */
+
+/** @brief Private type for work objects */
+typedef struct _mali_osk_wq_work_t_struct _mali_osk_wq_work_t;
+
+/** @brief Work queue handler function
+ *
+ * This function type is called when the work is scheduled by the work queue,
+ * e.g. as an IRQ bottom-half handler.
+ *
+ * Refer to \ref _mali_osk_wq_schedule_work() for more information on the
+ * work-queue and work handlers.
+ *
+ * @param arg resource-specific data
+ */
+typedef void (*_mali_osk_wq_work_handler_t)( void * arg );
+
+/* @} */ /* end group _mali_osk_wq */
/** @defgroup _mali_osk_irq OSK IRQ handling
* @{ */
@@ -127,7 +148,7 @@ typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)( void * arg );
*
* If an IRQ upper-half handler requires more work to be done than can be
* acheived in an IRQ context, then it may defer the work with
- * _mali_osk_irq_schedulework(). Refer to \ref _mali_osk_irq_schedulework() for
+ * _mali_osk_wq_schedule_work(). Refer to \ref _mali_osk_wq_create_work() for
* more information.
*
* @param arg resource-specific data
@@ -136,24 +157,6 @@ typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)( void * arg );
*/
typedef _mali_osk_errcode_t (*_mali_osk_irq_uhandler_t)( void * arg );
-/** @brief IRQ 'bottom-half' handler callback.
- *
- * This function is implemented by the common layer to do the deferred handling
- * of a resource's IRQ. Usually, this work cannot be carried out in IRQ context
- * by the IRQ upper-half handler.
- *
- * The IRQ bottom-half handler maps on to the concept of an IST that may
- * execute some time after the actual IRQ has fired.
- *
- * All OSK-registered IRQ bottom-half handlers will be serialized, across all
- * CPU-cores in the system.
- *
- * Refer to \ref _mali_osk_irq_schedulework() for more information on the
- * IRQ work-queue, and the calling of the IRQ bottom-half handler.
- *
- * @param arg resource-specific data
- */
-typedef void (*_mali_osk_irq_bhandler_t)( void * arg );
/** @} */ /* end group _mali_osk_irq */
@@ -197,21 +200,24 @@ typedef enum
{
_MALI_OSK_LOCK_ORDER_LAST = 0,
+ _MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS,
_MALI_OSK_LOCK_ORDER_PM_EXECUTE,
_MALI_OSK_LOCK_ORDER_UTILIZATION,
_MALI_OSK_LOCK_ORDER_L2_COUNTER,
_MALI_OSK_LOCK_ORDER_PROFILING,
_MALI_OSK_LOCK_ORDER_L2_COMMAND,
_MALI_OSK_LOCK_ORDER_PM_CORE_STATE,
- _MALI_OSK_LOCK_ORDER_GROUP,
+ _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED,
_MALI_OSK_LOCK_ORDER_SCHEDULER,
-
+ _MALI_OSK_LOCK_ORDER_GROUP,
+ _MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL,
_MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP,
_MALI_OSK_LOCK_ORDER_MEM_PT_CACHE,
_MALI_OSK_LOCK_ORDER_MEM_INFO,
_MALI_OSK_LOCK_ORDER_MEM_SESSION,
-
_MALI_OSK_LOCK_ORDER_SESSIONS,
+ _MALI_OSK_LOCK_ORDER_PM_DOMAIN,
+ _MALI_OSK_LOCK_ORDER_PMU,
_MALI_OSK_LOCK_ORDER_FIRST
} _mali_osk_lock_order_t;
@@ -311,6 +317,8 @@ typedef struct _mali_osk_lock_t_struct _mali_osk_lock_t;
/** @brief returns a lock's owner (thread id) if debugging is enabled
*/
u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock );
+#else
+#define MALI_DEBUG_ASSERT_LOCK_HELD(l) do {} while(0)
#endif
/** @} */ /* end group _mali_osk_lock */
@@ -429,7 +437,7 @@ typedef struct _mali_osk_notification_t_struct
*
* If a timer requires more work to be done than can be acheived in an IRQ
* context, then it may defer the work with a work-queue. For example, it may
- * use \ref _mali_osk_irq_schedulework() to make use of the IRQ bottom-half handler
+ * use \ref _mali_osk_wq_schedule_work() to make use of a bottom-half handler
* to carry out the remaining work.
*
* Stopping the timer with \ref _mali_osk_timer_del() blocks on compeletion of
@@ -473,6 +481,10 @@ typedef struct _mali_osk_list_s
* @param exp the name of the variable that the list will be defined as. */
#define _MALI_OSK_LIST_HEAD(exp) _mali_osk_list_t exp
+/** @brief Define a list variable, which is initialized.
+ * @param exp the name of the variable that the list will be defined as. */
+#define _MALI_OSK_LIST_HEAD_STATIC_INIT(exp) _mali_osk_list_t exp = { &exp, &exp }
+
/** @brief Find the containing structure of another structure
*
* This is the reverse of the operation 'offsetof'. This means that the
@@ -557,131 +569,68 @@ typedef struct _mali_osk_list_s
/** @addtogroup _mali_osk_miscellaneous
* @{ */
-/** @brief The known resource types
- *
- * @note \b IMPORTANT: these must remain fixed, and only be extended. This is
- * because not all systems use a header file for reading in their resources.
- * The resources may instead come from a data file where these resources are
- * 'hard-coded' in, because there's no easy way of transferring the enum values
- * into such data files. E.g. the C-Pre-processor does \em not process enums.
- */
-typedef enum _mali_osk_resource_type
-{
- RESOURCE_TYPE_FIRST =0, /**< Duplicate resource marker for the first resource*/
-
- MEMORY =0, /**< Physically contiguous memory block, not managed by the OS */
- OS_MEMORY =1, /**< Memory managed by and shared with the OS */
-
- MALI_PP =2, /**< Mali Pixel Processor core */
- MALI450PP =2, /**< Compatibility option */
- MALI400PP =2, /**< Compatibility option */
- MALI300PP =2, /**< Compatibility option */
- MALI200 =2, /**< Compatibility option */
-
- MALI_GP =3, /**< Mali Geometry Processor core */
- MALI450GP =3, /**< Compatibility option */
- MALI400GP =3, /**< Compatibility option */
- MALI300GP =3, /**< Compatibility option */
- MALIGP2 =3, /**< Compatibility option */
-
- MMU =4, /**< Mali MMU (Memory Management Unit) */
-
- FPGA_FRAMEWORK =5, /**< Mali registers specific to FPGA implementations */
-
- MALI_L2 =6, /**< Mali Level 2 cache core */
- MALI450L2 =6, /**< Compatibility option */
- MALI400L2 =6, /**< Compatibility option */
- MALI300L2 =6, /**< Compatibility option */
-
- MEM_VALIDATION =7, /**< External Memory Validator */
-
- PMU =8, /**< Power Manangement Unit */
-
- RESOURCE_TYPE_COUNT /**< The total number of known resources */
-} _mali_osk_resource_type_t;
-
/** @brief resource description struct
*
- * _mali_osk_resources_init() will enumerate objects of this type. Not all
- * members have a valid meaning across all types.
- *
- * The mmu_id is used to group resources to a certain MMU, since there may be
- * more than one MMU in the system, and each resource may be using a different
- * MMU:
- * - For MMU resources, the setting of mmu_id is a uniquely identifying number.
- * - For Other resources, the setting of mmu_id determines which MMU the
- * resource uses.
+ * Platform independent representation of a Mali HW resource
*/
typedef struct _mali_osk_resource
{
- _mali_osk_resource_type_t type; /**< type of the resource */
const char * description; /**< short description of the resource */
u32 base; /**< Physical base address of the resource, as seen by Mali resources. */
- s32 cpu_usage_adjust; /**< Offset added to the base address of the resource to arrive at the CPU physical address of the resource (if different from the Mali physical address) */
- u32 size; /**< Size in bytes of the resource - either the size of its register range, or the size of the memory block. */
u32 irq; /**< IRQ number delivered to the CPU, or -1 to tell the driver to probe for it (if possible) */
- u32 flags; /**< Resources-specific flags. */
- u32 mmu_id; /**< Identifier for Mali MMU resources. */
- u32 alloc_order; /**< Order in which MEMORY/OS_MEMORY resources are used */
} _mali_osk_resource_t;
/** @} */ /* end group _mali_osk_miscellaneous */
#include "mali_kernel_memory_engine.h" /* include for mali_memory_allocation and mali_physical_memory_allocation type */
-/** @addtogroup _mali_osk_irq
+/** @addtogroup _mali_osk_wq
* @{ */
-/** @brief Fake IRQ number for testing purposes
+/** @brief Initialize work queues (for deferred work)
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-#define _MALI_OSK_IRQ_NUMBER_FAKE ((u32)0xFFFFFFF1)
-
-/** @addtogroup _mali_osk_irq
- * @{ */
+_mali_osk_errcode_t _mali_osk_wq_init(void);
-/** @brief PMM Virtual IRQ number
+/** @brief Terminate work queues (for deferred work)
*/
-#define _MALI_OSK_IRQ_NUMBER_PMM ((u32)0xFFFFFFF2)
+void _mali_osk_wq_term(void);
-
-/** @brief Initialize IRQ handling for a resource
+/** @brief Create work in the work queue
*
- * The _mali_osk_irq_t returned must be written into the resource-specific data
- * pointed to by data. This is so that the upper and lower handlers can call
- * _mali_osk_irq_schedulework().
+ * Creates a work object which can be scheduled in the work queue. When
+ * scheduled, \a handler will be called with \a data as the argument.
*
- * @note The caller must ensure that the resource does not generate an
- * interrupt after _mali_osk_irq_init() finishes, and before the
- * _mali_osk_irq_t is written into the resource-specific data. Otherwise,
- * the upper-half handler will fail to call _mali_osk_irq_schedulework().
+ * Refer to \ref _mali_osk_wq_schedule_work() for details on how work
+ * is scheduled in the queue.
*
- * @param irqnum The IRQ number that the resource uses, as seen by the CPU.
- * The value -1 has a special meaning which indicates the use of probing, and trigger_func and ack_func must be
- * non-NULL.
- * @param uhandler The upper-half handler, corresponding to a ISR handler for
- * the resource
- * @param bhandler The lower-half handler, corresponding to an IST handler for
- * the resource
- * @param trigger_func Optional: a function to trigger the resource's irq, to
- * probe for the interrupt. Use NULL if irqnum != -1.
- * @param ack_func Optional: a function to acknowledge the resource's irq, to
- * probe for the interrupt. Use NULL if irqnum != -1.
- * @param data resource-specific data, which will be passed to uhandler,
- * bhandler and (if present) trigger_func and ack_funnc
- * @param description textual description of the IRQ resource.
- * @return on success, a pointer to a _mali_osk_irq_t object, which represents
- * the IRQ handling on this resource. NULL on failure.
+ * The returned pointer must be freed with \ref _mali_osk_wq_delete_work()
+ * when no longer needed.
+ */
+_mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data );
+
+/** @brief Delete a work object
+ *
+ * This will flush the work queue to ensure that the work handler will not
+ * be called after deletion.
+ */
+void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work );
+
+/** @brief Delete a work object
+ *
+ * This will NOT flush the work queue, so only call this if you are sure that the work handler will
+ * not be called after deletion.
*/
-_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description );
+void _mali_osk_wq_delete_work_nonflush( _mali_osk_wq_work_t *work );
-/** @brief Cause a queued, deferred call of the IRQ bottom-half.
+/** @brief Cause a queued, deferred call of the work handler
*
- * _mali_osk_irq_schedulework provides a mechanism for enqueuing deferred calls
- * to the IRQ bottom-half handler. The queue is known as the IRQ work-queue.
- * After calling _mali_osk_irq_schedulework(), the IRQ bottom-half handler will
- * be scheduled to run at some point in the future.
+ * _mali_osk_wq_schedule_work provides a mechanism for enqueuing deferred calls
+ * to the work handler. After calling \ref _mali_osk_wq_schedule_work(), the
+ * work handler will be scheduled to run at some point in the future.
*
- * This is called by the IRQ upper-half to defer further processing of
+ * Typically this is called by the IRQ upper-half to defer further processing of
* IRQ-related work to the IRQ bottom-half handler. This is necessary for work
* that cannot be done in an IRQ context by the IRQ upper-half handler. Timer
* callbacks also use this mechanism, because they are treated as though they
@@ -694,78 +643,97 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl
* IRQ bottom half to hold the same mutex, with a guarantee that they will not
* deadlock just by using this mechanism.
*
- * _mali_osk_irq_schedulework() places deferred call requests on a queue, to
+ * _mali_osk_wq_schedule_work() places deferred call requests on a queue, to
* allow for more than one thread to make a deferred call. Therfore, if it is
* called 'K' times, then the IRQ bottom-half will be scheduled 'K' times too.
* 'K' is a number that is implementation-specific.
*
- * _mali_osk_irq_schedulework() is guaranteed to not block on:
+ * _mali_osk_wq_schedule_work() is guaranteed to not block on:
* - enqueuing a deferred call request.
- * - the completion of the IRQ bottom-half handler.
+ * - the completion of the work handler.
*
- * This is to prevent deadlock. For example, if _mali_osk_irq_schedulework()
+ * This is to prevent deadlock. For example, if _mali_osk_wq_schedule_work()
* blocked, then it would cause a deadlock when the following two conditions
* hold:
- * - The IRQ bottom-half callback (of type _mali_osk_irq_bhandler_t) locks
+ * - The work handler callback (of type _mali_osk_wq_work_handler_t) locks
* a mutex
- * - And, at the same time, the caller of _mali_osk_irq_schedulework() also
+ * - And, at the same time, the caller of _mali_osk_wq_schedule_work() also
* holds the same mutex
*
* @note care must be taken to not overflow the queue that
- * _mali_osk_irq_schedulework() operates on. Code must be structured to
+ * _mali_osk_wq_schedule_work() operates on. Code must be structured to
* ensure that the number of requests made to the queue is bounded. Otherwise,
- * IRQs will be lost.
+ * work will be lost.
*
- * The queue that _mali_osk_irq_schedulework implements is a FIFO of N-writer,
- * 1-reader type. The writers are the callers of _mali_osk_irq_schedulework
+ * The queue that _mali_osk_wq_schedule_work implements is a FIFO of N-writer,
+ * 1-reader type. The writers are the callers of _mali_osk_wq_schedule_work
* (all OSK-registered IRQ upper-half handlers in the system, watchdog timers,
* callers from a Kernel-process context). The reader is a single thread that
- * handles all OSK-registered IRQs.
+ * handles all OSK-registered work.
*
- * The consequence of the queue being a 1-reader type is that calling
- * _mali_osk_irq_schedulework() on different _mali_osk_irq_t objects causes
- * their IRQ bottom-halves to be serialized, across all CPU-cores in the
- * system.
- *
- * @param irq a pointer to the _mali_osk_irq_t object corresponding to the
- * resource whose IRQ bottom-half must begin processing.
+ * @param work a pointer to the _mali_osk_wq_work_t object corresponding to the
+ * work to begin processing.
*/
-void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq );
+void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work );
-/** @brief Terminate IRQ handling on a resource.
+/** @brief Flush the work queue
+ *
+ * This will flush the OSK work queue, ensuring all work in the queue has
+ * completed before returning.
*
- * This will disable the interrupt from the device, and then waits for the
- * IRQ work-queue to finish the work that is currently in the queue. That is,
- * for every deferred call currently in the IRQ work-queue, it waits for each
- * of those to be processed by their respective IRQ bottom-half handler.
+ * Since this blocks on the completion of work in the work-queue, the
+ * caller of this function \b must \b not hold any mutexes that are taken by
+ * any registered work handler. To do so may cause a deadlock.
*
- * This function is used to ensure that the bottom-half handler of the supplied
- * IRQ object will not be running at the completion of this function call.
- * However, the caller must ensure that no other sources could call the
- * _mali_osk_irq_schedulework() on the same IRQ object. For example, the
- * relevant timers must be stopped.
+ */
+void _mali_osk_wq_flush(void);
+
+
+/** @} */ /* end group _mali_osk_wq */
+
+/** @addtogroup _mali_osk_irq
+ * @{ */
+
+/** @brief Initialize IRQ handling for a resource
*
- * @note While this function is being called, other OSK-registered IRQs in the
- * system may enqueue work for their respective bottom-half handlers. This
- * function will not wait for those entries in the work-queue to be flushed.
+ * Registers an interrupt handler \a uhandler for the given IRQ number \a irqnum.
+ * \a data will be passed as argument to the handler when an interrupt occurs.
*
- * Since this blocks on the completion of work in the IRQ work-queue, the
- * caller of this function \b must \b not hold any mutexes that are taken by
- * any OSK-registered IRQ bottom-half handler. To do so may cause a deadlock.
+ * If \a irqnum is -1, _mali_osk_irq_init will probe for the IRQ number using
+ * the supplied \a trigger_func and \a ack_func. These functions will also
+ * receive \a data as their argument.
*
- * @param irq a pointer to the _mali_osk_irq_t object corresponding to the
- * resource whose IRQ handling is to be terminated.
+ * @param irqnum The IRQ number that the resource uses, as seen by the CPU.
+ * The value -1 has a special meaning which indicates the use of probing, and
+ * trigger_func and ack_func must be non-NULL.
+ * @param uhandler The interrupt handler, corresponding to a ISR handler for
+ * the resource
+ * @param int_data resource specific data, which will be passed to uhandler
+ * @param trigger_func Optional: a function to trigger the resource's irq, to
+ * probe for the interrupt. Use NULL if irqnum != -1.
+ * @param ack_func Optional: a function to acknowledge the resource's irq, to
+ * probe for the interrupt. Use NULL if irqnum != -1.
+ * @param probe_data resource-specific data, which will be passed to
+ * (if present) trigger_func and ack_func
+ * @param description textual description of the IRQ resource.
+ * @return on success, a pointer to a _mali_osk_irq_t object, which represents
+ * the IRQ handling on this resource. NULL on failure.
*/
-void _mali_osk_irq_term( _mali_osk_irq_t *irq );
+_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description );
-/** @brief flushing workqueue.
+/** @brief Terminate IRQ handling on a resource.
+ *
+ * This will disable the interrupt from the device, and then waits for any
+ * currently executing IRQ handlers to complete.
*
- * This will flush the workqueue.
+ * @note If work is deferred to an IRQ bottom-half handler through
+ * \ref _mali_osk_wq_schedule_work(), be sure to flush any remaining work
+ * with \ref _mali_osk_wq_flush() or (implicitly) with \ref _mali_osk_wq_delete_work()
*
* @param irq a pointer to the _mali_osk_irq_t object corresponding to the
* resource whose IRQ handling is to be terminated.
*/
-void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq );
+void _mali_osk_irq_term( _mali_osk_irq_t *irq );
/** @} */ /* end group _mali_osk_irq */
@@ -1422,17 +1390,6 @@ void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue );
*/
void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object );
-#if MALI_STATE_TRACKING
-/** @brief Receive a notification from a queue
- *
- * Check if a notification queue is empty.
- *
- * @param queue The queue to check.
- * @return MALI_TRUE if queue is empty, otherwise MALI_FALSE.
- */
-mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue );
-#endif
-
/** @brief Receive a notification from a queue
*
* Receives a single notification from the given queue.
@@ -1504,23 +1461,22 @@ void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire );
/** @brief Modify a timer
*
- * Set the absolute time at which a timer will expire, and start it if it is
- * stopped. If \a expiry_tick is in the past (determined by
- * _mali_osk_time_after() ), the timer fires immediately.
+ * Set the relative time at which a timer will expire, and start it if it is
+ * stopped. If \a ticks_to_expire 0 the timer fires immediately.
*
* It is an error to modify a timer without setting the callback via
* _mali_osk_timer_setcallback().
*
- * The timer will expire at absolute time \a expiry_tick, at which point, the
- * callback function will be invoked with the callback-specific data, as set
- * by _mali_osk_timer_setcallback().
+ * The timer will expire at \a ticks_to_expire from the time of the call, at
+ * which point, the callback function will be invoked with the
+ * callback-specific data, as set by _mali_osk_timer_setcallback().
*
* @param tim the timer to modify, and start if necessary
- * @param expiry_tick the \em absolute time in ticks at which this timer should
- * trigger.
+ * @param ticks_to_expire the \em absolute time in ticks at which this timer
+ * should trigger.
*
*/
-void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick);
+void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 ticks_to_expire);
/** @brief Stop a timer, and block on its completion.
*
@@ -1532,9 +1488,9 @@ void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick);
* occur.
*
* @note While the callback itself is guaranteed to not be running, work
- * enqueued on the IRQ work-queue by the timer (with
- * \ref _mali_osk_irq_schedulework()) may still run. The timer callback and IRQ
- * bottom-half handler must take this into account.
+ * enqueued on the work-queue by the timer (with
+ * \ref _mali_osk_wq_schedule_work()) may still run. The timer callback and
+ * work handler must take this into account.
*
* It is legal to stop an already stopped timer.
*
@@ -1543,6 +1499,26 @@ void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick);
*/
void _mali_osk_timer_del( _mali_osk_timer_t *tim );
+/** @brief Stop a timer.
+ *
+ * Stop the timer. When the function returns, the timer's callback may still be
+ * running on any CPU core.
+ *
+ * It is legal to stop an already stopped timer.
+ *
+ * @param tim the timer to stop.
+ */
+void _mali_osk_timer_del_async( _mali_osk_timer_t *tim );
+
+/** @brief Check if timer is pending.
+ *
+ * Check if timer is active.
+ *
+ * @param tim the timer to check
+ * @return MALI_TRUE if time is active, MALI_FALSE if it is not active
+ */
+mali_bool _mali_osk_timer_pending( _mali_osk_timer_t *tim);
+
/** @brief Set a timer's callback parameters.
*
* This must be called at least once before a timer is started/modified.
@@ -1765,13 +1741,51 @@ u32 _mali_osk_get_tid(void);
*/
void _mali_osk_pm_dev_enable(void);
-/** @brief Tells the OS that device is now idle
+/** @brief Disable OS controlled runtime power management
+ */
+void _mali_osk_pm_dev_disable(void);
+
+
+/** @brief Take a reference to the power manager system for the Mali device.
+ *
+ * When function returns successfully, Mali is ON.
+ *
+ * @note Call \a _mali_osk_pm_dev_ref_dec() to release this reference.
+ */
+_mali_osk_errcode_t _mali_osk_pm_dev_ref_add(void);
+
+
+/** @brief Release the reference to the power manger system for the Mali device.
+ *
+ * When reference count reach zero, the cores can be off.
+ *
+ * @note This must be used to release references taken with \a _mali_osk_pm_dev_ref_add().
+ */
+void _mali_osk_pm_dev_ref_dec(void);
+
+
+/** @brief Take a reference to the power manager system for the Mali device.
+ *
+ * Will leave the cores powered off if they are already powered off.
+ *
+ * @note Call \a _mali_osk_pm_dev_ref_dec() to release this reference.
+ *
+ * @return MALI_TRUE if the Mali GPU is powered on, otherwise MALI_FALSE.
+ */
+mali_bool _mali_osk_pm_dev_ref_add_no_power_on(void);
+
+
+/** @brief Releasing the reference to the power manger system for the Mali device.
+ *
+ * When reference count reach zero, the cores can be off.
+ *
+ * @note This must be used to release references taken with \a _mali_osk_pm_dev_ref_add_no_power_on().
*/
-_mali_osk_errcode_t _mali_osk_pm_dev_idle(void);
+void _mali_osk_pm_dev_ref_dec_no_power_on(void);
-/** @brief Tells the OS that the device is about to become active
+/** @brief Block untill pending PM operations are done
*/
-_mali_osk_errcode_t _mali_osk_pm_dev_activate(void);
+void _mali_osk_pm_dev_barrier(void);
/** @} */ /* end group _mali_osk_miscellaneous */
@@ -1779,7 +1793,6 @@ _mali_osk_errcode_t _mali_osk_pm_dev_activate(void);
/** @} */ /* end group uddapi */
-
#ifdef __cplusplus
}
#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_osk_bitops.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.h
index ada1488..f262f7d 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_bitops.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.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/drivers/media/video/samsung/mali/common/mali_osk_list.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h
index 5987b0a..49f01b6 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_list.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h
@@ -16,6 +16,8 @@
#ifndef __MALI_OSK_LIST_H__
#define __MALI_OSK_LIST_H__
+#include "mali_kernel_common.h"
+
#ifdef __cplusplus
extern "C"
{
@@ -128,7 +130,7 @@ MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list )
* @param list the list to check.
* @return non-zero if the list is empty, and zero otherwise.
*/
-MALI_STATIC_INLINE int _mali_osk_list_empty( _mali_osk_list_t *list )
+MALI_STATIC_INLINE mali_bool _mali_osk_list_empty( _mali_osk_list_t *list )
{
return list->next == list;
}
@@ -150,30 +152,27 @@ MALI_STATIC_INLINE void _mali_osk_list_move( _mali_osk_list_t *move_entry, _mali
_mali_osk_list_add(move_entry, list);
}
-/** @brief Join two lists
+/** @brief Move an entire list
*
* The list element must be initialized.
*
- * Allows you to join a list into another list at a specific location
+ * Allows you to move a list from one list head to another list head
*
- * @param list the new list to add
- * @param at the location in a list to add the new list into
+ * @param old_list The existing list head
+ * @param new_list The new list head (must be an empty list)
*/
-MALI_STATIC_INLINE void _mali_osk_list_splice( _mali_osk_list_t *list, _mali_osk_list_t *at )
+MALI_STATIC_INLINE void _mali_osk_list_move_list( _mali_osk_list_t *old_list, _mali_osk_list_t *new_list )
{
- if (!_mali_osk_list_empty(list))
- {
- /* insert all items from 'list' after 'at' */
- _mali_osk_list_t *first = list->next;
- _mali_osk_list_t *last = list->prev;
- _mali_osk_list_t *split = at->next;
-
- first->prev = at;
- at->next = first;
-
- last->next = split;
- split->prev = last;
- }
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(new_list));
+ if (!_mali_osk_list_empty(old_list))
+ {
+ new_list->next = old_list->next;
+ new_list->prev = old_list->prev;
+ new_list->next->prev = new_list;
+ new_list->prev->next = new_list;
+ old_list->next = old_list;
+ old_list->prev = old_list;
+ }
}
/** @} */ /* end group _mali_osk_list */
diff --git a/drivers/media/video/samsung/mali/common/mali_osk_mali.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h
index 427fcc8..2916a0d 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_mali.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h
@@ -16,6 +16,7 @@
#ifndef __MALI_OSK_MALI_H__
#define __MALI_OSK_MALI_H__
+#include <linux/mali/mali_utgard.h>
#include <mali_osk.h>
#ifdef __cplusplus
@@ -26,33 +27,69 @@ extern "C"
/** @addtogroup _mali_osk_miscellaneous
* @{ */
-/** @brief Read the Mali Resource configuration
- *
- * Populates a _mali_arch_resource_t array from configuration settings, which
- * are stored in an OS-specific way.
- *
- * For example, these may be compiled in to a static structure, or read from
- * the filesystem at startup.
+/** @brief Struct with device specific configuration data
+ */
+struct _mali_osk_device_data
+{
+ /* Dedicated GPU memory range (physical). */
+ u32 dedicated_mem_start;
+ u32 dedicated_mem_size;
+
+ /* Shared GPU memory */
+ u32 shared_mem_size;
+
+ /* Frame buffer memory to be accessible by Mali GPU (physical) */
+ u32 fb_start;
+ u32 fb_size;
+
+ /* Report GPU utilization in this interval (specified in ms) */
+ u32 utilization_interval;
+
+ /* Function that will receive periodic GPU utilization numbers */
+ void (*utilization_callback)(struct mali_gpu_utilization_data *data);
+
+ /*
+ * Mali PMU switch delay.
+ * Only needed if the power gates are connected to the PMU in a high fanout
+ * network. This value is the number of Mali clock cycles it takes to
+ * enable the power gates and turn on the power mesh.
+ * This value will have no effect if a daisy chain implementation is used.
+ */
+ u32 pmu_switch_delay;
+};
+
+/** @brief Find Mali GPU HW resource
*
- * On failure, do not call _mali_osk_resources_term.
+ * @param addr Address of Mali GPU resource to find
+ * @param res Storage for resource information if resource is found.
+ * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if resource is not found
+ */
+_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res);
+
+
+/** @brief Find Mali GPU HW base address
*
- * @param arch_config a pointer to the store the pointer to the resources
- * @param num_resources the number of resources read
- * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_NOMEM on allocation
- * error. For other failures, a suitable _mali_osk_errcode_t is returned.
+ * @return 0 if resources are found, otherwise the Mali GPU component with lowest address.
*/
-_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources );
+u32 _mali_osk_resource_base_address(void);
-/** @brief Free resources allocated by _mali_osk_resources_init.
+/** @brief Retrieve the Mali GPU specific data
*
- * Frees the _mali_arch_resource_t array allocated by _mali_osk_resources_init
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_device_data_get(struct _mali_osk_device_data *data);
+
+/** @brief Determines if Mali GPU has been configured with shared interrupts.
*
- * @param arch_config a pointer to the stored the pointer to the resources
- * @param num_resources the number of resources in the array
+ * @return MALI_TRUE if shared interrupts, MALI_FALSE if not.
*/
-void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources);
+mali_bool _mali_osk_shared_interrupts(void);
+
/** @} */ /* end group _mali_osk_miscellaneous */
+
+
+
/** @addtogroup _mali_osk_low_level_memory
* @{ */
@@ -212,6 +249,16 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descri
* \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR set.
*/
void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags );
+
+/** @brief Copy as much data as possible from src to dest, do not crash if src or dest isn't available.
+ *
+ * @param dest Destination buffer (limited to user space mapped Mali memory)
+ * @param src Source buffer
+ * @param size Number of bytes to copy
+ * @return Number of bytes actually copied
+ */
+u32 _mali_osk_mem_write_safe(void *dest, const void *src, u32 size);
+
/** @} */ /* end group _mali_osk_low_level_memory */
diff --git a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h
index fd9a8fb..c4822e2 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h
@@ -11,13 +11,11 @@
#ifndef __MALI_OSK_PROFILING_H__
#define __MALI_OSK_PROFILING_H__
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
-#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
#include "mali_linux_trace.h"
-#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */
-
#include "mali_profiling_events.h"
+#include "mali_profiling_gator_api.h"
#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576
@@ -59,13 +57,8 @@ _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
* @param data4 Fifth data parameter, depending on event_id specified.
* @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
/* Call Linux tracepoint directly */
#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) trace_mali_timeline_event((event_id), (data0), (data1), (data2), (data3), (data4))
-#else
-/* Internal profiling is handled like a plain function call */
-void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
-#endif
/**
* Report a hardware counter event.
@@ -74,13 +67,8 @@ void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2
* @param value The value of the counter.
*/
-#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
/* Call Linux tracepoint directly */
#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value)
-#else
-/* Internal profiling is handled like a plain function call */
-void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value);
-#endif
/**
* Report SW counters
@@ -140,7 +128,13 @@ mali_bool _mali_osk_profiling_have_recording(void);
/** @} */ /* end group _mali_osk_profiling */
-#endif /* MALI_TIMELINE_PROFILING_ENABLED */
+#else /* defined(CONFIG_MALI400_PROFILING) && defined(CONFIG_TRACEPOINTS) */
+
+ /* Dummy add_event, for when profiling is disabled. */
+
+#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4)
+
+#endif /* defined(CONFIG_MALI400_PROFILING) && defined(CONFIG_TRACEPOINTS) */
#endif /* __MALI_OSK_PROFILING_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.c
new file mode 100644
index 0000000..e1d6aa4
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.c
@@ -0,0 +1,144 @@
+/*
+ * 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_pm.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_scheduler.h"
+#include "mali_kernel_utilization.h"
+#include "mali_group.h"
+#include "mali_pm_domain.h"
+#include "mali_pmu.h"
+
+static mali_bool mali_power_on = MALI_FALSE;
+
+_mali_osk_errcode_t mali_pm_initialize(void)
+{
+ _mali_osk_pm_dev_enable();
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pm_terminate(void)
+{
+ mali_pm_domain_terminate();
+ _mali_osk_pm_dev_disable();
+}
+
+/* Reset GPU after power up */
+static void mali_pm_reset_gpu(void)
+{
+ /* Reset all L2 caches */
+ mali_l2_cache_reset_all();
+
+ /* Reset all groups */
+ mali_scheduler_reset_all_groups();
+}
+
+void mali_pm_os_suspend(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali PM: OS suspend\n"));
+ mali_gp_scheduler_suspend();
+ mali_pp_scheduler_suspend();
+ mali_utilization_suspend();
+/* MALI_SEC */
+#if !defined(CONFIG_PM_RUNTIME)
+ mali_group_power_off();
+ mali_power_on = MALI_FALSE;
+#endif
+}
+
+void mali_pm_os_resume(void)
+{
+#if !defined(CONFIG_PM_RUNTIME)
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+ mali_bool do_reset = MALI_FALSE;
+#endif
+
+ MALI_DEBUG_PRINT(3, ("Mali PM: OS resume\n"));
+/* MALI_SEC */
+/******************************************************************
+ *
+ * <2013. 08. 23>
+ * In Pegasus prime, PMU is not enabled(Power off) while
+ * system wake up(suspend -> resume).
+ *
+ * Because PMU power is off, GPU does not work.
+ * Therefore code is commented like below.
+ *
+ *****************************************************************/
+#if !defined(CONFIG_PM_RUNTIME)
+ if (MALI_TRUE != mali_power_on)
+ {
+ do_reset = MALI_TRUE;
+ }
+
+ if (NULL != pmu)
+ {
+ mali_pmu_reset(pmu);
+ }
+
+ mali_power_on = MALI_TRUE;
+ _mali_osk_write_mem_barrier();
+
+ if (do_reset)
+ {
+ mali_pm_reset_gpu();
+ mali_group_power_on();
+ }
+#endif
+ mali_gp_scheduler_resume();
+ mali_pp_scheduler_resume();
+}
+
+void mali_pm_runtime_suspend(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali PM: Runtime suspend\n"));
+ mali_group_power_off();
+ mali_power_on = MALI_FALSE;
+}
+
+void mali_pm_runtime_resume(void)
+{
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+ mali_bool do_reset = MALI_FALSE;
+
+ MALI_DEBUG_PRINT(3, ("Mali PM: Runtime resume\n"));
+
+ if (MALI_TRUE != mali_power_on)
+ {
+ do_reset = MALI_TRUE;
+ }
+
+ if (NULL != pmu)
+ {
+ mali_pmu_reset(pmu);
+ }
+
+ mali_power_on = MALI_TRUE;
+ _mali_osk_write_mem_barrier();
+
+ if (do_reset)
+ {
+ mali_pm_reset_gpu();
+ mali_group_power_on();
+ }
+}
+
+void mali_pm_set_power_is_on(void)
+{
+ mali_power_on = MALI_TRUE;
+}
+
+mali_bool mali_pm_is_power_on(void)
+{
+ return mali_power_on;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_pm.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.h
index d4ccfde..36f0f50 100644
--- a/drivers/media/video/samsung/mali/common/mali_pm.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.h
@@ -13,44 +13,16 @@
#include "mali_osk.h"
-enum mali_core_event
-{
- MALI_CORE_EVENT_GP_START,
- MALI_CORE_EVENT_GP_STOP,
- MALI_CORE_EVENT_PP_START,
- MALI_CORE_EVENT_PP_STOP
-};
-
-enum mali_pm_event
-{
- MALI_PM_EVENT_CORES_WORKING,
- MALI_PM_EVENT_CORES_IDLE,
- MALI_PM_EVENT_TIMER_LIGHT_SLEEP,
- MALI_PM_EVENT_TIMER_DEEP_SLEEP,
- MALI_PM_EVENT_OS_SUSPEND,
- MALI_PM_EVENT_OS_RESUME,
- MALI_PM_EVENT_SCHEME_ALWAYS_ON,
- MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL,
-};
-
_mali_osk_errcode_t mali_pm_initialize(void);
void mali_pm_terminate(void);
-void mali_pm_always_on(mali_bool enable);
-
-void mali_pm_lock(void);
-void mali_pm_unlock(void);
-void mali_pm_execute_state_change_lock(void);
-
-void mali_pm_execute_state_change_unlock(void);
-
-mali_bool mali_pm_is_powered_on(void);
-
-void mali_pm_core_event(enum mali_core_event core_event);
+/* Callback functions registered for the runtime PMM system */
void mali_pm_os_suspend(void);
void mali_pm_os_resume(void);
void mali_pm_runtime_suspend(void);
void mali_pm_runtime_resume(void);
+void mali_pm_set_power_is_on(void);
+mali_bool mali_pm_is_power_on(void);
#endif /* __MALI_PM_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c
new file mode 100644
index 0000000..9193778
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c
@@ -0,0 +1,240 @@
+/*
+ * 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_pm_domain.h"
+#include "mali_pmu.h"
+#include "mali_pm.h"
+#include "mali_group.h"
+
+#define MALI_PM_DOMAIN_MAX_DOMAINS 7
+
+static struct mali_pm_domain *mali_pm_domains[MALI_PM_DOMAIN_MAX_DOMAINS] = { NULL, };
+
+static void mali_pm_domain_lock(struct mali_pm_domain *domain)
+{
+ _mali_osk_lock_wait(domain->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+static void mali_pm_domain_unlock(struct mali_pm_domain *domain)
+{
+ _mali_osk_lock_signal(domain->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+MALI_STATIC_INLINE void mali_pm_domain_state_set(struct mali_pm_domain *domain, mali_pm_domain_state state)
+{
+ domain->state = state;
+}
+
+struct mali_pm_domain *mali_pm_domain_create(u32 id, u32 pmu_mask)
+{
+ struct mali_pm_domain* domain;
+
+ MALI_DEBUG_PRINT(2, ("Mali PM domain: Creating Mali PM domain (mask=0x%08X)\n", pmu_mask));
+
+ domain = (struct mali_pm_domain *)_mali_osk_malloc(sizeof(struct mali_pm_domain));
+ if (NULL != domain)
+ {
+ _mali_osk_lock_flags_t flags = _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+ domain->lock = _mali_osk_lock_init(flags, 0, _MALI_OSK_LOCK_ORDER_PM_DOMAIN);
+ if (NULL == domain->lock)
+ {
+ _mali_osk_free(domain);
+ return NULL;
+ }
+
+ domain->state = MALI_PM_DOMAIN_ON;
+ domain->pmu_mask = pmu_mask;
+ domain->use_count = 0;
+ domain->group_list = NULL;
+ domain->group_count = 0;
+ domain->l2 = NULL;
+
+ MALI_DEBUG_ASSERT(MALI_PM_DOMAIN_MAX_DOMAINS > id);
+ mali_pm_domains[id] = domain;
+
+ return domain;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT_ERROR(("Unable to create PM domain\n"));
+ }
+
+ return NULL;
+}
+
+void mali_pm_domain_delete(struct mali_pm_domain *domain)
+{
+ if (NULL == domain)
+ {
+ return;
+ }
+ _mali_osk_lock_term(domain->lock);
+
+ _mali_osk_free(domain);
+}
+
+void mali_pm_domain_terminate(void)
+{
+ int i;
+
+ /* Delete all domains */
+ for (i = 0; i < MALI_PM_DOMAIN_MAX_DOMAINS; i++)
+ {
+ mali_pm_domain_delete(mali_pm_domains[i]);
+ }
+}
+
+void mali_pm_domain_add_group(u32 id, struct mali_group *group)
+{
+ struct mali_pm_domain *domain = mali_pm_domain_get(id);
+ struct mali_group *next;
+
+ if (NULL == domain) return;
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ /* Assume domain is on and group is enabled initially. */
+ mali_pm_domain_ref_get(domain);
+
+ ++domain->group_count;
+ next = domain->group_list;
+
+ domain->group_list = group;
+
+ group->pm_domain_list = next;
+
+ mali_group_set_pm_domain(group, domain);
+}
+
+void mali_pm_domain_add_l2(u32 id, struct mali_l2_cache_core *l2)
+{
+ struct mali_pm_domain *domain = mali_pm_domain_get(id);
+
+ if (NULL == domain) return;
+
+ MALI_DEBUG_ASSERT(NULL == domain->l2);
+ MALI_DEBUG_ASSERT(NULL != l2);
+
+ domain->l2 = l2;
+
+ mali_l2_cache_set_pm_domain(l2, domain);
+}
+
+struct mali_pm_domain *mali_pm_domain_get(u32 id)
+{
+ MALI_DEBUG_ASSERT(MALI_PM_DOMAIN_MAX_DOMAINS > id);
+
+ return mali_pm_domains[id];
+}
+
+void mali_pm_domain_ref_get(struct mali_pm_domain *domain)
+{
+ if (NULL == domain) return;
+
+ mali_pm_domain_lock(domain);
+ ++domain->use_count;
+
+ if (MALI_PM_DOMAIN_ON != domain->state)
+ {
+ /* Power on */
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(3, ("PM Domain: Powering on 0x%08x\n", domain->pmu_mask));
+
+ if (NULL != pmu)
+ {
+ _mali_osk_errcode_t err;
+
+ err = mali_pmu_power_up(pmu, domain->pmu_mask);
+
+ if (_MALI_OSK_ERR_OK != err && _MALI_OSK_ERR_BUSY != err)
+ {
+ MALI_PRINT_ERROR(("PM Domain: Failed to power up PM domain 0x%08x\n",
+ domain->pmu_mask));
+ }
+ }
+ mali_pm_domain_state_set(domain, MALI_PM_DOMAIN_ON);
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(MALI_PM_DOMAIN_ON == mali_pm_domain_state_get(domain));
+ }
+
+ mali_pm_domain_unlock(domain);
+}
+
+void mali_pm_domain_ref_put(struct mali_pm_domain *domain)
+{
+ if (NULL == domain) return;
+
+ mali_pm_domain_lock(domain);
+ --domain->use_count;
+
+ if (0 == domain->use_count && MALI_PM_DOMAIN_OFF != domain->state)
+ {
+ /* Power off */
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(3, ("PM Domain: Powering off 0x%08x\n", domain->pmu_mask));
+
+ mali_pm_domain_state_set(domain, MALI_PM_DOMAIN_OFF);
+
+ if (NULL != pmu)
+ {
+ _mali_osk_errcode_t err;
+
+ err = mali_pmu_power_down(pmu, domain->pmu_mask);
+
+ if (_MALI_OSK_ERR_OK != err && _MALI_OSK_ERR_BUSY != err)
+ {
+ MALI_PRINT_ERROR(("PM Domain: Failed to power down PM domain 0x%08x\n",
+ domain->pmu_mask));
+ }
+ }
+ }
+ mali_pm_domain_unlock(domain);
+}
+
+mali_bool mali_pm_domain_lock_state(struct mali_pm_domain *domain)
+{
+ mali_bool is_powered = MALI_TRUE;
+
+ /* Take a reference without powering on */
+ if (NULL != domain)
+ {
+ mali_pm_domain_lock(domain);
+ ++domain->use_count;
+
+ if (MALI_PM_DOMAIN_ON != domain->state)
+ {
+ is_powered = MALI_FALSE;
+ }
+ mali_pm_domain_unlock(domain);
+ }
+
+ if(!_mali_osk_pm_dev_ref_add_no_power_on())
+ {
+ is_powered = MALI_FALSE;
+ }
+
+ return is_powered;
+}
+
+void mali_pm_domain_unlock_state(struct mali_pm_domain *domain)
+{
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ if (NULL != domain)
+ {
+ mali_pm_domain_ref_put(domain);
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h
new file mode 100644
index 0000000..3f3fa24
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h
@@ -0,0 +1,73 @@
+/*
+ * 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_PM_DOMAIN_H__
+#define __MALI_PM_DOMAIN_H__
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+
+#include "mali_l2_cache.h"
+#include "mali_group.h"
+#include "mali_pmu.h"
+
+typedef enum
+{
+ MALI_PM_DOMAIN_ON,
+ MALI_PM_DOMAIN_OFF,
+} mali_pm_domain_state;
+
+struct mali_pm_domain
+{
+ mali_pm_domain_state state;
+ _mali_osk_lock_t *lock;
+
+ s32 use_count;
+
+ u32 pmu_mask;
+
+ int group_count;
+ struct mali_group *group_list;
+
+ struct mali_l2_cache_core *l2;
+};
+
+struct mali_pm_domain *mali_pm_domain_create(u32 id, u32 pmu_mask);
+void mali_pm_domain_add_group(u32 id, struct mali_group *group);
+void mali_pm_domain_add_l2(u32 id, struct mali_l2_cache_core *l2);
+void mali_pm_domain_delete(struct mali_pm_domain *domain);
+
+void mali_pm_domain_terminate(void);
+
+/** Get PM domain from domain ID
+ */
+struct mali_pm_domain *mali_pm_domain_get(u32 id);
+
+/* Ref counting */
+void mali_pm_domain_ref_get(struct mali_pm_domain *domain);
+void mali_pm_domain_ref_put(struct mali_pm_domain *domain);
+
+MALI_STATIC_INLINE struct mali_l2_cache_core *mali_pm_domain_l2_get(struct mali_pm_domain *domain)
+{
+ return domain->l2;
+}
+
+MALI_STATIC_INLINE mali_pm_domain_state mali_pm_domain_state_get(struct mali_pm_domain *domain)
+{
+ return domain->state;
+}
+
+mali_bool mali_pm_domain_lock_state(struct mali_pm_domain *domain);
+void mali_pm_domain_unlock_state(struct mali_pm_domain *domain);
+
+#define MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain) for ((group) = (domain)->group_list;\
+ NULL != (group); (group) = (group)->pm_domain_list)
+
+#endif /* __MALI_PM_DOMAIN_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c
new file mode 100644
index 0000000..668c8e9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c
@@ -0,0 +1,405 @@
+/*
+ * 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_pmu.c
+ * Mali driver functions for Mali 400 PMU hardware
+ */
+#include "mali_hw_core.h"
+#include "mali_pmu.h"
+#include "mali_pp.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_pm.h"
+#include "mali_osk_mali.h"
+
+static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches);
+
+/** @brief MALI inbuilt PMU hardware info and PMU hardware has knowledge of cores power mask
+ */
+struct mali_pmu_core
+{
+ struct mali_hw_core hw_core;
+ _mali_osk_lock_t *lock;
+ u32 registered_cores_mask;
+ u32 active_cores_mask;
+ u32 switch_delay;
+};
+
+static struct mali_pmu_core *mali_global_pmu_core = NULL;
+
+/** @brief Register layout for hardware PMU
+ */
+typedef enum {
+ PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */
+ PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */
+ PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */
+ PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */
+ PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */
+ PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */
+ PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Switch delay register */
+ PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */
+} pmu_reg_addr_mgmt_addr;
+
+#define PMU_REG_VAL_IRQ 1
+
+struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches)
+{
+ struct mali_pmu_core* pmu;
+
+ MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core);
+ MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n"));
+
+ pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core));
+ if (NULL != pmu)
+ {
+ pmu->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE,
+ 0, _MALI_OSK_LOCK_ORDER_PMU);
+ if (NULL != pmu->lock)
+ {
+ pmu->registered_cores_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches);
+ pmu->active_cores_mask = pmu->registered_cores_mask;
+
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE))
+ {
+ _mali_osk_errcode_t err;
+ struct _mali_osk_device_data data = { 0, };
+
+ err = _mali_osk_device_data_get(&data);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ pmu->switch_delay = data.pmu_switch_delay;
+ mali_global_pmu_core = pmu;
+ return pmu;
+ }
+ mali_hw_core_delete(&pmu->hw_core);
+ }
+ _mali_osk_lock_term(pmu->lock);
+ }
+ _mali_osk_free(pmu);
+ }
+
+ return NULL;
+}
+
+void mali_pmu_delete(struct mali_pmu_core *pmu)
+{
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu == mali_global_pmu_core);
+ MALI_DEBUG_PRINT(2, ("Mali PMU: Deleting Mali PMU core\n"));
+
+ _mali_osk_lock_term(pmu->lock);
+ mali_hw_core_delete(&pmu->hw_core);
+ _mali_osk_free(pmu);
+ mali_global_pmu_core = NULL;
+}
+
+static void mali_pmu_lock(struct mali_pmu_core *pmu)
+{
+ _mali_osk_lock_wait(pmu->lock, _MALI_OSK_LOCKMODE_RW);
+}
+static void mali_pmu_unlock(struct mali_pmu_core *pmu)
+{
+ _mali_osk_lock_signal(pmu->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+static _mali_osk_errcode_t mali_pmu_send_command_internal(struct mali_pmu_core *pmu, const u32 command, const u32 mask)
+{
+ u32 rawstat;
+ u32 timeout = MALI_REG_POLL_COUNT_SLOW;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(0 == (mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT)
+ & PMU_REG_VAL_IRQ));
+
+ mali_hw_core_register_write(&pmu->hw_core, command, mask);
+
+ /* Wait for the command to complete */
+ do
+ {
+ rawstat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT);
+ --timeout;
+ } while (0 == (rawstat & PMU_REG_VAL_IRQ) && 0 < timeout);
+
+ MALI_DEBUG_ASSERT(0 < timeout);
+ if (0 == timeout)
+ {
+ return _MALI_OSK_ERR_TIMEOUT;
+ }
+
+ mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_CLEAR, PMU_REG_VAL_IRQ);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_pmu_send_command(struct mali_pmu_core *pmu, const u32 command, const u32 mask)
+{
+ u32 stat;
+
+ if (0 == mask) return _MALI_OSK_ERR_OK;
+
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->registered_cores_mask;
+
+ switch (command)
+ {
+ case PMU_REG_ADDR_MGMT_POWER_DOWN:
+ if (mask == stat) return _MALI_OSK_ERR_OK;
+ break;
+ case PMU_REG_ADDR_MGMT_POWER_UP:
+ if (0 == (stat & mask)) return _MALI_OSK_ERR_OK;
+ break;
+ default:
+ MALI_DEBUG_ASSERT(0);
+ break;
+ }
+
+ mali_pmu_send_command_internal(pmu, command, mask);
+
+#if defined(DEBUG)
+ {
+ /* Get power status of cores */
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->registered_cores_mask;
+
+ switch (command)
+ {
+ case PMU_REG_ADDR_MGMT_POWER_DOWN:
+ MALI_DEBUG_ASSERT(mask == (stat & mask));
+ MALI_DEBUG_ASSERT(0 == (stat & pmu->active_cores_mask));
+ MALI_DEBUG_ASSERT((pmu->registered_cores_mask & ~pmu->active_cores_mask) == stat);
+ break;
+ case PMU_REG_ADDR_MGMT_POWER_UP:
+ MALI_DEBUG_ASSERT(0 == (stat & mask));
+ MALI_DEBUG_ASSERT(0 == (stat & pmu->active_cores_mask));
+ break;
+ default:
+ MALI_DEBUG_ASSERT(0);
+ break;
+ }
+ }
+#endif /* defined(DEBUG) */
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu)
+{
+ _mali_osk_errcode_t err;
+ u32 cores_off_mask, cores_on_mask, stat;
+
+ mali_pmu_lock(pmu);
+
+ /* Setup the desired defaults */
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay);
+
+ /* Get power status of cores */
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+
+ cores_off_mask = pmu->registered_cores_mask & ~(stat | pmu->active_cores_mask);
+ cores_on_mask = pmu->registered_cores_mask & (stat & pmu->active_cores_mask);
+
+ if (0 != cores_off_mask)
+ {
+ err = mali_pmu_send_command_internal(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, cores_off_mask);
+ if (_MALI_OSK_ERR_OK != err) return err;
+ }
+
+ if (0 != cores_on_mask)
+ {
+ err = mali_pmu_send_command_internal(pmu, PMU_REG_ADDR_MGMT_POWER_UP, cores_on_mask);
+ if (_MALI_OSK_ERR_OK != err) return err;
+ }
+
+#if defined(DEBUG)
+ {
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->registered_cores_mask;
+
+ MALI_DEBUG_ASSERT(stat == (pmu->registered_cores_mask & ~pmu->active_cores_mask));
+ }
+#endif /* defined(DEBUG) */
+
+ mali_pmu_unlock(pmu);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pmu_power_down(struct mali_pmu_core *pmu, u32 mask)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0 );
+
+ /* Make sure we have a valid power domain mask */
+ if (mask > pmu->registered_cores_mask)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ mali_pmu_lock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Power down (0x%08X)\n", mask));
+
+ pmu->active_cores_mask &= ~mask;
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ if (!mali_pm_is_power_on())
+ {
+ /* Don't touch hardware if all of Mali is powered off. */
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Skipping power down (0x%08X) since Mali is off\n", mask));
+
+ return _MALI_OSK_ERR_BUSY;
+ }
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, mask);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_pmu_power_up(struct mali_pmu_core *pmu, u32 mask)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0 );
+
+ /* Make sure we have a valid power domain mask */
+ if (mask & ~pmu->registered_cores_mask)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ mali_pmu_lock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Power up (0x%08X)\n", mask));
+
+ pmu->active_cores_mask |= mask;
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ if (!mali_pm_is_power_on())
+ {
+ /* Don't touch hardware if all of Mali is powered off. */
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Skipping power up (0x%08X) since Mali is off\n", mask));
+
+ return _MALI_OSK_ERR_BUSY;
+ }
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_UP, mask);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_pmu_power_down_all(struct mali_pmu_core *pmu)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0);
+
+ mali_pmu_lock(pmu);
+
+ /* Setup the desired defaults in case we were called before mali_pmu_reset() */
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay);
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->registered_cores_mask);
+
+ mali_pmu_unlock(pmu);
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_pmu_power_up_all(struct mali_pmu_core *pmu)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0);
+
+ mali_pmu_lock(pmu);
+
+ /* Setup the desired defaults in case we were called before mali_pmu_reset() */
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay);
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_UP, pmu->active_cores_mask);
+
+ mali_pmu_unlock(pmu);
+ return err;
+}
+
+struct mali_pmu_core *mali_pmu_get_global_pmu_core(void)
+{
+ return mali_global_pmu_core;
+}
+
+static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches)
+{
+ u32 mask = 0;
+
+ if (number_of_l2_caches == 1)
+ {
+ /* Mali-300 or Mali-400 */
+ u32 i;
+
+ /* GP */
+ mask = 0x01;
+
+ /* L2 cache */
+ mask |= 0x01<<1;
+
+ /* Set bit for each PP core */
+ for (i = 0; i < number_of_pp_cores; i++)
+ {
+ mask |= 0x01<<(i+2);
+ }
+ }
+ else if (number_of_l2_caches > 1)
+ {
+ /* Mali-450 */
+
+ /* GP (including its L2 cache) */
+ mask = 0x01;
+
+ /* There is always at least one PP (including its L2 cache) */
+ mask |= 0x01<<1;
+
+ /* Additional PP cores in same L2 cache */
+ if (number_of_pp_cores >= 2)
+ {
+ mask |= 0x01<<2;
+ }
+
+ /* Additional PP cores in a third L2 cache */
+ if (number_of_pp_cores >= 5)
+ {
+ mask |= 0x01<<3;
+ }
+ }
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Power mask is 0x%08X (%u + %u)\n", mask, number_of_pp_cores, number_of_l2_caches));
+
+ return mask;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h
index fd10c08..7e2f67c 100644
--- a/drivers/media/video/samsung/mali/common/mali_pmu.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h
@@ -13,8 +13,27 @@
* Platform specific Mali driver functions
*/
+#ifndef __MALI_PMU_H__
+#define __MALI_PMU_H__
+
#include "mali_osk.h"
+#define MALI_PMU_M450_DOM1 0
+#define MALI_PMU_M450_DOM1_MASK (1 << 1)
+#define MALI_PMU_M450_DOM2 1
+#define MALI_PMU_M450_DOM2_MASK (1 << 2)
+#define MALI_PMU_M450_DOM3 2
+#define MALI_PMU_M450_DOM3_MASK (1 << 3)
+
+#define MALI_PMU_M400_PP0 0
+#define MALI_PMU_M400_PP0_MASK (1 << 2)
+#define MALI_PMU_M400_PP1 1
+#define MALI_PMU_M400_PP1_MASK (1 << 3)
+#define MALI_PMU_M400_PP2 2
+#define MALI_PMU_M400_PP2_MASK (1 << 4)
+#define MALI_PMU_M400_PP3 3
+#define MALI_PMU_M400_PP3_MASK (1 << 5)
+
struct mali_pmu_core;
/** @brief Initialisation of MALI PMU
@@ -45,26 +64,50 @@ _mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu);
/** @brief MALI GPU power down using MALI in-built PMU
*
- * called to power down all cores
+ * Called to power down the specified cores. The mask will be saved so that \a
+ * mali_pmu_power_up_all will bring the PMU back to the previous state set with
+ * this function or \a mali_pmu_power_up.
*
* @param pmu Pointer to PMU core object to power down
+ * @param mask Mask specifying which power domains to power down
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmu_power_down(struct mali_pmu_core *pmu, u32 mask);
+
+/** @brief MALI GPU power up using MALI in-built PMU
+ *
+ * Called to power up the specified cores. The mask will be saved so that \a
+ * mali_pmu_power_up_all will bring the PMU back to the previous state set with
+ * this function or \a mali_pmu_power_down.
+ *
+ * @param pmu Pointer to PMU core object to power up
+ * @param mask Mask specifying which power domains to power up
* @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
*/
-_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu);
+_mali_osk_errcode_t mali_pmu_power_up(struct mali_pmu_core *pmu, u32 mask);
+/** @brief MALI GPU power down using MALI in-built PMU
+ *
+ * called to power down all cores
+ *
+ * @param pmu Pointer to PMU core object to power down
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmu_power_down_all(struct mali_pmu_core *pmu);
/** @brief MALI GPU power up using MALI in-built PMU
- *
+ *
* called to power up all cores
*
* @param pmu Pointer to PMU core object to power up
* @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
*/
-_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu);
-
+_mali_osk_errcode_t mali_pmu_power_up_all(struct mali_pmu_core *pmu);
/** @brief Retrieves the Mali PMU core object (if any)
*
* @return The Mali PMU object, or NULL if no PMU exists.
*/
struct mali_pmu_core *mali_pmu_get_global_pmu_core(void);
+
+#endif /* __MALI_PMU_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.c
new file mode 100644
index 0000000..8273239
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.c
@@ -0,0 +1,521 @@
+/*
+ * 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_pp_job.h"
+#include "mali_pp.h"
+#include "mali_hw_core.h"
+#include "mali_group.h"
+#include "regs/mali_200_regs.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+/* Number of frame registers on Mali-200 */
+#define MALI_PP_MALI200_NUM_FRAME_REGISTERS ((0x04C/4)+1)
+/* Number of frame registers on Mali-300 and later */
+#define MALI_PP_MALI400_NUM_FRAME_REGISTERS ((0x058/4)+1)
+
+static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES] = { NULL };
+static u32 mali_global_num_pp_cores = 0;
+
+/* Interrupt handlers */
+static void mali_pp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
+
+struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id)
+{
+ struct mali_pp_core* core = NULL;
+
+ MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base));
+
+ if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n"));
+ return NULL;
+ }
+
+ core = _mali_osk_malloc(sizeof(struct mali_pp_core));
+ if (NULL != core)
+ {
+ core->core_id = mali_global_num_pp_cores;
+ core->bcast_id = bcast_id;
+ 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, MALI200_REG_SIZEOF_REGISTER_BANK))
+ {
+ _mali_osk_errcode_t ret;
+
+ if (!is_virtual)
+ {
+ ret = mali_pp_reset(core);
+ }
+ else
+ {
+ ret = _MALI_OSK_ERR_OK;
+ }
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ ret = mali_group_add_pp_core(group, core);
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq);
+
+ core->irq = _mali_osk_irq_init(resource->irq,
+ mali_group_upper_half_pp,
+ group,
+ mali_pp_irq_probe_trigger,
+ mali_pp_irq_probe_ack,
+ core,
+ "mali_pp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ mali_global_pp_cores[mali_global_num_pp_cores] = core;
+ mali_global_num_pp_cores++;
+
+ return core;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description));
+ }
+ mali_group_remove_pp_core(group);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description));
+ }
+ }
+ mali_hw_core_delete(&core->hw_core);
+ }
+
+ _mali_osk_free(core);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_pp_delete(struct mali_pp_core *core)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ _mali_osk_irq_term(core->irq);
+ mali_hw_core_delete(&core->hw_core);
+
+ /* Remove core from global list */
+ for (i = 0; i < mali_global_num_pp_cores; i++)
+ {
+ if (mali_global_pp_cores[i] == core)
+ {
+ mali_global_pp_cores[i] = NULL;
+ mali_global_num_pp_cores--;
+
+ if (i != mali_global_num_pp_cores)
+ {
+ /* We removed a PP core from the middle of the array -- move the last
+ * PP core to the current position to close the gap */
+ mali_global_pp_cores[i] = mali_global_pp_cores[mali_global_num_pp_cores];
+ mali_global_pp_cores[mali_global_num_pp_cores] = NULL;
+ }
+
+ break;
+ }
+ }
+
+ _mali_osk_free(core);
+}
+
+void mali_pp_stop_bus(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ /* Will only send the stop bus command, and not wait for it to complete */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
+}
+
+_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
+{
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ /* Send the stop bus command. */
+ mali_pp_stop_bus(core);
+
+ /* Wait for bus to be stopped */
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
+ break;
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+/* Frame register reset values.
+ * Taken from the Mali400 TRM, 3.6. Pixel processor control register summary */
+static const u32 mali_frame_registers_reset_values[_MALI_PP_MAX_FRAME_REGISTERS] =
+{
+ 0x0, /* Renderer List Address Register */
+ 0x0, /* Renderer State Word Base Address Register */
+ 0x0, /* Renderer Vertex Base Register */
+ 0x2, /* Feature Enable Register */
+ 0x0, /* Z Clear Value Register */
+ 0x0, /* Stencil Clear Value Register */
+ 0x0, /* ABGR Clear Value 0 Register */
+ 0x0, /* ABGR Clear Value 1 Register */
+ 0x0, /* ABGR Clear Value 2 Register */
+ 0x0, /* ABGR Clear Value 3 Register */
+ 0x0, /* Bounding Box Left Right Register */
+ 0x0, /* Bounding Box Bottom Register */
+ 0x0, /* FS Stack Address Register */
+ 0x0, /* FS Stack Size and Initial Value Register */
+ 0x0, /* Reserved */
+ 0x0, /* Reserved */
+ 0x0, /* Origin Offset X Register */
+ 0x0, /* Origin Offset Y Register */
+ 0x75, /* Subpixel Specifier Register */
+ 0x0, /* Tiebreak mode Register */
+ 0x0, /* Polygon List Format Register */
+ 0x0, /* Scaling Register */
+ 0x0 /* Tilebuffer configuration Register */
+};
+
+/* WBx register reset values */
+static const u32 mali_wb_registers_reset_values[_MALI_PP_MAX_WB_REGISTERS] =
+{
+ 0x0, /* WBx Source Select Register */
+ 0x0, /* WBx Target Address Register */
+ 0x0, /* WBx Target Pixel Format Register */
+ 0x0, /* WBx Target AA Format Register */
+ 0x0, /* WBx Target Layout */
+ 0x0, /* WBx Target Scanline Length */
+ 0x0, /* WBx Target Flags Register */
+ 0x0, /* WBx MRT Enable Register */
+ 0x0, /* WBx MRT Offset Register */
+ 0x0, /* WBx Global Test Enable Register */
+ 0x0, /* WBx Global Test Reference Value Register */
+ 0x0 /* WBx Global Test Compare Function Register */
+};
+
+/* Performance Counter 0 Enable Register reset value */
+static const u32 mali_perf_cnt_enable_reset_value = 0;
+
+_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
+{
+ /* Bus must be stopped before calling this function */
+ const u32 reset_invalid_value = 0xC0FFE000;
+ const u32 reset_check_value = 0xC01A0000;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
+
+ /* Set register to a bogus value. The register will be used to detect when reset is complete */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
+
+ /* Force core to reset */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
+
+ /* Wait for reset to be complete */
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
+ if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW))
+ {
+ break;
+ }
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
+ }
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pp_reset_async(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
+}
+
+_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core)
+{
+ int i;
+ u32 rawstat = 0;
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ if (!(mali_pp_read_status(core) & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE))
+ {
+ rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT);
+ if (rawstat == MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ }
+ }
+
+ if (i == MALI_REG_POLL_COUNT_FAST)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n",
+ core->hw_core.description, rawstat));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
+{
+ mali_pp_reset_async(core);
+ return mali_pp_reset_wait(core);
+}
+
+void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual)
+{
+ u32 relative_address;
+ u32 start_index;
+ u32 nr_of_regs;
+ u32 *frame_registers = mali_pp_job_get_frame_registers(job);
+ u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
+ u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
+ u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
+ core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job);
+ core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ /* Write frame registers */
+
+ /*
+ * There are two frame registers which are different for each sub job:
+ * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
+ * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
+ */
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);
+
+ /* For virtual jobs, the stack address shouldn't be broadcast but written individually */
+ if (!mali_pp_job_is_virtual(job) || restart_virtual)
+ {
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
+ }
+
+ /* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
+ relative_address = MALI200_REG_ADDR_RSW;
+ start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
+ nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);
+
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
+ relative_address, &frame_registers[start_index],
+ nr_of_regs, &mali_frame_registers_reset_values[start_index]);
+
+ /* MALI200_REG_ADDR_STACK_SIZE */
+ relative_address = MALI200_REG_ADDR_STACK_SIZE;
+ start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);
+
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
+ relative_address, frame_registers[start_index],
+ mali_frame_registers_reset_values[start_index]);
+
+ /* Skip 2 reserved registers */
+
+ /* Write remaining registers */
+ relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
+ start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
+ nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
+
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
+ relative_address, &frame_registers[start_index],
+ nr_of_regs, &mali_frame_registers_reset_values[start_index]);
+
+ /* Write WBx registers */
+ if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
+ }
+
+ if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
+ }
+
+ if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ }
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));
+
+ /* Adding barrier to make sure all rester writes are finished */
+ _mali_osk_write_mem_barrier();
+
+ /* This is the command that starts the core. */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
+
+ /* Adding barrier to make sure previous rester writes is finished */
+ _mali_osk_write_mem_barrier();
+}
+
+u32 mali_pp_core_get_version(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION);
+}
+
+struct mali_pp_core* mali_pp_get_global_pp_core(u32 index)
+{
+ if (mali_global_num_pp_cores > index)
+ {
+ return mali_global_pp_cores[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_pp_get_glob_num_pp_cores(void)
+{
+ return mali_global_num_pp_cores;
+}
+
+/* ------------- interrupt handling below ------------------ */
+static void mali_pp_irq_probe_trigger(void *data)
+{
+ struct mali_pp_core *core = (struct mali_pp_core *)data;
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
+ _mali_osk_mem_barrier();
+}
+
+static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data)
+{
+ struct mali_pp_core *core = (struct mali_pp_core *)data;
+ u32 irq_readout;
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
+ if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG);
+ _mali_osk_mem_barrier();
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+
+#if 0
+static void mali_pp_print_registers(struct mali_pp_core *core)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
+}
+#endif
+
+#if 0
+void mali_pp_print_state(struct mali_pp_core *core)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) ));
+}
+#endif
+
+void mali_pp_update_performance_counters(struct mali_pp_core *parent, struct mali_pp_core *child, struct mali_pp_job *job, u32 subjob)
+{
+ u32 val0 = 0;
+ u32 val1 = 0;
+#if defined(CONFIG_MALI400_PROFILING)
+ int counter_index = COUNTER_FP_0_C0 + (2 * child->core_id);
+#endif
+
+ if (MALI_HW_CORE_NO_COUNTER != parent->counter_src0_used)
+ {
+ val0 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
+ mali_pp_job_set_perf_counter_value0(job, subjob, val0);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(counter_index, val0);
+#endif
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != parent->counter_src1_used)
+ {
+ val1 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+ mali_pp_job_set_perf_counter_value1(job, subjob, val1);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
+#endif
+ }
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description);
+
+ return n;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.h
new file mode 100644
index 0000000..dd8f350
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.h
@@ -0,0 +1,127 @@
+/*
+ * 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_PP_H__
+#define __MALI_PP_H__
+
+#include "mali_osk.h"
+#include "mali_pp_job.h"
+#include "mali_hw_core.h"
+
+struct mali_group;
+
+#define MALI_MAX_NUMBER_OF_PP_CORES 9
+
+/**
+ * Definition of the PP core struct
+ * Used to track a PP core in the system.
+ */
+struct mali_pp_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ u32 core_id; /**< Unique core ID */
+ u32 bcast_id; /**< The "flag" value used by the Mali-450 broadcast and DLBU unit */
+ 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 */
+};
+
+_mali_osk_errcode_t mali_pp_initialize(void);
+void mali_pp_terminate(void);
+
+struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t * resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id);
+void mali_pp_delete(struct mali_pp_core *core);
+
+void mali_pp_stop_bus(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core);
+void mali_pp_reset_async(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core);
+
+void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual);
+
+u32 mali_pp_core_get_version(struct mali_pp_core *core);
+
+MALI_STATIC_INLINE u32 mali_pp_core_get_id(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->core_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_core_get_bcast_id(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->bcast_id;
+}
+
+struct mali_pp_core* mali_pp_get_global_pp_core(u32 index);
+u32 mali_pp_get_glob_num_pp_cores(void);
+
+/* Debug */
+u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size);
+
+/**
+ * Put instrumented HW counters from the core(s) to the job object (if enabled)
+ *
+ * parent and child is always the same, except for virtual jobs on Mali-450.
+ * In this case, the counters will be enabled on the virtual core (parent),
+ * but values need to be read from the child cores.
+ *
+ * @param parent The core used to see if the counters was enabled
+ * @param child The core to actually read the values from
+ * @job Job object to update with counter values (if enabled)
+ * @subjob Which subjob the counters are applicable for (core ID for virtual jobs)
+ */
+void mali_pp_update_performance_counters(struct mali_pp_core *parent, struct mali_pp_core *child, struct mali_pp_job *job, u32 subjob);
+
+MALI_STATIC_INLINE const char *mali_pp_get_hw_core_desc(struct mali_pp_core *core)
+{
+ return core->hw_core.description;
+}
+
+/*** Register reading/writing functions ***/
+MALI_STATIC_INLINE u32 mali_pp_get_int_stat(struct mali_pp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
+}
+
+MALI_STATIC_INLINE u32 mali_pp_read_rawstat(struct mali_pp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_read_status(struct mali_pp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS);
+}
+
+MALI_STATIC_INLINE void mali_pp_mask_all_interrupts(struct mali_pp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
+}
+
+MALI_STATIC_INLINE void mali_pp_clear_hang_interrupt(struct mali_pp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
+}
+
+MALI_STATIC_INLINE void mali_pp_enable_interrupts(struct mali_pp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+}
+
+MALI_STATIC_INLINE void mali_pp_write_addr_stack(struct mali_pp_core *core, struct mali_pp_job *job)
+{
+ u32 addr = mali_pp_job_get_addr_stack(job, core->core_id);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, addr);
+}
+
+#endif /* __MALI_PP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c
new file mode 100644
index 0000000..ca0ea05
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c
@@ -0,0 +1,169 @@
+/*
+ * 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_pp_job.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_kernel_common.h"
+#include "mali_uk_types.h"
+#include "mali_pp_scheduler.h"
+
+static u32 pp_counter_src0 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
+static u32 pp_counter_src1 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
+
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id)
+{
+ struct mali_pp_job *job;
+ u32 perf_counter_flag;
+
+ job = _mali_osk_calloc(1, sizeof(struct mali_pp_job));
+ if (NULL != job)
+ {
+ if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_pp_start_job_s)))
+ {
+ goto fail;
+ }
+
+ if (job->uargs.num_cores > _MALI_PP_MAX_SUB_JOBS)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
+ goto fail;
+ }
+
+ if (!mali_pp_job_use_no_notification(job))
+ {
+ job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s));
+ if (NULL == job->finished_notification) goto fail;
+ }
+
+ perf_counter_flag = mali_pp_job_get_perf_counter_flag(job);
+
+ /* case when no counters came from user space
+ * so pass the debugfs / DS-5 provided global ones to the job object */
+ if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
+ (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)))
+ {
+ mali_pp_job_set_perf_counter_src0(job, mali_pp_job_get_pp_counter_src0());
+ mali_pp_job_set_perf_counter_src1(job, mali_pp_job_get_pp_counter_src1());
+ }
+
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ _mali_osk_list_init(&job->session_list);
+ job->id = id;
+
+ job->sub_jobs_num = job->uargs.num_cores ? job->uargs.num_cores : 1;
+ job->pid = _mali_osk_get_pid();
+ job->tid = _mali_osk_get_tid();
+
+ job->num_memory_cookies = job->uargs.num_memory_cookies;
+ if (job->num_memory_cookies > 0)
+ {
+ u32 size;
+
+ if (job->uargs.num_memory_cookies > session->descriptor_mapping->current_nr_mappings)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Too many memory cookies specified in job object\n"));
+ goto fail;
+ }
+
+ size = sizeof(*job->uargs.memory_cookies) * job->num_memory_cookies;
+
+ job->memory_cookies = _mali_osk_malloc(size);
+ if (NULL == job->memory_cookies)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Failed to allocate %d bytes of memory cookies!\n", size));
+ goto fail;
+ }
+
+ if (0 != _mali_osk_copy_from_user(job->memory_cookies, job->uargs.memory_cookies, size))
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Failed to copy %d bytes of memory cookies from user!\n", size));
+ goto fail;
+ }
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ job->num_dma_bufs = job->num_memory_cookies;
+ job->dma_bufs = _mali_osk_calloc(job->num_dma_bufs, sizeof(struct mali_dma_buf_attachment *));
+ if (NULL == job->dma_bufs)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Failed to allocate dma_bufs array!\n"));
+ goto fail;
+ }
+#endif
+ }
+ else
+ {
+ job->memory_cookies = NULL;
+ }
+
+ return job;
+ }
+
+fail:
+ if (NULL != job)
+ {
+ mali_pp_job_delete(job);
+ }
+
+ return NULL;
+}
+
+void mali_pp_job_delete(struct mali_pp_job *job)
+{
+#ifdef CONFIG_SYNC
+ /* It is safe to delete the work without flushing. */
+ if (NULL != job->sync_work) _mali_osk_wq_delete_work_nonflush(job->sync_work);
+ if (NULL != job->pre_fence) sync_fence_put(job->pre_fence);
+ if (NULL != job->sync_point) sync_fence_put(job->sync_point->fence);
+#endif
+ if (NULL != job->finished_notification)
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ }
+
+ _mali_osk_free(job->memory_cookies);
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* Unmap buffers attached to job */
+ if (0 < job->num_dma_bufs)
+ {
+ mali_dma_buf_unmap_job(job);
+ }
+
+ _mali_osk_free(job->dma_bufs);
+#endif /* CONFIG_DMA_SHARED_BUFFER */
+
+ _mali_osk_free(job);
+}
+
+u32 mali_pp_job_get_pp_counter_src0(void)
+{
+ return pp_counter_src0;
+}
+
+mali_bool mali_pp_job_set_pp_counter_src0(u32 counter)
+{
+ pp_counter_src0 = counter;
+
+ return MALI_TRUE;
+}
+
+u32 mali_pp_job_get_pp_counter_src1(void)
+{
+ return pp_counter_src1;
+}
+
+mali_bool mali_pp_job_set_pp_counter_src1(u32 counter)
+{
+ pp_counter_src1 = counter;
+
+ return MALI_TRUE;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h
index 4399c1d..2aed8cc 100644
--- a/drivers/media/video/samsung/mali/common/mali_pp_job.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h
@@ -17,50 +17,57 @@
#include "mali_session.h"
#include "mali_kernel_common.h"
#include "regs/mali_200_regs.h"
+#include "mali_kernel_core.h"
+#ifdef CONFIG_SYNC
+#include <linux/sync.h>
+#endif
+#include "mali_dlbu.h"
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+#include "linux/mali_dma_buf.h"
+#endif
/**
- * The structure represends a PP job, including all sub-jobs
- * (This struct unfortunatly needs to be public because of how the _mali_osk_list_*
+ * The structure represents a PP job, including all sub-jobs
+ * (This struct unfortunately needs to be public because of how the _mali_osk_list_*
* mechanism works)
*/
struct mali_pp_job
{
_mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */
struct mali_session_data *session; /**< Session which submitted this job */
- u32 id; /**< identifier for this job in kernel space (sequencial numbering) */
- u32 user_id; /**< identifier for the job in user space */
- u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< core specific registers associated with this job, see ARM DDI0415A */
- u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_FRAME registers for sub job 1-7 */
- u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_STACK registers for sub job 1-7 */
- u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 0 registers */
- u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 1 registers */
- u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 2 registers */
- u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
- u32 perf_counter_src0; /**< Source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
- u32 perf_counter_src1; /**< Source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
+ _mali_osk_list_t session_list; /**< Used to link jobs together in the session job list */
+ _mali_uk_pp_start_job_s uargs; /**< Arguments from user space */
+ u32 id; /**< Identifier for this job in kernel space (sequential numbering) */
u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 0 (to be returned to user space), one for each sub job */
- u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
- u32 sub_job_count; /**< Total number of sub-jobs in this superjob */
+ u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
+ u32 sub_jobs_num; /**< Number of subjobs; set to 1 for Mali-450 if DLBU is used, otherwise equals number of PP cores */
u32 sub_jobs_started; /**< Total number of sub-jobs started (always started in ascending order) */
u32 sub_jobs_completed; /**< Number of completed sub-jobs in this superjob */
u32 sub_job_errors; /**< Bitfield with errors (errors for each single sub-job is or'ed together) */
u32 pid; /**< Process ID of submitting process */
u32 tid; /**< Thread ID of submitting thread */
- u32 frame_builder_id; /**< id of the originating frame builder */
- u32 flush_id; /**< flush id within the originating frame builder */
- mali_bool barrier; /**< [in] MALI_TRUE means wait for all my previous jobs to complete before scheduling this one */
- mali_bool active_barrier; /**< [in] Changes from MALI_TRUE to MALI_FALSE when barrier has been resolved */
- mali_bool no_notification; /**< [in] MALI_TRUE means do not notify user space when this job has completed */
+ _mali_osk_notification_t *finished_notification; /**< Notification sent back to userspace on job complete */
+ u32 num_memory_cookies; /**< Number of memory cookies attached to job */
+ u32 *memory_cookies; /**< Memory cookies attached to job */
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ struct mali_dma_buf_attachment **dma_bufs; /**< Array of DMA-bufs used by job */
+ u32 num_dma_bufs; /**< Number of DMA-bufs used by job */
+#endif
+#ifdef CONFIG_SYNC
+ mali_sync_pt *sync_point; /**< Sync point to signal on completion */
+ struct sync_fence_waiter sync_waiter; /**< Sync waiter for async wait */
+ _mali_osk_wq_work_t *sync_work; /**< Work to schedule in callback */
+ struct sync_fence *pre_fence; /**< Sync fence this job must wait for */
+#endif
};
-struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id);
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id);
void mali_pp_job_delete(struct mali_pp_job *job);
-_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job);
-
-/******************************************************
- * simple utility functions for dealing with pp jobs:
- *****************************************************/
+u32 mali_pp_job_get_pp_counter_src0(void);
+mali_bool mali_pp_job_set_pp_counter_src0(u32 counter);
+u32 mali_pp_job_get_pp_counter_src1(void);
+mali_bool mali_pp_job_set_pp_counter_src1(u32 counter);
MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
{
@@ -69,33 +76,57 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job)
{
- return job->user_id;
+ return job->uargs.user_job_ptr;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job)
{
- return job->frame_builder_id;
+ return job->uargs.frame_builder_id;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job)
{
- return job->flush_id;
+ return job->uargs.flush_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_pid(struct mali_pp_job *job)
+{
+ return job->pid;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_tid(struct mali_pp_job *job)
+{
+ return job->tid;
}
MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job)
{
- return job->frame_registers;
+ return job->uargs.frame_registers;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_dlbu_registers(struct mali_pp_job *job)
+{
+ return job->uargs.dlbu_registers;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_is_virtual(struct mali_pp_job *job)
+{
+ return 0 == job->uargs.num_cores;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job)
{
- if (sub_job == 0)
+ if (mali_pp_job_is_virtual(job))
+ {
+ return MALI_DLBU_VIRT_ADDR;
+ }
+ else if (0 == sub_job)
{
- return job->frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
+ return job->uargs.frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
}
else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
{
- return job->frame_registers_addr_frame[sub_job - 1];
+ return job->uargs.frame_registers_addr_frame[sub_job - 1];
}
return 0;
@@ -103,13 +134,13 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 s
MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job)
{
- if (sub_job == 0)
+ if (0 == sub_job)
{
- return job->frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
+ return job->uargs.frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
}
else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
{
- return job->frame_registers_addr_stack[sub_job - 1];
+ return job->uargs.frame_registers_addr_stack[sub_job - 1];
}
return 0;
@@ -117,32 +148,32 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 s
MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job)
{
- return job->wb0_registers;
+ return job->uargs.wb0_registers;
}
MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job)
{
- return job->wb1_registers;
+ return job->uargs.wb1_registers;
}
MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job)
{
- return job->wb2_registers;
+ return job->uargs.wb2_registers;
}
MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job)
{
- job->wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+ job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
}
MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job)
{
- job->wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+ job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
}
MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job)
{
- job->wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+ job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
}
MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job)
@@ -152,37 +183,22 @@ MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali
MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job)
{
- return (job->sub_jobs_started < job->sub_job_count) ? MALI_TRUE : MALI_FALSE;
+ return (job->sub_jobs_started < job->sub_jobs_num) ? MALI_TRUE : MALI_FALSE;
}
/* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job.
- Makes sure that no new subjobs is started. */
-MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(struct mali_pp_job *job)
+ Makes sure that no new subjobs are started. */
+MALI_STATIC_INLINE void mali_pp_job_mark_unstarted_failed(struct mali_pp_job *job)
{
- /* All can not be started, since then it would not be in the job queue */
- MALI_DEBUG_ASSERT( job->sub_jobs_started != job->sub_job_count );
-
- /* If at least one job is started */
- if ( (job->sub_jobs_started > 0) )
- {
- /* If at least one job is currently being rendered, and thus assigned to a group and core */
- if (job->sub_jobs_started > job->sub_jobs_completed )
- {
- u32 jobs_remaining = job->sub_job_count - job->sub_jobs_started;
- job->sub_jobs_started += jobs_remaining;
- job->sub_jobs_completed += jobs_remaining;
- job->sub_job_errors += jobs_remaining;
- /* Returning TRUE indicating that we can not delete this job which is being redered */
- return MALI_TRUE;
- }
- }
- /* The job is not being rendered to at the moment and can then safely be deleted */
- return MALI_FALSE;
+ u32 jobs_remaining = job->sub_jobs_num - job->sub_jobs_started;
+ job->sub_jobs_started += jobs_remaining;
+ job->sub_jobs_completed += jobs_remaining;
+ job->sub_job_errors += jobs_remaining;
}
MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job)
{
- return (job->sub_job_count == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE;
+ return (job->sub_jobs_num == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job)
@@ -192,7 +208,7 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_jo
MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job)
{
- return job->sub_job_count;
+ return job->sub_jobs_num;
}
MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job)
@@ -222,32 +238,32 @@ MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job)
MALI_STATIC_INLINE mali_bool mali_pp_job_has_active_barrier(struct mali_pp_job *job)
{
- return job->active_barrier;
+ return job->uargs.flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE void mali_pp_job_barrier_enforced(struct mali_pp_job *job)
{
- job->active_barrier = MALI_FALSE;
+ job->uargs.flags &= ~_MALI_PP_JOB_FLAG_BARRIER;
}
MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(struct mali_pp_job *job)
{
- return job->no_notification;
+ return job->uargs.flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
{
- return job->perf_counter_flag;
+ return job->uargs.perf_counter_flag;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job)
{
- return job->perf_counter_src0;
+ return job->uargs.perf_counter_src0;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job)
{
- return job->perf_counter_src1;
+ return job->uargs.perf_counter_src1;
}
MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job)
@@ -260,6 +276,16 @@ MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *j
return job->perf_counter_value1[sub_job];
}
+MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_src0(struct mali_pp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src0 = src;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_src1(struct mali_pp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src1 = src;
+}
+
MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value0(struct mali_pp_job *job, u32 sub_job, u32 value)
{
job->perf_counter_value0[sub_job] = value;
@@ -270,4 +296,13 @@ MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *
job->perf_counter_value1[sub_job] = value;
}
+MALI_STATIC_INLINE _mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
+{
+ if (mali_pp_job_is_virtual(job) && job->sub_jobs_num != 1)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
#endif /* __MALI_PP_JOB_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c
new file mode 100644
index 0000000..3f10bdc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c
@@ -0,0 +1,1890 @@
+/*
+ * 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_pp_scheduler.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_scheduler.h"
+#include "mali_pp.h"
+#include "mali_pp_job.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_kernel_utilization.h"
+#include "mali_session.h"
+#include "mali_pm_domain.h"
+#include "linux/mali/mali_utgard.h"
+
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include "mali_dma_buf.h"
+#endif
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+#include <linux/sched.h>
+#include <trace/events/gpu.h>
+#endif
+
+
+/* With certain configurations, job deletion involves functions which cannot be called from atomic context.
+ * This #if checks for those cases and enables job deletion to be deferred and run in a different context. */
+#if defined(CONFIG_SYNC) || !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+#define MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE 1
+#endif
+
+/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
+#define MALI_MAX_NUMBER_OF_PP_GROUPS 9
+
+static mali_bool mali_pp_scheduler_is_suspended(void);
+static void mali_pp_scheduler_do_schedule(void *arg);
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+static void mali_pp_scheduler_do_job_delete(void *arg);
+#endif
+static void mali_pp_scheduler_job_queued(void);
+static void mali_pp_scheduler_job_completed(void);
+
+static u32 pp_version = 0;
+
+/* Physical job queue */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(job_queue); /* List of physical jobs with some unscheduled work */
+static u32 job_queue_depth = 0;
+
+/* Physical groups */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_working); /* List of physical groups with working jobs on the pp core */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_idle); /* List of physical groups with idle jobs on the pp core */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_disabled); /* List of disabled physical groups */
+
+/* Virtual job queue (Mali-450 only) */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(virtual_job_queue); /* List of unstarted jobs for the virtual group */
+static u32 virtual_job_queue_depth = 0;
+
+/* Virtual group (Mali-450 only) */
+static struct mali_group *virtual_group = NULL; /* Virtual group (if any) */
+static enum
+{
+ VIRTUAL_GROUP_IDLE,
+ VIRTUAL_GROUP_WORKING,
+ VIRTUAL_GROUP_DISABLED,
+}
+virtual_group_state = VIRTUAL_GROUP_IDLE; /* Flag which indicates whether the virtual group is working or idle */
+
+/* Number of physical cores */
+static u32 num_cores = 0;
+static u32 enabled_cores = 0;
+
+/* Variables to allow safe pausing of the scheduler */
+static _mali_osk_wait_queue_t *pp_scheduler_working_wait_queue = NULL;
+static u32 pause_count = 0;
+
+static _mali_osk_lock_t *pp_scheduler_lock = NULL;
+/* Contains tid of thread that locked the scheduler or 0, if not locked */
+MALI_DEBUG_CODE(static u32 pp_scheduler_lock_owner = 0);
+
+static _mali_osk_wq_work_t *pp_scheduler_wq_schedule = NULL;
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+static _mali_osk_wq_work_t *pp_scheduler_wq_job_delete = NULL;
+static _mali_osk_lock_t *pp_scheduler_job_delete_lock = NULL;
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(pp_scheduler_job_deletion_queue);
+#endif
+
+MALI_STATIC_INLINE mali_bool mali_pp_scheduler_has_virtual_group(void)
+{
+ return NULL != virtual_group;
+}
+
+_mali_osk_errcode_t mali_pp_scheduler_initialize(void)
+{
+ _mali_osk_lock_flags_t lock_flags;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#else
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#endif
+
+ pp_scheduler_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ if (NULL == pp_scheduler_lock)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
+ if (NULL == pp_scheduler_working_wait_queue)
+ {
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ pp_scheduler_wq_schedule = _mali_osk_wq_create_work(mali_pp_scheduler_do_schedule, NULL);
+ if (NULL == pp_scheduler_wq_schedule)
+ {
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ pp_scheduler_wq_job_delete = _mali_osk_wq_create_work(mali_pp_scheduler_do_job_delete, NULL);
+ if (NULL == pp_scheduler_wq_job_delete)
+ {
+ _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ pp_scheduler_job_delete_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED);
+ if (NULL == pp_scheduler_job_delete_lock)
+ {
+ _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete);
+ _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+#endif
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pp_scheduler_terminate(void)
+{
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ _mali_osk_lock_term(pp_scheduler_job_delete_lock);
+ _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete);
+#endif
+
+ _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+}
+
+void mali_pp_scheduler_populate(void)
+{
+ struct mali_group *group;
+ struct mali_pp_core *pp_core;
+ u32 num_groups;
+ u32 i;
+
+ num_groups = mali_group_get_glob_num_groups();
+
+ /* Do we have a virtual group? */
+ for (i = 0; i < num_groups; i++)
+ {
+ group = mali_group_get_glob_group(i);
+
+ if (mali_group_is_virtual(group))
+ {
+ MALI_DEBUG_PRINT(3, ("Found virtual group %p\n", group));
+
+ virtual_group = group;
+ break;
+ }
+ }
+
+ /* Find all the available PP cores */
+ for (i = 0; i < num_groups; i++)
+ {
+ group = mali_group_get_glob_group(i);
+ pp_core = mali_group_get_pp_core(group);
+
+ if (NULL != pp_core && !mali_group_is_virtual(group))
+ {
+ if (0 == pp_version)
+ {
+ /* Retrieve PP version from the first available PP core */
+ pp_version = mali_pp_core_get_version(pp_core);
+ }
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ /* Add all physical PP cores to the virtual group */
+ mali_group_lock(virtual_group);
+ group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
+ mali_group_add_group(virtual_group, group, MALI_TRUE);
+ mali_group_unlock(virtual_group);
+ }
+ else
+ {
+ _mali_osk_list_add(&group->pp_scheduler_list, &group_list_idle);
+ }
+
+ num_cores++;
+ }
+ }
+ enabled_cores = num_cores;
+}
+
+void mali_pp_scheduler_depopulate(void)
+{
+ struct mali_group *group, *temp;
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_WORKING != virtual_group_state);
+
+ /* Delete all groups owned by scheduler */
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_delete(virtual_group);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ mali_group_delete(group);
+ }
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_disabled, struct mali_group, pp_scheduler_list)
+ {
+ mali_group_delete(group);
+ }
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_lock(void)
+{
+ if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
+ {
+ /* Non-interruptable lock failed: this should never happen. */
+ MALI_DEBUG_ASSERT(0);
+ }
+ MALI_DEBUG_PRINT(5, ("Mali PP scheduler: PP scheduler lock taken\n"));
+ MALI_DEBUG_ASSERT(0 == pp_scheduler_lock_owner);
+ MALI_DEBUG_CODE(pp_scheduler_lock_owner = _mali_osk_get_tid());
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_unlock(void)
+{
+ MALI_DEBUG_PRINT(5, ("Mali PP scheduler: Releasing PP scheduler lock\n"));
+ MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
+ MALI_DEBUG_CODE(pp_scheduler_lock_owner = 0);
+ _mali_osk_lock_signal(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_disable_empty_virtual(void)
+{
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+
+ if (mali_group_virtual_disable_if_empty(virtual_group))
+ {
+ MALI_DEBUG_PRINT(4, ("Disabling empty virtual group\n"));
+
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_IDLE == virtual_group_state);
+
+ virtual_group_state = VIRTUAL_GROUP_DISABLED;
+ }
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_enable_empty_virtual(void)
+{
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+
+ if (mali_group_virtual_enable_if_empty(virtual_group))
+ {
+ MALI_DEBUG_PRINT(4, ("Re-enabling empty virtual group\n"));
+
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_DISABLED == virtual_group_state);
+
+ virtual_group_state = VIRTUAL_GROUP_IDLE;
+ }
+}
+
+#ifdef DEBUG
+MALI_STATIC_INLINE void mali_pp_scheduler_assert_locked(void)
+{
+ MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
+}
+#define MALI_ASSERT_PP_SCHEDULER_LOCKED() mali_pp_scheduler_assert_locked()
+#else
+#define MALI_ASSERT_PP_SCHEDULER_LOCKED()
+#endif
+
+/**
+ * Returns a physical job if a physical job is ready to run (no barrier present)
+ */
+MALI_STATIC_INLINE struct mali_pp_job *mali_pp_scheduler_get_physical_job(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+
+ if (!_mali_osk_list_empty(&job_queue))
+ {
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT(job_queue_depth > 0);
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
+
+ if (!mali_pp_job_has_active_barrier(job))
+ {
+ return job;
+ }
+ }
+
+ return NULL;
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_dequeue_physical_job(struct mali_pp_job *job)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT(job_queue_depth > 0);
+
+ /* Remove job from queue */
+ if (!mali_pp_job_has_unstarted_sub_jobs(job))
+ {
+ /* All sub jobs have been started: remove job from queue */
+ _mali_osk_list_delinit(&job->list);
+ }
+
+ --job_queue_depth;
+}
+
+/**
+ * Returns a virtual job if a virtual job is ready to run (no barrier present)
+ */
+MALI_STATIC_INLINE struct mali_pp_job *mali_pp_scheduler_get_virtual_job(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT_POINTER(virtual_group);
+
+ if (!_mali_osk_list_empty(&virtual_job_queue))
+ {
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT(virtual_job_queue_depth > 0);
+ job = _MALI_OSK_LIST_ENTRY(virtual_job_queue.next, struct mali_pp_job, list);
+
+ if (!mali_pp_job_has_active_barrier(job))
+ {
+ return job;
+ }
+ }
+
+ return NULL;
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_dequeue_virtual_job(struct mali_pp_job *job)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT(virtual_job_queue_depth > 0);
+
+ /* Remove job from queue */
+ _mali_osk_list_delinit(&job->list);
+ --virtual_job_queue_depth;
+}
+
+/**
+ * Checks if the criteria is met for removing a physical core from virtual group
+ */
+MALI_STATIC_INLINE mali_bool mali_pp_scheduler_can_move_virtual_to_physical(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT(mali_pp_scheduler_has_virtual_group());
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+ /*
+ * The criteria for taking out a physical group from a virtual group are the following:
+ * - There virtual group is idle
+ * - There are currently no physical groups (idle and working)
+ * - There are physical jobs to be scheduled (without a barrier)
+ */
+ return (VIRTUAL_GROUP_IDLE == virtual_group_state) &&
+ _mali_osk_list_empty(&group_list_idle) &&
+ _mali_osk_list_empty(&group_list_working) &&
+ (NULL != mali_pp_scheduler_get_physical_job());
+}
+
+MALI_STATIC_INLINE struct mali_group *mali_pp_scheduler_acquire_physical_group(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+
+ if (!_mali_osk_list_empty(&group_list_idle))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquiring physical group from idle list\n"));
+ return _MALI_OSK_LIST_ENTRY(group_list_idle.next, struct mali_group, pp_scheduler_list);
+ }
+ else if (mali_pp_scheduler_has_virtual_group())
+ {
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+ if (mali_pp_scheduler_can_move_virtual_to_physical())
+ {
+ struct mali_group *group;
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquiring physical group from virtual group\n"));
+ group = mali_group_acquire_group(virtual_group);
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_pp_scheduler_disable_empty_virtual();
+ }
+
+ return group;
+ }
+ }
+
+ return NULL;
+}
+
+static void mali_pp_scheduler_schedule(void)
+{
+ struct mali_group* physical_groups_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
+ struct mali_pp_job* physical_jobs_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
+ u32 physical_subjobs_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
+ int num_physical_jobs_to_start = 0;
+ int i;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ /* Need to lock the virtual group because we might need to grab a physical group from it */
+ mali_group_lock(virtual_group);
+ }
+
+ mali_pp_scheduler_lock();
+ if (pause_count > 0)
+ {
+ /* Scheduler is suspended, don't schedule any jobs */
+ mali_pp_scheduler_unlock();
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_unlock(virtual_group);
+ }
+ return;
+ }
+
+ /* Find physical job(s) to schedule first */
+ while (1)
+ {
+ struct mali_group *group;
+ struct mali_pp_job *job;
+ u32 subjob;
+
+ job = mali_pp_scheduler_get_physical_job();
+ if (NULL == job)
+ {
+ break; /* No job, early out */
+ }
+
+ MALI_DEBUG_ASSERT(!mali_pp_job_is_virtual(job));
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+ MALI_DEBUG_ASSERT(1 <= mali_pp_job_get_sub_job_count(job));
+
+ /* Acquire a physical group, either from the idle list or from the virtual group.
+ * In case the group was acquired from the virtual group, it's state will be
+ * LEAVING_VIRTUAL and must be set to IDLE before it can be used. */
+ group = mali_pp_scheduler_acquire_physical_group();
+ if (NULL == group)
+ {
+ /* Could not get a group to run the job on, early out */
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: No more physical groups available.\n"));
+ break;
+ }
+
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquired physical group %p\n", group));
+
+ /* Mark subjob as started */
+ subjob = mali_pp_job_get_first_unstarted_sub_job(job);
+ mali_pp_job_mark_sub_job_started(job, subjob);
+
+ /* Remove job from queue (if we now got the last subjob) */
+ mali_pp_scheduler_dequeue_physical_job(job);
+
+ /* Move group to working list */
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_working);
+
+ /* Keep track of this group, so that we actually can start the job once we are done with the scheduler lock we are now holding */
+ physical_groups_to_start[num_physical_jobs_to_start] = group;
+ physical_jobs_to_start[num_physical_jobs_to_start] = job;
+ physical_subjobs_to_start[num_physical_jobs_to_start] = subjob;
+ ++num_physical_jobs_to_start;
+
+ MALI_DEBUG_ASSERT(num_physical_jobs_to_start < MALI_MAX_NUMBER_OF_PP_GROUPS);
+ }
+
+ /* See if we have a virtual job to schedule */
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ if (VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ struct mali_pp_job *job = mali_pp_scheduler_get_virtual_job();
+ if (NULL != job)
+ {
+ MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+ MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
+
+ /* Mark the one and only subjob as started */
+ mali_pp_job_mark_sub_job_started(job, 0);
+
+ /* Remove job from queue */
+ mali_pp_scheduler_dequeue_virtual_job(job);
+
+ /* Virtual group is now working */
+ virtual_group_state = VIRTUAL_GROUP_WORKING;
+
+ /*
+ * We no longer need the scheduler lock,
+ * but we still need the virtual lock in order to start the virtual job
+ */
+ mali_pp_scheduler_unlock();
+
+ /* Start job */
+ mali_group_start_pp_job(virtual_group, job, 0);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Virtual job %u (0x%08X) part %u/%u started (from schedule)\n",
+ mali_pp_job_get_id(job), job, 1,
+ mali_pp_job_get_sub_job_count(job)));
+
+ /* And now we are all done with the virtual_group lock as well */
+ mali_group_unlock(virtual_group);
+ }
+ else
+ {
+ /* No virtual job, release the two locks we are holding */
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(virtual_group);
+ }
+ }
+ else
+ {
+ /* Virtual core busy, release the two locks we are holding */
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(virtual_group);
+ }
+
+ }
+ else
+ {
+ /* There is no virtual group, release the only lock we are holding */
+ mali_pp_scheduler_unlock();
+ }
+
+ /*
+ * Now we have released the scheduler lock, and we are ready to kick of the actual starting of the
+ * physical jobs.
+ * The reason we want to wait until we have released the scheduler lock is that job start actually
+ * may take quite a bit of time (quite many registers needs to be written). This will allow new jobs
+ * from user space to come in, and post processing of other PP jobs to happen at the same time as we
+ * start jobs.
+ */
+ for (i = 0; i < num_physical_jobs_to_start; i++)
+ {
+ struct mali_group *group = physical_groups_to_start[i];
+ struct mali_pp_job *job = physical_jobs_to_start[i];
+ u32 sub_job = physical_subjobs_to_start[i];
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+ mali_group_lock(group);
+
+ /* In case this group was acquired from a virtual core, update it's state to IDLE */
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ mali_group_start_pp_job(group, job, sub_job);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from schedule)\n",
+ mali_pp_job_get_id(job), job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(job)));
+
+ mali_group_unlock(group);
+
+ /* remove the return value from mali_group_start_xx_job, since we can't fail on Mali-300++ */
+ }
+}
+
+static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job, mali_bool deferred)
+{
+ if (MALI_FALSE == mali_pp_job_use_no_notification(job))
+ {
+ u32 i;
+ u32 num_counters_to_copy;
+ mali_bool success = mali_pp_job_was_success(job);
+
+ _mali_uk_pp_job_finished_s *jobres = job->finished_notification->result_buffer;
+ _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
+ jobres->user_job_ptr = mali_pp_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;
+ }
+
+ if (mali_pp_job_is_virtual(job))
+ {
+ num_counters_to_copy = num_cores; /* Number of physical cores available */
+ }
+ else
+ {
+ num_counters_to_copy = mali_pp_job_get_sub_job_count(job);
+ }
+
+ for (i = 0; i < num_counters_to_copy; i++)
+ {
+ jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i);
+ jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i);
+ }
+
+ mali_session_send_notification(mali_pp_job_get_session(job), job->finished_notification);
+ job->finished_notification = NULL;
+ }
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ if (MALI_TRUE == deferred)
+ {
+ /* The deletion of the job object (releasing sync refs etc) must be done in a different context */
+ _mali_osk_lock_wait(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&job->list)); /* This job object should not be on any list */
+ _mali_osk_list_addtail(&job->list, &pp_scheduler_job_deletion_queue);
+
+ _mali_osk_lock_signal(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_wq_schedule_work(pp_scheduler_wq_job_delete);
+ }
+ else
+ {
+ mali_pp_job_delete(job);
+ }
+#else
+ MALI_DEBUG_ASSERT(MALI_FALSE == deferred); /* no use cases need this in this configuration */
+ mali_pp_job_delete(job);
+#endif
+}
+
+static void mali_pp_scheduler_do_schedule(void *arg)
+{
+ MALI_IGNORE(arg);
+
+ mali_pp_scheduler_schedule();
+}
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+static void mali_pp_scheduler_do_job_delete(void *arg)
+{
+ _MALI_OSK_LIST_HEAD_STATIC_INIT(list);
+ struct mali_pp_job *job;
+ struct mali_pp_job *tmp;
+
+ MALI_IGNORE(arg);
+
+ _mali_osk_lock_wait(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /*
+ * Quickly "unhook" the jobs pending to be deleted, so we can release the lock before
+ * we start deleting the job objects (without any locks held
+ */
+ _mali_osk_list_move_list(&pp_scheduler_job_deletion_queue, &list);
+
+ _mali_osk_lock_signal(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &list, struct mali_pp_job, list)
+ {
+ mali_pp_job_delete(job); /* delete the job object itself */
+ }
+}
+#endif
+
+void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
+{
+ mali_bool job_is_done;
+ mali_bool barrier_enforced = MALI_FALSE;
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: %s job %u (0x%08X) part %u/%u completed (%s)\n",
+ mali_pp_job_is_virtual(job) ? "Virtual" : "Physical",
+ mali_pp_job_get_id(job),
+ job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(job),
+ success ? "success" : "failure"));
+ MALI_ASSERT_GROUP_LOCKED(group);
+ mali_pp_scheduler_lock();
+
+ mali_pp_job_mark_sub_job_completed(job, success);
+
+ MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job) == mali_group_is_virtual(group));
+
+ job_is_done = mali_pp_job_is_complete(job);
+
+ if (job_is_done)
+ {
+ struct mali_session_data *session = mali_pp_job_get_session(job);
+ struct mali_pp_job *job_head;
+
+ /* Remove job from session list */
+ _mali_osk_list_del(&job->session_list);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for %s job %u (0x%08X)\n",
+ mali_pp_job_is_virtual(job) ? "virtual" : "physical",
+ mali_pp_job_get_id(job), job));
+#if defined(CONFIG_SYNC)
+ if (job->sync_point)
+ {
+ int error;
+ if (success) error = 0;
+ else error = -EFAULT;
+ MALI_DEBUG_PRINT(4, ("Sync: Signal %spoint for job %d\n",
+ success ? "" : "failed ",
+ mali_pp_job_get_id(job)));
+ mali_sync_signal_pt(job->sync_point, error);
+ }
+#endif
+
+ /* Send notification back to user space */
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ mali_pp_scheduler_return_job_to_user(job, MALI_TRUE);
+#else
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE);
+#endif
+
+ mali_pp_scheduler_job_completed();
+
+ /* Resolve any barriers */
+ if (!_mali_osk_list_empty(&session->job_list))
+ {
+ job_head = _MALI_OSK_LIST_ENTRY(session->job_list.next, struct mali_pp_job, session_list);
+ if (mali_pp_job_has_active_barrier(job_head))
+ {
+ barrier_enforced = MALI_TRUE;
+ mali_pp_job_barrier_enforced(job_head);
+ }
+ }
+ }
+
+ /* If paused, then this was the last job, so wake up sleeping workers */
+ if (pause_count > 0)
+ {
+ /* Wake up sleeping workers. Their wake-up condition is that
+ * num_slots == num_slots_idle, so unless we are done working, no
+ * threads will actually be woken up.
+ */
+ if (mali_group_is_virtual(group))
+ {
+ virtual_group_state = VIRTUAL_GROUP_IDLE;
+ }
+ else
+ {
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
+ }
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_pp_get_hw_core_desc(group->pp_core), sched_clock(), 0, 0, 0);
+#endif
+ _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
+ mali_pp_scheduler_unlock();
+ return;
+ }
+
+ if (barrier_enforced)
+ {
+ /* A barrier was resolved, so schedule previously blocked jobs */
+ _mali_osk_wq_schedule_work(pp_scheduler_wq_schedule);
+ }
+
+ /* Recycle variables */
+ job = NULL;
+ sub_job = 0;
+
+ if (mali_group_is_virtual(group))
+ {
+ /* Virtual group */
+
+ /* Now that the virtual group is idle, check if we should reconfigure */
+ struct mali_pp_job *physical_job = NULL;
+ struct mali_group *physical_group = NULL;
+
+ /* Obey the policy */
+ virtual_group_state = VIRTUAL_GROUP_IDLE;
+
+ if (mali_pp_scheduler_can_move_virtual_to_physical())
+ {
+ /* There is a runnable physical job and we can acquire a physical group */
+ physical_job = mali_pp_scheduler_get_physical_job();
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(physical_job));
+
+ /* Mark subjob as started */
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(physical_job);
+ mali_pp_job_mark_sub_job_started(physical_job, sub_job);
+
+ /* Remove job from queue (if we now got the last subjob) */
+ mali_pp_scheduler_dequeue_physical_job(physical_job);
+
+ /* Acquire a physical group from the virtual group
+ * It's state will be LEAVING_VIRTUAL and must be set to IDLE before it can be used */
+ physical_group = mali_group_acquire_group(virtual_group);
+
+ /* Move physical group to the working list, as we will soon start a job on it */
+ _mali_osk_list_move(&(physical_group->pp_scheduler_list), &group_list_working);
+
+ mali_pp_scheduler_disable_empty_virtual();
+ }
+
+ /* Start the next virtual job */
+ job = mali_pp_scheduler_get_virtual_job();
+ if (NULL != job && VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ /* There is a runnable virtual job */
+ MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+ MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
+
+ mali_pp_job_mark_sub_job_started(job, 0);
+
+ /* Remove job from queue */
+ mali_pp_scheduler_dequeue_virtual_job(job);
+
+ /* Virtual group is now working */
+ virtual_group_state = VIRTUAL_GROUP_WORKING;
+
+ mali_pp_scheduler_unlock();
+
+ /* Start job */
+ mali_group_start_pp_job(group, job, 0);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Virtual job %u (0x%08X) part %u/%u started (from job_done)\n",
+ mali_pp_job_get_id(job), job, 1,
+ mali_pp_job_get_sub_job_count(job)));
+ }
+ else
+ {
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch("Mali_Virtual_PP", sched_clock(), 0, 0, 0);
+#endif
+ mali_pp_scheduler_unlock();
+ }
+
+ /* Start a physical job (if we acquired a physical group earlier) */
+ if (NULL != physical_job && NULL != physical_group)
+ {
+ mali_group_lock(physical_group);
+
+ /* Set the group state from LEAVING_VIRTUAL to IDLE to complete the transition */
+ physical_group->state = MALI_GROUP_STATE_IDLE;
+
+ /* Start job on core */
+ mali_group_start_pp_job(physical_group, physical_job, sub_job);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from job_done)\n",
+ mali_pp_job_get_id(physical_job), physical_job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(physical_job)));
+
+ mali_group_unlock(physical_group);
+ }
+ }
+ else
+ {
+ /* Physical group */
+ job = mali_pp_scheduler_get_physical_job();
+ if (NULL != job)
+ {
+ /* There is a runnable physical job */
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+
+ /* Mark subjob as started */
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
+ mali_pp_job_mark_sub_job_started(job, sub_job);
+
+ /* Remove job from queue (if we now got the last subjob) */
+ mali_pp_scheduler_dequeue_physical_job(job);
+
+ mali_pp_scheduler_unlock();
+
+ /* Group is already on the working list, so start the job */
+ mali_group_start_pp_job(group, job, sub_job);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from job_done)\n",
+ mali_pp_job_get_id(job), job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(job)));
+ }
+ else if (mali_pp_scheduler_has_virtual_group())
+ {
+ /* Rejoin virtual group */
+ /* In the future, a policy check might be useful here */
+
+ /* We're no longer needed on the scheduler list */
+ _mali_osk_list_delinit(&(group->pp_scheduler_list));
+
+ /* Make sure no interrupts are handled for this group during
+ * the transition from physical to virtual */
+ group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
+
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+
+ mali_group_lock(virtual_group);
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_pp_scheduler_enable_empty_virtual();
+ }
+
+ /* We need to recheck the group state since it is possible that someone has
+ * modified the group before we locked the virtual group. */
+ if (MALI_GROUP_STATE_JOINING_VIRTUAL == group->state)
+ {
+ mali_group_add_group(virtual_group, group, MALI_TRUE);
+ }
+
+ mali_group_unlock(virtual_group);
+
+ if (mali_pp_scheduler_has_virtual_group() && VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ _mali_osk_wq_schedule_work(pp_scheduler_wq_schedule);
+ }
+
+ /* We need to return from this function with the group lock held */
+ mali_group_lock(group);
+ }
+ else
+ {
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_pp_get_hw_core_desc(group->pp_core), sched_clock(), 0, 0, 0);
+#endif
+ mali_pp_scheduler_unlock();
+ }
+ }
+}
+
+void mali_pp_scheduler_suspend(void)
+{
+ mali_pp_scheduler_lock();
+ pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
+ mali_pp_scheduler_unlock();
+
+ /* Go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
+ * mali_pp_scheduler_suspended() function will be called. This will return true
+ * iff state is idle and pause_count > 0, so if the core is active this
+ * will not do anything.
+ */
+ _mali_osk_wait_queue_wait_event(pp_scheduler_working_wait_queue, mali_pp_scheduler_is_suspended);
+}
+
+void mali_pp_scheduler_resume(void)
+{
+ mali_pp_scheduler_lock();
+ pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
+ mali_pp_scheduler_unlock();
+ if (0 == pause_count)
+ {
+ mali_pp_scheduler_schedule();
+ }
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_queue_job(struct mali_pp_job *job, struct mali_session_data *session)
+{
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_job_enqueue(mali_pp_job_get_tid(job), mali_pp_job_get_id(job), "PP");
+#endif
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* Map buffers attached to job */
+ if (0 != job->num_memory_cookies)
+ {
+ mali_dma_buf_map_job(job);
+ }
+#endif /* CONFIG_DMA_SHARED_BUFFER */
+
+ mali_pp_scheduler_job_queued();
+
+ mali_pp_scheduler_lock();
+
+ if (mali_pp_job_is_virtual(job))
+ {
+ /* Virtual job */
+ virtual_job_queue_depth += 1;
+ _mali_osk_list_addtail(&job->list, &virtual_job_queue);
+ }
+ else
+ {
+ job_queue_depth += mali_pp_job_get_sub_job_count(job);
+ _mali_osk_list_addtail(&job->list, &job_queue);
+ }
+
+ if (mali_pp_job_has_active_barrier(job) && _mali_osk_list_empty(&session->job_list))
+ {
+ /* No running jobs on this session, so barrier condition already met */
+ mali_pp_job_barrier_enforced(job);
+ }
+
+ /* Add job to session list */
+ _mali_osk_list_addtail(&job->session_list, &session->job_list);
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: %s job %u (0x%08X) with %u parts queued\n",
+ mali_pp_job_is_virtual(job) ? "Virtual" : "Physical",
+ mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
+
+ mali_pp_scheduler_unlock();
+}
+
+#if defined(CONFIG_SYNC)
+static void sync_callback(struct sync_fence *fence, struct sync_fence_waiter *waiter)
+{
+ struct mali_pp_job *job = _MALI_OSK_CONTAINER_OF(waiter, struct mali_pp_job, sync_waiter);
+
+ /* Schedule sync_callback_work */
+ _mali_osk_wq_schedule_work(job->sync_work);
+}
+
+static void sync_callback_work(void *arg)
+{
+ struct mali_pp_job *job = (struct mali_pp_job *)arg;
+ struct mali_session_data *session;
+ int err;
+
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+ session = job->session;
+
+ /* Remove job from session pending job list */
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_delinit(&job->list);
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+
+ err = sync_fence_wait(job->pre_fence, 0);
+ if (likely(0 == err))
+ {
+ MALI_DEBUG_PRINT(3, ("Mali sync: Job %d ready to run\n", mali_pp_job_get_id(job)));
+
+ mali_pp_scheduler_queue_job(job, session);
+
+ mali_pp_scheduler_schedule();
+ }
+ else
+ {
+ /* Fence signaled error */
+ MALI_DEBUG_PRINT(3, ("Mali sync: Job %d abort due to sync error\n", mali_pp_job_get_id(job)));
+
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, err);
+
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ }
+}
+#endif
+
+_mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *uargs, int *fence)
+{
+ struct mali_session_data *session;
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT_POINTER(uargs);
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+
+ session = (struct mali_session_data*)ctx;
+
+ job = mali_pp_job_create(session, uargs, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ MALI_PRINT_ERROR(("Failed to create job!\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_pp_job_check(job))
+ {
+ /* Not a valid job, return to user immediately */
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+#if PROFILING_SKIP_PP_JOBS || PROFILING_SKIP_PP_AND_GP_JOBS
+#warning PP jobs will not be executed
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE);
+ return _MALI_OSK_ERR_OK;
+#endif
+
+#if defined(CONFIG_SYNC)
+ if (_MALI_PP_JOB_FLAG_FENCE & job->uargs.flags)
+ {
+ int post_fence = -1;
+
+ job->sync_point = mali_stream_create_point(job->uargs.stream);
+
+ if (unlikely(NULL == job->sync_point))
+ {
+ /* Fence creation failed. */
+ MALI_DEBUG_PRINT(2, ("Failed to create sync point for job %d\n", mali_pp_job_get_id(job)));
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ post_fence = mali_stream_create_fence(job->sync_point);
+
+ if (unlikely(0 > post_fence))
+ {
+ /* Fence creation failed. */
+ /* mali_stream_create_fence already freed the sync_point */
+ MALI_DEBUG_PRINT(2, ("Failed to create fence for job %d\n", mali_pp_job_get_id(job)));
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ /* Grab a reference to the fence. It must be around when the
+ * job is completed, so the point can be signalled. */
+ sync_fence_fdget(post_fence);
+
+ *fence = post_fence;
+
+ MALI_DEBUG_PRINT(3, ("Sync: Created fence %d for job %d\n", post_fence, mali_pp_job_get_id(job)));
+ }
+ else if (_MALI_PP_JOB_FLAG_EMPTY_FENCE & job->uargs.flags)
+ {
+ int empty_fence_fd = job->uargs.stream;
+ struct sync_fence *empty_fence;
+ struct sync_pt *pt;
+ int ret;
+
+ /* Grab and keep a reference to the fence. It must be around
+ * when the job is completed, so the point can be signalled. */
+ empty_fence = sync_fence_fdget(empty_fence_fd);
+
+ if (unlikely(NULL == empty_fence))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to accept empty fence: %d\n", empty_fence_fd));
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK;
+ }
+
+ if (unlikely(list_empty(&empty_fence->pt_list_head)))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to accept empty fence: %d\n", empty_fence_fd));
+ sync_fence_put(empty_fence);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK;
+ }
+
+ pt = list_first_entry(&empty_fence->pt_list_head, struct sync_pt, pt_list);
+
+ ret = mali_sync_timed_commit(pt);
+
+ if (unlikely(0 != ret))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Empty fence not valid: %d\n", empty_fence_fd));
+ sync_fence_put(empty_fence);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK;
+ }
+
+ job->sync_point = pt;
+
+ *fence = empty_fence_fd;
+
+ MALI_DEBUG_PRINT(3, ("Sync: Job %d now backs fence %d\n", mali_pp_job_get_id(job), empty_fence_fd));
+ }
+
+ if (0 < job->uargs.fence)
+ {
+ int pre_fence_fd = job->uargs.fence;
+ int err;
+
+ MALI_DEBUG_PRINT(3, ("Sync: Job %d waiting for fence %d\n", mali_pp_job_get_id(job), pre_fence_fd));
+
+ job->pre_fence = sync_fence_fdget(pre_fence_fd); /* Reference will be released when job is deleted. */
+ if (NULL == job->pre_fence)
+ {
+ MALI_DEBUG_PRINT(2, ("Failed to import fence %d\n", pre_fence_fd));
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, -EINVAL);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ job->sync_work = _mali_osk_wq_create_work(sync_callback_work, (void*)job);
+ if (NULL == job->sync_work)
+ {
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, -ENOMEM);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ /* Add pending job to session pending job list */
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_addtail(&job->list, &session->pending_jobs);
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+
+ sync_fence_waiter_init(&job->sync_waiter, sync_callback);
+ err = sync_fence_wait_async(job->pre_fence, &job->sync_waiter);
+
+ if (0 != err)
+ {
+ /* No async wait started, remove job from session pending job list */
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_delinit(&job->list);
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+
+ if (1 == err)
+ {
+ /* Fence has already signalled */
+ mali_pp_scheduler_queue_job(job, session);
+ if (!_mali_osk_list_empty(&group_list_idle) || VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ mali_pp_scheduler_schedule();
+ }
+ return _MALI_OSK_ERR_OK;
+ }
+ else if (0 > err)
+ {
+ /* Sync fail */
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, err);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ }
+ else
+#endif /* CONFIG_SYNC */
+ {
+ mali_pp_scheduler_queue_job(job, session);
+
+ if (!_mali_osk_list_empty(&group_list_idle) || VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ mali_pp_scheduler_schedule();
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores(_mali_uk_get_pp_number_of_cores_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+ args->number_of_total_cores = num_cores;
+ args->number_of_enabled_cores = enabled_cores;
+ return _MALI_OSK_ERR_OK;
+}
+
+u32 mali_pp_scheduler_get_num_cores_total(void)
+{
+ return num_cores;
+}
+
+u32 mali_pp_scheduler_get_num_cores_enabled(void)
+{
+ return enabled_cores;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_pp_core_version(_mali_uk_get_pp_core_version_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+ args->version = pp_version;
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
+{
+ struct mali_session_data *session;
+ struct mali_pp_job *job;
+ struct mali_pp_job *tmp;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+
+ session = (struct mali_session_data*)args->ctx;
+
+ /* Check queue for jobs that match */
+ mali_pp_scheduler_lock();
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list)
+ {
+ if (mali_pp_job_get_session(job) == session &&
+ mali_pp_job_get_frame_builder_id(job) == (u32)args->fb_id &&
+ mali_pp_job_get_flush_id(job) == (u32)args->flush_id)
+ {
+ if (args->wbx & _MALI_UK_PP_JOB_WB0)
+ {
+ mali_pp_job_disable_wb0(job);
+ }
+ if (args->wbx & _MALI_UK_PP_JOB_WB1)
+ {
+ mali_pp_job_disable_wb1(job);
+ }
+ if (args->wbx & _MALI_UK_PP_JOB_WB2)
+ {
+ mali_pp_job_disable_wb2(job);
+ }
+ break;
+ }
+ }
+ mali_pp_scheduler_unlock();
+}
+
+void mali_pp_scheduler_abort_session(struct mali_session_data *session)
+{
+ struct mali_pp_job *job, *tmp_job;
+ struct mali_group *group, *tmp_group;
+ struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
+ s32 i = 0;
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ _MALI_OSK_LIST_HEAD_STATIC_INIT(deferred_deletion_list);
+#endif
+
+ mali_pp_scheduler_lock();
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Aborting all jobs from session 0x%08x\n", session));
+
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp_job, &session->job_list, struct mali_pp_job, session_list)
+ {
+ /* Remove job from queue (if it's not queued, list_del has no effect) */
+ _mali_osk_list_delinit(&job->list);
+
+ if (mali_pp_job_is_virtual(job))
+ {
+ MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
+ if (0 == mali_pp_job_get_first_unstarted_sub_job(job))
+ {
+ --virtual_job_queue_depth;
+ }
+ }
+ else
+ {
+ job_queue_depth -= mali_pp_job_get_sub_job_count(job) - mali_pp_job_get_first_unstarted_sub_job(job);
+ }
+
+ /* Mark all unstarted jobs as failed */
+ mali_pp_job_mark_unstarted_failed(job);
+
+ if (mali_pp_job_is_complete(job))
+ {
+ _mali_osk_list_del(&job->session_list);
+
+ /* It is safe to delete the job, since it won't land in job_done() */
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborted PP job 0x%08x\n", job));
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&job->list));
+ _mali_osk_list_addtail(&job->list, &deferred_deletion_list);
+#else
+ mali_pp_job_delete(job);
+#endif
+
+ mali_pp_scheduler_job_completed();
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in session\n", job));
+ }
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_working, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+
+ mali_pp_scheduler_unlock();
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp_job, &deferred_deletion_list, struct mali_pp_job, list)
+ {
+ mali_pp_job_delete(job);
+ }
+#endif
+
+ /* Abort running jobs from this session */
+ while (i > 0)
+ {
+ mali_group_abort_session(groups[--i], session);
+ }
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_abort_session(virtual_group, session);
+ }
+}
+
+static mali_bool mali_pp_scheduler_is_suspended(void)
+{
+ mali_bool ret;
+
+ mali_pp_scheduler_lock();
+
+ ret = pause_count > 0
+ && _mali_osk_list_empty(&group_list_working)
+ && VIRTUAL_GROUP_WORKING != virtual_group_state;
+
+ mali_pp_scheduler_unlock();
+
+ return ret;
+}
+
+int mali_pp_scheduler_get_queue_depth(void)
+{
+ return job_queue_depth;
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
+{
+ int n = 0;
+ struct mali_group *group;
+ struct mali_group *temp;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "PP:\n");
+ n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_working, struct mali_group, pp_scheduler_list)
+ {
+ n += mali_group_dump_state(group, buf + n, size - n);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ n += mali_group_dump_state(group, buf + n, size - n);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_disabled, struct mali_group, pp_scheduler_list)
+ {
+ n += mali_group_dump_state(group, buf + n, size - n);
+ }
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ n += mali_group_dump_state(virtual_group, buf + n, size -n);
+ }
+
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+ return n;
+}
+#endif
+
+/* This function is intended for power on reset of all cores.
+ * No locking is done for the list iteration, which can only be safe if the
+ * scheduler is paused and all cores idle. That is always the case on init and
+ * power on. */
+void mali_pp_scheduler_reset_all_groups(void)
+{
+ struct mali_group *group, *temp;
+ struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
+ s32 i = 0;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_lock(virtual_group);
+ mali_group_reset(virtual_group);
+ mali_group_unlock(virtual_group);
+ }
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_WORKING != virtual_group_state);
+ mali_pp_scheduler_lock();
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+ mali_pp_scheduler_unlock();
+
+ while (i > 0)
+ {
+ group = groups[--i];
+
+ mali_group_lock(group);
+ mali_group_reset(group);
+ mali_group_unlock(group);
+ }
+}
+
+void mali_pp_scheduler_zap_all_active(struct mali_session_data *session)
+{
+ struct mali_group *group, *temp;
+ struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
+ s32 i = 0;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_zap_session(virtual_group, session);
+ }
+
+ mali_pp_scheduler_lock();
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_working, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+ mali_pp_scheduler_unlock();
+
+ while (i > 0)
+ {
+ mali_group_zap_session(groups[--i], session);
+ }
+}
+
+/* A pm reference must be taken with _mali_osk_pm_dev_ref_add_no_power_on
+ * before calling this function to avoid Mali powering down as HW is accessed.
+ */
+static void mali_pp_scheduler_enable_group_internal(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ mali_group_lock(group);
+
+ if (MALI_GROUP_STATE_DISABLED != group->state)
+ {
+ mali_group_unlock(group);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: PP group %p already enabled\n", group));
+ return;
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Enabling PP group %p\n", group));
+
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+ ++enabled_cores;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_bool update_hw;
+
+ /* Add group to virtual group */
+ _mali_osk_list_delinit(&(group->pp_scheduler_list));
+ group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
+
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+
+ mali_group_lock(virtual_group);
+
+ update_hw = mali_pm_is_power_on();
+
+ mali_pm_domain_ref_get(group->pm_domain);
+ MALI_DEBUG_ASSERT(NULL == group->pm_domain ||
+ MALI_PM_DOMAIN_ON == mali_pm_domain_state_get(group->pm_domain));
+
+ if (update_hw)
+ {
+ mali_group_lock(group);
+ mali_group_power_on_group(group);
+ mali_group_reset(group);
+ mali_group_unlock(group);
+ }
+
+ mali_pp_scheduler_enable_empty_virtual();
+ mali_group_add_group(virtual_group, group, update_hw);
+ MALI_DEBUG_PRINT(4, ("Done enabling group %p. Added to virtual group.\n", group));
+
+ mali_group_unlock(virtual_group);
+ }
+ else
+ {
+ mali_pm_domain_ref_get(group->pm_domain);
+ MALI_DEBUG_ASSERT(NULL == group->pm_domain ||
+ MALI_PM_DOMAIN_ON == mali_pm_domain_state_get(group->pm_domain));
+
+ /* Put group on idle list */
+ if (mali_pm_is_power_on())
+ {
+ mali_group_power_on_group(group);
+ mali_group_reset(group);
+ }
+
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ MALI_DEBUG_PRINT(4, ("Done enabling group %p. Now on idle list.\n", group));
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+ }
+}
+
+void mali_pp_scheduler_enable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+
+ mali_pp_scheduler_enable_group_internal(group);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ /* Pick up any jobs that might have been queued if all PP groups were disabled. */
+ mali_pp_scheduler_schedule();
+}
+
+static void mali_pp_scheduler_disable_group_internal(struct mali_group *group)
+{
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_lock(virtual_group);
+
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_WORKING != virtual_group_state);
+ if (MALI_GROUP_STATE_JOINING_VIRTUAL == group->state)
+ {
+ /* The group was in the process of being added to the virtual group. We
+ * only need to change the state to reverse this. */
+ group->state = MALI_GROUP_STATE_LEAVING_VIRTUAL;
+ }
+ else if (MALI_GROUP_STATE_IN_VIRTUAL == group->state)
+ {
+ /* Remove group from virtual group. The state of the group will be
+ * LEAVING_VIRTUAL and the group will not be on any scheduler list. */
+ mali_group_remove_group(virtual_group, group);
+
+ mali_pp_scheduler_disable_empty_virtual();
+ }
+
+ mali_group_unlock(virtual_group);
+ }
+
+ mali_group_lock(group);
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: PP group %p already disabled\n", group));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Disabling PP group %p\n", group));
+
+ --enabled_cores;
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_disabled);
+ group->state = MALI_GROUP_STATE_DISABLED;
+
+ mali_group_power_off_group(group);
+ mali_pm_domain_ref_put(group->pm_domain);
+ }
+
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+}
+
+void mali_pp_scheduler_disable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ mali_pp_scheduler_suspend();
+ _mali_osk_pm_dev_ref_add_no_power_on();
+
+ mali_pp_scheduler_disable_group_internal(group);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pp_scheduler_resume();
+}
+
+
+static void mali_pp_scheduler_notify_core_change(u32 num_cores)
+{
+ if (!mali_is_mali450())
+ {
+ /* Notify all user space sessions about the change, so number of master tile lists can be adapter */
+ struct mali_session_data *session, *tmp;
+
+ mali_session_lock();
+ MALI_SESSION_FOREACH(session, tmp, link)
+ {
+ _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_NUM_CORE_CHANGE, sizeof(_mali_uk_pp_num_cores_changed_s));
+ if (NULL != notobj)
+ {
+ _mali_uk_pp_num_cores_changed_s *data = notobj->result_buffer;
+ data->number_of_enabled_cores = num_cores;
+ mali_session_send_notification(session, notobj);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to notify user space session about num PP core change\n"));
+ }
+ }
+ mali_session_unlock();
+ }
+}
+
+static void mali_pp_scheduler_set_perf_level_mali400(u32 target_core_nr)
+{
+ struct mali_group *group;
+ MALI_DEBUG_ASSERT(mali_is_mali400());
+
+ if (target_core_nr > enabled_cores)
+ {
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: enabling %d cores\n", target_core_nr, target_core_nr - enabled_cores));
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ _mali_osk_pm_dev_barrier();
+
+ while (target_core_nr > enabled_cores)
+ {
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&group_list_disabled));
+
+ group = _MALI_OSK_LIST_ENTRY(group_list_disabled.next, struct mali_group, pp_scheduler_list);
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+
+ mali_pp_scheduler_unlock();
+
+ mali_pp_scheduler_enable_group_internal(group);
+ }
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ mali_pp_scheduler_schedule();
+ }
+ else if (target_core_nr < enabled_cores)
+ {
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: disabling %d cores\n", target_core_nr, enabled_cores - target_core_nr));
+
+ mali_pp_scheduler_suspend();
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+
+ while (target_core_nr < enabled_cores)
+ {
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&group_list_idle));
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+
+ group = _MALI_OSK_LIST_ENTRY(group_list_idle.next, struct mali_group, pp_scheduler_list);
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ mali_pp_scheduler_unlock();
+
+ mali_pp_scheduler_disable_group_internal(group);
+ }
+
+ mali_pp_scheduler_resume();
+ }
+
+ mali_pp_scheduler_notify_core_change(target_core_nr);
+}
+
+static void mali_pp_scheduler_set_perf_level_mali450(u32 target_core_nr)
+{
+ struct mali_group *group;
+ MALI_DEBUG_ASSERT(mali_is_mali450());
+
+ if (target_core_nr > enabled_cores)
+ {
+ /* Enable some cores */
+ struct mali_pm_domain *domain;
+
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: enabling %d cores\n", target_core_nr, target_core_nr - enabled_cores));
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ _mali_osk_pm_dev_barrier();
+
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM2);
+
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_enable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+
+ if (target_core_nr > enabled_cores)
+ {
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM3);
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_enable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+ }
+
+ MALI_DEBUG_ASSERT(target_core_nr == enabled_cores);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ mali_pp_scheduler_schedule();
+ }
+ else if (target_core_nr < enabled_cores)
+ {
+ /* Disable some cores */
+ struct mali_pm_domain *domain;
+
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: disabling %d cores\n", target_core_nr, enabled_cores - target_core_nr));
+
+ mali_pp_scheduler_suspend();
+
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM3);
+ if (NULL != domain)
+ {
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_disable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+ }
+
+ if (target_core_nr < enabled_cores)
+ {
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM2);
+ MALI_DEBUG_ASSERT_POINTER(domain);
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_disable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+ }
+
+ MALI_DEBUG_ASSERT(target_core_nr == enabled_cores);
+
+ mali_pp_scheduler_resume();
+ }
+}
+
+int mali_pp_scheduler_set_perf_level(unsigned int cores)
+{
+ if (cores == enabled_cores) return 0;
+ if (cores > num_cores) return -EINVAL;
+ if (0 == cores) return -EINVAL;
+
+ if (!mali_pp_scheduler_has_virtual_group())
+ {
+ /* Mali-400 */
+ mali_pp_scheduler_set_perf_level_mali400(cores);
+ }
+ else
+ {
+ /* Mali-450 */
+ mali_pp_scheduler_set_perf_level_mali450(cores);
+ }
+
+ return 0;
+}
+
+static void mali_pp_scheduler_job_queued(void)
+{
+ /* We hold a PM reference for every job we hold queued (and running) */
+ _mali_osk_pm_dev_ref_add();
+
+ if (mali_utilization_enabled())
+ {
+ /*
+ * We cheat a little bit by counting the PP as busy from the time a PP job is queued.
+ * This will be fine because we only loose the tiny idle gap between jobs, but
+ * we will instead get less utilization work to do (less locks taken)
+ */
+ mali_utilization_pp_start();
+ }
+}
+
+static void mali_pp_scheduler_job_completed(void)
+{
+ /* Release the PM reference we got in the mali_pp_scheduler_job_queued() function */
+ _mali_osk_pm_dev_ref_dec();
+
+ if (mali_utilization_enabled())
+ {
+ mali_utilization_pp_end();
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h
new file mode 100644
index 0000000..71ec042
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h
@@ -0,0 +1,80 @@
+/*
+ * 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_PP_SCHEDULER_H__
+#define __MALI_PP_SCHEDULER_H__
+
+#include "mali_osk.h"
+#include "mali_pp_job.h"
+#include "mali_group.h"
+#include "linux/mali/mali_utgard.h"
+
+/** Initalize the HW independent parts of the PP scheduler
+ */
+_mali_osk_errcode_t mali_pp_scheduler_initialize(void);
+void mali_pp_scheduler_terminate(void);
+
+/** Poplulate the PP scheduler with groups
+ */
+void mali_pp_scheduler_populate(void);
+void mali_pp_scheduler_depopulate(void);
+
+void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success);
+
+void mali_pp_scheduler_suspend(void);
+void mali_pp_scheduler_resume(void);
+
+/** @brief Abort all PP jobs from session running or queued
+ *
+ * This functions aborts all PP jobs from the specified session. Queued jobs are removed from the queue and jobs
+ * currently running on a core will be aborted.
+ *
+ * @param session Pointer to session whose jobs should be aborted
+ */
+void mali_pp_scheduler_abort_session(struct mali_session_data *session);
+
+/**
+ * @brief Reset all groups
+ *
+ * This function resets all groups known by the PP scheuduler. This must be
+ * called after the Mali HW has been powered on in order to reset the HW.
+ *
+ * This function is intended for power on reset of all cores.
+ * No locking is done, which can only be safe if the scheduler is paused and
+ * all cores idle. That is always the case on init and power on.
+ */
+void mali_pp_scheduler_reset_all_groups(void);
+
+/**
+ * @brief Zap TLB on all groups with \a session active
+ *
+ * The scheculer will zap the session on all groups it owns.
+ */
+void mali_pp_scheduler_zap_all_active(struct mali_session_data *session);
+
+int mali_pp_scheduler_get_queue_depth(void);
+u32 mali_pp_scheduler_dump_state(char *buf, u32 size);
+
+void mali_pp_scheduler_enable_group(struct mali_group *group);
+void mali_pp_scheduler_disable_group(struct mali_group *group);
+
+int mali_pp_scheduler_set_perf_level(u32 cores);
+
+u32 mali_pp_scheduler_get_num_cores_total(void);
+u32 mali_pp_scheduler_get_num_cores_enabled(void);
+
+/**
+ * @brief Returns the number of Pixel Processors in the system irrespective of the context
+ *
+ * @return number of physical Pixel Processor cores in the system
+ */
+u32 mali_pp_scheduler_get_num_cores_total(void);
+
+#endif /* __MALI_PP_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.c b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c
index f360209..f360209 100644
--- a/drivers/media/video/samsung/mali/common/mali_scheduler.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c
diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.h b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h
index 74f0947..63e5be8 100644
--- a/drivers/media/video/samsung/mali/common/mali_scheduler.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h
@@ -12,10 +12,36 @@
#define __MALI_SCHEDULER_H__
#include "mali_osk.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
_mali_osk_errcode_t mali_scheduler_initialize(void);
void mali_scheduler_terminate(void);
u32 mali_scheduler_get_new_id(void);
+/**
+ * @brief Reset all groups
+ *
+ * This function resets all groups known by the both the PP and GP scheuduler.
+ * This must be called after the Mali HW has been powered on in order to reset
+ * the HW.
+ */
+MALI_STATIC_INLINE void mali_scheduler_reset_all_groups(void)
+{
+ mali_gp_scheduler_reset_all_groups();
+ mali_pp_scheduler_reset_all_groups();
+}
+
+/**
+ * @brief Zap TLB on all active groups running \a session
+ *
+ * @param session Pointer to the session to zap
+ */
+MALI_STATIC_INLINE void mali_scheduler_zap_all_active(struct mali_session_data *session)
+{
+ mali_gp_scheduler_zap_all_active(session);
+ mali_pp_scheduler_zap_all_active(session);
+}
+
#endif /* __MALI_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_session.c b/drivers/gpu/mali400/r3p2/mali/common/mali_session.c
index 2394bb9..2394bb9 100644
--- a/drivers/media/video/samsung/mali/common/mali_session.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_session.c
diff --git a/drivers/media/video/samsung/mali/common/mali_session.h b/drivers/gpu/mali400/r3p2/mali/common/mali_session.h
index c8640b5..5c34dde 100644
--- a/drivers/media/video/samsung/mali/common/mali_session.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_session.h
@@ -20,6 +20,11 @@ struct mali_session_data
{
_mali_osk_notification_queue_t * ioctl_queue;
+#ifdef CONFIG_SYNC
+ _mali_osk_list_t pending_jobs;
+ _mali_osk_lock_t *pending_jobs_lock;
+#endif
+
_mali_osk_lock_t *memory_lock; /**< Lock protecting the vm manipulation */
mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
_mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */
@@ -27,6 +32,8 @@ struct mali_session_data
struct mali_page_directory *page_directory; /**< MMU page directory for this session */
_MALI_OSK_LIST_HEAD(link); /**< Link for list of all sessions */
+
+ _MALI_OSK_LIST_HEAD(job_list); /**< List of all jobs on this session */
};
_mali_osk_errcode_t mali_session_initialize(void);
diff --git a/drivers/media/video/samsung/mali/common/mali_ukk.h b/drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h
index 6b018d0..1f8a320 100644
--- a/drivers/media/video/samsung/mali/common/mali_ukk.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h
@@ -357,6 +357,12 @@ _mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu
*/
_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args );
+/** @brief Write user data to specified Mali memory without causing segfaults.
+ * @param args see _mali_uk_mem_write_safe_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_mem_write_safe( _mali_uk_mem_write_safe_s *args );
+
/** @brief Map a physically contiguous range of memory into Mali
* @param args see _mali_uk_map_external_mem_s in mali_utgard_uk_types.h
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
@@ -369,7 +375,7 @@ _mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *arg
*/
_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args );
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#if defined(CONFIG_MALI400_UMP)
/** @brief Map UMP memory into Mali
* @param args see _mali_uk_attach_ump_mem_s in mali_utgard_uk_types.h
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
@@ -380,7 +386,7 @@ _mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args );
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
*/
_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args );
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */
+#endif /* CONFIG_MALI400_UMP */
/** @brief Determine virtual-to-physical mapping of a contiguous memory range
* (optional)
@@ -449,10 +455,11 @@ _mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args );
*
* Job completion can be awaited with _mali_ukk_wait_for_notification().
*
- * @param args see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h"
+ * @oaram ctx user-kernel context (mali_session)
+ * @param uargs see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
*/
-_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args );
+_mali_osk_errcode_t _mali_ukk_pp_start_job( void *ctx, _mali_uk_pp_start_job_s *uargs, int *fence );
/** @brief Returns the number of Fragment Processors in the system
*
@@ -502,10 +509,11 @@ void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args);
*
* Job completion can be awaited with _mali_ukk_wait_for_notification().
*
- * @param args see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h"
+ * @oaram ctx user-kernel context (mali_session)
+ * @param uargs see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
* @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
*/
-_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args );
+_mali_osk_errcode_t _mali_ukk_gp_start_job( void *ctx, _mali_uk_gp_start_job_s *uargs );
/** @brief Returns the number of Vertex Processors in the system.
*
@@ -536,7 +544,7 @@ _mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_
/** @} */ /* end group _mali_uk_gp */
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_PROFILING)
/** @addtogroup _mali_uk_profiling U/K Timeline profiling module
* @{ */
@@ -605,6 +613,12 @@ _mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *
u32 _mali_ukk_report_memory_usage(void);
+u32 _mali_ukk_utilization_gp_pp(void);
+
+u32 _mali_ukk_utilization_gp(void);
+
+u32 _mali_ukk_utilization_pp(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c
index d3f1e50..8720b9a 100644
--- a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c
@@ -38,7 +38,11 @@ void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value)
{
mali_bool notify = MALI_FALSE;
- MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0);
+ if (setting >= _MALI_UK_USER_SETTING_MAX || setting < 0)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Invalid user setting %ud\n"));
+ return;
+ }
if (mali_user_settings[setting] != value)
{
@@ -55,7 +59,10 @@ void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value)
u32 mali_get_user_setting(_mali_uk_user_setting_t setting)
{
- MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0);
+ if (setting >= _MALI_UK_USER_SETTING_MAX || setting < 0)
+ {
+ return 0;
+ }
return mali_user_settings[setting];
}
diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h
index fbb9415..fbb9415 100644
--- a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h
new file mode 100644
index 0000000..cf3374a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h
@@ -0,0 +1,390 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file mali_utgard.h
+ * Defines types and interface exposed by the Mali Utgard device driver
+ */
+
+#ifndef __MALI_UTGARD_H__
+#define __MALI_UTGARD_H__
+
+#define MALI_GPU_NAME_UTGARD "mali-utgard"
+
+/* Mali-200 */
+
+#define MALI_GPU_RESOURCES_MALI200(base_addr, gp_irq, pp_irq, mmu_irq) \
+ MALI_GPU_RESOURCE_PP(base_addr + 0x0000, pp_irq) \
+ MALI_GPU_RESOURCE_GP(base_addr + 0x2000, gp_irq) \
+ MALI_GPU_RESOURCE_MMU(base_addr + 0x3000, mmu_irq)
+
+/* Mali-300 */
+
+#define MALI_GPU_RESOURCES_MALI300(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI300_PMU(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP1_PMU(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq)
+
+/* Mali-400 */
+
+#define MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP1_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+#define MALI_GPU_RESOURCES_MALI400_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP2_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+#define MALI_GPU_RESOURCES_MALI400_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0xC000, pp2_irq, base_addr + 0x6000, pp2_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP3_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+#define MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0xC000, pp2_irq, base_addr + 0x6000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0xE000, pp3_irq, base_addr + 0x7000, pp3_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP4_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+/* Mali-450 */
+#define MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP2_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP3_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x0E000, pp3_irq, base_addr + 0x07000, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP4_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP6(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x11000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x28000, pp3_irq, base_addr + 0x1C000, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(4, base_addr + 0x2A000, pp4_irq, base_addr + 0x1D000, pp4_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(5, base_addr + 0x2C000, pp5_irq, base_addr + 0x1E000, pp5_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP6_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP6(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP8(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x0E000, pp3_irq, base_addr + 0x07000, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x11000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(4, base_addr + 0x28000, pp4_irq, base_addr + 0x1C000, pp4_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(5, base_addr + 0x2A000, pp5_irq, base_addr + 0x1D000, pp5_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(6, base_addr + 0x2C000, pp6_irq, base_addr + 0x1E000, pp6_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(7, base_addr + 0x2E000, pp7_irq, base_addr + 0x1F000, pp7_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP8_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP8(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCE_L2(addr) \
+ { \
+ .name = "Mali_L2", \
+ .flags = IORESOURCE_MEM, \
+ .start = addr, \
+ .end = addr + 0x200, \
+ },
+
+#define MALI_GPU_RESOURCE_GP(gp_addr, gp_irq) \
+ { \
+ .name = "Mali_GP", \
+ .flags = IORESOURCE_MEM, \
+ .start = gp_addr, \
+ .end = gp_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_GP_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = gp_irq, \
+ .end = gp_irq, \
+ }, \
+
+#define MALI_GPU_RESOURCE_GP_WITH_MMU(gp_addr, gp_irq, gp_mmu_addr, gp_mmu_irq) \
+ { \
+ .name = "Mali_GP", \
+ .flags = IORESOURCE_MEM, \
+ .start = gp_addr, \
+ .end = gp_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_GP_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = gp_irq, \
+ .end = gp_irq, \
+ }, \
+ { \
+ .name = "Mali_GP_MMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = gp_mmu_addr, \
+ .end = gp_mmu_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_GP_MMU_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = gp_mmu_irq, \
+ .end = gp_mmu_irq, \
+ },
+
+#define MALI_GPU_RESOURCE_PP(pp_addr, pp_irq) \
+ { \
+ .name = "Mali_PP", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_addr, \
+ .end = pp_addr + 0x1100, \
+ }, \
+ { \
+ .name = "Mali_PP_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_irq, \
+ .end = pp_irq, \
+ }, \
+
+#define MALI_GPU_RESOURCE_PP_WITH_MMU(id, pp_addr, pp_irq, pp_mmu_addr, pp_mmu_irq) \
+ { \
+ .name = "Mali_PP" #id, \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_addr, \
+ .end = pp_addr + 0x1100, \
+ }, \
+ { \
+ .name = "Mali_PP" #id "_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_irq, \
+ .end = pp_irq, \
+ }, \
+ { \
+ .name = "Mali_PP" #id "_MMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_mmu_addr, \
+ .end = pp_mmu_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_PP" #id "_MMU_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_mmu_irq, \
+ .end = pp_mmu_irq, \
+ },
+
+#define MALI_GPU_RESOURCE_MMU(mmu_addr, mmu_irq) \
+ { \
+ .name = "Mali_MMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = mmu_addr, \
+ .end = mmu_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_MMU_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = mmu_irq, \
+ .end = mmu_irq, \
+ },
+
+#define MALI_GPU_RESOURCE_PMU(pmu_addr) \
+ { \
+ .name = "Mali_PMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = pmu_addr, \
+ .end = pmu_addr + 0x100, \
+ },
+
+#define MALI_GPU_RESOURCE_DLBU(dlbu_addr) \
+ { \
+ .name = "Mali_DLBU", \
+ .flags = IORESOURCE_MEM, \
+ .start = dlbu_addr, \
+ .end = dlbu_addr + 0x100, \
+ },
+
+#define MALI_GPU_RESOURCE_BCAST(bcast_addr) \
+ { \
+ .name = "Mali_Broadcast", \
+ .flags = IORESOURCE_MEM, \
+ .start = bcast_addr, \
+ .end = bcast_addr + 0x100, \
+ },
+
+#define MALI_GPU_RESOURCE_PP_BCAST(pp_addr, pp_irq) \
+ { \
+ .name = "Mali_PP_Broadcast", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_addr, \
+ .end = pp_addr + 0x1100, \
+ }, \
+ { \
+ .name = "Mali_PP_Broadcast_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_irq, \
+ .end = pp_irq, \
+ }, \
+
+#define MALI_GPU_RESOURCE_PP_MMU_BCAST(pp_mmu_bcast_addr) \
+ { \
+ .name = "Mali_PP_MMU_Broadcast", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_mmu_bcast_addr, \
+ .end = pp_mmu_bcast_addr + 0x100, \
+ },
+
+struct mali_gpu_utilization_data
+{
+ unsigned int utilization_gpu; /* Utilization for GP and all PP cores combined, 0 = no utilization, 256 = full utilization */
+ unsigned int utilization_gp; /* Utilization for GP core only, 0 = no utilization, 256 = full utilization */
+ unsigned int utilization_pp; /* Utilization for all PP cores combined, 0 = no utilization, 256 = full utilization */
+};
+
+struct mali_gpu_device_data
+{
+ /* Dedicated GPU memory range (physical). */
+ unsigned long dedicated_mem_start;
+ unsigned long dedicated_mem_size;
+
+ /* Shared GPU memory */
+ unsigned long shared_mem_size;
+
+ /* Frame buffer memory to be accessible by Mali GPU (physical) */
+ unsigned long fb_start;
+ unsigned long fb_size;
+
+ /* Report GPU utilization in this interval (specified in ms) */
+ unsigned long utilization_interval;
+
+ /* Function that will receive periodic GPU utilization numbers */
+ void (*utilization_callback)(struct mali_gpu_utilization_data *data);
+
+ /*
+ * Mali PMU switch delay.
+ * Only needed if the power gates are connected to the PMU in a high fanout
+ * network. This value is the number of Mali clock cycles it takes to
+ * enable the power gates and turn on the power mesh.
+ * This value will have no effect if a daisy chain implementation is used.
+ */
+ unsigned long pmu_switch_delay;
+};
+
+/** @brief MALI GPU power down using MALI in-built PMU
+ *
+ * called to power down all cores
+ */
+int mali_pmu_powerdown(void);
+
+
+/** @brief MALI GPU power up using MALI in-built PMU
+ *
+ * called to power up all cores
+ */
+int mali_pmu_powerup(void);
+
+/**
+ * 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.
+ */
+void mali_dev_pause(void);
+
+/**
+ * Resume scheduling and allow power changes in Mali device driver.
+ * This must always be called after mali_dev_pause().
+ */
+void mali_dev_resume(void);
+
+/** @brief Set the desired number of PP cores to use.
+ *
+ * The internal Mali PMU will be used, if present, to physically power off the PP cores.
+ *
+ * @param num_cores The number of desired cores
+ * @return 0 on success, otherwise error. -EINVAL means an invalid number of cores was specified.
+ */
+int mali_perf_set_num_pp_cores(unsigned int num_cores);
+
+#endif
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h
index 40822f7..3ef9a28 100644
--- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h
@@ -212,7 +212,7 @@ typedef enum
MALI_CINSTR_PP_RSW_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 15,
MALI_CINSTR_PP_VERTEX_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 16,
MALI_CINSTR_PP_UNIFORM_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 17,
- MALI_CINSTR_PP_PROGRAM_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19,
+ MALI_CINSTR_PP_PROGRAM_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 18,
MALI_CINSTR_PP_VARYING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19,
MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 20,
MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 21,
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h
index 7935448..6043a7d 100644
--- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h
@@ -44,6 +44,9 @@ extern "C"
#define MALI_IOC_POST_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *)
#define MALI_IOC_GET_USER_SETTING _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTING, _mali_uk_get_user_setting_s *)
#define MALI_IOC_GET_USER_SETTINGS _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTINGS, _mali_uk_get_user_settings_s *)
+#define MALI_IOC_STREAM_CREATE _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_STREAM_CREATE, _mali_uk_stream_create_s *)
+#define MALI_IOC_FENCE_CREATE_EMPTY _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_FENCE_CREATE_EMPTY, _mali_uk_fence_create_empty_s *)
+#define MALI_IOC_FENCE_VALIDATE _IOR(MALI_IOC_CORE_BASE, _MALI_UK_FENCE_VALIDATE, _mali_uk_fence_validate_s *)
#define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, void *)
#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, void *)
@@ -58,6 +61,7 @@ extern "C"
#define MALI_IOC_MEM_RELEASE_UMP _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s *)
#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s *)
#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s *)
+#define MALI_IOC_MEM_WRITE_SAFE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MEM_WRITE_SAFE, _mali_uk_mem_write_safe_s *)
#define MALI_IOC_PP_START_JOB _IOWR(MALI_IOC_PP_BASE, _MALI_UK_PP_START_JOB, _mali_uk_pp_start_job_s *)
#define MALI_IOC_PP_NUMBER_OF_CORES_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_NUMBER_OF_CORES, _mali_uk_get_pp_number_of_cores_s *)
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h
index b96596e..99864b8 100644
--- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h
@@ -66,20 +66,38 @@ typedef enum
MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_GP_ENQUEUE = 5,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_PP_ENQUEUE = 6,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_READBACK = 7,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_WRITEBACK = 8,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_ENTER_API_FUNC = 10,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC = 11,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_DISCARD_ATTACHMENTS = 13,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_TRY_LOCK = 53,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK = 54,
MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK = 55,
+ MALI_PROFILING_EVENT_REASON_SINGLE_LOCK_CONTENDED = 56,
} cinstr_profiling_event_reason_single_sw_t;
/**
* These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
+ * to inform whether the core is physical or virtual
*/
typedef enum
{
- MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0,
- MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1,
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL = 0,
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL = 1,
+} cinstr_profiling_event_reason_start_stop_hw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
+ */
+typedef enum
+{
+ /*MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0,*/
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_MALI = 1,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_CALLBACK_THREAD = 2,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_WORKER_THREAD = 3,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF = 4,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF = 5,
} cinstr_profiling_event_reason_start_stop_sw_t;
/**
@@ -87,7 +105,7 @@ typedef enum
*/
typedef enum
{
- MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, /* NOT used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, /* used */
MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1, /* NOT used */
MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26, /* used in some build configurations */
MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT = 27, /* USED */
@@ -103,6 +121,8 @@ typedef enum
MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_GLOBAL_LOCK = 37, /* Not currently used */
MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_SWAP = 38, /* Not currently used */
MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_MALI_EGL_IMAGE_SYNC_WAIT = 39, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GP_JOB_HANDLING =40, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PP_JOB_HANDLING =41, /* USED */
} cinstr_profiling_event_reason_suspend_resume_sw_t;
/**
@@ -122,6 +142,31 @@ typedef enum
{
MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0,
MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS = 2,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS = 3,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS = 4,
} cinstr_profiling_event_reason_single_gpu_t;
+/**
+ * These values are applicable for the 3rd data parameter when
+ * the type MALI_PROFILING_EVENT_TYPE_START is used from the software channel
+ * with the MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF reason.
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_DATA_CORE_GP0 = 1,
+ MALI_PROFILING_EVENT_DATA_CORE_PP0 = 5,
+ MALI_PROFILING_EVENT_DATA_CORE_PP1 = 6,
+ MALI_PROFILING_EVENT_DATA_CORE_PP2 = 7,
+ MALI_PROFILING_EVENT_DATA_CORE_PP3 = 8,
+ MALI_PROFILING_EVENT_DATA_CORE_PP4 = 9,
+ MALI_PROFILING_EVENT_DATA_CORE_PP5 = 10,
+ MALI_PROFILING_EVENT_DATA_CORE_PP6 = 11,
+ MALI_PROFILING_EVENT_DATA_CORE_PP7 = 12,
+} cinstr_profiling_event_data_core_t;
+
+#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(num) (MALI_PROFILING_EVENT_DATA_CORE_GP0 + (num))
+#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(num) (MALI_PROFILING_EVENT_DATA_CORE_PP0 + (num))
+
+
#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h
new file mode 100644
index 0000000..c449215
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h
@@ -0,0 +1,202 @@
+/*
+ * 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_UTGARD_PROFILING_GATOR_API_H__
+#define __MALI_UTGARD_PROFILING_GATOR_API_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MALI_PROFILING_API_VERSION 4
+
+#define MAX_NUM_L2_CACHE_CORES 3
+#define MAX_NUM_FP_CORES 8
+#define MAX_NUM_VP_CORES 1
+
+/** The list of events supported by the Mali DDK. */
+typedef enum
+{
+ /* Vertex processor activity */
+ ACTIVITY_VP_0 = 0,
+
+ /* Fragment processor activity */
+ ACTIVITY_FP_0,
+ ACTIVITY_FP_1,
+ ACTIVITY_FP_2,
+ ACTIVITY_FP_3,
+ ACTIVITY_FP_4,
+ ACTIVITY_FP_5,
+ ACTIVITY_FP_6,
+ ACTIVITY_FP_7,
+
+ /* L2 cache counters */
+ COUNTER_L2_0_C0,
+ COUNTER_L2_0_C1,
+ COUNTER_L2_1_C0,
+ COUNTER_L2_1_C1,
+ COUNTER_L2_2_C0,
+ COUNTER_L2_2_C1,
+
+ /* Vertex processor counters */
+ COUNTER_VP_0_C0,
+ COUNTER_VP_0_C1,
+
+ /* Fragment processor counters */
+ COUNTER_FP_0_C0,
+ COUNTER_FP_0_C1,
+ COUNTER_FP_1_C0,
+ COUNTER_FP_1_C1,
+ COUNTER_FP_2_C0,
+ COUNTER_FP_2_C1,
+ COUNTER_FP_3_C0,
+ COUNTER_FP_3_C1,
+ COUNTER_FP_4_C0,
+ COUNTER_FP_4_C1,
+ COUNTER_FP_5_C0,
+ COUNTER_FP_5_C1,
+ COUNTER_FP_6_C0,
+ COUNTER_FP_6_C1,
+ COUNTER_FP_7_C0,
+ COUNTER_FP_7_C1,
+
+ /*
+ * If more hardware counters are added, the _mali_osk_hw_counter_table
+ * below should also be updated.
+ */
+
+ /* EGL software counters */
+ COUNTER_EGL_BLIT_TIME,
+
+ /* GLES software counters */
+ COUNTER_GLES_DRAW_ELEMENTS_CALLS,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_ARRAYS_CALLS,
+ COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_POINTS,
+ COUNTER_GLES_DRAW_LINES,
+ COUNTER_GLES_DRAW_LINE_LOOP,
+ COUNTER_GLES_DRAW_LINE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLES,
+ COUNTER_GLES_DRAW_TRIANGLE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLE_FAN,
+ COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
+ COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
+ COUNTER_GLES_UPLOAD_TEXTURE_TIME,
+ COUNTER_GLES_UPLOAD_VBO_TIME,
+ COUNTER_GLES_NUM_FLUSHES,
+ COUNTER_GLES_NUM_VSHADERS_GENERATED,
+ COUNTER_GLES_NUM_FSHADERS_GENERATED,
+ COUNTER_GLES_VSHADER_GEN_TIME,
+ COUNTER_GLES_FSHADER_GEN_TIME,
+ COUNTER_GLES_INPUT_TRIANGLES,
+ COUNTER_GLES_VXCACHE_HIT,
+ COUNTER_GLES_VXCACHE_MISS,
+ COUNTER_GLES_VXCACHE_COLLISION,
+ COUNTER_GLES_CULLED_TRIANGLES,
+ COUNTER_GLES_CULLED_LINES,
+ COUNTER_GLES_BACKFACE_TRIANGLES,
+ COUNTER_GLES_GBCLIP_TRIANGLES,
+ COUNTER_GLES_GBCLIP_LINES,
+ COUNTER_GLES_TRIANGLES_DRAWN,
+ COUNTER_GLES_DRAWCALL_TIME,
+ COUNTER_GLES_TRIANGLES_COUNT,
+ COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
+ COUNTER_GLES_STRIP_TRIANGLES_COUNT,
+ COUNTER_GLES_FAN_TRIANGLES_COUNT,
+ COUNTER_GLES_LINES_COUNT,
+ COUNTER_GLES_INDEPENDENT_LINES_COUNT,
+ COUNTER_GLES_STRIP_LINES_COUNT,
+ COUNTER_GLES_LOOP_LINES_COUNT,
+
+ /* Framebuffer capture pseudo-counter */
+ COUNTER_FILMSTRIP,
+
+ NUMBER_OF_EVENTS
+} _mali_osk_counter_id;
+
+#define FIRST_ACTIVITY_EVENT ACTIVITY_VP_0
+#define LAST_ACTIVITY_EVENT ACTIVITY_FP_7
+
+#define FIRST_HW_COUNTER COUNTER_L2_0_C0
+#define LAST_HW_COUNTER COUNTER_FP_7_C1
+
+#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME
+#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT
+
+#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP
+#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP
+
+/**
+ * Structure to pass performance counter data of a Mali core
+ */
+typedef struct _mali_profiling_core_counters
+{
+ u32 source0;
+ u32 value0;
+ u32 source1;
+ u32 value1;
+} _mali_profiling_core_counters;
+
+/**
+ * Structure to pass performance counter data of Mali L2 cache cores
+ */
+typedef struct _mali_profiling_l2_counter_values
+{
+ struct _mali_profiling_core_counters cores[MAX_NUM_L2_CACHE_CORES];
+} _mali_profiling_l2_counter_values;
+
+/**
+ * Structure to pass data defining Mali instance in use:
+ *
+ * mali_product_id - Mali product id
+ * mali_version_major - Mali version major number
+ * mali_version_minor - Mali version minor number
+ * num_of_l2_cores - number of L2 cache cores
+ * num_of_fp_cores - number of fragment processor cores
+ * num_of_vp_cores - number of vertex processor cores
+ */
+typedef struct _mali_profiling_mali_version
+{
+ u32 mali_product_id;
+ u32 mali_version_major;
+ u32 mali_version_minor;
+ u32 num_of_l2_cores;
+ u32 num_of_fp_cores;
+ u32 num_of_vp_cores;
+} _mali_profiling_mali_version;
+
+/*
+ * List of possible actions to be controlled by Streamline.
+ * The following numbers are used by gator to control the frame buffer dumping and s/w counter reporting.
+ * We cannot use the enums in mali_uk_types.h because they are unknown inside gator.
+ */
+#define FBDUMP_CONTROL_ENABLE (1)
+#define FBDUMP_CONTROL_RATE (2)
+#define SW_COUNTER_ENABLE (3)
+#define FBDUMP_CONTROL_RESIZE_FACTOR (4)
+
+void _mali_profiling_control(u32 action, u32 value);
+
+u32 _mali_profiling_get_l2_counters(_mali_profiling_l2_counter_values *values);
+
+int _mali_profiling_set_event(u32 counter_id, s32 event_id);
+
+u32 _mali_profiling_get_api_version(void);
+
+void _mali_profiling_get_mali_version(struct _mali_profiling_mali_version *values);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_UTGARD_PROFILING_GATOR_API_H__ */
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h
index b35a715..4957095 100644
--- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h
@@ -68,6 +68,9 @@ typedef enum
_MALI_UK_POST_NOTIFICATION, /**< _mali_ukk_post_notification() */
_MALI_UK_GET_USER_SETTING, /**< _mali_ukk_get_user_setting() *//**< [out] */
_MALI_UK_GET_USER_SETTINGS, /**< _mali_ukk_get_user_settings() *//**< [out] */
+ _MALI_UK_STREAM_CREATE, /**< _mali_ukk_stream_create() */
+ _MALI_UK_FENCE_CREATE_EMPTY, /**< _mali_ukk_fence_create_empty() */
+ _MALI_UK_FENCE_VALIDATE, /**< _mali_ukk_fence_validate() */
/** Memory functions */
@@ -87,6 +90,7 @@ typedef enum
_MALI_UK_MAP_EXT_MEM, /**< _mali_uku_map_external_mem() */
_MALI_UK_UNMAP_EXT_MEM, /**< _mali_uku_unmap_external_mem() */
_MALI_UK_VA_TO_MALI_PA, /**< _mali_uku_va_to_mali_pa() */
+ _MALI_UK_MEM_WRITE_SAFE, /**< _mali_uku_mem_write_safe() */
/** Common functions for each core */
@@ -417,9 +421,13 @@ typedef struct
#define _MALI_PP_MAX_WB_REGISTERS ((0x02C/4)+1)
+#define _MALI_DLBU_MAX_REGISTERS 4
+
/** Flag for _mali_uk_pp_start_job_s */
#define _MALI_PP_JOB_FLAG_NO_NOTIFICATION (1<<0)
#define _MALI_PP_JOB_FLAG_BARRIER (1<<1)
+#define _MALI_PP_JOB_FLAG_FENCE (1<<2)
+#define _MALI_PP_JOB_FLAG_EMPTY_FENCE (1<<3)
/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job
* @{ */
@@ -476,6 +484,7 @@ typedef struct
u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS];
u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS];
u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS];
+ u32 dlbu_registers[_MALI_DLBU_MAX_REGISTERS]; /**< [in] Dynamic load balancing unit registers */
u32 num_cores; /**< [in] Number of cores to set up (valid range: 1-4) */
u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
@@ -483,6 +492,10 @@ typedef struct
u32 frame_builder_id; /**< [in] id of the originating frame builder */
u32 flush_id; /**< [in] flush id within the originating frame builder */
u32 flags; /**< [in] See _MALI_PP_JOB_FLAG_* for a list of avaiable flags */
+ s32 fence; /**< [in,out] Fence to wait on / fence that will be signalled on job completion, if _MALI_PP_JOB_FLAG_FENCE is set */
+ s32 stream; /**< [in] Steam identifier if _MALI_PP_JOB_FLAG_FENCE, an empty fence to use for this job if _MALI_PP_JOB_FLAG_EMPTY_FENCE is set */
+ u32 num_memory_cookies; /**< [in] number of memory cookies attached to job */
+ u32 *memory_cookies; /**< [in] memory cookies attached to job */
} _mali_uk_pp_start_job_s;
/** @} */ /* end group _mali_uk_ppstartjob_s */
@@ -494,6 +507,13 @@ typedef struct
u32 perf_counter1[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 1 (see ARM DDI0415A), one for each sub job */
} _mali_uk_pp_job_finished_s;
+typedef struct
+{
+ u32 number_of_enabled_cores; /**< [out] the new number of enabled cores */
+} _mali_uk_pp_num_cores_changed_s;
+
+
+
/**
* Flags to indicate write-back units
*/
@@ -543,6 +563,7 @@ typedef enum
/** Fragment Processor notifications */
_MALI_NOTIFICATION_PP_FINISHED = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10,
+ _MALI_NOTIFICATION_PP_NUM_CORE_CHANGE = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x20,
/** Vertex Processor notifications */
@@ -700,7 +721,7 @@ typedef struct
* The 16bit integer is stored twice in a 32bit integer
* For example, for version 1 the value would be 0x00010001
*/
-#define _MALI_API_VERSION 17
+#define _MALI_API_VERSION 23
#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
/**
@@ -869,6 +890,16 @@ typedef struct
u32 size; /**< [in,out] Size of the range, in bytes. */
} _mali_uk_va_to_mali_pa_s;
+/**
+ * @brief Arguments for _mali_uk[uk]_mem_write_safe()
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ const void *src; /**< [in] Pointer to source data */
+ void *dest; /**< [in] Destination Mali buffer */
+ u32 size; /**< [in,out] Number of bytes to write/copy on input, number of bytes actually written/copied on output */
+} _mali_uk_mem_write_safe_s;
typedef struct
{
@@ -901,8 +932,9 @@ typedef struct
*/
typedef struct
{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 number_of_cores; /**< [out] number of Fragment Processor cores in the system */
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 number_of_total_cores; /**< [out] Total number of Fragment Processor cores in the system */
+ u32 number_of_enabled_cores; /**< [out] Number of enabled Fragment Processor cores */
} _mali_uk_get_pp_number_of_cores_s;
/** @brief Arguments for _mali_ukk_get_pp_core_version()
@@ -1084,6 +1116,44 @@ typedef struct
/** @} */ /* end group _mali_uk_sw_counters_report */
+/** @defgroup _mali_uk_stream U/K Mali stream module
+ * @{ */
+
+/** @brief Create stream
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [out] file descriptor describing stream */
+} _mali_uk_stream_create_s;
+
+/** @brief Destroy stream
+*/
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [in] file descriptor describing stream */
+} _mali_uk_stream_destroy_s;
+
+/** @brief Create empty fence
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ s32 stream; /**< [in] stream to create fence on */
+ s32 fence; /**< [out] file descriptor describing fence */
+} _mali_uk_fence_create_empty_s;
+
+/** @brief Check fence validity
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [in] file descriptor describing fence */
+} _mali_uk_fence_validate_s;
+
+/** @} */ /* end group _mali_uk_stream */
+
/** @} */ /* end group u_k_api */
/** @} */ /* end group uddapi */
diff --git a/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h b/drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.h
index 52bb5e0..e9e5e55 100644
--- a/drivers/media/video/samsung/mali/linux/license/gpl/mali_kernel_license.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.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/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c
index 6af1279..0b82cba 100644
--- a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c
@@ -1,4 +1,4 @@
-/**
+/*
* 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
@@ -13,34 +13,23 @@
* Implementation of the Mali pause/resume functionality
*/
+#include <linux/module.h>
+#include <linux/mali/mali_utgard.h>
#include "mali_gp_scheduler.h"
#include "mali_pp_scheduler.h"
-#include "mali_pm.h"
-void mali_dev_pause(mali_bool *power_is_on)
+void mali_dev_pause(void)
{
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();
- }
}
+EXPORT_SYMBOL(mali_dev_pause);
+
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/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c
new file mode 100644
index 0000000..c34b2c6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c
@@ -0,0 +1,480 @@
+/*
+ * 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 <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+#include <linux/dma-buf.h>
+#include <linux/scatterlist.h>
+#include <linux/rbtree.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_kernel_linux.h"
+
+#include "mali_kernel_memory_engine.h"
+#include "mali_memory.h"
+#include "mali_dma_buf.h"
+
+
+struct mali_dma_buf_attachment {
+ struct dma_buf *buf;
+ struct dma_buf_attachment *attachment;
+ struct sg_table *sgt;
+ struct mali_session_data *session;
+ int map_ref;
+ struct mutex map_lock;
+ mali_bool is_mapped;
+ wait_queue_head_t wait_queue;
+};
+
+void mali_dma_buf_release(void *ctx, void *handle)
+{
+ struct mali_dma_buf_attachment *mem;
+
+ mem = (struct mali_dma_buf_attachment *)handle;
+
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release attachment %p\n", mem));
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT_POINTER(mem->attachment);
+ MALI_DEBUG_ASSERT_POINTER(mem->buf);
+
+#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* We mapped implicitly on attach, so we need to unmap on release */
+ mali_dma_buf_unmap(mem);
+#endif
+
+ /* Wait for buffer to become unmapped */
+ wait_event(mem->wait_queue, !mem->is_mapped);
+ MALI_DEBUG_ASSERT(!mem->is_mapped);
+
+ dma_buf_detach(mem->buf, mem->attachment);
+ dma_buf_put(mem->buf);
+
+ _mali_osk_free(mem);
+}
+
+/*
+ * Map DMA buf attachment \a mem into \a session at virtual address \a virt.
+ */
+int mali_dma_buf_map(struct mali_dma_buf_attachment *mem, struct mali_session_data *session, u32 virt, u32 *offset, u32 flags)
+{
+ struct mali_page_directory *pagedir;
+ struct scatterlist *sg;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT_POINTER(session);
+ MALI_DEBUG_ASSERT(mem->session == session);
+
+ mutex_lock(&mem->map_lock);
+
+ mem->map_ref++;
+
+ MALI_DEBUG_PRINT(5, ("Mali DMA-buf: map attachment %p, new map_ref = %d\n", mem, mem->map_ref));
+
+ if (1 == mem->map_ref)
+ {
+ /* First reference taken, so we need to map the dma buf */
+ MALI_DEBUG_ASSERT(!mem->is_mapped);
+
+ pagedir = mali_session_get_page_directory(session);
+ MALI_DEBUG_ASSERT_POINTER(pagedir);
+
+ mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL);
+ if (IS_ERR_OR_NULL(mem->sgt))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf attachment\n"));
+ return -EFAULT;
+ }
+
+ for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i)
+ {
+ u32 size = sg_dma_len(sg);
+ dma_addr_t phys = sg_dma_address(sg);
+
+ /* sg must be page aligned. */
+ MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
+
+ mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_CACHE_STANDARD);
+
+ virt += size;
+ *offset += size;
+ }
+
+ if (flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
+ {
+ u32 guard_phys;
+ MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n"));
+
+ guard_phys = sg_dma_address(mem->sgt->sgl);
+ mali_mmu_pagedir_update(pagedir, virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_CACHE_STANDARD);
+ }
+
+ mem->is_mapped = MALI_TRUE;
+ mutex_unlock(&mem->map_lock);
+
+ /* Wake up any thread waiting for buffer to become mapped */
+ wake_up_all(&mem->wait_queue);
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(mem->is_mapped);
+ mutex_unlock(&mem->map_lock);
+ }
+
+ return 0;
+}
+
+void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem)
+{
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT_POINTER(mem->attachment);
+ MALI_DEBUG_ASSERT_POINTER(mem->buf);
+
+ mutex_lock(&mem->map_lock);
+
+ mem->map_ref--;
+
+ MALI_DEBUG_PRINT(5, ("Mali DMA-buf: unmap attachment %p, new map_ref = %d\n", mem, mem->map_ref));
+
+ if (0 == mem->map_ref)
+ {
+ dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
+
+ mem->is_mapped = MALI_FALSE;
+ }
+
+ mutex_unlock(&mem->map_lock);
+
+ /* Wake up any thread waiting for buffer to become unmapped */
+ wake_up_all(&mem->wait_queue);
+}
+
+#if !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+int mali_dma_buf_map_job(struct mali_pp_job *job)
+{
+ mali_memory_allocation *descriptor;
+ struct mali_dma_buf_attachment *mem;
+ _mali_osk_errcode_t err;
+ int i;
+ u32 offset = 0;
+ int ret = 0;
+
+ _mali_osk_lock_wait( job->session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ for (i = 0; i < job->num_memory_cookies; i++)
+ {
+ int cookie = job->memory_cookies[i];
+
+ if (0 == cookie)
+ {
+ /* 0 is not a valid cookie */
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ MALI_DEBUG_ASSERT(0 < cookie);
+
+ err = mali_descriptor_mapping_get(job->session->descriptor_mapping,
+ cookie, (void**)&descriptor);
+
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to get descriptor for cookie %d\n", cookie));
+ ret = -EFAULT;
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ if (mali_dma_buf_release != descriptor->physical_allocation.release)
+ {
+ /* Not a DMA-buf */
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ mem = (struct mali_dma_buf_attachment *)descriptor->physical_allocation.handle;
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT(mem->session == job->session);
+
+ err = mali_dma_buf_map(mem, mem->session, descriptor->mali_address, &offset, descriptor->flags);
+ if (0 != err)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to map dma-buf for cookie %d at mali address %x\b",
+ cookie, descriptor->mali_address));
+ ret = -EFAULT;
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ /* Add mem to list of DMA-bufs mapped for this job */
+ job->dma_bufs[i] = mem;
+ }
+
+ _mali_osk_lock_signal( job->session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ return ret;
+}
+
+void mali_dma_buf_unmap_job(struct mali_pp_job *job)
+{
+ int i;
+ for (i = 0; i < job->num_dma_bufs; i++)
+ {
+ if (NULL == job->dma_bufs[i]) continue;
+
+ mali_dma_buf_unmap(job->dma_bufs[i]);
+ job->dma_bufs[i] = NULL;
+ }
+}
+#endif /* !CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH */
+
+/* Callback from memory engine which will map into Mali virtual address space */
+static mali_physical_memory_allocation_result mali_dma_buf_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
+{
+ struct mali_session_data *session;
+ struct mali_dma_buf_attachment *mem;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(offset);
+ MALI_DEBUG_ASSERT_POINTER(alloc_info);
+
+ /* Mapping dma-buf with an offset is not supported. */
+ MALI_DEBUG_ASSERT(0 == *offset);
+
+ session = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ mem = (struct mali_dma_buf_attachment *)ctx;
+
+ MALI_DEBUG_ASSERT(mem->session == session);
+
+#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ if (0 == mali_dma_buf_map(mem, session, descriptor->mali_address, offset, descriptor->flags))
+ {
+ MALI_DEBUG_ASSERT(*offset == descriptor->size);
+#else
+ {
+#endif
+ alloc_info->ctx = NULL;
+ alloc_info->handle = mem;
+ alloc_info->next = NULL;
+ alloc_info->release = mali_dma_buf_release;
+
+ return MALI_MEM_ALLOC_FINISHED;
+ }
+
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+}
+
+int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg)
+{
+ mali_physical_memory_allocator external_memory_allocator;
+ struct dma_buf *buf;
+ struct mali_dma_buf_attachment *mem;
+ _mali_uk_attach_dma_buf_s args;
+ mali_memory_allocation *descriptor;
+ int md;
+ int fd;
+
+ /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s)))
+ {
+ return -EFAULT;
+ }
+
+ fd = args.mem_fd;
+
+ buf = dma_buf_get(fd);
+ if (IS_ERR_OR_NULL(buf))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to get dma-buf from fd: %d\n", fd));
+ return PTR_RET(buf);
+ }
+
+ /* Currently, mapping of the full buffer are supported. */
+ if (args.size != buf->size)
+ {
+ MALI_DEBUG_PRINT_ERROR(("dma-buf size doesn't match mapping size.\n"));
+ dma_buf_put(buf);
+ return -EINVAL;
+ }
+
+ mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
+ if (NULL == mem)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n"));
+ dma_buf_put(buf);
+ return -ENOMEM;
+ }
+
+ mem->buf = buf;
+ mem->session = session;
+ mem->map_ref = 0;
+ mutex_init(&mem->map_lock);
+ init_waitqueue_head(&mem->wait_queue);
+
+ mem->attachment = dma_buf_attach(mem->buf, &mali_platform_device->dev);
+ if (NULL == mem->attachment)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to attach to dma-buf %d\n", fd));
+ dma_buf_put(mem->buf);
+ _mali_osk_free(mem);
+ return -EFAULT;
+ }
+
+ /* Map dma-buf into this session's page tables */
+
+ /* Set up Mali memory descriptor */
+ descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
+ if (NULL == descriptor)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd));
+ mali_dma_buf_release(NULL, mem);
+ return -ENOMEM;
+ }
+
+ descriptor->size = args.size;
+ descriptor->mapping = NULL;
+ descriptor->mali_address = args.mali_address;
+ descriptor->mali_addr_mapping_info = (void*)session;
+ descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
+ descriptor->lock = session->memory_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 );
+
+ /* Get descriptor mapping for memory. */
+ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd));
+ _mali_osk_free(descriptor);
+ mali_dma_buf_release(NULL, mem);
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_ASSERT(0 < md);
+
+ external_memory_allocator.allocate = mali_dma_buf_commit;
+ external_memory_allocator.allocate_page_table_block = NULL;
+ external_memory_allocator.ctx = mem;
+ external_memory_allocator.name = "DMA-BUF Memory";
+ external_memory_allocator.next = NULL;
+
+ /* Map memory into session's Mali virtual address space. */
+ _mali_osk_lock_wait(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(mali_mem_get_memory_engine(), descriptor, &external_memory_allocator, NULL))
+ {
+ _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd));
+ mali_descriptor_mapping_free(session->descriptor_mapping, md);
+ mali_dma_buf_release(NULL, mem);
+ return -ENOMEM;
+ }
+ _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* Return stuff to user space */
+ if (0 != put_user(md, &user_arg->cookie))
+ {
+ /* Roll back */
+ MALI_DEBUG_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd));
+ mali_descriptor_mapping_free(session->descriptor_mapping, md);
+ mali_dma_buf_release(NULL, mem);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg)
+{
+ int ret = 0;
+ _mali_uk_release_dma_buf_s args;
+ mali_memory_allocation *descriptor;
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s)) )
+ {
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release descriptor cookie %d\n", args.cookie));
+
+ _mali_osk_lock_wait( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args.cookie);
+
+ if (NULL != descriptor)
+ {
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: Releasing dma-buf at mali address %x\n", descriptor->mali_address));
+
+ /* Will call back to mali_dma_buf_release() which will release the dma-buf attachment. */
+ mali_allocation_engine_release_memory(mali_mem_get_memory_engine(), descriptor);
+
+ _mali_osk_free(descriptor);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT_ERROR(("Invalid memory descriptor %d used to release dma-buf\n", args.cookie));
+ ret = -EINVAL;
+ }
+
+ _mali_osk_lock_signal( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ /* Return the error that _mali_ukk_map_external_ump_mem produced */
+ return ret;
+}
+
+int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
+{
+ _mali_uk_dma_buf_get_size_s args;
+ int fd;
+ struct dma_buf *buf;
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s)) )
+ {
+ return -EFAULT;
+ }
+
+ /* Do DMA-BUF stuff */
+ fd = args.mem_fd;
+
+ buf = dma_buf_get(fd);
+ if (IS_ERR_OR_NULL(buf))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to get dma-buf from fd: %d\n", fd));
+ return PTR_RET(buf);
+ }
+
+ if (0 != put_user(buf->size, &user_arg->size))
+ {
+ dma_buf_put(buf);
+ return -EFAULT;
+ }
+
+ dma_buf_put(buf);
+
+ return 0;
+}
diff --git a/drivers/media/video/samsung/mali/linux/mali_dma_buf.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h
index ee9a0ed..1af3efc 100644
--- a/drivers/media/video/samsung/mali/linux/mali_dma_buf.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h
@@ -17,10 +17,21 @@ extern "C"
#endif
#include "mali_osk.h"
+#include "common/mali_pp_job.h"
+
+struct mali_dma_buf_attachment;
int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *arg);
int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *arg);
int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *arg);
+int mali_dma_buf_map(struct mali_dma_buf_attachment *mem, struct mali_session_data *session, u32 virt, u32 *offset, u32 flags);
+void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem);
+void mali_dma_buf_release(void *ctx, void *handle);
+
+#if !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+int mali_dma_buf_map_job(struct mali_pp_job *job);
+void mali_dma_buf_unmap_job(struct mali_pp_job *job);
+#endif
#ifdef __cplusplus
}
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c
index 233c0ca..f337d09 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c
@@ -17,6 +17,12 @@
#include <linux/cdev.h> /* character device definitions */
#include <linux/mm.h> /* memory manager definitions */
#include <linux/mali/mali_utgard_ioctl.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include "mali_kernel_license.h"
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/mali/mali_utgard.h>
#include "mali_kernel_common.h"
#include "mali_session.h"
#include "mali_kernel_core.h"
@@ -24,24 +30,27 @@
#include "mali_kernel_linux.h"
#include "mali_ukk.h"
#include "mali_ukk_wrappers.h"
-#include "mali_kernel_pm.h"
#include "mali_kernel_sysfs.h"
-#include "mali_platform.h"
+#include "mali_pm.h"
#include "mali_kernel_license.h"
#include "mali_dma_buf.h"
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+#include "mali_profiling_internal.h"
+#endif
+/* MALI_SEC */
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4210)
+#include "../platform/pegasus-m400/exynos4_pmm.h"
+#elif defined(CONFIG_SOC_EXYNOS3470)
+#include "../platform/exynos4270/exynos4_pmm.h"
+#endif
/* Streamline support for the Mali driver */
-#if defined(CONFIG_TRACEPOINTS) && MALI_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_MALI400_PROFILING)
/* Ask Linux to create the tracepoints */
#define CREATE_TRACE_POINTS
#include "mali_linux_trace.h"
#endif /* CONFIG_TRACEPOINTS */
-static _mali_osk_errcode_t initialize_kernel_device(void);
-static int initialize_sysfs(void);
-static void terminate_kernel_device(void);
-
-
/* from the __malidrv_build_info.c file that is generated during build */
extern const char *__malidrv_build_info(void);
@@ -50,18 +59,6 @@ int mali_debug_level = 2;
module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output");
-/* By default the module uses any available major, but it's possible to set it at load time to a specific number */
-#if MALI_MAJOR_PREDEFINE
-int mali_major = 244;
-#else
-int mali_major = 0;
-#endif
-module_param(mali_major, int, S_IRUGO); /* r--r--r-- */
-MODULE_PARM_DESC(mali_major, "Device major number");
-
-module_param(mali_hang_check_interval, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
-MODULE_PARM_DESC(mali_hang_check_interval, "Interval at which to check for progress after the hw watchdog has been triggered");
-
module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what");
@@ -69,120 +66,121 @@ extern int mali_l2_max_reads;
module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache");
-#if MALI_TIMELINE_PROFILING_ENABLED
+extern unsigned int mali_dedicated_mem_start;
+module_param(mali_dedicated_mem_start, uint, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_dedicated_mem_start, "Physical start address of dedicated Mali GPU memory.");
+
+extern unsigned int mali_dedicated_mem_size;
+module_param(mali_dedicated_mem_size, uint, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_dedicated_mem_size, "Size of dedicated Mali GPU memory.");
+
+extern unsigned int mali_shared_mem_size;
+module_param(mali_shared_mem_size, uint, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_shared_mem_size, "Size of shared Mali GPU memory.");
+
+#if defined(CONFIG_MALI400_PROFILING)
extern int mali_boot_profiling;
module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization");
#endif
+extern int mali_max_pp_cores_group_1;
+module_param(mali_max_pp_cores_group_1, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_max_pp_cores_group_1, "Limit the number of PP cores to use from first PP group.");
+
+extern int mali_max_pp_cores_group_2;
+module_param(mali_max_pp_cores_group_2, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_max_pp_cores_group_2, "Limit the number of PP cores to use from second PP group (Mali-450 only).");
+
/* Export symbols from common code: mali_user_settings.c */
#include "mali_user_settings_db.h"
EXPORT_SYMBOL(mali_set_user_setting);
EXPORT_SYMBOL(mali_get_user_setting);
-#if MALI_DVFS_ENABLED
-extern int mali_dvfs_control;
-module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
-#if defined(CONFIG_CPU_EXYNOS4210)
-#else
-extern int step0_clk;
-module_param(step0_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step0_clk, "Mali Current step0_clk");
-#ifdef DEBUG
-extern int step0_vol;
-module_param(step0_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step0_vol, "Mali Current step0_vol");
-#endif
-#if (MALI_DVFS_STEPS > 1)
-extern int step1_clk;
-module_param(step1_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step1_clk, "Mali Current step1_clk");
-
-extern int step0_up;
-module_param(step0_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step0_up, "Mali Current step0_up");
-
-extern int step1_down;
-module_param(step1_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step1_down, "Mali Current step1_down");
-#ifdef DEBUG
-extern int step1_vol;
-module_param(step1_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step1_vol, "Mali Current step1_vol");
-#endif
+static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
-#if (MALI_DVFS_STEPS > 2)
-extern int step2_clk;
-module_param(step2_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step2_clk, "Mali Current step2_clk");
-
-extern int step1_up;
-module_param(step1_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step1_up, "Mali Current step1_up");
-
-extern int step2_down;
-module_param(step2_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step2_down, "Mali Current step2_down");
-#ifdef DEBUG
-extern int step2_vol;
-module_param(step2_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step2_vol, "Mali Current step2_vol");
-#endif
+/* This driver only supports one Mali device, and this variable stores this single platform device */
+struct platform_device *mali_platform_device = NULL;
-#if (MALI_DVFS_STEPS > 3)
-extern int step3_clk;
-module_param(step3_clk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step3_clk, "Mali Current step3_clk");
-
-extern int step2_up;
-module_param(step2_up, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step2_up, "Mali Current step2_up");
-
-extern int step3_down;
-module_param(step3_down, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step3_down, "Mali Current step3_down");
-#ifdef DEBUG
-extern int step3_vol;
-module_param(step3_vol, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(step3_vol, "Mali Current step3_vol");
-#endif
-#endif
-#endif
-#endif
-#endif
+/* This driver only supports one Mali device, and this variable stores the exposed misc device (/dev/mali) */
+static struct miscdevice mali_miscdevice = { 0, };
-extern int mali_gpu_clk;
-module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
-MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock");
+static int mali_miscdevice_register(struct platform_device *pdev);
+static void mali_miscdevice_unregister(void);
-extern int mali_gpu_vol;
-module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
-MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
-
-extern int gpu_power_state;
-module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
-MODULE_PARM_DESC(gpu_power_state, "Mali Power State");
+static int mali_open(struct inode *inode, struct file *filp);
+static int mali_release(struct inode *inode, struct file *filp);
+#ifdef HAVE_UNLOCKED_IOCTL
+static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#else
+static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
#endif
+static int mali_mmap(struct file * filp, struct vm_area_struct * vma);
+static int mali_probe(struct platform_device *pdev);
+static int mali_remove(struct platform_device *pdev);
-static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
+static int mali_driver_suspend_scheduler(struct device *dev);
+static int mali_driver_resume_scheduler(struct device *dev);
-/* the mali device */
-static struct mali_dev device;
+#ifdef CONFIG_PM_RUNTIME
+static int mali_driver_runtime_suspend(struct device *dev);
+static int mali_driver_runtime_resume(struct device *dev);
+static int mali_driver_runtime_idle(struct device *dev);
+#endif
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+extern int mali_platform_device_register(void);
+extern int mali_platform_device_unregister(void);
+#endif
-static int mali_open(struct inode *inode, struct file *filp);
-static int mali_release(struct inode *inode, struct file *filp);
-#ifdef HAVE_UNLOCKED_IOCTL
-static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+/* Linux power management operations provided by the Mali device driver */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+struct pm_ext_ops mali_dev_ext_pm_ops =
+{
+ .base =
+ {
+ .suspend = mali_driver_suspend_scheduler,
+ .resume = mali_driver_resume_scheduler,
+ .freeze = mali_driver_suspend_scheduler,
+ .thaw = mali_driver_resume_scheduler,
+ },
+};
#else
-static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+static const struct dev_pm_ops mali_dev_pm_ops =
+{
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = mali_driver_runtime_suspend,
+ .runtime_resume = mali_driver_runtime_resume,
+ .runtime_idle = mali_driver_runtime_idle,
+#endif
+ .suspend = mali_driver_suspend_scheduler,
+ .resume = mali_driver_resume_scheduler,
+ .freeze = mali_driver_suspend_scheduler,
+ .thaw = mali_driver_resume_scheduler,
+};
#endif
-static int mali_mmap(struct file * filp, struct vm_area_struct * vma);
+/* The Mali device driver struct */
+static struct platform_driver mali_platform_driver =
+{
+ .probe = mali_probe,
+ .remove = mali_remove,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+ .pm = &mali_dev_ext_pm_ops,
+#endif
+ .driver =
+ {
+ .name = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */
+ .owner = THIS_MODULE,
+ .bus = &platform_bus_type,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+ .pm = &mali_dev_pm_ops,
+#endif
+ },
+};
-/* Linux char file operations provided by the Mali module */
+/* Linux misc device operations (/dev/mali) */
struct file_operations mali_fops =
{
.owner = THIS_MODULE,
@@ -196,140 +194,204 @@ struct file_operations mali_fops =
.mmap = mali_mmap
};
-
-int mali_driver_init(void)
+int mali_module_init(void)
{
- int ret = 0;
+ int err = 0;
- 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, ("Driver revision: %s\n", SVN_REV_STRING));
- ret = _mali_dev_platform_register();
- if (0 != ret) goto platform_register_failed;
- ret = map_errcode(initialize_kernel_device());
- if (0 != ret) goto initialize_kernel_device_failed;
+ /* Initialize module wide settings */
+ mali_osk_low_level_mem_init();
- ret = map_errcode(mali_platform_init());
- if (0 != ret) goto platform_init_failed;
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+ MALI_DEBUG_PRINT(2, ("mali_module_init() registering device\n"));
+ err = mali_platform_device_register();
+ if (0 != err)
+ {
+ return err;
+ }
+#endif
- mali_osk_low_level_mem_init();
+ MALI_DEBUG_PRINT(2, ("mali_module_init() registering driver\n"));
- ret = map_errcode(mali_initialize_subsystems());
- if (0 != ret) goto initialize_subsystems_failed;
+ err = platform_driver_register(&mali_platform_driver);
- ret = initialize_sysfs();
- if (0 != ret) goto initialize_sysfs_failed;
+ if (0 != err)
+ {
+ MALI_DEBUG_PRINT(2, ("mali_module_init() Failed to register driver (%d)\n", err));
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+ mali_platform_device_unregister();
+#endif
+ mali_platform_device = NULL;
+ return err;
+ }
+
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+ err = _mali_internal_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
+ if (0 != 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
MALI_PRINT(("Mali device driver loaded\n"));
return 0; /* Success */
-
- /* Error handling */
-initialize_sysfs_failed:
- mali_terminate_subsystems();
-initialize_subsystems_failed:
- mali_osk_low_level_mem_term();
- mali_platform_deinit();
-platform_init_failed:
- terminate_kernel_device();
-initialize_kernel_device_failed:
- _mali_dev_platform_unregister();
-platform_register_failed:
- return ret;
}
-void mali_driver_exit(void)
+void mali_module_exit(void)
{
- MALI_DEBUG_PRINT(2, ("\n"));
MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
- /* No need to terminate sysfs, this will be done automatically along with device termination */
-
- mali_terminate_subsystems();
-
- mali_osk_low_level_mem_term();
+ MALI_DEBUG_PRINT(2, ("mali_module_exit() unregistering driver\n"));
- mali_platform_deinit();
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+ _mali_internal_profiling_term();
+#endif
- terminate_kernel_device();
- _mali_dev_platform_unregister();
+ platform_driver_unregister(&mali_platform_driver);
-#if MALI_LICENSE_IS_GPL
- /* @@@@ clean up the work queues! This should not be terminated here, since it isn't inited in the function above! */
- flush_workqueue(mali_wq);
- destroy_workqueue(mali_wq);
- mali_wq = NULL;
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+ MALI_DEBUG_PRINT(2, ("mali_module_exit() unregistering device\n"));
+ mali_platform_device_unregister();
#endif
+ mali_osk_low_level_mem_term();
+
MALI_PRINT(("Mali device driver unloaded\n"));
}
-static int initialize_kernel_device(void)
+static int mali_probe(struct platform_device *pdev)
{
int err;
- dev_t dev = 0;
- if (0 == mali_major)
- {
- /* auto select a major */
- err = alloc_chrdev_region(&dev, 0/*first minor*/, 1/*count*/, mali_dev_name);
- mali_major = MAJOR(dev);
- }
- else
+
+ MALI_DEBUG_PRINT(2, ("mali_probe(): Called for platform device %s\n", pdev->name));
+
+ if (NULL != mali_platform_device)
{
- /* use load time defined major number */
- dev = MKDEV(mali_major, 0);
- err = register_chrdev_region(dev, 1/*count*/, mali_dev_name);
+ /* Already connected to a device, return error */
+ MALI_PRINT_ERROR(("mali_probe(): The Mali driver is already connected with a Mali device."));
+ return -EEXIST;
}
- if (err)
+ mali_platform_device = pdev;
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_wq_init())
{
- goto init_chrdev_err;
+ /* Initialize the Mali GPU HW specified by pdev */
+ if (_MALI_OSK_ERR_OK == mali_initialize_subsystems())
+ {
+ /* Register a misc device (so we are accessible from user space) */
+ err = mali_miscdevice_register(pdev);
+ if (0 == err)
+ {
+ /* Setup sysfs entries */
+ err = mali_sysfs_register(mali_dev_name);
+ if (0 == err)
+ {
+ MALI_DEBUG_PRINT(2, ("mali_probe(): Successfully initialized driver for platform device %s\n", pdev->name));
+ return 0;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("mali_probe(): failed to register sysfs entries"));
+ }
+ mali_miscdevice_unregister();
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("mali_probe(): failed to register Mali misc device."));
+ }
+ mali_terminate_subsystems();
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("mali_probe(): Failed to initialize Mali device driver."));
+ }
+ _mali_osk_wq_term();
}
- memset(&device, 0, sizeof(device));
+ mali_platform_device = NULL;
+ return -EFAULT;
+}
- /* initialize our char dev data */
- cdev_init(&device.cdev, &mali_fops);
- device.cdev.owner = THIS_MODULE;
- device.cdev.ops = &mali_fops;
+static int mali_remove(struct platform_device *pdev)
+{
+ MALI_DEBUG_PRINT(2, ("mali_remove() called for platform device %s\n", pdev->name));
+ mali_sysfs_unregister();
+ mali_miscdevice_unregister();
+ mali_terminate_subsystems();
+ _mali_osk_wq_term();
+ mali_platform_device = NULL;
+ return 0;
+}
- /* register char dev with the kernel */
- err = cdev_add(&device.cdev, dev, 1/*count*/);
- if (err)
+static int mali_miscdevice_register(struct platform_device *pdev)
+{
+ int err;
+
+ mali_miscdevice.minor = MISC_DYNAMIC_MINOR;
+ mali_miscdevice.name = mali_dev_name;
+ mali_miscdevice.fops = &mali_fops;
+ mali_miscdevice.parent = get_device(&pdev->dev);
+
+ err = misc_register(&mali_miscdevice);
+ if (0 != err)
{
- goto init_cdev_err;
+ MALI_PRINT_ERROR(("Failed to register misc device, misc_register() returned %d\n", err));
}
- /* Success! */
- return 0;
-
-init_cdev_err:
- unregister_chrdev_region(dev, 1/*count*/);
-init_chrdev_err:
return err;
}
-static int initialize_sysfs(void)
+static void mali_miscdevice_unregister(void)
{
- dev_t dev = MKDEV(mali_major, 0);
- return mali_sysfs_register(&device, dev, mali_dev_name);
+ misc_deregister(&mali_miscdevice);
}
-static void terminate_kernel_device(void)
+static int mali_driver_suspend_scheduler(struct device *dev)
{
- dev_t dev = MKDEV(mali_major, 0);
+ mali_pm_os_suspend();
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP);
+ return 0;
+}
- mali_sysfs_unregister(&device, dev, mali_dev_name);
+static int mali_driver_resume_scheduler(struct device *dev)
+{
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
+ mali_pm_os_resume();
+ return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int mali_driver_runtime_suspend(struct device *dev)
+{
+ mali_pm_runtime_suspend();
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_LIGHT_SLEEP);
+ return 0;
+}
- /* unregister char device */
- cdev_del(&device.cdev);
- /* free major */
- unregister_chrdev_region(dev, 1/*count*/);
- return;
+static int mali_driver_runtime_resume(struct device *dev)
+{
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
+ mali_pm_runtime_resume();
+ return 0;
}
+static int mali_driver_runtime_idle(struct device *dev)
+{
+ /* Nothing to do */
+ return 0;
+}
+#endif
+
/** @note munmap handler is done by vma close handler */
static int mali_mmap(struct file * filp, struct vm_area_struct * vma)
{
@@ -376,7 +438,11 @@ static int mali_open(struct inode *inode, struct file *filp)
_mali_osk_errcode_t err;
/* input validation */
- if (0 != MINOR(inode->i_rdev)) return -ENODEV;
+ if (mali_miscdevice.minor != iminor(inode))
+ {
+ MALI_PRINT_ERROR(("mali_open() Minor does not match\n"));
+ return -ENODEV;
+ }
/* allocated struct to track this session */
err = _mali_ukk_open((void **)&session_data);
@@ -395,8 +461,12 @@ static int mali_release(struct inode *inode, struct file *filp)
{
_mali_osk_errcode_t err;
- /* input validation */
- if (0 != MINOR(inode->i_rdev)) return -ENODEV;
+ /* input validation */
+ if (mali_miscdevice.minor != iminor(inode))
+ {
+ MALI_PRINT_ERROR(("mali_release() Minor does not match\n"));
+ return -ENODEV;
+ }
err = _mali_ukk_close((void **)&filp->private_data);
if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
@@ -467,7 +537,7 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg);
break;
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_PROFILING)
case MALI_IOC_PROFILING_START:
err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg);
break;
@@ -520,6 +590,10 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg);
break;
+ case MALI_IOC_MEM_WRITE_SAFE:
+ err = mem_write_safe_wrapper(session_data, (_mali_uk_mem_write_safe_s __user *)arg);
+ break;
+
case MALI_IOC_MEM_MAP_EXT:
err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg);
break;
@@ -536,7 +610,7 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg);
break;
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#if defined(CONFIG_MALI400_UMP)
case MALI_IOC_MEM_ATTACH_UMP:
err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg);
@@ -569,6 +643,8 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
break;
#else
+ case MALI_IOC_MEM_ATTACH_DMA_BUF: /* FALL-THROUGH */
+ case MALI_IOC_MEM_RELEASE_DMA_BUF: /* FALL-THROUGH */
case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */
MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n"));
err = -ENOTTY;
@@ -611,6 +687,26 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg);
break;
+ case MALI_IOC_STREAM_CREATE:
+#if defined(CONFIG_SYNC)
+ err = stream_create_wrapper(session_data, (_mali_uk_stream_create_s __user *)arg);
+ break;
+#endif
+ case MALI_IOC_FENCE_CREATE_EMPTY:
+#if defined(CONFIG_SYNC)
+ err = sync_fence_create_empty_wrapper(session_data, (_mali_uk_fence_create_empty_s __user *)arg);
+ break;
+#endif
+ case MALI_IOC_FENCE_VALIDATE:
+#if defined(CONFIG_SYNC)
+ err = sync_fence_validate_wrapper(session_data, (_mali_uk_fence_validate_s __user *)arg);
+ break;
+#else
+ MALI_DEBUG_PRINT(2, ("Sync objects not supported\n"));
+ err = -ENOTTY;
+ break;
+#endif
+
case MALI_IOC_MEM_GET_BIG_BLOCK: /* Fallthrough */
case MALI_IOC_MEM_FREE_BIG_BLOCK:
MALI_PRINT_ERROR(("Non-MMU mode is no longer supported.\n"));
@@ -626,8 +722,8 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
}
-module_init(mali_driver_init);
-module_exit(mali_driver_exit);
+module_init(mali_module_init);
+module_exit(mali_module_exit);
MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE);
MODULE_AUTHOR("ARM Ltd.");
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h
index 22dc9a4..8bc4c39 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h
@@ -20,13 +20,7 @@ extern "C"
#include "mali_kernel_license.h"
#include "mali_osk.h"
-struct mali_dev
-{
- struct cdev cdev;
-#if MALI_LICENSE_IS_GPL
- struct class * mali_class;
-#endif
-};
+extern struct platform_device *mali_platform_device;
#if MALI_LICENSE_IS_GPL
/* Defined in mali_osk_irq.h */
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c
index e2dc17b..fa1fa9c 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c
@@ -20,7 +20,6 @@
#include <linux/module.h>
#include "mali_kernel_license.h"
#include "mali_kernel_common.h"
-#include "mali_kernel_linux.h"
#include "mali_ukk.h"
#if MALI_LICENSE_IS_GPL
@@ -29,13 +28,16 @@
#include <linux/debugfs.h>
#include <asm/uaccess.h>
#include <linux/module.h>
+#include <linux/mali/mali_utgard.h>
#include "mali_kernel_sysfs.h"
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
#include <linux/slab.h>
#include "mali_osk_profiling.h"
#endif
+
+#include <linux/mali/mali_utgard.h>
#include "mali_pm.h"
-#include "mali_cluster.h"
+#include "mali_pmu.h"
#include "mali_group.h"
#include "mali_gp.h"
#include "mali_pp.h"
@@ -43,11 +45,13 @@
#include "mali_hw_core.h"
#include "mali_kernel_core.h"
#include "mali_user_settings_db.h"
-#include "mali_device_pause_resume.h"
+#include "mali_profiling_internal.h"
+#include "mali_gp_job.h"
+#include "mali_pp_job.h"
+#include "mali_pp_scheduler.h"
#define POWER_BUFFER_SIZE 3
-struct device *mali_device;
static struct dentry *mali_debugfs_dir = NULL;
typedef enum
@@ -66,8 +70,7 @@ static const char* const mali_power_events[_MALI_MAX_EVENTS] = {
[_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume",
};
-static u32 virtual_power_status_register=0;
-static char pwr_buf[POWER_BUFFER_SIZE];
+static mali_bool power_always_on_enabled = MALI_FALSE;
static int open_copy_private_data(struct inode *inode, struct file *filp)
{
@@ -75,20 +78,104 @@ static int open_copy_private_data(struct inode *inode, struct file *filp)
return 0;
}
+static ssize_t group_enabled_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+ struct mali_group *group;
+
+ group = (struct mali_group *)filp->private_data;
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ r = sprintf(buffer, "%u\n", mali_group_is_enabled(group) ? 1 : 0);
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static ssize_t group_enabled_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+ unsigned long val;
+ struct mali_group *group;
+
+ group = (struct mali_group *)filp->private_data;
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ r = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != r)
+ {
+ return -EINVAL;
+ }
+
+ switch (val)
+ {
+ case 1:
+ mali_group_enable(group);
+ break;
+ case 0:
+ mali_group_disable(group);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static const struct file_operations group_enabled_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = group_enabled_read,
+ .write = group_enabled_write,
+};
+
+static ssize_t hw_core_base_addr_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+ struct mali_hw_core *hw_core;
+
+ hw_core = (struct mali_hw_core *)filp->private_data;
+ MALI_DEBUG_ASSERT_POINTER(hw_core);
+
+ r = sprintf(buffer, "0x%08X\n", hw_core->phys_addr);
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations hw_core_base_addr_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = hw_core_base_addr_read,
+};
+
static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
{
char buf[64];
int r;
u32 val;
- struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data;
if (0 == src_id)
{
- val = mali_gp_core_get_counter_src0(gp_core);
+ val = mali_gp_job_get_gp_counter_src0();
}
else
{
- val = mali_gp_core_get_counter_src1(gp_core);
+ val = mali_gp_job_get_gp_counter_src1();
}
if (MALI_HW_CORE_NO_COUNTER == val)
@@ -104,7 +191,6 @@ static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, si
static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
{
- struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data;
char buf[64];
long val;
int ret;
@@ -135,14 +221,14 @@ static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *u
if (0 == src_id)
{
- if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val))
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
{
return 0;
}
}
else
{
- if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val))
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
{
return 0;
}
@@ -157,8 +243,8 @@ static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *u
char buf[64];
long val;
int ret;
- u32 ci;
- struct mali_cluster *cluster;
+ u32 num_groups;
+ int i;
if (cnt >= sizeof(buf))
{
@@ -184,41 +270,29 @@ static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *u
val = MALI_HW_CORE_NO_COUNTER;
}
- ci = 0;
- cluster = mali_cluster_get_global_cluster(ci);
- while (NULL != cluster)
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
{
- u32 gi = 0;
- struct mali_group *group = mali_cluster_get_group(cluster, gi);
- while (NULL != group)
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
+ if (NULL != gp_core)
{
- struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
- if (NULL != gp_core)
+ if (0 == src_id)
{
- if (0 == src_id)
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
{
- if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val))
- {
- return 0;
- }
+ return 0;
}
- else
+ }
+ else
+ {
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
{
- if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val))
- {
- return 0;
- }
- }
+ return 0;
+ }
}
-
- /* try next group */
- gi++;
- group = mali_cluster_get_group(cluster, gi);
}
-
- /* try next cluster */
- ci++;
- cluster = mali_cluster_get_global_cluster(ci);
}
*gpos += cnt;
@@ -284,15 +358,14 @@ static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, si
char buf[64];
int r;
u32 val;
- struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data;
if (0 == src_id)
{
- val = mali_pp_core_get_counter_src0(pp_core);
+ val = mali_pp_job_get_pp_counter_src0();
}
else
{
- val = mali_pp_core_get_counter_src1(pp_core);
+ val = mali_pp_job_get_pp_counter_src1();
}
if (MALI_HW_CORE_NO_COUNTER == val)
@@ -308,7 +381,6 @@ static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, si
static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
{
- struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data;
char buf[64];
long val;
int ret;
@@ -339,14 +411,14 @@ static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *u
if (0 == src_id)
{
- if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val))
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
{
return 0;
}
}
else
{
- if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val))
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
{
return 0;
}
@@ -361,8 +433,8 @@ static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *u
char buf[64];
long val;
int ret;
- u32 ci;
- struct mali_cluster *cluster;
+ u32 num_groups;
+ int i;
if (cnt >= sizeof(buf))
{
@@ -388,41 +460,29 @@ static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *u
val = MALI_HW_CORE_NO_COUNTER;
}
- ci = 0;
- cluster = mali_cluster_get_global_cluster(ci);
- while (NULL != cluster)
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
{
- u32 gi = 0;
- struct mali_group *group = mali_cluster_get_group(cluster, gi);
- while (NULL != group)
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+ if (NULL != pp_core)
{
- struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
- if (NULL != pp_core)
+ if (0 == src_id)
{
- if (0 == src_id)
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
{
- if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val))
- {
- return 0;
- }
+ return 0;
}
- else
+ }
+ else
+ {
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
{
- if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val))
- {
- return 0;
- }
- }
+ return 0;
+ }
}
-
- /* try next group */
- gi++;
- group = mali_cluster_get_group(cluster, gi);
}
-
- /* try next cluster */
- ci++;
- cluster = mali_cluster_get_global_cluster(ci);
}
*ppos += cnt;
@@ -483,11 +543,6 @@ static const struct file_operations pp_all_counter_src1_fops = {
.write = pp_all_counter_src1_write,
};
-
-
-
-
-
static ssize_t l2_l2x_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
{
char buf[64];
@@ -679,71 +734,95 @@ static const struct file_operations l2_all_counter_src1_fops = {
.write = l2_all_counter_src1_write,
};
-static ssize_t power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+static ssize_t power_always_on_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
-
- memset(pwr_buf,0,POWER_BUFFER_SIZE);
- virtual_power_status_register = 0;
+ unsigned long val;
+ int ret;
+ char buf[32];
+
+ cnt = min(cnt, sizeof(buf) - 1);
+ if (copy_from_user(buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+ buf[cnt] = '\0';
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (0 != ret)
+ {
+ return ret;
+ }
+
+ /* Update setting (not exactly thread safe) */
+ if (1 == val && MALI_FALSE == power_always_on_enabled)
+ {
+ power_always_on_enabled = MALI_TRUE;
+ _mali_osk_pm_dev_ref_add();
+ }
+ else if (0 == val && MALI_TRUE == power_always_on_enabled)
+ {
+ power_always_on_enabled = MALI_FALSE;
+ _mali_osk_pm_dev_ref_dec();
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t power_always_on_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ if (MALI_TRUE == power_always_on_enabled)
+ {
+ return simple_read_from_buffer(ubuf, cnt, ppos, "1\n", 2);
+ }
+ else
+ {
+ return simple_read_from_buffer(ubuf, cnt, ppos, "0\n", 2);
+ }
+}
+
+static const struct file_operations power_always_on_fops = {
+ .owner = THIS_MODULE,
+ .read = power_always_on_read,
+ .write = power_always_on_write,
+};
+
+static ssize_t power_power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+
if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND])))
{
mali_pm_os_suspend();
- /* @@@@ assuming currently suspend is successful later on to tune as per previous*/
- virtual_power_status_register =1;
}
else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME])))
{
mali_pm_os_resume();
-
- /* @@@@ assuming currently resume is successful later on to tune as per previous */
- virtual_power_status_register = 1;
}
else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE])))
{
- mali_bool power_on;
- mali_dev_pause(&power_on);
- if (!power_on)
- {
- virtual_power_status_register = 2;
- mali_dev_resume();
- }
- else
- {
- /* @@@@ assuming currently resume is successful later on to tune as per previous */
- virtual_power_status_register =1;
- }
+ mali_dev_pause();
}
else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME])))
{
mali_dev_resume();
- /* @@@@ assuming currently resume is successful later on to tune as per previous */
- virtual_power_status_register = 1;
-
}
*ppos += cnt;
- sprintf(pwr_buf, "%d",virtual_power_status_register);
return cnt;
}
-static ssize_t power_events_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
-{
- return simple_read_from_buffer(ubuf, cnt, ppos, pwr_buf, POWER_BUFFER_SIZE);
-}
-
-static loff_t power_events_seek(struct file *file, loff_t offset, int orig)
+static loff_t power_power_events_seek(struct file *file, loff_t offset, int orig)
{
file->f_pos = offset;
return 0;
}
-static const struct file_operations power_events_fops = {
+static const struct file_operations power_power_events_fops = {
.owner = THIS_MODULE,
- .read = power_events_read,
- .write = power_events_write,
- .llseek = power_events_seek,
+ .write = power_power_events_write,
+ .llseek = power_power_events_seek,
};
-
#if MALI_STATE_TRACKING
static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
{
@@ -783,14 +862,13 @@ static const struct file_operations mali_seq_internal_state_fops = {
};
#endif /* MALI_STATE_TRACKING */
-
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{
char buf[64];
int r;
- r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0);
+ r = sprintf(buf, "%u\n", _mali_internal_profiling_is_recording() ? 1 : 0);
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
@@ -823,16 +901,16 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */
/* check if we are already recording */
- if (MALI_TRUE == _mali_osk_profiling_is_recording())
+ if (MALI_TRUE == _mali_internal_profiling_is_recording())
{
MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n"));
return -EFAULT;
}
/* check if we need to clear out an old recording first */
- if (MALI_TRUE == _mali_osk_profiling_have_recording())
+ if (MALI_TRUE == _mali_internal_profiling_have_recording())
{
- if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear())
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_clear())
{
MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
return -EFAULT;
@@ -840,7 +918,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
}
/* start recording profiling data */
- if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
{
MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
return -EFAULT;
@@ -852,7 +930,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
{
/* stop recording profiling data */
u32 count = 0;
- if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count))
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_stop(&count))
{
MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
return -EFAULT;
@@ -876,7 +954,7 @@ static void *profiling_events_start(struct seq_file *s, loff_t *pos)
loff_t *spos;
/* check if we have data avaiable */
- if (MALI_TRUE != _mali_osk_profiling_have_recording())
+ if (MALI_TRUE != _mali_internal_profiling_have_recording())
{
return NULL;
}
@@ -896,13 +974,13 @@ static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos)
loff_t *spos = v;
/* check if we have data avaiable */
- if (MALI_TRUE != _mali_osk_profiling_have_recording())
+ if (MALI_TRUE != _mali_internal_profiling_have_recording())
{
return NULL;
}
/* check if the next entry actually is avaiable */
- if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1))
+ if (_mali_internal_profiling_get_count() <= (u32)(*spos + 1))
{
return NULL;
}
@@ -927,7 +1005,7 @@ static int profiling_events_show(struct seq_file *seq_file, void *v)
index = (u32)*spos;
/* Retrieve all events */
- if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, &timestamp, &event_id, data))
+ if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
{
seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
return 0;
@@ -936,6 +1014,128 @@ static int profiling_events_show(struct seq_file *seq_file, void *v)
return 0;
}
+static int profiling_events_show_human_readable(struct seq_file *seq_file, void *v)
+{
+ #define MALI_EVENT_ID_IS_HW(event_id) (((event_id & 0x00FF0000) >= MALI_PROFILING_EVENT_CHANNEL_GP0) && ((event_id & 0x00FF0000) <= MALI_PROFILING_EVENT_CHANNEL_PP7))
+
+ static u64 start_time = 0;
+ loff_t *spos = v;
+ u32 index;
+ u64 timestamp;
+ u32 event_id;
+ u32 data[5];
+
+ index = (u32)*spos;
+
+ /* Retrieve all events */
+ if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
+ {
+ seq_printf(seq_file, "%llu %u %u %u %u %u %u # ", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
+
+ if (0 == index)
+ {
+ start_time = timestamp;
+ }
+
+ seq_printf(seq_file, "[%06u] ", index);
+
+ switch(event_id & 0x0F000000)
+ {
+ case MALI_PROFILING_EVENT_TYPE_SINGLE:
+ seq_printf(seq_file, "SINGLE | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_START:
+ seq_printf(seq_file, "START | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_STOP:
+ seq_printf(seq_file, "STOP | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_SUSPEND:
+ seq_printf(seq_file, "SUSPEND | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_RESUME:
+ seq_printf(seq_file, "RESUME | ");
+ break;
+ default:
+ seq_printf(seq_file, "0x%01X | ", (event_id & 0x0F000000) >> 24);
+ break;
+ }
+
+ switch(event_id & 0x00FF0000)
+ {
+ case MALI_PROFILING_EVENT_CHANNEL_SOFTWARE:
+ seq_printf(seq_file, "SW | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_GP0:
+ seq_printf(seq_file, "GP0 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP0:
+ seq_printf(seq_file, "PP0 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP1:
+ seq_printf(seq_file, "PP1 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP2:
+ seq_printf(seq_file, "PP2 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP3:
+ seq_printf(seq_file, "PP3 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP4:
+ seq_printf(seq_file, "PP4 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP5:
+ seq_printf(seq_file, "PP5 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP6:
+ seq_printf(seq_file, "PP6 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP7:
+ seq_printf(seq_file, "PP7 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_GPU:
+ seq_printf(seq_file, "GPU | ");
+ break;
+ default:
+ seq_printf(seq_file, "0x%02X | ", (event_id & 0x00FF0000) >> 16);
+ break;
+ }
+
+ if (MALI_EVENT_ID_IS_HW(event_id))
+ {
+ if (((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_START) || ((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_STOP))
+ {
+ switch(event_id & 0x0000FFFF)
+ {
+ case MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL:
+ seq_printf(seq_file, "PHYSICAL | ");
+ break;
+ case MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL:
+ seq_printf(seq_file, "VIRTUAL | ");
+ break;
+ default:
+ seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
+ break;
+ }
+ }
+ else
+ {
+ seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
+ }
+ }
+ else
+ {
+ seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
+ }
+
+ seq_printf(seq_file, "T0 + 0x%016llX\n", timestamp - start_time);
+
+ return 0;
+ }
+
+ return 0;
+}
+
static const struct seq_operations profiling_events_seq_ops = {
.start = profiling_events_start,
.next = profiling_events_next,
@@ -955,6 +1155,27 @@ static const struct file_operations profiling_events_fops = {
.llseek = seq_lseek,
.release = seq_release,
};
+
+static const struct seq_operations profiling_events_human_readable_seq_ops = {
+ .start = profiling_events_start,
+ .next = profiling_events_next,
+ .stop = profiling_events_stop,
+ .show = profiling_events_show_human_readable
+};
+
+static int profiling_events_human_readable_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &profiling_events_human_readable_seq_ops);
+}
+
+static const struct file_operations profiling_events_human_readable_fops = {
+ .owner = THIS_MODULE,
+ .open = profiling_events_human_readable_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
#endif
static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
@@ -972,6 +1193,51 @@ static const struct file_operations memory_usage_fops = {
.read = memory_used_read,
};
+static ssize_t utilization_gp_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 uval= _mali_ukk_utilization_gp_pp();
+
+ r = snprintf(buf, 64, "%u\n", uval);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t utilization_gp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 uval= _mali_ukk_utilization_gp();
+
+ r = snprintf(buf, 64, "%u\n", uval);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t utilization_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 uval= _mali_ukk_utilization_pp();
+
+ r = snprintf(buf, 64, "%u\n", uval);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+
+static const struct file_operations utilization_gp_pp_fops = {
+ .owner = THIS_MODULE,
+ .read = utilization_gp_pp_read,
+};
+
+static const struct file_operations utilization_gp_fops = {
+ .owner = THIS_MODULE,
+ .read = utilization_gp_read,
+};
+
+static const struct file_operations utilization_pp_fops = {
+ .owner = THIS_MODULE,
+ .read = utilization_pp_read,
+};
static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
@@ -1038,23 +1304,191 @@ static int mali_sysfs_user_settings_register(void)
return 0;
}
-int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
+static ssize_t pmu_power_down_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int ret;
+ char buffer[32];
+ unsigned long val;
+ struct mali_pmu_core *pmu;
+ _mali_osk_errcode_t err;
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ ret = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != ret)
+ {
+ return -EINVAL;
+ }
+
+ pmu = mali_pmu_get_global_pmu_core();
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+
+ err = mali_pmu_power_down(pmu, val);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return -EINVAL;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static ssize_t pmu_power_up_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int ret;
+ char buffer[32];
+ unsigned long val;
+ struct mali_pmu_core *pmu;
+ _mali_osk_errcode_t err;
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ ret = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != ret)
+ {
+ return -EINVAL;
+ }
+
+ pmu = mali_pmu_get_global_pmu_core();
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+
+ err = mali_pmu_power_up(pmu, val);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return -EINVAL;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static const struct file_operations pmu_power_down_fops = {
+ .owner = THIS_MODULE,
+ .write = pmu_power_down_write,
+};
+
+static const struct file_operations pmu_power_up_fops = {
+ .owner = THIS_MODULE,
+ .write = pmu_power_up_write,
+};
+
+static ssize_t pp_num_cores_enabled_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
{
- int err = 0;
+ int ret;
+ char buffer[32];
+ unsigned long val;
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
- device->mali_class = class_create(THIS_MODULE, mali_dev_name);
- if (IS_ERR(device->mali_class))
+ ret = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != ret)
{
- err = PTR_ERR(device->mali_class);
- goto init_class_err;
+ return -EINVAL;
}
- mali_device = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name);
- if (IS_ERR(mali_device))
+
+ ret = mali_perf_set_num_pp_cores(val);
+ if (ret)
{
- err = PTR_ERR(mali_device);
- goto init_mdev_err;
+ return ret;
}
+ *offp += count;
+ return count;
+}
+
+static ssize_t pp_num_cores_enabled_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+
+ r = sprintf(buffer, "%u\n", mali_pp_scheduler_get_num_cores_enabled());
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations pp_num_cores_enabled_fops = {
+ .owner = THIS_MODULE,
+ .write = pp_num_cores_enabled_write,
+ .read = pp_num_cores_enabled_read,
+};
+
+static ssize_t pp_num_cores_total_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+
+ r = sprintf(buffer, "%u\n", mali_pp_scheduler_get_num_cores_total());
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations pp_num_cores_total_fops = {
+ .owner = THIS_MODULE,
+ .read = pp_num_cores_total_read,
+};
+
+
+static ssize_t version_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r = 0;
+ char buffer[64];
+
+ switch (mali_kernel_core_get_product_id())
+ {
+ case _MALI_PRODUCT_ID_MALI200:
+ r = sprintf(buffer, "Mali-200\n");
+ break;
+ case _MALI_PRODUCT_ID_MALI300:
+ r = sprintf(buffer, "Mali-300\n");
+ break;
+ case _MALI_PRODUCT_ID_MALI400:
+ r = sprintf(buffer, "Mali-400 MP\n");
+ break;
+ case _MALI_PRODUCT_ID_MALI450:
+ r = sprintf(buffer, "Mali-450 MP\n");
+ break;
+ case _MALI_PRODUCT_ID_UNKNOWN:
+ return -EINVAL;
+ break;
+ };
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations version_fops = {
+ .owner = THIS_MODULE,
+ .read = version_read,
+};
+
+int mali_sysfs_register(const char *mali_dev_name)
+{
mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL);
if(ERR_PTR(-ENODEV) == mali_debugfs_dir)
{
@@ -1066,63 +1500,67 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
if(NULL != mali_debugfs_dir)
{
/* Debugfs directory created successfully; create files now */
+ struct dentry *mali_pmu_dir;
struct dentry *mali_power_dir;
struct dentry *mali_gp_dir;
struct dentry *mali_pp_dir;
struct dentry *mali_l2_dir;
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
struct dentry *mali_profiling_dir;
#endif
+ debugfs_create_file("version", 0400, mali_debugfs_dir, NULL, &version_fops);
+
+ mali_pmu_dir = debugfs_create_dir("pmu", mali_debugfs_dir);
+ if (NULL != mali_pmu_dir)
+ {
+ debugfs_create_file("power_down", 0200, mali_pmu_dir, NULL, &pmu_power_down_fops);
+ debugfs_create_file("power_up", 0200, mali_pmu_dir, NULL, &pmu_power_up_fops);
+ }
+
mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir);
if (mali_power_dir != NULL)
{
- debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_events_fops);
+ /* MALI_SEC : 0600 -> 0400 */
+ debugfs_create_file("always_on", 0400, mali_power_dir, NULL, &power_always_on_fops);
+ /* MALI_SEC : 0200 -> 0400 */
+ debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_power_events_fops);
}
mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir);
if (mali_gp_dir != NULL)
{
struct dentry *mali_gp_all_dir;
- u32 ci;
- struct mali_cluster *cluster;
+ u32 num_groups;
+ int i;
mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir);
if (mali_gp_all_dir != NULL)
{
- debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
- debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
+ debugfs_create_file("counter_src0", 0200, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0200, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
}
- ci = 0;
- cluster = mali_cluster_get_global_cluster(ci);
- while (NULL != cluster)
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
{
- u32 gi = 0;
- struct mali_group *group = mali_cluster_get_group(cluster, gi);
- while (NULL != group)
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
+ if (NULL != gp_core)
{
- struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
- if (NULL != gp_core)
+ struct dentry *mali_gp_gpx_dir;
+ mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir);
+ if (NULL != mali_gp_gpx_dir)
{
- struct dentry *mali_gp_gpx_dir;
- mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir);
- if (NULL != mali_gp_gpx_dir)
- {
- debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops);
- debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops);
- }
- break; /* no need to look for any other GP cores */
+ debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops);
+ debugfs_create_file("base_addr", 0400, mali_gp_gpx_dir, &gp_core->hw_core, &hw_core_base_addr_fops);
+ debugfs_create_file("enabled", 0600, mali_gp_gpx_dir, group, &group_enabled_fops);
}
-
- /* try next group */
- gi++;
- group = mali_cluster_get_group(cluster, gi);
+ break; /* no need to look for any other GP cores */
}
- /* try next cluster */
- ci++;
- cluster = mali_cluster_get_global_cluster(ci);
}
}
@@ -1130,46 +1568,42 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
if (mali_pp_dir != NULL)
{
struct dentry *mali_pp_all_dir;
- u32 ci;
- struct mali_cluster *cluster;
+ u32 num_groups;
+ int i;
+
+ debugfs_create_file("num_cores_total", 0400, mali_pp_dir, NULL, &pp_num_cores_total_fops);
+ debugfs_create_file("num_cores_enabled", 0600, mali_pp_dir, NULL, &pp_num_cores_enabled_fops);
mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir);
if (mali_pp_all_dir != NULL)
{
- debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
- debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
+ debugfs_create_file("counter_src0", 0200, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0200, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
}
- ci = 0;
- cluster = mali_cluster_get_global_cluster(ci);
- while (NULL != cluster)
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
{
- u32 gi = 0;
- struct mali_group *group = mali_cluster_get_group(cluster, gi);
- while (NULL != group)
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+ if (NULL != pp_core)
{
- struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
- if (NULL != pp_core)
+ char buf[16];
+ struct dentry *mali_pp_ppx_dir;
+ _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core));
+ mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir);
+ if (NULL != mali_pp_ppx_dir)
{
- char buf[16];
- struct dentry *mali_pp_ppx_dir;
- _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core));
- mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir);
- if (NULL != mali_pp_ppx_dir)
+ debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops);
+ debugfs_create_file("base_addr", 0400, mali_pp_ppx_dir, &pp_core->hw_core, &hw_core_base_addr_fops);
+ if (!mali_group_is_virtual(group))
{
- debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops);
- debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops);
+ debugfs_create_file("enabled", 0600, mali_pp_ppx_dir, group, &group_enabled_fops);
}
}
-
- /* try next group */
- gi++;
- group = mali_cluster_get_group(cluster, gi);
}
-
- /* try next cluster */
- ci++;
- cluster = mali_cluster_get_global_cluster(ci);
}
}
@@ -1183,8 +1617,8 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir);
if (mali_l2_all_dir != NULL)
{
- debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
- debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops);
+ debugfs_create_file("counter_src0", 0200, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0200, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops);
}
l2_id = 0;
@@ -1199,6 +1633,7 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
{
debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops);
debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops);
+ debugfs_create_file("base_addr", 0400, mali_l2_l2x_dir, &l2_cache->hw_core, &hw_core_base_addr_fops);
}
/* try next L2 */
@@ -1209,7 +1644,11 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops);
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ debugfs_create_file("utilization_gp_pp", 0400, mali_debugfs_dir, NULL, &utilization_gp_pp_fops);
+ debugfs_create_file("utilization_gp", 0400, mali_debugfs_dir, NULL, &utilization_gp_fops);
+ debugfs_create_file("utilization_pp", 0400, mali_debugfs_dir, NULL, &utilization_pp_fops);
+
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir);
if (mali_profiling_dir != NULL)
{
@@ -1224,6 +1663,7 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
}
debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops);
debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops);
+ debugfs_create_file("events_human_readable", 0400, mali_profiling_dir, NULL, &profiling_events_human_readable_fops);
}
#endif
@@ -1241,28 +1681,18 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
/* Success! */
return 0;
-
- /* Error handling */
-init_mdev_err:
- class_destroy(device->mali_class);
-init_class_err:
-
- return err;
}
-int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
+int mali_sysfs_unregister(void)
{
if(NULL != mali_debugfs_dir)
{
debugfs_remove_recursive(mali_debugfs_dir);
}
- device_destroy(device->mali_class, dev);
- class_destroy(device->mali_class);
-
return 0;
}
-#else
+#else /* MALI_LICENSE_IS_GPL */
/* Dummy implementations for non-GPL */
@@ -1271,10 +1701,9 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
return 0;
}
-int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
+int mali_sysfs_unregister(void)
{
return 0;
}
-
-#endif
+#endif /* MALI_LICENSE_IS_GPL */
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h
index 24acca9..f970f0f 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h
@@ -20,13 +20,8 @@ extern "C"
#define MALI_PROC_DIR "driver/mali"
-extern struct device *mali_device;
-struct mali_dev;
-
-int mali_sysfs_register(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name);
-
-int mali_sysfs_unregister(struct mali_dev *mali_class, dev_t dev, const char *mali_dev_name);
-
+int mali_sysfs_register(const char *mali_dev_name);
+int mali_sysfs_unregister(void);
#ifdef __cplusplus
}
diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h
index 5329ba3..5329ba3 100644
--- a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c
index 32f8e6b..05831c5 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_atomics.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c
@@ -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/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c
new file mode 100644
index 0000000..787a145
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c
@@ -0,0 +1,139 @@
+/*
+ * 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_osk_irq.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/slab.h> /* For memory allocation */
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "linux/interrupt.h"
+
+typedef struct _mali_osk_irq_t_struct
+{
+ u32 irqnum;
+ void *data;
+ _mali_osk_irq_uhandler_t uhandler;
+} mali_osk_irq_object_t;
+
+typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
+static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/
+
+_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description )
+{
+ mali_osk_irq_object_t *irq_object;
+ unsigned long irq_flags = 0;
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ irq_flags |= IRQF_SHARED;
+#endif /* defined(CONFIG_MALI_SHARED_INTERRUPTS) */
+
+ irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL);
+ if (NULL == irq_object)
+ {
+ return NULL;
+ }
+
+ if (-1 == irqnum)
+ {
+ /* Probe for IRQ */
+ if ( (NULL != trigger_func) && (NULL != ack_func) )
+ {
+ unsigned long probe_count = 3;
+ _mali_osk_errcode_t err;
+ int irq;
+
+ MALI_DEBUG_PRINT(2, ("Probing for irq\n"));
+
+ do
+ {
+ unsigned long mask;
+
+ mask = probe_irq_on();
+ trigger_func(probe_data);
+
+ _mali_osk_time_ubusydelay(5);
+
+ irq = probe_irq_off(mask);
+ err = ack_func(probe_data);
+ }
+ while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--);
+
+ if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1;
+ else irqnum = irq;
+ }
+ else irqnum = -1; /* no probe functions, fault */
+
+ if (-1 != irqnum)
+ {
+ /* found an irq */
+ MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Probe for irq failed\n"));
+ }
+ }
+
+ irq_object->irqnum = irqnum;
+ irq_object->uhandler = uhandler;
+ irq_object->data = int_data;
+
+ if (-1 == irqnum)
+ {
+ MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description));
+ kfree(irq_object);
+ return NULL;
+ }
+
+ if (0 != request_irq(irqnum, irq_handler_upper_half, irq_flags, description, irq_object))
+ {
+ MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description));
+ kfree(irq_object);
+ return NULL;
+ }
+
+ return irq_object;
+}
+
+void _mali_osk_irq_term( _mali_osk_irq_t *irq )
+{
+ mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
+ free_irq(irq_object->irqnum, irq_object);
+ kfree(irq_object);
+}
+
+
+/** This function is called directly in interrupt context from the OS just after
+ * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel.
+ * It is registered one of these function for each mali core. When an interrupt
+ * arrives this function will be called equal times as registered mali cores.
+ * That means that we only check one mali core in one function call, and the
+ * core we check for each turn is given by the \a dev_id variable.
+ * If we detect an pending interrupt on the given core, we mask the interrupt
+ * out by settging the core's IRQ_MASK register to zero.
+ * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority
+ * work queue job.
+ */
+static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/
+{
+ irqreturn_t ret = IRQ_NONE;
+ mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id;
+
+ if (_MALI_OSK_ERR_OK == irq_object->uhandler(irq_object->data))
+ {
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c
index ee857d5..cce946a 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c
@@ -13,19 +13,12 @@
* Implemenation of the OS abstraction layer for the kernel device driver
*/
-/* needed to detect kernel version specific code */
-#include <linux/version.h>
-
#include <linux/spinlock.h>
#include <linux/rwsem.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-#include <linux/semaphore.h>
-#else /* pre 2.6.26 the file was in the arch specific location */
-#include <asm/semaphore.h>
-#endif
+#include <linux/mutex.h>
#include <linux/slab.h>
+
#include "mali_osk.h"
#include "mali_kernel_common.h"
@@ -34,9 +27,9 @@ typedef enum
{
_MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */
_MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ, /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */
- _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use up()/down_interruptable() */
- _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use up()/down() */
- _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {up,down}{read,write}() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use mutex_unlock()/down_interruptable() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use mutex_unlock()/down() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {mutex_unlock,down}{read,write}() */
/* Linux supports, but we do not support:
* Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off
@@ -55,7 +48,7 @@ struct _mali_osk_lock_t_struct
union
{
spinlock_t spinlock;
- struct semaphore sema;
+ struct mutex mutex;
struct rw_semaphore rw_sema;
} obj;
MALI_DEBUG_CODE(
@@ -65,9 +58,6 @@ struct _mali_osk_lock_t_struct
/* id of the thread currently holding this lock, 0 if no
* threads hold it. */
u32 owner;
- /* number of owners this lock currently has (can be > 1 if
- * taken in R/O mode. */
- u32 nOwners;
/* what mode the lock was taken in */
_mali_osk_lock_mode_t mode;
); /* MALI_DEBUG_CODE */
@@ -132,7 +122,7 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
}
/* Initially unlocked */
- sema_init( &lock->obj.sema, 1 );
+ mutex_init(&lock->obj.mutex);
}
#ifdef DEBUG
@@ -141,7 +131,6 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
/* Debug tracking of lock owner */
lock->owner = 0;
- lock->nOwners = 0;
#endif /* DEBUG */
return lock;
@@ -153,11 +142,6 @@ u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock )
return lock->owner;
}
-u32 _mali_osk_lock_get_number_owners( _mali_osk_lock_t *lock )
-{
- return lock->nOwners;
-}
-
u32 _mali_osk_lock_get_mode( _mali_osk_lock_t *lock )
{
return lock->mode;
@@ -194,7 +178,7 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
- if ( down_interruptible(&lock->obj.sema) )
+ if (mutex_lock_interruptible(&lock->obj.mutex))
{
MALI_PRINT_ERROR(("Can not lock mutex\n"));
err = _MALI_OSK_ERR_RESTARTSYSCALL;
@@ -202,7 +186,7 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
- down(&lock->obj.sema);
+ mutex_lock(&lock->obj.mutex);
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
@@ -229,7 +213,6 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
{
if (mode == _MALI_OSK_LOCKMODE_RW)
{
- /*MALI_DEBUG_ASSERT(0 == lock->owner);*/
if (0 != lock->owner)
{
printk(KERN_ERR "%d: ERROR: Lock %p already has owner %d\n", _mali_osk_get_tid(), lock, lock->owner);
@@ -237,13 +220,10 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
}
lock->owner = _mali_osk_get_tid();
lock->mode = mode;
- ++lock->nOwners;
}
else /* mode == _MALI_OSK_LOCKMODE_RO */
{
- lock->owner |= _mali_osk_get_tid();
lock->mode = mode;
- ++lock->nOwners;
}
}
#endif
@@ -269,7 +249,6 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
/* make sure the thread releasing the lock actually was the owner */
if (mode == _MALI_OSK_LOCKMODE_RW)
{
- /*MALI_DEBUG_ASSERT(_mali_osk_get_tid() == lock->owner);*/
if (_mali_osk_get_tid() != lock->owner)
{
printk(KERN_ERR "%d: ERROR: Lock %p owner was %d\n", _mali_osk_get_tid(), lock, lock->owner);
@@ -277,23 +256,7 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
}
/* This lock now has no owner */
lock->owner = 0;
- --lock->nOwners;
- }
- else /* mode == _MALI_OSK_LOCKMODE_RO */
- {
- if ((_mali_osk_get_tid() & lock->owner) != _mali_osk_get_tid())
- {
- printk(KERN_ERR "%d: ERROR: Not an owner of %p lock.\n", _mali_osk_get_tid(), lock);
- dump_stack();
- }
-
- /* if this is the last thread holding this lock in R/O mode, set owner
- * back to 0 */
- if (0 == --lock->nOwners)
- {
- lock->owner = 0;
- }
- }
+ } /* else if (mode == _MALI_OSK_LOCKMODE_RO) Nothing to check */
#endif /* DEBUG */
switch ( lock->type )
@@ -308,7 +271,7 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
/* FALLTHROUGH */
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
- up(&lock->obj.sema);
+ mutex_unlock(&lock->obj.mutex);
break;
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c
index 02558a0..8c0ef17 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c
@@ -25,6 +25,9 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
#include <linux/shrinker.h>
#endif
+#include <linux/sched.h>
+#include <linux/mm_types.h>
+#include <linux/rwsem.h>
#include "mali_osk.h"
#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */
@@ -48,6 +51,7 @@ typedef struct mali_vma_usage_tracker
u32 cookie;
} mali_vma_usage_tracker;
+#define INVALID_PAGE 0xffffffff
/* Linked list structure to hold details of all OS allocations in a particular
* mapping
@@ -188,7 +192,7 @@ static u32 _kernel_page_allocate(void)
if ( NULL == new_page )
{
- return 0;
+ return INVALID_PAGE;
}
/* Ensure page is flushed from CPU caches. */
@@ -234,7 +238,7 @@ static AllocationList * _allocation_list_item_get(void)
}
item->physaddr = _kernel_page_allocate();
- if ( 0 == item->physaddr )
+ if ( INVALID_PAGE == item->physaddr )
{
/* Non-fatal error condition, out of memory. Upper levels will handle this. */
_mali_osk_free( item );
@@ -261,7 +265,6 @@ static void _allocation_list_item_release(AllocationList * item)
_mali_osk_free( item );
}
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
#else
@@ -280,6 +283,8 @@ static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_st
MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n"));
MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void*)address));
+ MALI_IGNORE(address);
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
return VM_FAULT_SIGBUS;
#else
@@ -333,7 +338,6 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma)
* In the case of the memory engine, it is called as the release function that has been registered with the engine*/
}
-
void _mali_osk_mem_barrier( void )
{
mb();
@@ -364,7 +368,7 @@ mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size )
/* dma_alloc_* uses a limited region of address space. On most arch/marchs
* 2 to 14 MiB is available. This should be enough for the page tables, which
* currently is the only user of this function. */
- virt = dma_alloc_coherent(NULL, size, phys, GFP_KERNEL | GFP_DMA );
+ virt = dma_alloc_writecombine(NULL, size, phys, GFP_KERNEL | GFP_DMA | __GFP_ZERO);
MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys));
@@ -385,17 +389,23 @@ void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt )
MALI_DEBUG_ASSERT( 0 != size );
MALI_DEBUG_ASSERT( 0 == (phys & ( (1 << PAGE_SHIFT) - 1 )) );
- dma_free_coherent(NULL, size, virt, phys);
+ dma_free_writecombine(NULL, size, virt, phys);
}
_mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description )
{
+#if MALI_LICENSE_IS_GPL
+ return _MALI_OSK_ERR_OK; /* GPL driver gets the mem region for the resources registered automatically */
+#else
return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK);
+#endif
}
void inline _mali_osk_mem_unreqregion( u32 phys, u32 size )
{
+#if !MALI_LICENSE_IS_GPL
release_mem_region(phys, size);
+#endif
}
void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val )
@@ -464,8 +474,14 @@ _mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descr
The memory is reserved, meaning that it's present and can never be paged out (see also previous entry)
*/
vma->vm_flags |= VM_IO;
- vma->vm_flags |= VM_RESERVED;
vma->vm_flags |= VM_DONTCOPY;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+ vma->vm_flags |= VM_RESERVED;
+#else
+ vma->vm_flags |= VM_DONTDUMP;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags |= VM_PFNMAP;
+#endif
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */
@@ -658,3 +674,50 @@ void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 off
return;
}
+
+u32 _mali_osk_mem_write_safe(void *dest, const void *src, u32 size)
+{
+#define MALI_MEM_SAFE_COPY_BLOCK_SIZE 4096
+ u32 retval = 0;
+ void *temp_buf;
+
+ temp_buf = kmalloc(MALI_MEM_SAFE_COPY_BLOCK_SIZE, GFP_KERNEL);
+ if (NULL != temp_buf)
+ {
+ u32 bytes_left_to_copy = size;
+ u32 i;
+ for (i = 0; i < size; i += MALI_MEM_SAFE_COPY_BLOCK_SIZE)
+ {
+ u32 size_to_copy;
+ u32 size_copied;
+ u32 bytes_left;
+
+ if (bytes_left_to_copy > MALI_MEM_SAFE_COPY_BLOCK_SIZE)
+ {
+ size_to_copy = MALI_MEM_SAFE_COPY_BLOCK_SIZE;
+ }
+ else
+ {
+ size_to_copy = bytes_left_to_copy;
+ }
+
+ bytes_left = copy_from_user(temp_buf, ((char*)src) + i, size_to_copy);
+ size_copied = size_to_copy - bytes_left;
+
+ bytes_left = copy_to_user(((char*)dest) + i, temp_buf, size_copied);
+ size_copied -= bytes_left;
+
+ bytes_left_to_copy -= size_copied;
+ retval += size_copied;
+
+ if (size_copied != size_to_copy)
+ {
+ break; /* Early out, we was not able to copy this entire block */
+ }
+ }
+
+ kfree(temp_buf);
+ }
+
+ return retval;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c
new file mode 100644
index 0000000..50d6ddf
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c
@@ -0,0 +1,140 @@
+/*
+ * 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_osk_mali.c
+ * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
+ */
+#include <linux/kernel.h>
+#include <asm/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/mali/mali_utgard.h>
+
+#include "mali_osk_mali.h"
+#include "mali_kernel_common.h" /* MALI_xxx macros */
+#include "mali_osk.h" /* kernel side OS functions */
+#include "mali_uk_types.h"
+#include "mali_kernel_linux.h"
+
+_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res)
+{
+ int i;
+
+ if (NULL == mali_platform_device)
+ {
+ /* Not connected to a device */
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+ }
+
+ for (i = 0; i < mali_platform_device->num_resources; i++)
+ {
+ if (IORESOURCE_MEM == resource_type(&(mali_platform_device->resource[i])) &&
+ mali_platform_device->resource[i].start == addr)
+ {
+ if (NULL != res)
+ {
+ res->base = addr;
+ res->description = mali_platform_device->resource[i].name;
+
+ /* Any (optional) IRQ resource belonging to this resource will follow */
+ if ((i + 1) < mali_platform_device->num_resources &&
+ IORESOURCE_IRQ == resource_type(&(mali_platform_device->resource[i+1])))
+ {
+ res->irq = mali_platform_device->resource[i+1].start;
+ }
+ else
+ {
+ res->irq = -1;
+ }
+ }
+ return _MALI_OSK_ERR_OK;
+ }
+ }
+
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+}
+
+u32 _mali_osk_resource_base_address(void)
+{
+ u32 lowest_addr = 0xFFFFFFFF;
+ u32 ret = 0;
+
+ if (NULL != mali_platform_device)
+ {
+ int i;
+ for (i = 0; i < mali_platform_device->num_resources; i++)
+ {
+ if (mali_platform_device->resource[i].flags & IORESOURCE_MEM &&
+ mali_platform_device->resource[i].start < lowest_addr)
+ {
+ lowest_addr = mali_platform_device->resource[i].start;
+ ret = lowest_addr;
+ }
+ }
+ }
+
+ return ret;
+}
+
+_mali_osk_errcode_t _mali_osk_device_data_get(struct _mali_osk_device_data *data)
+{
+ MALI_DEBUG_ASSERT_POINTER(data);
+
+ if (NULL != mali_platform_device)
+ {
+ struct mali_gpu_device_data* os_data = NULL;
+
+ os_data = (struct mali_gpu_device_data*)mali_platform_device->dev.platform_data;
+ if (NULL != os_data)
+ {
+ /* Copy data from OS dependant struct to Mali neutral struct (identical!) */
+ data->dedicated_mem_start = os_data->dedicated_mem_start;
+ data->dedicated_mem_size = os_data->dedicated_mem_size;
+ data->shared_mem_size = os_data->shared_mem_size;
+ data->fb_start = os_data->fb_start;
+ data->fb_size = os_data->fb_size;
+ data->utilization_interval = os_data->utilization_interval;
+ data->utilization_callback = os_data->utilization_callback;
+ data->pmu_switch_delay = os_data->pmu_switch_delay;
+ return _MALI_OSK_ERR_OK;
+ }
+ }
+
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+}
+
+mali_bool _mali_osk_shared_interrupts(void)
+{
+ u32 irqs[128];
+ u32 i, j, irq, num_irqs_found = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ MALI_DEBUG_ASSERT(128 >= mali_platform_device->num_resources);
+
+ for (i = 0; i < mali_platform_device->num_resources; i++)
+ {
+ if (IORESOURCE_IRQ & mali_platform_device->resource[i].flags)
+ {
+ irq = mali_platform_device->resource[i].start;
+
+ for (j = 0; j < num_irqs_found; ++j)
+ {
+ if (irq == irqs[j])
+ {
+ return MALI_TRUE;
+ }
+ }
+
+ irqs[num_irqs_found++] = irq;
+ }
+ }
+
+ return MALI_FALSE;
+}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_math.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c
index bb25e7d..3e62e51 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_math.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c
@@ -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/drivers/media/video/samsung/mali/linux/mali_osk_memory.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c
index 5354e85..7bb470f 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c
@@ -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/drivers/media/video/samsung/mali/linux/mali_osk_misc.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c
index ad486db..ad486db 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c
index c14c0d5..c265f88 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c
@@ -16,16 +16,9 @@
#include "mali_osk.h"
#include "mali_kernel_common.h"
-/* needed to detect kernel version specific code */
-#include <linux/version.h>
-
#include <linux/sched.h>
#include <linux/slab.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-#include <linux/semaphore.h>
-#else /* pre 2.6.26 the file was in the arch specific location */
-#include <asm/semaphore.h>
-#endif
+#include <linux/spinlock.h>
/**
* Declaration of the notification queue object type
@@ -35,15 +28,15 @@
*/
struct _mali_osk_notification_queue_t_struct
{
- struct semaphore mutex; /**< Mutex protecting the list */
+ spinlock_t mutex; /**< Mutex protecting the list */
wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */
struct list_head head; /**< List of notifications waiting to be picked up */
};
typedef struct _mali_osk_notification_wrapper_t_struct
{
- struct list_head list; /**< Internal linked list variable */
- _mali_osk_notification_t data; /**< Notification data */
+ struct list_head list; /**< Internal linked list variable */
+ _mali_osk_notification_t data; /**< Notification data */
} _mali_osk_notification_wrapper_t;
_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
@@ -53,7 +46,7 @@ _mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL);
if (NULL == result) return NULL;
- sema_init(&result->mutex, 1);
+ spin_lock_init(&result->mutex);
init_waitqueue_head(&result->receive_queue);
INIT_LIST_HEAD(&result->head);
@@ -63,15 +56,15 @@ _mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
{
/* OPT Recycling of notification objects */
- _mali_osk_notification_wrapper_t *notification;
+ _mali_osk_notification_wrapper_t *notification;
notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size,
GFP_KERNEL | __GFP_HIGH | __GFP_REPEAT);
- if (NULL == notification)
- {
+ if (NULL == notification)
+ {
MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n"));
return NULL;
- }
+ }
/* Init the list */
INIT_LIST_HEAD(&notification->list);
@@ -90,7 +83,7 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
notification->data.result_buffer_size = size;
/* all ok */
- return &(notification->data);
+ return &(notification->data);
}
void _mali_osk_notification_delete( _mali_osk_notification_t *object )
@@ -98,7 +91,7 @@ void _mali_osk_notification_delete( _mali_osk_notification_t *object )
_mali_osk_notification_wrapper_t *notification;
MALI_DEBUG_ASSERT_POINTER( object );
- notification = container_of( object, _mali_osk_notification_wrapper_t, data );
+ notification = container_of( object, _mali_osk_notification_wrapper_t, data );
/* Free the container */
kfree(notification);
@@ -106,54 +99,61 @@ void _mali_osk_notification_delete( _mali_osk_notification_t *object )
void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue )
{
+ _mali_osk_notification_t *result;
MALI_DEBUG_ASSERT_POINTER( queue );
+ while (_MALI_OSK_ERR_OK == _mali_osk_notification_queue_dequeue(queue, &result))
+ {
+ _mali_osk_notification_delete( result );
+ }
+
/* not much to do, just free the memory */
kfree(queue);
}
-
void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object )
{
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ unsigned long irq_flags;
+#endif
+
_mali_osk_notification_wrapper_t *notification;
MALI_DEBUG_ASSERT_POINTER( queue );
MALI_DEBUG_ASSERT_POINTER( object );
- notification = container_of( object, _mali_osk_notification_wrapper_t, data );
+ notification = container_of( object, _mali_osk_notification_wrapper_t, data );
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_lock_irqsave(&queue->mutex, irq_flags);
+#else
+ spin_lock(&queue->mutex);
+#endif
- /* lock queue access */
- down(&queue->mutex);
- /* add to list */
list_add_tail(&notification->list, &queue->head);
- /* unlock the queue */
- up(&queue->mutex);
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_unlock_irqrestore(&queue->mutex, irq_flags);
+#else
+ spin_unlock(&queue->mutex);
+#endif
/* and wake up one possible exclusive waiter */
wake_up(&queue->receive_queue);
}
-static int _mali_notification_queue_is_empty( _mali_osk_notification_queue_t *queue )
-{
- int ret;
-
- down(&queue->mutex);
- ret = list_empty(&queue->head);
- up(&queue->mutex);
- return ret;
-}
-
-#if MALI_STATE_TRACKING
-mali_bool _mali_osk_notification_queue_is_empty( _mali_osk_notification_queue_t *queue )
+_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
{
- return _mali_notification_queue_is_empty(queue) ? MALI_TRUE : MALI_FALSE;
-}
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ unsigned long irq_flags;
#endif
-_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
-{
_mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND;
_mali_osk_notification_wrapper_t *wrapper_object;
- down(&queue->mutex);
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_lock_irqsave(&queue->mutex, irq_flags);
+#else
+ spin_lock(&queue->mutex);
+#endif
if (!list_empty(&queue->head))
{
@@ -163,7 +163,11 @@ _mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification
ret = _MALI_OSK_ERR_OK;
}
- up(&queue->mutex);
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_unlock_irqrestore(&queue->mutex, irq_flags);
+#else
+ spin_unlock(&queue->mutex);
+#endif
return ret;
}
@@ -174,15 +178,13 @@ _mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification
MALI_DEBUG_ASSERT_POINTER( queue );
MALI_DEBUG_ASSERT_POINTER( result );
- /* default result */
+ /* default result */
*result = NULL;
- while (_MALI_OSK_ERR_OK != _mali_osk_notification_queue_dequeue(queue, result))
+ if (wait_event_interruptible(queue->receive_queue,
+ _MALI_OSK_ERR_OK == _mali_osk_notification_queue_dequeue(queue, result)))
{
- if (wait_event_interruptible(queue->receive_queue, !_mali_notification_queue_is_empty(queue)))
- {
- return _MALI_OSK_ERR_RESTARTSYSCALL;
- }
+ return _MALI_OSK_ERR_RESTARTSYSCALL;
}
return _MALI_OSK_ERR_OK; /* all ok */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c
new file mode 100644
index 0000000..bc19af9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c
@@ -0,0 +1,110 @@
+/**
+ * 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_osk_pm.c
+ * Implementation of the callback functions from common power management
+ */
+
+#include <linux/sched.h>
+
+#ifdef CONFIG_PM_RUNTIME
+#include <linux/pm_runtime.h>
+#endif /* CONFIG_PM_RUNTIME */
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_linux.h"
+
+static _mali_osk_atomic_t mali_pm_ref_count;
+
+void _mali_osk_pm_dev_enable(void)
+{
+ _mali_osk_atomic_init(&mali_pm_ref_count, 0);
+}
+
+void _mali_osk_pm_dev_disable(void)
+{
+ _mali_osk_atomic_term(&mali_pm_ref_count);
+}
+
+/* Can NOT run in atomic context */
+_mali_osk_errcode_t _mali_osk_pm_dev_ref_add(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ int err;
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ err = pm_runtime_get_sync(&(mali_platform_device->dev));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_mark_last_busy(&(mali_platform_device->dev));
+#endif
+ if (0 > err)
+ {
+ MALI_PRINT_ERROR(("Mali OSK PM: pm_runtime_get_sync() returned error code %d\n", err));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ _mali_osk_atomic_inc(&mali_pm_ref_count);
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: Power ref taken (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+#endif
+ return _MALI_OSK_ERR_OK;
+}
+
+/* Can run in atomic context */
+void _mali_osk_pm_dev_ref_dec(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ _mali_osk_atomic_dec(&mali_pm_ref_count);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_mark_last_busy(&(mali_platform_device->dev));
+ pm_runtime_put_autosuspend(&(mali_platform_device->dev));
+#else
+ pm_runtime_put(&(mali_platform_device->dev));
+#endif
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: Power ref released (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+#endif
+}
+
+/* Can run in atomic context */
+mali_bool _mali_osk_pm_dev_ref_add_no_power_on(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ u32 ref;
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ pm_runtime_get_noresume(&(mali_platform_device->dev));
+ ref = _mali_osk_atomic_read(&mali_pm_ref_count);
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: No-power ref taken (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+ return ref > 0 ? MALI_TRUE : MALI_FALSE;
+#else
+ return MALI_TRUE;
+#endif
+}
+
+/* Can run in atomic context */
+void _mali_osk_pm_dev_ref_dec_no_power_on(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_put_autosuspend(&(mali_platform_device->dev));
+#else
+ pm_runtime_put(&(mali_platform_device->dev));
+#endif
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: No-power ref released (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+#endif
+}
+
+void _mali_osk_pm_dev_barrier(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ pm_runtime_barrier(&(mali_platform_device->dev));
+#endif
+}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c
index 95bee53..5429329 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
+#include <mali_profiling_gator_api.h>
#include "mali_kernel_common.h"
#include "mali_osk.h"
#include "mali_ukk.h"
@@ -18,6 +19,7 @@
#include "mali_linux_trace.h"
#include "mali_gp.h"
#include "mali_pp.h"
+#include "mali_pp_scheduler.h"
#include "mali_l2_cache.h"
#include "mali_user_settings_db.h"
@@ -125,59 +127,46 @@ _mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *
*/
int _mali_profiling_set_event(u32 counter_id, s32 event_id)
{
+ if (COUNTER_VP_0_C0 == counter_id)
+ {
+ if (MALI_TRUE == mali_gp_job_set_gp_counter_src0(event_id))
+ {
+ return 1;
+ }
+ }
- if (COUNTER_VP_C0 == counter_id)
+ if (COUNTER_VP_0_C1 == counter_id)
{
- struct mali_gp_core* gp_core = mali_gp_get_global_gp_core();
- if (NULL != gp_core)
+ if (MALI_TRUE == mali_gp_job_set_gp_counter_src1(event_id))
{
- if (MALI_TRUE == mali_gp_core_set_counter_src0(gp_core, event_id))
- {
- return 1;
- }
+ return 1;
}
}
- if (COUNTER_VP_C1 == counter_id)
+
+ if (COUNTER_FP_0_C0 == counter_id)
{
- struct mali_gp_core* gp_core = mali_gp_get_global_gp_core();
- if (NULL != gp_core)
+ if (MALI_TRUE == mali_pp_job_set_pp_counter_src0(event_id))
{
- if (MALI_TRUE == mali_gp_core_set_counter_src1(gp_core, event_id))
- {
- return 1;
- }
+ return 1;
}
}
- if (COUNTER_FP0_C0 <= counter_id && COUNTER_FP3_C1 >= counter_id)
+
+ if (COUNTER_FP_0_C1 == counter_id)
{
- u32 core_id = (counter_id - COUNTER_FP0_C0) >> 1;
- struct mali_pp_core* pp_core = mali_pp_get_global_pp_core(core_id);
- if (NULL != pp_core)
+ if (MALI_TRUE == mali_pp_job_set_pp_counter_src1(event_id))
{
- u32 counter_src = (counter_id - COUNTER_FP0_C0) & 1;
- if (0 == counter_src)
- {
- if (MALI_TRUE == mali_pp_core_set_counter_src0(pp_core, event_id))
- {
- return 1;
- }
- }
- else
- {
- if (MALI_TRUE == mali_pp_core_set_counter_src1(pp_core, event_id))
- {
- return 1;
- }
- }
+ return 1;
}
}
- if (COUNTER_L2_C0 <= counter_id && COUNTER_L2_C1 >= counter_id)
+
+ if (COUNTER_L2_0_C0 <= counter_id && COUNTER_L2_2_C1 >= counter_id)
{
- u32 core_id = (counter_id - COUNTER_L2_C0) >> 1;
+ u32 core_id = (counter_id - COUNTER_L2_0_C0) >> 1;
struct mali_l2_cache_core* l2_cache_core = mali_l2_cache_core_get_glob_l2_core(core_id);
+
if (NULL != l2_cache_core)
{
- u32 counter_src = (counter_id - COUNTER_L2_C0) & 1;
+ u32 counter_src = (counter_id - COUNTER_L2_0_C0) & 1;
if (0 == counter_src)
{
if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id))
@@ -199,38 +188,51 @@ int _mali_profiling_set_event(u32 counter_id, s32 event_id)
}
/**
- * Called by gator.ko to retrieve the L2 cache counter values for the first L2 cache.
+ * Called by gator.ko to retrieve the L2 cache counter values for all L2 cache cores.
* The L2 cache counters are unique in that they are polled by gator, rather than being
- * transmitted via the tracepoint mechanism.
+ * transmitted via the tracepoint mechanism.
*
- * @param src0 First L2 cache counter ID.
- * @param val0 First L2 cache counter value.
- * @param src1 Second L2 cache counter ID.
- * @param val1 Second L2 cache counter value.
+ * @param values Pointer to a _mali_profiling_l2_counter_values structure where
+ * the counter sources and values will be output
+ * @return 0 if all went well; otherwise, return the mask with the bits set for the powered off cores
*/
-void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1)
+u32 _mali_profiling_get_l2_counters(_mali_profiling_l2_counter_values *values)
{
- struct mali_l2_cache_core *l2_cache = mali_l2_cache_core_get_glob_l2_core(0);
- if (NULL != l2_cache)
- {
+ struct mali_l2_cache_core *l2_cache;
+ u32 l2_cores_num = mali_l2_cache_core_get_glob_num_l2_cores();
+ u32 i;
+ u32 ret = 0;
+
+ MALI_DEBUG_ASSERT(l2_cores_num <= 3);
+
+ for (i = 0; i < l2_cores_num; i++)
+ {
+ l2_cache = mali_l2_cache_core_get_glob_l2_core(i);
+
+ if (NULL == l2_cache)
+ {
+ continue;
+ }
+
if (MALI_TRUE == mali_l2_cache_lock_power_state(l2_cache))
{
/* It is now safe to access the L2 cache core in order to retrieve the counters */
- mali_l2_cache_core_get_counter_values(l2_cache, src0, val0, src1, val1);
+ mali_l2_cache_core_get_counter_values(l2_cache,
+ &values->cores[i].source0,
+ &values->cores[i].value0,
+ &values->cores[i].source1,
+ &values->cores[i].value1);
+ }
+ else
+ {
+ /* The core was not available, set the right bit in the mask. */
+ ret |= (1 << i);
}
mali_l2_cache_unlock_power_state(l2_cache);
- }
-}
+ }
-/*
- * List of possible actions to be controlled by Streamline.
- * The following numbers are used by gator to control the frame buffer dumping and s/w counter reporting.
- * We cannot use the enums in mali_uk_types.h because they are unknown inside gator.
- */
-#define FBDUMP_CONTROL_ENABLE (1)
-#define FBDUMP_CONTROL_RATE (2)
-#define SW_COUNTER_ENABLE (3)
-#define FBDUMP_CONTROL_RESIZE_FACTOR (4)
+ return ret;
+}
/**
* Called by gator to control the production of profiling information at runtime.
@@ -256,6 +258,30 @@ void _mali_profiling_control(u32 action, u32 value)
}
}
+/**
+ * Called by gator to get mali api version.
+ */
+u32 _mali_profiling_get_api_version(void)
+{
+ return MALI_PROFILING_API_VERSION;
+}
+
+/**
+* Called by gator to get the data about Mali instance in use:
+* product id, version, number of cores
+*/
+void _mali_profiling_get_mali_version(struct _mali_profiling_mali_version *values)
+{
+ values->mali_product_id = (u32)mali_kernel_core_get_product_id();
+ values->mali_version_major = mali_kernel_core_get_gpu_major_version();
+ values->mali_version_minor = mali_kernel_core_get_gpu_minor_version();
+ values->num_of_l2_cores = mali_l2_cache_core_get_glob_num_l2_cores();
+ values->num_of_fp_cores = mali_pp_scheduler_get_num_cores_total();
+ values->num_of_vp_cores = 1;
+}
+
EXPORT_SYMBOL(_mali_profiling_set_event);
-EXPORT_SYMBOL(_mali_profiling_get_counters);
+EXPORT_SYMBOL(_mali_profiling_get_l2_counters);
EXPORT_SYMBOL(_mali_profiling_control);
+EXPORT_SYMBOL(_mali_profiling_get_api_version);
+EXPORT_SYMBOL(_mali_profiling_get_mali_version);
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h
new file mode 100644
index 0000000..15d98e0
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h
@@ -0,0 +1,37 @@
+/*
+ * 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_osk_specific.h
+ * Defines per-OS Kernel level specifics, such as unusual workarounds for
+ * certain OSs.
+ */
+
+#ifndef __MALI_OSK_SPECIFIC_H__
+#define __MALI_OSK_SPECIFIC_H__
+
+#include <asm/uaccess.h>
+
+#include "mali_sync.h"
+
+#define MALI_STATIC_INLINE static inline
+#define MALI_NON_STATIC_INLINE inline
+
+#ifdef CONFIG_SYNC
+typedef struct sync_timeline mali_sync_tl;
+typedef struct sync_pt mali_sync_pt;
+#endif /* CONFIG_SYNC */
+
+MALI_STATIC_INLINE u32 _mali_osk_copy_from_user(void *to, void *from, u32 n)
+{
+ return (u32)copy_from_user(to, from, (unsigned long)n);
+}
+
+#endif /* __MALI_OSK_SPECIFIC_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_time.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c
index b399b87..2aa6588 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_time.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c
index e5829a3..0e28b32 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c
@@ -35,14 +35,14 @@ _mali_osk_timer_t *_mali_osk_timer_init(void)
void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire )
{
MALI_DEBUG_ASSERT_POINTER(tim);
- tim->timer.expires = _mali_osk_time_tickcount() + ticks_to_expire;
+ tim->timer.expires = jiffies + ticks_to_expire;
add_timer(&(tim->timer));
}
-void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 expiry_tick)
+void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 ticks_to_expire)
{
MALI_DEBUG_ASSERT_POINTER(tim);
- mod_timer(&(tim->timer), expiry_tick);
+ mod_timer(&(tim->timer), jiffies + ticks_to_expire);
}
void _mali_osk_timer_del( _mali_osk_timer_t *tim )
@@ -51,6 +51,18 @@ void _mali_osk_timer_del( _mali_osk_timer_t *tim )
del_timer_sync(&(tim->timer));
}
+void _mali_osk_timer_del_async( _mali_osk_timer_t *tim )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ del_timer(&(tim->timer));
+}
+
+mali_bool _mali_osk_timer_pending( _mali_osk_timer_t *tim )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ return 1 == timer_pending(&(tim->timer));
+}
+
void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data )
{
MALI_DEBUG_ASSERT_POINTER(tim);
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c
index ce0561d..ce0561d 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c
new file mode 100644
index 0000000..23f5720
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c
@@ -0,0 +1,124 @@
+/*
+ * 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_osk_wq.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/slab.h> /* For memory allocation */
+#include <linux/workqueue.h>
+#include <linux/version.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_license.h"
+#include "mali_kernel_linux.h"
+
+typedef struct _mali_osk_wq_work_t_struct
+{
+ _mali_osk_wq_work_handler_t handler;
+ void *data;
+ struct work_struct work_handle;
+} mali_osk_wq_work_object_t;
+
+#if MALI_LICENSE_IS_GPL
+struct workqueue_struct *mali_wq = NULL;
+#endif
+
+static void _mali_osk_wq_work_func ( struct work_struct *work );
+
+_mali_osk_errcode_t _mali_osk_wq_init(void)
+{
+#if MALI_LICENSE_IS_GPL
+ MALI_DEBUG_ASSERT(NULL == mali_wq);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
+ mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0);
+#else
+ mali_wq = create_workqueue("mali");
+#endif
+ if(NULL == mali_wq)
+ {
+ MALI_PRINT_ERROR(("Unable to create Mali workqueue\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_osk_wq_flush(void)
+{
+#if MALI_LICENSE_IS_GPL
+ flush_workqueue(mali_wq);
+#else
+ flush_scheduled_work();
+#endif
+}
+
+void _mali_osk_wq_term(void)
+{
+#if MALI_LICENSE_IS_GPL
+ MALI_DEBUG_ASSERT(NULL != mali_wq);
+
+ flush_workqueue(mali_wq);
+ destroy_workqueue(mali_wq);
+ mali_wq = NULL;
+#else
+ flush_scheduled_work();
+#endif
+}
+
+_mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data )
+{
+ mali_osk_wq_work_object_t *work = kmalloc(sizeof(mali_osk_wq_work_object_t), GFP_KERNEL);
+
+ if (NULL == work) return NULL;
+
+ work->handler = handler;
+ work->data = data;
+
+ INIT_WORK( &work->work_handle, _mali_osk_wq_work_func );
+
+ return work;
+}
+
+void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work )
+{
+ mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
+ _mali_osk_wq_flush();
+ kfree(work_object);
+}
+
+void _mali_osk_wq_delete_work_nonflush( _mali_osk_wq_work_t *work )
+{
+ mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
+ kfree(work_object);
+}
+
+void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work )
+{
+ mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
+#if MALI_LICENSE_IS_GPL
+ queue_work(mali_wq, &work_object->work_handle);
+#else
+ schedule_work(&work_object->work_handle);
+#endif
+}
+
+static void _mali_osk_wq_work_func ( struct work_struct *work )
+{
+ mali_osk_wq_work_object_t *work_object;
+
+ work_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_wq_work_object_t, work_handle);
+ work_object->handler(work_object->data);
+}
+
diff --git a/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c
index f3b0a2c..05dc291 100644
--- a/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c
@@ -18,6 +18,7 @@
#include "mali_osk.h"
#include "mali_kernel_common.h"
#include "mali_pmu.h"
+#include "mali_pp_scheduler.h"
#include "linux/mali/mali_utgard.h"
/* Mali PMU power up/down APIs */
@@ -28,12 +29,13 @@ int mali_pmu_powerup(void)
MALI_DEBUG_PRINT(5, ("Mali PMU: Power up\n"));
+ MALI_DEBUG_ASSERT_POINTER(pmu);
if (NULL == pmu)
{
return -ENXIO;
}
- if (_MALI_OSK_ERR_OK != mali_pmu_powerup_all(pmu))
+ if (_MALI_OSK_ERR_OK != mali_pmu_power_up_all(pmu))
{
return -EFAULT;
}
@@ -49,12 +51,13 @@ int mali_pmu_powerdown(void)
MALI_DEBUG_PRINT(5, ("Mali PMU: Power down\n"));
+ MALI_DEBUG_ASSERT_POINTER(pmu);
if (NULL == pmu)
{
return -ENXIO;
}
- if (_MALI_OSK_ERR_OK != mali_pmu_powerdown_all(pmu))
+ if (_MALI_OSK_ERR_OK != mali_pmu_power_down_all(pmu))
{
return -EFAULT;
}
@@ -63,3 +66,10 @@ int mali_pmu_powerdown(void)
}
EXPORT_SYMBOL(mali_pmu_powerdown);
+
+int mali_perf_set_num_pp_cores(unsigned int num_cores)
+{
+ return mali_pp_scheduler_set_perf_level(num_cores);
+}
+
+EXPORT_SYMBOL(mali_perf_set_num_pp_cores);
diff --git a/drivers/media/video/samsung/mali/linux/mali_profiling_events.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h
index 2639a40..2639a40 100644
--- a/drivers/media/video/samsung/mali/linux/mali_profiling_events.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h
diff --git a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h
index 532fc94..c111cfd 100644
--- a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h
@@ -8,11 +8,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
+#ifndef __MALI_PROFILING_GATOR_API_H__
+#define __MALI_PROFILING_GATOR_API_H__
-#define ARCH_UMP_BACKEND_DEFAULT 0
-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xCE000000
-#define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL
+/* Simple wrapper in order to find the OS specific location of this file */
+#include <linux/mali/mali_utgard_profiling_gator_api.h>
-#endif /* __ARCH_CONFIG_H__ */
+#endif /* __MALI_PROFILING_GATOR_API_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c
new file mode 100644
index 0000000..e40a800
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+#include "mali_timestamp.h"
+#include "mali_osk_profiling.h"
+#include "mali_user_settings_db.h"
+#include "mali_profiling_internal.h"
+
+typedef struct mali_profiling_entry
+{
+ u64 timestamp;
+ u32 event_id;
+ u32 data[5];
+} mali_profiling_entry;
+
+
+typedef enum mali_profiling_state
+{
+ MALI_PROFILING_STATE_UNINITIALIZED,
+ MALI_PROFILING_STATE_IDLE,
+ MALI_PROFILING_STATE_RUNNING,
+ MALI_PROFILING_STATE_RETURN,
+} mali_profiling_state;
+
+static _mali_osk_lock_t *lock = NULL;
+static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
+static mali_profiling_entry* profile_entries = NULL;
+static _mali_osk_atomic_t profile_insert_index;
+static u32 profile_mask = 0;
+static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
+
+void probe_mali_timeline_event(void *data, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned
+ int d2, unsigned int d3, unsigned int d4))
+{
+ add_event(event_id, d0, d1, d2, d3, d4);
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_init(mali_bool auto_start)
+{
+ profile_entries = NULL;
+ profile_mask = 0;
+ _mali_osk_atomic_init(&profile_insert_index, 0);
+
+ lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
+ if (NULL == lock)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ prof_state = MALI_PROFILING_STATE_IDLE;
+
+ if (MALI_TRUE == auto_start)
+ {
+ u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
+
+ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_internal_profiling_term(void)
+{
+ u32 count;
+
+ /* Ensure profiling is stopped */
+ _mali_internal_profiling_stop(&count);
+
+ prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
+
+ if (NULL != profile_entries)
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ if (NULL != lock)
+ {
+ _mali_osk_lock_term(lock);
+ lock = NULL;
+ }
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_start(u32 * limit)
+{
+ _mali_osk_errcode_t ret;
+ mali_profiling_entry *new_profile_entries;
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (MALI_PROFILING_STATE_RUNNING == prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_BUSY;
+ }
+
+ new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry));
+
+ if (NULL == new_profile_entries)
+ {
+ _mali_osk_vfree(new_profile_entries);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ if (MALI_PROFILING_MAX_BUFFER_ENTRIES < *limit)
+ {
+ *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
+ }
+
+ profile_mask = 1;
+ while (profile_mask <= *limit)
+ {
+ profile_mask <<= 1;
+ }
+ profile_mask >>= 1;
+
+ *limit = profile_mask;
+
+ profile_mask--; /* turns the power of two into a mask of one less */
+
+ if (MALI_PROFILING_STATE_IDLE != prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_vfree(new_profile_entries);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ profile_entries = new_profile_entries;
+
+ ret = _mali_timestamp_reset();
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ prof_state = MALI_PROFILING_STATE_RUNNING;
+ }
+ else
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ register_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return ret;
+}
+
+static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
+{
+ u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) & profile_mask;
+
+ profile_entries[cur_index].timestamp = _mali_timestamp_get();
+ profile_entries[cur_index].event_id = event_id;
+ profile_entries[cur_index].data[0] = data0;
+ profile_entries[cur_index].data[1] = data1;
+ profile_entries[cur_index].data[2] = data2;
+ profile_entries[cur_index].data[3] = data3;
+ profile_entries[cur_index].data[4] = data4;
+
+ /* If event is "leave API function", add current memory usage to the event
+ * as data point 4. This is used in timeline profiling to indicate how
+ * much memory was used when leaving a function. */
+ if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC))
+ {
+ profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage();
+ }
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_stop(u32 * count)
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (MALI_PROFILING_STATE_RUNNING != prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ /* go into return state (user to retreive events), no more events will be added after this */
+ prof_state = MALI_PROFILING_STATE_RETURN;
+
+ unregister_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+
+ tracepoint_synchronize_unregister();
+
+ *count = _mali_osk_atomic_read(&profile_insert_index);
+ if (*count > profile_mask) *count = profile_mask;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+u32 _mali_internal_profiling_get_count(void)
+{
+ u32 retval = 0;
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+ if (MALI_PROFILING_STATE_RETURN == prof_state)
+ {
+ retval = _mali_osk_atomic_read(&profile_insert_index);
+ if (retval > profile_mask) retval = profile_mask;
+ }
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+
+ return retval;
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
+{
+ u32 raw_index = _mali_osk_atomic_read(&profile_insert_index);
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (index < profile_mask)
+ {
+ if ((raw_index & ~profile_mask) != 0)
+ {
+ index += raw_index;
+ index &= profile_mask;
+ }
+
+ if (prof_state != MALI_PROFILING_STATE_RETURN)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ if(index >= raw_index)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ *timestamp = profile_entries[index].timestamp;
+ *event_id = profile_entries[index].event_id;
+ data[0] = profile_entries[index].data[0];
+ data[1] = profile_entries[index].data[1];
+ data[2] = profile_entries[index].data[2];
+ data[3] = profile_entries[index].data[3];
+ data[4] = profile_entries[index].data[4];
+ }
+ else
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_clear(void)
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (MALI_PROFILING_STATE_RETURN != prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ prof_state = MALI_PROFILING_STATE_IDLE;
+ profile_mask = 0;
+ _mali_osk_atomic_init(&profile_insert_index, 0);
+
+ if (NULL != profile_entries)
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_OK;
+}
+
+mali_bool _mali_internal_profiling_is_recording(void)
+{
+ return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
+}
+
+mali_bool _mali_internal_profiling_have_recording(void)
+{
+ return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h
new file mode 100644
index 0000000..092b9b0
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PROFILING_INTERNAL_H__
+#define __MALI_PROFILING_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mali_osk.h"
+
+int _mali_internal_profiling_init(mali_bool auto_start);
+void _mali_internal_profiling_term(void);
+
+mali_bool _mali_internal_profiling_is_recording(void);
+mali_bool _mali_internal_profiling_have_recording(void);
+_mali_osk_errcode_t _mali_internal_profiling_clear(void);
+_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
+u32 _mali_internal_profiling_get_count(void);
+int _mali_internal_profiling_stop(u32 * count);
+int _mali_internal_profiling_start(u32 * limit);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_PROFILING_INTERNAL_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c
new file mode 100644
index 0000000..6293610
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file mali_sync.c
+ *
+ */
+
+#include <linux/seq_file.h>
+#include <linux/sync.h>
+#include <linux/timer.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+struct mali_sync_timeline
+{
+ struct sync_timeline timeline;
+ atomic_t counter;
+ atomic_t signalled;
+};
+
+struct mali_sync_pt
+{
+ struct sync_pt pt;
+ u32 order;
+ s32 error;
+ struct timer_list timer;
+};
+
+static void mali_sync_timed_pt_timeout(unsigned long data);
+
+static inline struct mali_sync_timeline *to_mali_sync_timeline(struct sync_timeline *timeline)
+{
+ return container_of(timeline, struct mali_sync_timeline, timeline);
+}
+
+static inline struct mali_sync_pt *to_mali_sync_pt(struct sync_pt *pt)
+{
+ return container_of(pt, struct mali_sync_pt, pt);
+}
+
+static struct sync_pt *timeline_dup(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ struct mali_sync_pt *new_mpt;
+ struct sync_pt *new_pt = sync_pt_create(pt->parent, sizeof(struct mali_sync_pt));
+
+ if (!new_pt)
+ {
+ return NULL;
+ }
+
+ new_mpt = to_mali_sync_pt(new_pt);
+ new_mpt->order = mpt->order;
+
+ return new_pt;
+
+}
+
+static int timeline_has_signaled(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(pt->parent);
+ long diff;
+
+ if (0 != mpt->error)
+ {
+ return mpt->error;
+ }
+
+ diff = atomic_read(&mtl->signalled) - mpt->order;
+
+ return diff >= 0;
+}
+
+static int timeline_compare(struct sync_pt *a, struct sync_pt *b)
+{
+ struct mali_sync_pt *ma = container_of(a, struct mali_sync_pt, pt);
+ struct mali_sync_pt *mb = container_of(b, struct mali_sync_pt, pt);
+
+ long diff = ma->order - mb->order;
+
+ if (diff < 0)
+ {
+ return -1;
+ }
+ else if (diff == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+static void timeline_free_pt(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+
+ if (mpt->timer.function == mali_sync_timed_pt_timeout)
+ {
+ del_timer_sync(&mpt->timer);
+ }
+}
+
+static void timeline_print_tl(struct seq_file *s, struct sync_timeline *sync_timeline)
+{
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(sync_timeline);
+
+ seq_printf(s, "%u, %u", atomic_read(&mtl->signalled), atomic_read(&mtl->counter));
+}
+
+static void timeline_print_pt(struct seq_file *s, struct sync_pt *sync_pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(sync_pt);
+
+ seq_printf(s, "%u", mpt->order);
+
+}
+
+static struct sync_timeline_ops mali_timeline_ops = {
+ .driver_name = "Mali",
+ .dup = timeline_dup,
+ .has_signaled = timeline_has_signaled,
+ .compare = timeline_compare,
+ .free_pt = timeline_free_pt,
+ .print_obj = timeline_print_tl,
+ .print_pt = timeline_print_pt
+};
+
+int mali_sync_timeline_is_ours(struct sync_timeline *timeline)
+{
+ return (timeline->ops == &mali_timeline_ops);
+}
+
+struct sync_timeline *mali_sync_timeline_alloc(const char * name)
+{
+ struct sync_timeline *tl;
+ struct mali_sync_timeline *mtl;
+
+ tl = sync_timeline_create(&mali_timeline_ops,
+ sizeof(struct mali_sync_timeline), name);
+ if (!tl)
+ {
+ return NULL;
+ }
+
+ /* Set the counter in our private struct */
+ mtl = to_mali_sync_timeline(tl);
+ atomic_set(&mtl->counter, 0);
+ atomic_set(&mtl->signalled, 0);
+
+ return tl;
+}
+
+struct sync_pt *mali_sync_pt_alloc(struct sync_timeline *parent)
+{
+ struct sync_pt *pt = sync_pt_create(parent, sizeof(struct mali_sync_pt));
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(parent);
+ struct mali_sync_pt *mpt;
+
+ if (!pt)
+ {
+ return NULL;
+ }
+
+ mpt = to_mali_sync_pt(pt);
+ mpt->order = atomic_inc_return(&mtl->counter);
+ mpt->error = 0;
+
+ return pt;
+}
+
+static void mali_sync_timed_pt_timeout(unsigned long data)
+{
+ struct sync_pt *pt = (struct sync_pt *)data;
+
+ MALI_DEBUG_ASSERT_POINTER(pt);
+
+ mali_sync_signal_pt(pt, -ETIME);
+}
+
+struct sync_pt *mali_sync_timed_pt_alloc(struct sync_timeline *parent)
+{
+ struct sync_pt *pt;
+ struct mali_sync_pt *mpt;
+ const u32 timeout = msecs_to_jiffies(MALI_SYNC_TIMED_FENCE_TIMEOUT);
+
+ pt = mali_sync_pt_alloc(parent);
+ if (NULL == pt) return NULL;
+ mpt = to_mali_sync_pt(pt);
+
+ init_timer(&mpt->timer);
+
+ mpt->timer.function = mali_sync_timed_pt_timeout;
+ mpt->timer.data = (unsigned long)pt;
+ mpt->timer.expires = jiffies + timeout;
+
+ add_timer(&mpt->timer);
+
+ return pt;
+}
+
+/*
+ * Returns 0 if sync_pt has been committed and are ready for use, -ETIME if
+ * timeout already happened and the fence has been signalled.
+ *
+ * If an error occurs the sync point can not be used.
+ */
+int mali_sync_timed_commit(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ int ret;
+
+ if (!mali_sync_timeline_is_ours(pt->parent))
+ {
+ return -EINVAL;
+ }
+
+ /* Stop timer */
+ ret = del_timer_sync(&mpt->timer);
+
+ if (0 == ret)
+ {
+ return -ETIME;
+ }
+
+ MALI_DEBUG_ASSERT(0 == timeline_has_signaled(pt));
+
+ return 0;
+}
+
+void mali_sync_signal_pt(struct sync_pt *pt, int error)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(pt->parent);
+ int signalled;
+ long diff;
+
+ if (0 != error)
+ {
+ MALI_DEBUG_ASSERT(0 > error);
+ mpt->error = error;
+ }
+
+ do {
+
+ signalled = atomic_read(&mtl->signalled);
+
+ diff = signalled - mpt->order;
+
+ if (diff > 0)
+ {
+ /* The timeline is already at or ahead of this point. This should not happen unless userspace
+ * has been signalling fences out of order, so warn but don't violate the sync_pt API.
+ * The warning is only in debug builds to prevent a malicious user being able to spam dmesg.
+ */
+ MALI_DEBUG_PRINT_ERROR(("Sync points were triggerd in a different order to allocation!\n"));
+ return;
+ }
+ } while (atomic_cmpxchg(&mtl->signalled, signalled, mpt->order) != signalled);
+
+ sync_timeline_signal(pt->parent);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h
new file mode 100644
index 0000000..4415ec6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file mali_sync.h
+ *
+ */
+
+#ifndef _MALI_SYNC_H_
+#define _MALI_SYNC_H_
+
+#ifdef CONFIG_SYNC
+
+#include <linux/seq_file.h>
+#include <linux/sync.h>
+
+#define MALI_SYNC_TIMED_FENCE_TIMEOUT 4000 /* 4s */
+
+/*
+ * Create a stream object.
+ * Built on top of timeline object.
+ * Exposed as a file descriptor.
+ * Life-time controlled via the file descriptor:
+ * - dup to add a ref
+ * - close to remove a ref
+ */
+_mali_osk_errcode_t mali_stream_create(const char * name, int * out_fd);
+
+/*
+ * Create a fence in a stream object
+ */
+struct sync_pt *mali_stream_create_point(int tl_fd);
+int mali_stream_create_fence(struct sync_pt *pt);
+int mali_stream_create_empty_fence(int tl_fd);
+
+/**
+ * Commit an empty timed fence
+ *
+ * This stops the timer of the empty fence and returns wether or not the fence
+ * is still suitable for use.
+ *
+ * Returns -ETIME if fence is already signalled, in which case it can not be
+ * used, or 0 when the timer was stopped and the fence is OK to use.
+ */
+int mali_sync_timed_commit(struct sync_pt *pt);
+
+/*
+ * Validate a fd to be a valid fence
+ * No reference is taken.
+ *
+ * This function is only usable to catch unintentional user errors early,
+ * it does not stop malicious code changing the fd after this function returns.
+ */
+_mali_osk_errcode_t mali_fence_validate(int fd);
+
+
+/* Returns true if the specified timeline is allocated by Mali */
+int mali_sync_timeline_is_ours(struct sync_timeline *timeline);
+
+/* Allocates a timeline for Mali
+ *
+ * One timeline should be allocated per API context.
+ */
+struct sync_timeline *mali_sync_timeline_alloc(const char *name);
+
+/* Allocates a sync point within the timeline.
+ *
+ * The timeline must be the one allocated by mali_sync_timeline_alloc
+ *
+ * Sync points must be triggered in *exactly* the same order as they are allocated.
+ */
+struct sync_pt *mali_sync_pt_alloc(struct sync_timeline *parent);
+
+/* Allocates a timed sync point within the timeline.
+ *
+ * The timeline must be the one allocated by mali_sync_timeline_alloc
+ *
+ * Sync points must be triggered in *exactly* the same order as they are allocated.
+ *
+ * Timed sync points should be backed by a proper event before reaching the
+ * timeout. If timeout is reached the fence will be signalled with an error (-ETIME).
+ */
+struct sync_pt *mali_sync_timed_pt_alloc(struct sync_timeline *parent);
+
+/* Signals a particular sync point
+ *
+ * Sync points must be triggered in *exactly* the same order as they are allocated.
+ *
+ * If they are signalled in the wrong order then a message will be printed in debug
+ * builds and otherwise attempts to signal order sync_pts will be ignored.
+ */
+void mali_sync_signal_pt(struct sync_pt *pt, int error);
+
+#endif /* CONFIG_SYNC */
+#endif /* _MALI_SYNC_H_ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c
new file mode 100644
index 0000000..7f0fddfc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file mali_sync_user.c
+ *
+ */
+
+#ifdef CONFIG_SYNC
+
+#include <linux/sched.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/anon_inodes.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_sync.h"
+
+static int mali_stream_close(struct inode * inode, struct file * file)
+{
+ struct sync_timeline * tl;
+ tl = (struct sync_timeline*)file->private_data;
+ BUG_ON(!tl);
+ sync_timeline_destroy(tl);
+ return 0;
+}
+
+static struct file_operations stream_fops =
+{
+ .owner = THIS_MODULE,
+ .release = mali_stream_close,
+};
+
+_mali_osk_errcode_t mali_stream_create(const char * name, int *out_fd)
+{
+ struct sync_timeline * tl;
+ BUG_ON(!out_fd);
+
+ tl = mali_sync_timeline_alloc(name);
+ if (!tl)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ *out_fd = anon_inode_getfd(name, &stream_fops, tl, O_RDONLY | O_CLOEXEC);
+
+ if (*out_fd < 0)
+ {
+ sync_timeline_destroy(tl);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ else
+ {
+ return _MALI_OSK_ERR_OK;
+ }
+}
+
+static mali_sync_pt *mali_stream_create_point_internal(int tl_fd, mali_bool timed)
+{
+ struct sync_timeline *tl;
+ struct sync_pt * pt;
+ struct file *tl_file;
+
+ tl_file = fget(tl_fd);
+ if (tl_file == NULL)
+ return NULL;
+
+ if (tl_file->f_op != &stream_fops)
+ {
+ pt = NULL;
+ goto out;
+ }
+
+ tl = tl_file->private_data;
+
+ if (unlikely(timed))
+ {
+ pt = mali_sync_timed_pt_alloc(tl);
+ }
+ else
+ {
+ pt = mali_sync_pt_alloc(tl);
+ }
+
+ if (!pt)
+ {
+ pt = NULL;
+ goto out;
+ }
+
+out:
+ fput(tl_file);
+
+ return pt;
+}
+
+mali_sync_pt *mali_stream_create_point(int tl_fd)
+{
+ return mali_stream_create_point_internal(tl_fd, MALI_FALSE);
+}
+
+int mali_stream_create_fence(mali_sync_pt *pt)
+{
+ struct sync_fence *fence;
+ struct fdtable * fdt;
+ struct files_struct * files;
+ int fd = -1;
+
+ fence = sync_fence_create("mali_fence", pt);
+ if (!fence)
+ {
+ sync_pt_free(pt);
+ fd = -EFAULT;
+ goto out;
+ }
+
+ /* create a fd representing the fence */
+ fd = get_unused_fd();
+ if (fd < 0)
+ {
+ sync_fence_put(fence);
+ goto out;
+ }
+
+ files = current->files;
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ __set_close_on_exec(fd, fdt);
+#else
+ FD_SET(fd, fdt->close_on_exec);
+#endif
+ spin_unlock(&files->file_lock);
+
+ /* bind fence to the new fd */
+ sync_fence_install(fence, fd);
+
+out:
+ return fd;
+}
+
+int mali_stream_create_empty_fence(int tl_fd)
+{
+ int fd;
+ mali_sync_pt *pt;
+
+ pt = mali_stream_create_point_internal(tl_fd, MALI_TRUE);
+
+ if (NULL == pt) return -ENOMEM;
+
+ fd = mali_stream_create_fence(pt);
+
+ return fd;
+}
+
+_mali_osk_errcode_t mali_fence_validate(int fd)
+{
+ struct sync_fence * fence;
+ fence = sync_fence_fdget(fd);
+ if (NULL != fence)
+ {
+ sync_fence_put(fence);
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+}
+
+#endif /* CONFIG_SYNC */
diff --git a/drivers/media/video/samsung/mali/linux/mali_uk_types.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h
index 1a81246..fbe902a 100644
--- a/drivers/media/video/samsung/mali/linux/mali_uk_types.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h
@@ -12,7 +12,6 @@
#define __MALI_UK_TYPES_H__
/* Simple wrapper in order to find the OS specific location of this file */
-//#include <linux/mali/mali_utgard_uk_types.h>
-#include "../include/linux/mali/mali_utgard_uk_types.h"
+#include <linux/mali/mali_utgard_uk_types.h>
#endif /* __MALI_UK_TYPES_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c
index 22262fe..1768ff2 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c
@@ -10,18 +10,23 @@
#include <linux/fs.h> /* file system operations */
#include <linux/slab.h> /* memort allocation functions */
#include <asm/uaccess.h> /* user space access */
+#include <linux/pid.h>
#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
#include "mali_session.h"
#include "mali_ukk_wrappers.h"
+#include "mali_sync.h"
int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs)
{
_mali_uk_get_api_version_s kargs;
_mali_osk_errcode_t err;
+ u32 mem = _mali_ukk_report_memory_usage();
+ printk("Mali: mem_usage before %d : %u\n", _mali_osk_get_pid(), mem);
+
MALI_CHECK_NON_NULL(uargs, -EINVAL);
if (0 != get_user(kargs.version, &uargs->version)) return -EFAULT;
@@ -102,3 +107,68 @@ int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_g
return 0;
}
+
+#ifdef CONFIG_SYNC
+int stream_create_wrapper(struct mali_session_data *session_data, _mali_uk_stream_create_s __user *uargs)
+{
+ _mali_uk_stream_create_s kargs;
+ _mali_osk_errcode_t err;
+ char name[32];
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ snprintf(name, 32, "mali-%u", _mali_osk_get_pid());
+
+ kargs.ctx = session_data;
+ err = mali_stream_create(name, &kargs.fd);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_stream_create_s))) return -EFAULT;
+
+ return 0;
+}
+
+int sync_fence_create_empty_wrapper(struct mali_session_data *session_data, _mali_uk_fence_create_empty_s __user *uargs)
+{
+ _mali_uk_fence_create_empty_s kargs;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != get_user(kargs.stream, &uargs->stream)) return -EFAULT;
+
+ kargs.fence = mali_stream_create_empty_fence(kargs.stream);
+ if (0 > kargs.fence)
+ {
+ return kargs.fence;
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_fence_create_empty_s))) return -EFAULT;
+
+ return 0;
+}
+
+int sync_fence_validate_wrapper(struct mali_session_data *session, _mali_uk_fence_validate_s __user *uargs)
+{
+ int fd;
+ _mali_osk_errcode_t err;
+
+ if (0 != get_user(fd, &uargs->fd))
+ {
+ return -EFAULT;
+ }
+
+ err = mali_fence_validate(fd);
+
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ return 0;
+ }
+
+ return -EINVAL;
+}
+#endif
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c
index 7070016..4ee4a81 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c
@@ -18,40 +18,15 @@
int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs)
{
- _mali_uk_gp_start_job_s kargs;
- _mali_osk_errcode_t err;
+ _mali_osk_errcode_t err;
- MALI_CHECK_NON_NULL(uargs, -EINVAL);
- MALI_CHECK_NON_NULL(session_data, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_gp_start_job_s)))
- {
- return -EFAULT;
- }
+ err = _mali_ukk_gp_start_job(session_data, uargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
- if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_start_job_s))) return -EFAULT;
-
- kargs.ctx = session_data;
- err = _mali_ukk_gp_start_job(&kargs);
- if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
-
- kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
-
- if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_gp_start_job_s)))
- {
- /*
- * If this happens, then user space will not know that the job was actually started,
- * and if we return a queued job, then user space will still think that one is still queued.
- * This will typically lead to a deadlock in user space.
- * This could however only happen if user space deliberately passes a user buffer which
- * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user().
- * The official Mali driver will never attempt to do that, and kernel space should not be affected.
- * That is why we do not bother to do a complex rollback in this very very very rare case.
- */
- return -EFAULT;
- }
-
- return 0;
+ return 0;
}
int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs)
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c
index 260f257..7d1d23d 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c
@@ -65,6 +65,49 @@ int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s
return 0;
}
+int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user * uargs)
+{
+ _mali_uk_mem_write_safe_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_mem_write_safe_s)))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+
+ /* Check if we can access the buffers */
+ if (!access_ok(VERIFY_WRITE, kargs.dest, kargs.size)
+ || !access_ok(VERIFY_READ, kargs.src, kargs.size))
+ {
+ return -EINVAL;
+ }
+
+ /* Check if size wraps */
+ if ((kargs.size + kargs.dest) <= kargs.dest
+ || (kargs.size + kargs.src) <= kargs.src)
+ {
+ return -EINVAL;
+ }
+
+ err = _mali_ukk_mem_write_safe(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ if (0 != put_user(kargs.size, &uargs->size))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument)
{
_mali_uk_map_external_mem_s uk_args;
@@ -127,7 +170,7 @@ int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap
return map_errcode(err_code);
}
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#if defined(CONFIG_MALI400_UMP)
int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument)
{
_mali_uk_release_ump_mem_s uk_args;
@@ -189,7 +232,7 @@ int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_atta
/* Return the error that _mali_ukk_map_external_ump_mem produced */
return map_errcode(err_code);
}
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */
+#endif /* CONFIG_MALI400_UMP */
int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs)
{
@@ -230,6 +273,7 @@ int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mal
if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit;
/* allocate temporary buffer (kernel side) to store mmu page table info */
+ MALI_CHECK(kargs.size > 0, -ENOMEM);
kargs.buffer = _mali_osk_valloc(kargs.size);
if (NULL == kargs.buffer)
{
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c
index c11c61b..6663e7f 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c
@@ -18,41 +18,48 @@
int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs)
{
- _mali_uk_pp_start_job_s kargs;
_mali_osk_errcode_t err;
+ int fence = -1;
MALI_CHECK_NON_NULL(uargs, -EINVAL);
MALI_CHECK_NON_NULL(session_data, -EINVAL);
- if (!access_ok(VERIFY_WRITE, uargs, sizeof(_mali_uk_pp_start_job_s)))
+ err = _mali_ukk_pp_start_job(session_data, uargs, &fence);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+#if defined(CONFIG_SYNC)
+ if (0 != put_user(fence, &uargs->fence))
{
- return -EFAULT;
+ /* Since the job has started we can't return an error. */
}
+#endif /* CONFIG_SYNC */
- if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_start_job_s))) return -EFAULT;
-
- kargs.ctx = session_data;
- err = _mali_ukk_pp_start_job(&kargs);
- if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
-
- return 0;
+ return 0;
}
int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs)
{
- _mali_uk_get_pp_number_of_cores_s kargs;
- _mali_osk_errcode_t err;
+ _mali_uk_get_pp_number_of_cores_s kargs;
+ _mali_osk_errcode_t err;
- MALI_CHECK_NON_NULL(uargs, -EINVAL);
- MALI_CHECK_NON_NULL(session_data, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- kargs.ctx = session_data;
- err = _mali_ukk_get_pp_number_of_cores(&kargs);
- if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+ kargs.ctx = session_data;
+
+ err = _mali_ukk_get_pp_number_of_cores(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
- if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT;
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_get_pp_number_of_cores_s)))
+ {
+ return -EFAULT;
+ }
- return 0;
+ return 0;
}
int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs)
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c
index f4e31c9..f4e31c9 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c
index f9b5a3e..f9b5a3e 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h
index 65857fd..08bdae4 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h
@@ -27,18 +27,24 @@ extern "C"
int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs);
int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs);
int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs);
+#if defined(CONFIG_SYNC)
+int stream_create_wrapper(struct mali_session_data *session_data, _mali_uk_stream_create_s __user *uargs);
+int sync_fence_create_empty_wrapper(struct mali_session_data *session_data, _mali_uk_fence_create_empty_s __user *uargs);
+int sync_fence_validate_wrapper(struct mali_session_data *session, _mali_uk_fence_validate_s __user *uargs);
+#endif
int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs);
int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs);
int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs);
+int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user * uargs);
int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument);
int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument);
int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs);
int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs);
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#if defined(CONFIG_MALI400_UMP)
int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument);
int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument);
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */
+#endif
int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs);
int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs);
diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c
new file mode 100644
index 0000000..bf83249
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c
@@ -0,0 +1,405 @@
+/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4.c
+ *
+ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
+ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
+ *
+ * Samsung SoC Mali400 DVFS driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software FoundatIon.
+ */
+
+/**
+ * @file exynos4.c
+ * Platform specific Mali driver functions for the exynos 4XXX based platforms
+ */
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include <linux/pm.h>
+#include <linux/suspend.h>
+
+#ifdef CONFIG_PM_RUNTIME
+#include <linux/pm_runtime.h>
+#endif
+
+#ifdef CONFIG_MALI_DVFS
+#include "mali_kernel_utilization.h"
+#endif /* CONFIG_MALI_DVFS */
+
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_common.h"
+#include "mali_kernel_linux.h"
+#include "mali_pm.h"
+
+#include <plat/pd.h>
+
+#include "exynos4_pmm.h"
+
+#if defined(CONFIG_PM_RUNTIME)
+/* We does not need PM NOTIFIER in r3p2 DDK */
+//#define USE_PM_NOTIFIER
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+struct exynos_pm_domain;
+extern struct exynos_pm_domain exynos4_pd_g3d;
+void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+extern struct platform_device exynos4_device_pd[];
+#else
+extern struct platform_device s5pv310_device_pd[];
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+
+static void mali_platform_device_release(struct device *device);
+
+#if defined(CONFIG_PM_RUNTIME)
+#if defined(USE_PM_NOTIFIER)
+static int mali_os_suspend(struct device *device);
+static int mali_os_resume(struct device *device);
+static int mali_os_freeze(struct device *device);
+static int mali_os_thaw(struct device *device);
+
+static int mali_runtime_suspend(struct device *device);
+static int mali_runtime_resume(struct device *device);
+static int mali_runtime_idle(struct device *device);
+#endif
+#endif
+
+#if defined(CONFIG_ARCH_S5PV310) && !defined(CONFIG_BOARD_HKDKC210)
+
+/* This is for other SMDK boards */
+#define MALI_BASE_IRQ 232
+
+#else
+
+/* This is for the Odroid boards */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
+#define MALI_BASE_IRQ 182
+#else
+#define MALI_BASE_IRQ 150
+#endif
+
+#endif
+
+#define MALI_GP_IRQ MALI_BASE_IRQ + 9
+#define MALI_PP0_IRQ MALI_BASE_IRQ + 5
+#define MALI_PP1_IRQ MALI_BASE_IRQ + 6
+#define MALI_PP2_IRQ MALI_BASE_IRQ + 7
+#define MALI_PP3_IRQ MALI_BASE_IRQ + 8
+#define MALI_GP_MMU_IRQ MALI_BASE_IRQ + 4
+#define MALI_PP0_MMU_IRQ MALI_BASE_IRQ + 0
+#define MALI_PP1_MMU_IRQ MALI_BASE_IRQ + 1
+#define MALI_PP2_MMU_IRQ MALI_BASE_IRQ + 2
+#define MALI_PP3_MMU_IRQ MALI_BASE_IRQ + 3
+
+static struct resource mali_gpu_resources[] =
+{
+ MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
+ MALI_GP_IRQ, MALI_GP_MMU_IRQ,
+ MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
+ MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
+ MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
+ MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
+};
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy);
+
+static struct notifier_block mali_pwr_notif_block = {
+ .notifier_call = mali_pwr_suspend_notifier
+};
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+
+#if 0
+static struct dev_pm_ops mali_gpu_device_type_pm_ops =
+{
+#ifndef CONFIG_PM_RUNTIME
+ .suspend = mali_os_suspend,
+ .resume = mali_os_resume,
+#endif
+ .freeze = mali_os_freeze,
+ .thaw = mali_os_thaw,
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = mali_runtime_suspend,
+ .runtime_resume = mali_runtime_resume,
+ .runtime_idle = mali_runtime_idle,
+#endif
+};
+#endif
+
+#if defined(USE_PM_NOTIFIER)
+static struct device_type mali_gpu_device_device_type =
+{
+ .pm = &mali_gpu_device_type_pm_ops,
+};
+#endif
+
+static struct platform_device mali_gpu_device =
+{
+ .name = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */
+ .id = 0,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ /* Set in mali_platform_device_register() for these kernels */
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+ .dev.parent = &exynos4_device_pd[PD_G3D].dev,
+#else
+ .dev.parent = &s5pv310_device_pd[PD_G3D].dev,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+ .dev.release = mali_platform_device_release,
+#if 0
+ /*
+ * We temporarily make use of a device type so that we can control the Mali power
+ * from within the mali.ko (since the default platform bus implementation will not do that).
+ * Ideally .dev.pm_domain should be used instead, as this is the new framework designed
+ * to control the power of devices.
+ */
+ .dev.type = &mali_gpu_device_device_type, /* We should probably use the pm_domain instead of type on newer kernels */
+#endif
+};
+
+static struct mali_gpu_device_data mali_gpu_data =
+{
+ .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
+ .fb_start = 0x40000000,
+ .fb_size = 0xb1000000,
+ .utilization_interval = 100, /* 100ms */
+ .utilization_callback = mali_gpu_utilization_handler,
+};
+
+int mali_platform_device_register(void)
+{
+ int err;
+
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ exynos_pm_add_dev_to_genpd(&mali_gpu_device, &exynos4_pd_g3d);
+#endif
+
+ /* Connect resources to the device */
+ err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
+ if (0 == err)
+ {
+ err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data));
+ if (0 == err)
+ {
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+ err = register_pm_notifier(&mali_pwr_notif_block);
+ if (err)
+ {
+ goto plat_init_err;
+ }
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+
+ /* Register the platform device */
+ err = platform_device_register(&mali_gpu_device);
+ if (0 == err)
+ {
+ mali_platform_init(&(mali_gpu_device.dev));
+
+#ifdef CONFIG_PM_RUNTIME
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
+ pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
+#endif
+ pm_runtime_enable(&(mali_gpu_device.dev));
+#endif
+
+ return 0;
+ }
+ }
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+plat_init_err:
+ unregister_pm_notifier(&mali_pwr_notif_block);
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+ platform_device_unregister(&mali_gpu_device);
+ }
+
+ return err;
+}
+
+void mali_platform_device_unregister(void)
+{
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+ unregister_pm_notifier(&mali_pwr_notif_block);
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+
+ mali_platform_deinit(&(mali_gpu_device.dev));
+
+ platform_device_unregister(&mali_gpu_device);
+}
+
+static void mali_platform_device_release(struct device *device)
+{
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
+}
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy)
+{
+ int err = 0;
+ switch (event)
+ {
+ case PM_SUSPEND_PREPARE:
+ mali_pm_os_suspend();
+ err = mali_os_suspend(&(mali_platform_device->dev));
+ break;
+
+ case PM_POST_SUSPEND:
+ err = mali_os_resume(&(mali_platform_device->dev));
+ mali_pm_os_resume();
+ break;
+ default:
+ break;
+ }
+ return err;
+}
+
+static int mali_os_suspend(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+
+#ifdef CONFIG_MALI_DVFS
+ mali_utilization_suspend();
+#endif
+
+ if (NULL != device &&
+ NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->suspend)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->suspend(device);
+ }
+
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_DEEP_SLEEP);
+
+ return ret;
+}
+
+static int mali_os_resume(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
+#ifdef CONFIG_REGULATOR
+ mali_regulator_enable();
+ g3d_power_domain_control(1);
+#endif
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_ON);
+
+ if (NULL != device &&
+ NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->resume)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->resume(device);
+ }
+
+ return ret;
+}
+
+static int mali_os_freeze(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
+
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->freeze)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->freeze(device);
+ }
+
+ return ret;
+}
+
+static int mali_os_thaw(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
+
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->thaw)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->thaw(device);
+ }
+
+ return ret;
+}
+
+static int mali_runtime_suspend(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->runtime_suspend)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_suspend(device);
+ }
+
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_LIGHT_SLEEP);
+
+ return ret;
+}
+
+static int mali_runtime_resume(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
+
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_ON);
+
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->runtime_resume)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_resume(device);
+ }
+
+ return ret;
+}
+
+static int mali_runtime_idle(struct device *device)
+{
+ MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->runtime_idle)
+ {
+ int ret = 0;
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_idle(device);
+ if (0 != ret)
+ {
+ return ret;
+ }
+ }
+
+ return 1;
+}
+
+#endif /* USE_PM_NOTIFIER */
+#endif /* CONFIG_PM_RUNTIME */
diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c
new file mode 100644
index 0000000..346ad7f
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c
@@ -0,0 +1,1373 @@
+/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+ *
+ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
+ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
+ *
+ * Samsung SoC Mali400 DVFS driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software FoundatIon.
+ */
+
+/**
+ * @file exynos4_pmm.c
+ * Platform specific Mali driver functions for the exynos 4XXX based platforms
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "exynos4_pmm.h"
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+#if defined(CONFIG_PM_RUNTIME)
+#include <plat/pd.h>
+#endif
+
+#include <asm/io.h>
+#include <mach/regs-pmu.h>
+
+#include <linux/workqueue.h>
+
+#ifdef CONFIG_CPU_EXYNOS4210
+#define MALI_DVFS_STEPS 2
+#define MALI_DVFS_WATING 10 /* msec */
+#define MALI_DVFS_DEFAULT_STEP 0
+#else
+#define MALI_DVFS_STEPS 5
+#define MALI_DVFS_WATING 10 /* msec */
+#define MALI_DVFS_DEFAULT_STEP 1
+#define PD_G3D_LOCK_FLAG 2
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+#include <mach/asv.h>
+#define EXYNOS4_ASV_ENABLED
+#endif
+
+#define MALI_DVFS_CLK_DEBUG 0
+#define SEC_THRESHOLD 1
+
+#define CPUFREQ_LOCK_DURING_440 0
+#define CHIPID_REG (S5P_VA_CHIPID + 0x4)
+
+static int bMaliDvfsRun = 0;
+
+typedef struct mali_dvfs_tableTag{
+ unsigned int clock;
+ unsigned int freq;
+ unsigned int vol;
+#if SEC_THRESHOLD
+ unsigned int downthreshold;
+ unsigned int upthreshold;
+#endif
+}mali_dvfs_table;
+
+typedef struct mali_dvfs_statusTag{
+ unsigned int currentStep;
+ mali_dvfs_table * pCurrentDvfs;
+
+} mali_dvfs_status_t;
+
+/* dvfs status */
+mali_dvfs_status_t maliDvfsStatus;
+int mali_dvfs_control;
+
+typedef struct mali_runtime_resumeTag{
+ int clk;
+ int vol;
+ unsigned int step;
+}mali_runtime_resume_table;
+
+mali_runtime_resume_table mali_runtime_resume = {266, 900000, 1};
+
+/* dvfs table */
+mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ /* step 0 */{160 ,1000000 ,875000 , 0 , 70},
+ /* step 1 */{266 ,1000000 ,900000 ,62 , 90},
+ /* step 2 */{350 ,1000000 ,950000 ,85 , 90},
+ /* step 3 */{440 ,1000000 ,1025000 ,85 , 90},
+ /* step 4 */{533 ,1000000 ,1075000 ,95 ,100} };
+#else
+ /* step 0 */{134 ,1000000 , 950000 ,85 , 90},
+ /* step 1 */{267 ,1000000 ,1050000 ,85 ,100} };
+#endif
+
+#ifdef EXYNOS4_ASV_ENABLED
+#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */
+#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */
+#define ASV_LEVEL_PD 13
+#define ASV_LEVEL_4210_12 8
+#define ASV_LEVEL_4210_14 5
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
+ { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */
+#endif
+#endif
+#endif
+};
+static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
+ { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */
+#endif
+#endif
+#endif
+};
+
+static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = {
+ { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000, 850000}, /* L4(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 875000, 875000}, /* L3(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 912500, 900000, 887500}, /* L2(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 975000, 962500, 950000}, /* L1(440Mhz) */
+#if (MALI_DVFS_STEPS > 4)
+ { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1037500, 1025000, 1012500}, /* L0(533Mhz) */
+#endif
+#endif
+#endif
+#endif
+};
+
+static unsigned int asv_3d_volt_4212_9_table[MALI_DVFS_STEPS][ASV_LEVEL_PD] = {
+ { 950000, 925000, 900000, 900000, 900000, 900000, 900000, 900000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 950000, 925000, 925000, 925000, 925000, 925000, 900000, 900000, 900000, 875000, 875000, 875000}, /* L2(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1025000, 1000000, 975000, 975000, 975000, 950000, 950000, 925000, 925000, 925000, 925000, 900000, 875000}, /* L1(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1100000, 1075000, 1050000, 1050000, 1050000, 1050000, 1025000, 1000000, 1000000, 975000, 975000, 950000, 925000}, /* L0(440Mhz) */
+#endif
+#endif
+#endif
+};
+
+#else
+
+static unsigned int asv_3d_volt_4210_12_table[MALI_DVFS_STEPS][ASV_LEVEL_4210_12] = {
+ { 1000000, 1000000, 1000000, 950000, 950000, 950000, 950000, 950000}, /* L1(134Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 1100000, 1100000, 1100000, 1000000, 1000000, 1000000, 1000000, 950000}, /* L0(266Mhz) */
+#endif
+};
+
+static unsigned int asv_3d_volt_4210_14_table[MALI_DVFS_STEPS][ASV_LEVEL_4210_14] = {
+ { 1000000, 1000000, 950000, 950000, 950000}, /* L1(134Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 1100000, 1100000, 1000000, 1000000, 950000}, /* L0(266Mhz) */
+#endif
+};
+#endif
+#endif /* ASV_LEVEL */
+
+#define EXTXTALCLK_NAME "ext_xtal"
+#define VPLLSRCCLK_NAME "vpll_src"
+#define FOUTVPLLCLK_NAME "fout_vpll"
+#define SCLVPLLCLK_NAME "sclk_vpll"
+#define GPUMOUT1CLK_NAME "mout_g3d1"
+
+#define MPLLCLK_NAME "mout_mpll"
+#define GPUMOUT0CLK_NAME "mout_g3d0"
+#define GPUCLK_NAME "sclk_g3d"
+#define CLK_DIV_STAT_G3D 0x1003C62C
+#define CLK_DESC "clk-divider-status"
+
+static struct clk *ext_xtal_clock = NULL;
+static struct clk *vpll_src_clock = NULL;
+static struct clk *fout_vpll_clock = NULL;
+static struct clk *sclk_vpll_clock = NULL;
+
+static struct clk *mpll_clock = NULL;
+static struct clk *mali_parent_clock = NULL;
+static struct clk *mali_mout0_clock = NULL;
+static struct clk *mali_clock = NULL;
+
+#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212)
+/* Pegasus */
+static const mali_bool bis_vpll = MALI_TRUE;
+int mali_gpu_clk = 440;
+int mali_gpu_vol = 1025000;
+#else
+/* Orion */
+static const mali_bool bis_vpll = MALI_FALSE;
+int mali_gpu_clk = 267;
+int mali_gpu_vol = 1050000;
+#endif
+
+static unsigned int GPU_MHZ = 1000000;
+
+int gpu_power_state;
+static int bPoweroff;
+atomic_t clk_active;
+
+#define MAX_MALI_DVFS_STEPS 5
+static _mali_osk_atomic_t bottomlock_status;
+int bottom_lock_step = 0;
+
+#if MALI_VOLTAGE_LOCK
+int mali_lock_vol = 0;
+static _mali_osk_atomic_t voltage_lock_status;
+static mali_bool mali_vol_lock_flag = 0;
+#endif
+
+/* Declare for sysfs */
+#ifdef CONFIG_MALI_DVFS
+module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
+
+DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state);
+MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS");
+#endif
+
+module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock");
+
+module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
+
+module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(gpu_power_state, "Mali Power State");
+
+#ifdef CONFIG_REGULATOR
+struct regulator *g3d_regulator = NULL;
+#endif
+
+mali_io_address clk_register_map = 0;
+
+/* DVFS */
+static unsigned int mali_dvfs_utilization = 255;
+u64 mali_dvfs_time[MALI_DVFS_STEPS];
+#ifdef CONFIG_MALI_DVFS
+static void update_time_in_state(int level);
+#endif
+static void mali_dvfs_work_handler(struct work_struct *w);
+static struct workqueue_struct *mali_dvfs_wq = 0;
+extern mali_io_address clk_register_map;
+_mali_osk_lock_t *mali_dvfs_lock;
+int mali_runtime_resumed = -1;
+static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
+
+#ifdef CONFIG_REGULATOR
+void mali_regulator_disable(void)
+{
+ if(IS_ERR_OR_NULL(g3d_regulator))
+ {
+ MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
+ return;
+ }
+ regulator_disable(g3d_regulator);
+}
+
+void mali_regulator_enable(void)
+{
+ if(IS_ERR_OR_NULL(g3d_regulator))
+ {
+ MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
+ return;
+ }
+ regulator_enable(g3d_regulator);
+}
+
+void mali_regulator_set_voltage(int min_uV, int max_uV)
+{
+ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ if(IS_ERR_OR_NULL(g3d_regulator))
+ {
+ MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return;
+ }
+ MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
+ regulator_set_voltage(g3d_regulator, min_uV, max_uV);
+ mali_gpu_vol = regulator_get_voltage(g3d_regulator);
+ MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+}
+#endif
+
+unsigned long mali_clk_get_rate(void)
+{
+ return clk_get_rate(mali_clock);
+}
+
+
+static unsigned int get_mali_dvfs_status(void)
+{
+ return maliDvfsStatus.currentStep;
+}
+
+mali_bool mali_clk_get(void)
+{
+ if (bis_vpll)
+ {
+ if (ext_xtal_clock == NULL)
+ {
+ ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME);
+ if (IS_ERR(ext_xtal_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (vpll_src_clock == NULL)
+ {
+ vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME);
+ if (IS_ERR(vpll_src_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (fout_vpll_clock == NULL)
+ {
+ fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME);
+ if (IS_ERR(fout_vpll_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (sclk_vpll_clock == NULL)
+ {
+ sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME);
+ if (IS_ERR(sclk_vpll_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (mali_parent_clock == NULL)
+ {
+ mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
+
+ if (IS_ERR(mali_parent_clock)) {
+ MALI_PRINT(( "MALI Error : failed to get source mali parent clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (mali_mout0_clock == NULL)
+ {
+ mali_mout0_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
+
+ if (IS_ERR(mali_mout0_clock)) {
+ MALI_PRINT( ( "MALI Error : failed to get source mali mout0 clock\n"));
+ return MALI_FALSE;
+ }
+ }
+ }
+ else /* mpll */
+ {
+ if (mpll_clock == NULL)
+ {
+ mpll_clock = clk_get(NULL, MPLLCLK_NAME);
+
+ if (IS_ERR(mpll_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source mpll clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (mali_parent_clock == NULL)
+ {
+ mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
+
+ if (IS_ERR(mali_parent_clock)) {
+ MALI_PRINT(( "MALI Error : failed to get source mali parent clock\n"));
+ return MALI_FALSE;
+ }
+ }
+ }
+
+ /* mali clock get always. */
+ if (mali_clock == NULL)
+ {
+ mali_clock = clk_get(NULL, GPUCLK_NAME);
+
+ if (IS_ERR(mali_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source mali clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ return MALI_TRUE;
+}
+
+void mali_clk_put(mali_bool binc_mali_clock)
+{
+ if (mali_parent_clock)
+ {
+ clk_put(mali_parent_clock);
+ mali_parent_clock = NULL;
+ }
+
+ if (mali_mout0_clock)
+ {
+ clk_put(mali_mout0_clock);
+ mali_mout0_clock = NULL;
+ }
+
+ if (mpll_clock)
+ {
+ clk_put(mpll_clock);
+ mpll_clock = NULL;
+ }
+
+ if (sclk_vpll_clock)
+ {
+ clk_put(sclk_vpll_clock);
+ sclk_vpll_clock = NULL;
+ }
+
+ if (binc_mali_clock && fout_vpll_clock)
+ {
+ clk_put(fout_vpll_clock);
+ fout_vpll_clock = NULL;
+ }
+
+ if (vpll_src_clock)
+ {
+ clk_put(vpll_src_clock);
+ vpll_src_clock = NULL;
+ }
+
+ if (ext_xtal_clock)
+ {
+ clk_put(ext_xtal_clock);
+ ext_xtal_clock = NULL;
+ }
+
+ if (binc_mali_clock && mali_clock)
+ {
+ clk_put(mali_clock);
+ mali_clock = NULL;
+ }
+}
+
+void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
+{
+ int err;
+ unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
+
+ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
+
+ if (mali_clk_get() == MALI_FALSE) {
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return;
+ }
+
+ if (bis_vpll)
+ {
+ clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ);
+ clk_set_parent(vpll_src_clock, ext_xtal_clock);
+ clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
+
+ clk_set_parent(mali_parent_clock, sclk_vpll_clock);
+ clk_set_parent(mali_clock, mali_parent_clock);
+ }
+ else
+ {
+ clk_set_parent(mali_parent_clock, mpll_clock);
+ clk_set_parent(mali_clock, mali_parent_clock);
+ }
+
+ if (atomic_read(&clk_active) == 0) {
+ if (clk_enable(mali_clock) < 0) {
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return;
+ }
+ atomic_set(&clk_active, 1);
+ }
+
+ err = clk_set_rate(mali_clock, rate);
+ if (err > 0)
+ MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
+
+ rate = mali_clk_get_rate();
+
+ MALI_PRINT(("Mali frequency %d\n", rate / mhz));
+ GPU_MHZ = mhz;
+ mali_gpu_clk = (int)(rate / mhz);
+
+ mali_clk_put(MALI_FALSE);
+
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+int get_mali_dvfs_control_status(void)
+{
+ return mali_dvfs_control;
+}
+
+mali_bool set_mali_dvfs_current_step(unsigned int step)
+{
+ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
+ if (step >= MALI_DVFS_STEPS)
+ mali_runtime_resumed = maliDvfsStatus.currentStep;
+
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return MALI_TRUE;
+}
+
+
+static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
+{
+ u32 validatedStep=step;
+#if MALI_DVFS_CLK_DEBUG
+ unsigned int *pRegMaliClkDiv;
+ unsigned int *pRegMaliMpll;
+#endif
+
+ if(boostup) {
+#ifdef CONFIG_REGULATOR
+ /* change the voltage */
+ mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+#endif
+ /* change the clock */
+ mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+ } else {
+ /* change the clock */
+ mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+#ifdef CONFIG_REGULATOR
+ /* change the voltage */
+ mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+#endif
+ }
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_EVENT_CHANNEL_GPU|
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+#endif
+ mali_clk_put(MALI_FALSE);
+
+#if MALI_DVFS_CLK_DEBUG
+ pRegMaliClkDiv = ioremap(0x1003c52c,32);
+ pRegMaliMpll = ioremap(0x1003c22c,32);
+ MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
+#endif
+
+#ifdef EXYNOS4_ASV_ENABLED
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_dvfs[step].clock == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
+#endif
+
+ set_mali_dvfs_current_step(validatedStep);
+ /* for future use */
+ maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
+
+#if CPUFREQ_LOCK_DURING_440
+ /* lock/unlock CPU freq by Mali */
+ if (mali_dvfs[step].clock >= 440)
+ err = cpufreq_lock_by_mali(400);
+ else
+ cpufreq_unlock_by_mali();
+#endif
+
+
+ return MALI_TRUE;
+}
+
+static void mali_platform_wating(u32 msec)
+{
+ /*
+ * sample wating
+ * change this in the future with proper check routine.
+ */
+ unsigned int read_val;
+ while(1) {
+ read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
+ if ((read_val & 0x8000)==0x0000) break;
+
+ _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
+ }
+}
+
+static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
+{
+ MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
+
+ if (!set_mali_dvfs_status(step, boostup)) {
+ MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
+ return MALI_FALSE;
+ }
+
+ /* wait until clock and voltage is stablized */
+ mali_platform_wating(MALI_DVFS_WATING); /* msec */
+
+ return MALI_TRUE;
+}
+
+#ifdef EXYNOS4_ASV_ENABLED
+extern unsigned int exynos_result_of_asv;
+
+static mali_bool mali_dvfs_table_update(void)
+{
+ unsigned int step_num = MALI_DVFS_STEPS;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ unsigned int i, tmp, g3d_lock_volt = 0;
+ bool lock_flag_g3d = false;
+
+ if(samsung_rev() < EXYNOS4412_REV_2_0)
+ step_num = MALI_DVFS_STEPS - 1;
+
+ if(soc_is_exynos4412()) {
+ if (exynos_armclk_max == 1000000) {
+ MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) {
+ MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000;
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ } else if (samsung_rev() >= EXYNOS4412_REV_2_0) {
+ MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ } else {
+ MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ }
+ }
+ else if(soc_is_exynos4212()) {
+ tmp = __raw_readl(CHIPID_REG);
+ lock_flag_g3d = (tmp >> PD_G3D_LOCK_FLAG) & 0x1;
+ if (lock_flag_g3d)
+ g3d_lock_volt = 25000;
+
+ for (i = 0; i < step_num; i++) {
+ MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ mali_dvfs[i].vol = asv_3d_volt_4212_9_table[i][exynos_result_of_asv] + g3d_lock_volt;
+ MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ }
+#else
+ unsigned int i, exynos_result_of_asv_group, target_asv;
+
+ exynos_result_of_asv_group = exynos_result_of_asv & 0xf;
+ target_asv = exynos_result_of_asv >> 28;
+ MALI_PRINT(("exynos_result_of_asv_group = 0x%x, target_asv = 0x%x\n", exynos_result_of_asv_group, target_asv));
+
+ for (i = 0; i < step_num; i++) {
+ if (target_asv == 0x8) { //SUPPORT_1400MHZ
+ mali_dvfs[i].vol = asv_3d_volt_4210_14_table[i][exynos_result_of_asv_group];
+ } else if (target_asv == 0x4){ //SUPPORT_1200MHZ
+ mali_dvfs[i].vol = asv_3d_volt_4210_12_table[i][exynos_result_of_asv_group];
+ }
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+#endif
+
+ return MALI_TRUE;
+}
+#endif
+
+static unsigned int decideNextStatus(unsigned int utilization)
+{
+ static unsigned int level = 0;
+ int iStepCount = 0;
+ if (mali_runtime_resumed >= 0) {
+ level = mali_runtime_resumed;
+ mali_runtime_resumed = -1;
+ }
+
+ if (mali_dvfs_control == 0 && level == get_mali_dvfs_status()) {
+ if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
+ level < MALI_DVFS_STEPS - 1) {
+ level++;
+ if ((samsung_rev() < EXYNOS4412_REV_2_0) && 3 == get_mali_dvfs_status()) {
+ level=get_mali_dvfs_status();
+ }
+ }
+ else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
+ level > 0) {
+ level--;
+ }
+
+ if (_mali_osk_atomic_read(&bottomlock_status) > 0) {
+ if (level < bottom_lock_step)
+ level = bottom_lock_step;
+ }
+ } else {
+ for (iStepCount = MALI_DVFS_STEPS-1; iStepCount >= 0; iStepCount--) {
+ if ( mali_dvfs_control >= mali_dvfs[iStepCount].clock ) {
+ level = iStepCount;
+ break;
+ }
+ }
+ }
+
+ return level;
+}
+
+
+static mali_bool mali_dvfs_status(unsigned int utilization)
+{
+ unsigned int nextStatus = 0;
+ unsigned int curStatus = 0;
+ mali_bool boostup = MALI_FALSE;
+ static int stay_count = 5;
+
+ MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
+
+ /* decide next step */
+ curStatus = get_mali_dvfs_status();
+ nextStatus = decideNextStatus(utilization);
+
+ MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
+ /* if next status is same with current status, don't change anything */
+ if(curStatus != nextStatus) {
+ /*check if boost up or not*/
+ if(maliDvfsStatus.currentStep < nextStatus) {
+ boostup = 1;
+ stay_count = 5;
+ } else if (maliDvfsStatus.currentStep > nextStatus){
+ stay_count--;
+ }
+ if( boostup == 1 || stay_count <= 0){
+ /*change mali dvfs status*/
+#ifdef CONFIG_MALI_DVFS
+ update_time_in_state(curStatus);
+#endif
+ if (!change_mali_dvfs_status(nextStatus,boostup)) {
+ MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
+ return MALI_FALSE;
+ }
+ boostup = 0;
+ stay_count = 5;
+ }
+ }
+ else
+ stay_count = 5;
+ return MALI_TRUE;
+}
+
+
+int mali_dvfs_is_running(void)
+{
+ return bMaliDvfsRun;
+}
+
+
+static void mali_dvfs_work_handler(struct work_struct *w)
+{
+ bMaliDvfsRun=1;
+
+ MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
+
+ if(!mali_dvfs_status(mali_dvfs_utilization))
+ MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler"));
+
+ bMaliDvfsRun=0;
+}
+
+mali_bool init_mali_dvfs_status(void)
+{
+ /*
+ * default status
+ * add here with the right function to get initilization value.
+ */
+
+ if (!mali_dvfs_wq)
+ mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
+
+ _mali_osk_atomic_init(&bottomlock_status, 0);
+
+ /* add a error handling here */
+ maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+
+ return MALI_TRUE;
+}
+
+void deinit_mali_dvfs_status(void)
+{
+ if (mali_dvfs_wq)
+ destroy_workqueue(mali_dvfs_wq);
+
+ _mali_osk_atomic_term(&bottomlock_status);
+
+ mali_dvfs_wq = NULL;
+}
+
+mali_bool mali_dvfs_handler(unsigned int utilization)
+{
+ mali_dvfs_utilization = utilization;
+ queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work);
+
+ return MALI_TRUE;
+}
+
+static mali_bool init_mali_clock(void)
+{
+ mali_bool ret = MALI_TRUE;
+ gpu_power_state = 1;
+ bPoweroff = 1;
+
+ if (mali_clock != 0)
+ return ret; /* already initialized */
+
+ mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
+ | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
+ if (mali_dvfs_lock == NULL)
+ return _MALI_OSK_ERR_FAULT;
+
+ if (!mali_clk_get())
+ {
+ MALI_PRINT(("Error: Failed to get Mali clock\n"));
+ goto err_clk;
+ }
+
+ mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+
+ MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
+
+#ifdef CONFIG_REGULATOR
+ g3d_regulator = regulator_get(NULL, "vdd_g3d");
+
+ if (IS_ERR(g3d_regulator))
+ {
+ MALI_PRINT(("MALI Error : failed to get vdd_g3d\n"));
+ ret = MALI_FALSE;
+ goto err_regulator;
+ }
+
+ regulator_enable(g3d_regulator);
+ mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
+
+#ifdef EXYNOS4_ASV_ENABLED
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_gpu_clk == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
+#endif
+#endif
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_EVENT_CHANNEL_GPU|
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+#endif
+
+ mali_clk_put(MALI_FALSE);
+
+ return MALI_TRUE;
+
+#ifdef CONFIG_REGULATOR
+err_regulator:
+ regulator_put(g3d_regulator);
+#endif
+err_clk:
+ mali_clk_put(MALI_TRUE);
+
+ return ret;
+}
+
+static mali_bool deinit_mali_clock(void)
+{
+ if (mali_clock == 0)
+ return MALI_TRUE;
+
+#ifdef CONFIG_REGULATOR
+ if (g3d_regulator)
+ {
+ regulator_put(g3d_regulator);
+ g3d_regulator = NULL;
+ }
+#endif
+
+ mali_clk_put(MALI_TRUE);
+
+ return MALI_TRUE;
+}
+
+
+static _mali_osk_errcode_t enable_mali_clocks(void)
+{
+ int err;
+
+ if (atomic_read(&clk_active) == 0) {
+ err = clk_enable(mali_clock);
+ MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
+ atomic_set(&clk_active, 1);
+ gpu_power_state = 1;
+ }
+
+ /* set clock rate */
+#ifdef CONFIG_MALI_DVFS
+ if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk) {
+ mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
+ } else {
+#ifdef CONFIG_REGULATOR
+ mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
+
+#ifdef EXYNOS4_ASV_ENABLED
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_runtime_resume.clk == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
+#endif
+#endif
+ mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
+ set_mali_dvfs_current_step(mali_runtime_resume.step);
+ }
+#else
+ mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+ maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+#endif
+
+
+ MALI_SUCCESS;
+}
+
+static _mali_osk_errcode_t disable_mali_clocks(void)
+{
+ if (atomic_read(&clk_active) == 1) {
+ clk_disable(mali_clock);
+ atomic_set(&clk_active, 0);
+ gpu_power_state = 0;
+ }
+ MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p \n", mali_clock));
+
+ MALI_SUCCESS;
+}
+
+/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
+#ifndef S5P_G3D_CONFIGURATION
+#define S5P_G3D_CONFIGURATION S5P_PMU_G3D_CONF
+#endif
+#ifndef S5P_G3D_STATUS
+#define S5P_G3D_STATUS S5P_PMU_G3D_CONF + 0x4
+#endif
+
+_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
+{
+ if (bpower_on)
+ {
+ void __iomem *status;
+ u32 timeout;
+ __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
+ status = S5P_G3D_STATUS;
+
+ timeout = 10;
+ while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
+ != S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ MALI_PRINTF(("Power domain enable failed.\n"));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ _mali_osk_time_ubusydelay(100);
+ }
+ }
+ else
+ {
+ void __iomem *status;
+ u32 timeout;
+ __raw_writel(0, S5P_G3D_CONFIGURATION);
+
+ status = S5P_G3D_STATUS;
+ /* Wait max 1ms */
+ timeout = 10;
+ while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
+ {
+ if (timeout == 0) {
+ MALI_PRINTF(("Power domain disable failed.\n" ));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ _mali_osk_time_ubusydelay(100);
+ }
+ }
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_init(struct device *dev)
+{
+#ifdef EXYNOS4_ASV_ENABLED
+ mali_dvfs_table_update();
+#endif
+
+ MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
+
+ atomic_set(&clk_active, 0);
+
+#ifdef CONFIG_MALI_DVFS
+ /* Create sysfs for time-in-state */
+ if (device_create_file(dev, &dev_attr_time_in_state)) {
+ dev_err(dev, "Couldn't create sysfs file [time_in_state]\n");
+ }
+
+ if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
+ if (!init_mali_dvfs_status())
+ MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
+#endif
+
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_deinit(struct device *dev)
+{
+
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP);
+ deinit_mali_clock();
+
+#ifdef CONFIG_MALI_DVFS
+ deinit_mali_dvfs_status();
+ if (clk_register_map )
+ {
+ _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
+ clk_register_map = NULL;
+ }
+#endif
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode)
+{
+ switch (power_mode)
+ {
+ case MALI_POWER_MODE_ON:
+ MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
+ bPoweroff ? "powering on" : "already on"));
+ if (bPoweroff == 1)
+ {
+#if !defined(CONFIG_PM_RUNTIME)
+ g3d_power_domain_control(1);
+#endif
+ MALI_DEBUG_PRINT(4, ("enable clock \n"));
+ enable_mali_clocks();
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+
+#endif
+ bPoweroff=0;
+ }
+ break;
+ case MALI_POWER_MODE_LIGHT_SLEEP:
+ case MALI_POWER_MODE_DEEP_SLEEP:
+ MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
+ MALI_POWER_MODE_LIGHT_SLEEP ? "MALI_POWER_MODE_LIGHT_SLEEP" :
+ "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
+ if (bPoweroff == 0)
+ {
+ disable_mali_clocks();
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ 0, 0, 0, 0, 0);
+#endif
+
+#if !defined(CONFIG_PM_RUNTIME)
+ g3d_power_domain_control(0);
+#endif
+ bPoweroff=1;
+ }
+
+ break;
+ }
+ MALI_SUCCESS;
+}
+
+void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data)
+{
+ if (bPoweroff==0)
+ {
+#ifdef CONFIG_MALI_DVFS
+ if(!mali_dvfs_handler(data->utilization_gpu))
+ MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n"));
+#endif
+ }
+}
+
+#ifdef CONFIG_CPU_EXYNOS4210
+int mali_dvfs_bottom_lock_push()
+{
+ int prev_status = _mali_osk_atomic_read(&bottomlock_status);
+
+ if (prev_status < 0) {
+ MALI_PRINT(("gpu bottom lock status is not valid for push\n"));
+ return -1;
+ }
+ if (prev_status == 0) {
+ mali_regulator_set_voltage(mali_dvfs[1].vol, mali_dvfs[1].vol);
+ mali_clk_set_rate(mali_dvfs[1].clock, mali_dvfs[1].freq);
+ set_mali_dvfs_current_step(1);
+ }
+ return _mali_osk_atomic_inc_return(&bottomlock_status);
+}
+#else
+int mali_dvfs_bottom_lock_push(int lock_step)
+{
+ int prev_status = _mali_osk_atomic_read(&bottomlock_status);
+
+ if (prev_status < 0) {
+ MALI_PRINT(("gpu bottom lock status is not valid for push\n"));
+ return -1;
+ }
+ if (bottom_lock_step < lock_step) {
+ bottom_lock_step = lock_step;
+ if (get_mali_dvfs_status() < lock_step) {
+ mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol);
+ mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq);
+ set_mali_dvfs_current_step(lock_step);
+ }
+ }
+ return _mali_osk_atomic_inc_return(&bottomlock_status);
+}
+#endif
+
+int mali_dvfs_bottom_lock_pop(void)
+{
+ int prev_status = _mali_osk_atomic_read(&bottomlock_status);
+ if (prev_status <= 0) {
+ MALI_PRINT(("gpu bottom lock status is not valid for pop\n"));
+ return -1;
+ } else if (prev_status == 1) {
+ bottom_lock_step = 0;
+ MALI_PRINT(("gpu bottom lock release\n"));
+ }
+
+ return _mali_osk_atomic_dec_return(&bottomlock_status);
+}
+
+int mali_dvfs_get_vol(int step)
+{
+ step = step % MAX_MALI_DVFS_STEPS;
+ MALI_DEBUG_ASSERT(step<MAX_MALI_DVFS_STEPS);
+ return mali_dvfs[step].vol;
+}
+
+#if MALI_VOLTAGE_LOCK
+int mali_voltage_lock_push(int lock_vol)
+{
+ int prev_status = _mali_osk_atomic_read(&voltage_lock_status);
+
+ if (prev_status < 0) {
+ MALI_PRINT(("gpu voltage lock status is not valid for push\n"));
+ return -1;
+ }
+ if (prev_status == 0) {
+ mali_lock_vol = lock_vol;
+ if (mali_gpu_vol < mali_lock_vol)
+ mali_regulator_set_voltage(mali_lock_vol, mali_lock_vol);
+ } else {
+ MALI_PRINT(("gpu voltage lock status is already pushed, current lock voltage : %d\n", mali_lock_vol));
+ return -1;
+ }
+
+ return _mali_osk_atomic_inc_return(&voltage_lock_status);
+}
+
+int mali_voltage_lock_pop(void)
+{
+ if (_mali_osk_atomic_read(&voltage_lock_status) <= 0) {
+ MALI_PRINT(("gpu voltage lock status is not valid for pop\n"));
+ return -1;
+ }
+ return _mali_osk_atomic_dec_return(&voltage_lock_status);
+}
+
+int mali_voltage_lock_init(void)
+{
+ mali_vol_lock_flag = MALI_TRUE;
+
+ MALI_SUCCESS;
+}
+
+int mali_vol_get_from_table(int vol)
+{
+ int i;
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ if (mali_dvfs[i].vol >= vol)
+ return mali_dvfs[i].vol;
+ }
+ MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol));
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_MALI_DVFS
+static void update_time_in_state(int level)
+{
+ u64 current_time;
+ static u64 prev_time=0;
+
+ if (prev_time ==0)
+ prev_time=get_jiffies_64();
+
+ current_time = get_jiffies_64();
+ mali_dvfs_time[level] += current_time-prev_time;
+ prev_time = current_time;
+}
+
+ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = 0;
+ int i;
+
+ update_time_in_state(maliDvfsStatus.currentStep);
+
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d %llu\n",
+ mali_dvfs[i].clock,
+ mali_dvfs_time[i]);
+ }
+
+ if (ret < PAGE_SIZE - 1) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+ } else {
+ buf[PAGE_SIZE-2] = '\n';
+ buf[PAGE_SIZE-1] = '\0';
+ ret = PAGE_SIZE-1;
+ }
+
+ return ret;
+}
+
+ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int i;
+
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ mali_dvfs_time[i] = 0;
+ }
+
+ return count;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h
new file mode 100644
index 0000000..1b9cf57
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h
@@ -0,0 +1,121 @@
+/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+ *
+ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
+ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
+ *
+ * Samsung SoC Mali400 DVFS driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software FoundatIon.
+ */
+
+/**
+ * @file exynos4_pmm.h
+ * Platform specific Mali driver functions for the exynos 4XXX based platforms
+ */
+
+#ifndef __EXYNOS4_PMM_H__
+#define __EXYNOS4_PMM_H__
+
+#include "mali_utgard.h"
+#include "mali_osk.h"
+#include <linux/platform_device.h>
+/* @Enable or Disable Mali GPU Bottom Lock feature */
+#define MALI_GPU_BOTTOM_LOCK 1
+#define MALI_VOLTAGE_LOCK 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief description of power change reasons
+ */
+typedef enum mali_power_mode_tag
+{
+ MALI_POWER_MODE_ON,
+ MALI_POWER_MODE_LIGHT_SLEEP,
+ MALI_POWER_MODE_DEEP_SLEEP,
+} mali_power_mode;
+
+/** @brief Platform specific setup and initialisation of MALI
+ *
+ * This is called from the entrypoint of the driver to initialize the platform
+ *
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_platform_init(struct device *dev);
+
+/** @brief Platform specific deinitialisation of MALI
+ *
+ * This is called on the exit of the driver to terminate the platform
+ *
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_platform_deinit(struct device *dev);
+
+/** @brief Platform specific powerdown sequence of MALI
+ *
+ * Call as part of platform init if there is no PMM support, else the
+ * PMM will call it.
+ * There are three power modes defined:
+ * 1) MALI_POWER_MODE_ON
+ * 2) MALI_POWER_MODE_LIGHT_SLEEP
+ * 3) MALI_POWER_MODE_DEEP_SLEEP
+ * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
+ * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
+ * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
+ * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
+ * off.
+ * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
+ * mode.
+ * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
+ * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
+ * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
+ * @param power_mode defines the power modes
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode);
+
+
+/** @brief Platform specific handling of GPU utilization data
+ *
+ * When GPU utilization data is enabled, this function will be
+ * periodically called.
+ *
+ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
+ */
+void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data);
+
+_mali_osk_errcode_t g3d_power_domain_control(int bpower_on);
+
+#ifdef CONFIG_REGULATOR
+void mali_regulator_disable(void);
+void mali_regulator_enable(void);
+void mali_regulator_set_voltage(int min_uV, int max_uV);
+#endif
+
+#ifdef CONFIG_MALI_DVFS
+ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf);
+ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+#ifdef CONFIG_CPU_EXYNOS4210
+#if MALI_GPU_BOTTOM_LOCK
+int mali_dvfs_bottom_lock_push(void);
+int mali_dvfs_bottom_lock_pop(void);
+#endif
+#else
+int mali_dvfs_bottom_lock_push(int lock_step);
+int mali_dvfs_bottom_lock_pop(void);
+#endif
+#endif
+
+#if MALI_VOLTAGE_LOCK
+int mali_voltage_lock_push(int lock_vol);
+int mali_voltage_lock_pop(void);
+int mali_voltage_lock_init(void);
+int mali_vol_get_from_table(int vol);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/drivers/media/video/samsung/mali/regs/mali_200_regs.h b/drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h
index 59e92c8..dd75149 100644
--- a/drivers/media/video/samsung/mali/regs/mali_200_regs.h
+++ b/drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h
@@ -46,14 +46,10 @@ enum mali200_mgmt_reg
enum mali200_mgmt_ctrl_mgmt {
MALI200_REG_VAL_CTRL_MGMT_STOP_BUS = (1<<0),
-#if defined(USING_MALI200)
MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES = (1<<3),
-#endif
MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET = (1<<5),
MALI200_REG_VAL_CTRL_MGMT_START_RENDERING = (1<<6),
-#if defined(USING_MALI400) || defined(USING_MALI450)
- MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7),
-#endif
+ MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7), /* Only valid for Mali-300 and later */
};
enum mali200_mgmt_irq {
@@ -72,18 +68,6 @@ enum mali200_mgmt_irq {
MALI400PP_REG_VAL_IRQ_RESET_COMPLETED = (1<<12),
};
-#if defined(USING_MALI200)
-#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\
- MALI200_REG_VAL_IRQ_END_OF_FRAME |\
- MALI200_REG_VAL_IRQ_END_OF_TILE |\
- MALI200_REG_VAL_IRQ_HANG |\
- MALI200_REG_VAL_IRQ_FORCE_HANG |\
- MALI200_REG_VAL_IRQ_BUS_ERROR |\
- MALI200_REG_VAL_IRQ_BUS_STOP |\
- MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\
- MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\
- MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR))
-#elif defined(USING_MALI400) || defined(USING_MALI450)
#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\
MALI200_REG_VAL_IRQ_END_OF_FRAME |\
MALI200_REG_VAL_IRQ_END_OF_TILE |\
@@ -98,31 +82,15 @@ enum mali200_mgmt_irq {
MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\
MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW |\
MALI400PP_REG_VAL_IRQ_RESET_COMPLETED))
-#else
-#error "No supported mali core defined"
-#endif
-#if defined(USING_MALI200)
#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\
MALI200_REG_VAL_IRQ_END_OF_FRAME |\
- MALI200_REG_VAL_IRQ_HANG |\
MALI200_REG_VAL_IRQ_FORCE_HANG |\
MALI200_REG_VAL_IRQ_BUS_ERROR |\
- MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR))
-#elif defined(USING_MALI400) || defined(USING_MALI450)
-#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\
- MALI200_REG_VAL_IRQ_END_OF_FRAME |\
- MALI200_REG_VAL_IRQ_HANG |\
- MALI200_REG_VAL_IRQ_FORCE_HANG |\
- MALI200_REG_VAL_IRQ_BUS_ERROR |\
- MALI200_REG_VAL_IRQ_BUS_STOP |\
MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\
MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\
MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\
MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW))
-#else
-#error "No supported mali core defined"
-#endif
#define MALI200_REG_VAL_IRQ_MASK_NONE ((enum mali200_mgmt_irq)(0))
@@ -134,19 +102,12 @@ enum mali200_mgmt_status {
enum mali200_render_unit
{
MALI200_REG_ADDR_FRAME = 0x0000,
- MALI200_REG_ADDR_STACK = 0x0030
+ MALI200_REG_ADDR_RSW = 0x0004,
+ MALI200_REG_ADDR_STACK = 0x0030,
+ MALI200_REG_ADDR_STACK_SIZE = 0x0034,
+ MALI200_REG_ADDR_ORIGIN_OFFSET_X = 0x0040
};
-#if defined(USING_MALI200)
-#define MALI200_NUM_REGS_FRAME ((0x04C/4)+1)
-#elif defined(USING_MALI400)
-#define MALI200_NUM_REGS_FRAME ((0x058/4)+1)
-#elif defined(USING_MALI450)
-#define MALI200_NUM_REGS_FRAME ((0x058/4)+1)
-#else
-#error "No supported mali core defined"
-#endif
-
enum mali200_wb_unit {
MALI200_REG_ADDR_WB0 = 0x0100,
MALI200_REG_ADDR_WB1 = 0x0200,
@@ -157,11 +118,6 @@ enum mali200_wb_unit_regs {
MALI200_REG_ADDR_WB_SOURCE_SELECT = 0x0000,
};
-/** The number of registers in one single writeback unit */
-#ifndef MALI200_NUM_REGS_WBx
-#define MALI200_NUM_REGS_WBx ((0x02C/4)+1)
-#endif
-
/* This should be in the top 16 bit of the version register of Mali PP */
#define MALI200_PP_PRODUCT_ID 0xC807
#define MALI300_PP_PRODUCT_ID 0xCE07
diff --git a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h b/drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h
index 21c83c0..c204901 100644
--- a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
+++ b/drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h
@@ -60,9 +60,7 @@ typedef enum
MALIGP2_REG_VAL_CMD_RESET = (1<< 5),
MALIGP2_REG_VAL_CMD_FORCE_HANG = (1<< 6),
MALIGP2_REG_VAL_CMD_STOP_BUS = (1<< 9),
-#if defined(USING_MALI400) || defined(USING_MALI450)
- MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10),
-#endif
+ MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10), /* only valid for Mali-300 and later */
} mgp_contr_reg_val_cmd;
@@ -84,7 +82,6 @@ typedef enum
#define MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR (1 << 9)
#define MALIGP2_REG_VAL_IRQ_SYNC_ERROR (1 << 10)
#define MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR (1 << 11)
-#if defined(USING_MALI400) || defined(USING_MALI450)
#define MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED (1 << 12)
#define MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD (1 << 13)
#define MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD (1 << 14)
@@ -92,27 +89,8 @@ typedef enum
#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW (1 << 20)
#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW (1 << 21)
#define MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22)
-#elif !defined USING_MALI200
-#error "No supported mali core defined"
-#endif
-/* Mask defining all IRQs in MaliGP2 */
-#if defined(USING_MALI200)
-#define MALIGP2_REG_VAL_IRQ_MASK_ALL \
- (\
- MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
- MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
- MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
- MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ | \
- MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ | \
- MALIGP2_REG_VAL_IRQ_HANG | \
- MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
- MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT | \
- MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT | \
- MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
- MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
- MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR)
-#elif defined(USING_MALI400) || defined(USING_MALI450)
+/* Mask defining all IRQs in Mali GP */
#define MALIGP2_REG_VAL_IRQ_MASK_ALL \
(\
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
@@ -134,41 +112,22 @@ typedef enum
MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \
MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \
MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
-#else
-#error "No supported mali core defined"
-#endif
-/* Mask defining the IRQs in MaliGP2 which we use*/
-#if defined(USING_MALI200)
+/* Mask defining the IRQs in Mali GP which we use */
#define MALIGP2_REG_VAL_IRQ_MASK_USED \
(\
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
- MALIGP2_REG_VAL_IRQ_HANG | \
MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
- MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
- MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR)
-#elif defined(USING_MALI400) || defined(USING_MALI450)
-#define MALIGP2_REG_VAL_IRQ_MASK_USED \
- (\
- MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
- MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
- MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
- MALIGP2_REG_VAL_IRQ_HANG | \
- MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
- MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
- MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
+ MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \
MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \
MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \
MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \
MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \
MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
-#else
-#error "No supported mali core defined"
-#endif
/* Mask defining non IRQs on MaliGP2*/
#define MALIGP2_REG_VAL_IRQ_MASK_NONE 0
diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c
index 2426853..a6b1d76 100644
--- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c
@@ -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/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.h
index 0551726..3279dae 100644
--- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.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/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c
index 2426853..a6b1d76 100644
--- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c
@@ -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/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.h
index e6d3f2a..94b842a 100644
--- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.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/drivers/gpu/mali400/r3p2/ump/Kbuild b/drivers/gpu/mali400/r3p2/ump/Kbuild
new file mode 100644
index 0000000..4ca1aae
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Kbuild
@@ -0,0 +1,78 @@
+#
+# 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.
+#
+
+# Set default configuration to use, if Makefile didn't provide one.
+# Change this to use a different config.h
+# MALI_SEC
+# CONFIG ?= os_memory_64m
+CONFIG ?= pegasus-m400
+
+# Validate selected config
+ifneq ($(shell [ -d $(srctree)/$(src)/arch-$(CONFIG) ] && [ -f $(srctree)/$(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
+$(warning Current directory is $(srctree)/$(src))
+$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists)
+else
+# Link arch to the selected arch-config directory
+$(shell [ -L $(srctree)/$(src)/arch ] && rm $(srctree)/$(src)/arch)
+$(shell ln -sf arch-$(CONFIG) $(srctree)/$(src)/arch)
+$(shell touch $(srctree)/$(src)/arch/config.h)
+endif
+
+UDD_FILE_PREFIX = ../mali/
+
+# Get subversion revision number, fall back to 0000 if no svn info is available
+SVN_REV := 0000
+
+ccflags-y += -DSVN_REV=$(SVN_REV)
+ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
+
+ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/../mali/common -I$(srctree)/$(src)/../mali/linux -I$(srctree)/$(src)/../../ump/include/ump
+
+# MALI_SEC
+ccflags-y += -I$(srctree)/$(src)/include
+ccflags-y += -DUSING_MEMORY=1 -DUMP_MEM_SIZE=512
+
+ccflags-y += -DMALI_STATE_TRACKING=0
+ccflags-$(CONFIG_UMP_DEBUG) += -DDEBUG
+
+# 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 $(srctree)/$(src)/linux/license/gpl/*),)
+ccflags-y += -I$(srctree)/$(src)/linux/license/proprietary
+else
+ccflags-y += -I$(srctree)/$(src)/linux/license/gpl
+endif
+
+ump-y = common/ump_kernel_common.o \
+ common/ump_kernel_descriptor_mapping.o \
+ common/ump_kernel_api.o \
+ common/ump_kernel_ref_drv.o \
+ linux/ump_kernel_linux.o \
+ linux/ump_kernel_memory_backend_os.o \
+ linux/ump_kernel_memory_backend_dedicated.o \
+ linux/ump_memory_backend.o \
+ linux/ump_ukk_wrappers.o \
+ linux/ump_ukk_ref_wrappers.o \
+ linux/ump_osk_atomics.o \
+ linux/ump_osk_low_level_mem.o \
+ linux/ump_osk_misc.o
+
+# MALI_SEC
+# $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
+
+# MALI_SEC
+obj-$(CONFIG_MALI400_UMP) := ump.o
+
diff --git a/drivers/gpu/mali400/r3p2/ump/Kconfig b/drivers/gpu/mali400/r3p2/ump/Kconfig
new file mode 100644
index 0000000..13785e2
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Kconfig
@@ -0,0 +1,7 @@
+config UMP_DEBUG
+ bool "Enable extra debug in UMP"
+ depends on MALI400_UMP
+ default n
+ ---help---
+ This enabled extra debug checks and messages in UMP.
+
diff --git a/drivers/gpu/mali400/r3p2/ump/Makefile b/drivers/gpu/mali400/r3p2/ump/Makefile
new file mode 100644
index 0000000..e2aa8e5
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Makefile
@@ -0,0 +1,67 @@
+#
+# 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.
+#
+
+# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH
+
+export ARCH ?= arm
+BUILD ?= debug
+
+check_cc2 = \
+ $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
+ then \
+ echo "$(2)"; \
+ else \
+ echo "$(3)"; \
+ fi ;)
+
+# Check that required parameters are supplied.
+ifeq ($(CONFIG),)
+$(error "CONFIG must be specified.")
+endif
+ifeq ($(CPU)$(KDIR),)
+$(error "KDIR or CPU must be specified.")
+endif
+
+# Get any user defined KDIR-<names> or maybe even a hardcoded KDIR
+-include KDIR_CONFIGURATION
+
+# Define host system directory
+KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
+
+ifeq ($(ARCH), arm)
+# when compiling for ARM we're cross compiling
+export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
+endif
+
+# look up KDIR based om CPU selection
+KDIR ?= $(KDIR-$(CPU))
+
+export CONFIG
+
+export CONFIG_UMP := m
+ifeq ($(BUILD),debug)
+export CONFIG_UMP_DEBUG := y
+else
+export CONFIG_UMP_DEBUG := n
+endif
+
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(CPU))
+endif
+
+all:
+ $(MAKE) -C $(KDIR) M=$(CURDIR) modules
+
+kernelrelease:
+ $(MAKE) -C $(KDIR) kernelrelease
+
+clean:
+ $(MAKE) -C $(KDIR) M=$(CURDIR) clean
+ $(MAKE) -C $(KDIR) M=$(CURDIR)/../mali clean
diff --git a/drivers/media/video/samsung/ump/Makefile.common b/drivers/gpu/mali400/r3p2/ump/Makefile.common
index 26a3d6c..c6aa633 100644
--- a/drivers/media/video/samsung/ump/Makefile.common
+++ b/drivers/gpu/mali400/r3p2/ump/Makefile.common
@@ -1,9 +1,9 @@
#
-# 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.
-#
+#
# 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.
#
@@ -14,7 +14,7 @@ SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \
$(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c
# Get subversion revision number, fall back to 0000 if no svn info is available
-SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
+SVN_REV:=$(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV)
EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\"
diff --git a/drivers/media/video/samsung/ump/arch-orion-m400/config.h b/drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h
index 7afbca6..7afbca6 100644
--- a/drivers/media/video/samsung/ump/arch-orion-m400/config.h
+++ b/drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h
diff --git a/drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m400 b/drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m400
new file mode 120000
index 0000000..4006f31
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m400
@@ -0,0 +1 @@
+arch-pegasus-m400 \ No newline at end of file
diff --git a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h b/drivers/gpu/mali400/r3p2/ump/arch/config.h
index 7afbca6..7afbca6 100644
--- a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h
+++ b/drivers/gpu/mali400/r3p2/ump/arch/config.h
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_api.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c
index 83f0d30..013f4c6 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_api.c
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c
@@ -1,9 +1,9 @@
/*
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
- *
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -55,6 +55,7 @@ UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secu
return (ump_dd_handle)mem;
}
+/* MALI_SEC */
UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id)
{
ump_dd_mem * mem;
@@ -277,7 +278,7 @@ _mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info )
}
_mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id));
+ DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id));
DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret));
return ret;
@@ -520,8 +521,6 @@ void _ump_ukk_lock(_ump_uk_lock_s *args )
mem->lock_usage = (ump_lock_usage) args->lock_usage;
- /** TODO: TAKE LOCK HERE */
-
ump_dd_reference_release(mem);
}
@@ -545,7 +544,5 @@ void _ump_ukk_unlock(_ump_uk_unlock_s *args )
mem->lock_usage = (ump_lock_usage) UMP_NOT_LOCKED;
- /** TODO: RELEASE LOCK HERE */
-
ump_dd_reference_release(mem);
}
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c
index a27bc77..306ea3d 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_common.c
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c
@@ -233,6 +233,7 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
return _MALI_OSK_ERR_INVALID_ARGS;
}
+ /* MALI_SEC */
/* SEC kernel stability 2012-02-17 */
if (NULL == session_data->cookies_map)
{
@@ -288,6 +289,7 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
args->is_cached = 1;
DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id));
}
+ /* MALI_SEC */
else if ( args->is_cached)
{
mem->is_cached = 1;
@@ -371,6 +373,7 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args )
MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
return;
}
+ /* MALI_SEC */
/* SEC kernel stability 2012-02-17 */
if (NULL == session_data->cookies_map)
{
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h
index 6e3a2e9..6e3a2e9 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_common.h
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c
index cc7b8be..2531f80 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c
@@ -1,9 +1,9 @@
/*
- * 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.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -65,9 +65,9 @@ void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map)
int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target)
{
- int descriptor = -1;/*-EFAULT;*/
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
- descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
+ int descriptor = -1;/*-EFAULT;*/
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
if (descriptor == map->current_nr_mappings)
{
int nr_mappings_new;
@@ -89,8 +89,8 @@ int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void *
goto unlock_and_exit;
}
- _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
- _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
+ _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
+ _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
map->table = new_table;
map->current_nr_mappings = nr_mappings_new;
descriptor_table_free(old_table);
@@ -107,10 +107,10 @@ unlock_and_exit:
int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target)
{
- int result = -1;/*-EFAULT;*/
- DEBUG_ASSERT(map);
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ int result = -1;/*-EFAULT;*/
+ DEBUG_ASSERT(map);
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
{
*target = map->table->mappings[descriptor];
result = 0;
@@ -122,9 +122,9 @@ int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, voi
int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target)
{
- int result = -1;/*-EFAULT;*/
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ int result = -1;/*-EFAULT;*/
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
{
map->table->mappings[descriptor] = target;
result = 0;
@@ -135,8 +135,8 @@ int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, voi
void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor)
{
- _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
- if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
{
map->table->mappings[descriptor] = NULL;
_mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
@@ -163,3 +163,4 @@ static void descriptor_table_free(ump_descriptor_table * table)
{
_mali_osk_free(table);
}
+
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.h
index 05b3982..92bbe54 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.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/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h
index 73915ee..8b11452 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h
@@ -1,9 +1,9 @@
/*
- * 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.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -40,6 +40,7 @@ typedef struct ump_memory_backend
u32 (*stat)(struct ump_memory_backend *backend);
int (*pre_allocate_physical_check)(void *ctx, u32 size);
u32 (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys);
+ /* MALI_SEC */
void *(*get)(ump_dd_mem *mem, void *args);
void (*set)(ump_dd_mem *mem, void *args);
void * ctx;
@@ -49,3 +50,4 @@ ump_memory_backend * ump_memory_backend_create ( void );
void ump_memory_backend_destroy( void );
#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */
+
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c
index cb13232..6335bf6 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c
@@ -196,7 +196,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
return _MALI_OSK_ERR_OK;
}
-
+/* MALI_SEC */
UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args)
{
ump_dd_mem * mem;
@@ -257,4 +257,3 @@ UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long v
return (ump_dd_handle)mem;
}
-
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_types.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h
index 19a9755..19a9755 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_types.h
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h
diff --git a/drivers/media/video/samsung/ump/common/ump_osk.h b/drivers/gpu/mali400/r3p2/ump/common/ump_osk.h
index dabdc7f..d9d182a 100644
--- a/drivers/media/video/samsung/ump/common/ump_osk.h
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_osk.h
@@ -1,9 +1,9 @@
/*
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
- *
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -42,6 +42,7 @@ void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor );
void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data );
+/* MALI_SEC */
void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr);
#ifdef __cplusplus
diff --git a/drivers/media/video/samsung/ump/common/ump_ukk.h b/drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h
index 56e4be3..56e4be3 100644
--- a/drivers/media/video/samsung/ump/common/ump_ukk.h
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h
index 042c8b1..042c8b1 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h
index 36c5c9d..b253de5 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h
@@ -1,9 +1,9 @@
/*
* Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
- *
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h
index 4349605..4349605 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h
diff --git a/drivers/media/video/samsung/ump/common/ump_uk_types.h b/drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h
index 143588d..2f87272 100644
--- a/drivers/media/video/samsung/ump/common/ump_uk_types.h
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h
@@ -1,9 +1,9 @@
/*
* Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
- *
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -49,9 +49,7 @@ typedef enum
_UMP_IOC_SWITCH_HW_USAGE,
_UMP_IOC_LOCK,
_UMP_IOC_UNLOCK,
-#ifdef CONFIG_ION_EXYNOS
_UMP_IOC_ION_IMPORT,
-#endif
}_ump_uk_functions;
typedef enum
@@ -110,7 +108,6 @@ typedef struct _ump_uk_allocate_s
ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
} _ump_uk_allocate_s;
-#ifdef CONFIG_ION_EXYNOS
typedef struct _ump_uk_ion_import_s
{
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
@@ -119,7 +116,6 @@ typedef struct _ump_uk_ion_import_s
u32 size; /**< Input and output. Requested size; input. Returned size; output */
ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
} _ump_uk_ion_import_s;
-#endif
/**
* SIZE_GET ([in] u32 secure_id, [out]size )
diff --git a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h b/drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h
index 187e33b..187e33b 100644
--- a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h
diff --git a/drivers/media/video/samsung/ump/linux/ump_ioctl.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h
index 83bb2a4..dcc343a 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ioctl.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h
@@ -40,13 +40,11 @@ extern "C"
#define UMP_IOC_RELEASE _IOR(UMP_IOCTL_NR, _UMP_IOC_RELEASE, _ump_uk_release_s)
#define UMP_IOC_SIZE_GET _IOWR(UMP_IOCTL_NR, _UMP_IOC_SIZE_GET, _ump_uk_size_get_s)
#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_msync_s)
-#ifdef CONFIG_ION_EXYNOS
+/* MALI_SEC */
#define UMP_IOC_ION_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s)
-#endif
-#ifdef CONFIG_DMA_SHARED_BUFFER
+/* MALI_SEC */
#define UMP_IOC_DMABUF_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_DMABUF_IMPORT,\
struct ump_uk_dmabuf)
-#endif
#define UMP_IOC_CACHE_OPERATIONS_CONTROL _IOW(UMP_IOCTL_NR, _UMP_IOC_CACHE_OPERATIONS_CONTROL, _ump_uk_cache_operations_control_s)
#define UMP_IOC_SWITCH_HW_USAGE _IOW(UMP_IOCTL_NR, _UMP_IOC_SWITCH_HW_USAGE, _ump_uk_switch_hw_usage_s)
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c
index a358a3c..b509f43 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c
@@ -35,19 +35,25 @@
#include "ump_ukk_wrappers.h"
#include "ump_ukk_ref_wrappers.h"
+/* MALI_SEC */
#ifdef CONFIG_ION_EXYNOS
#include <linux/ion.h>
extern struct ion_device *ion_exynos;
struct ion_client *ion_client_ump = NULL;
#endif
+/* MALI_SEC */
+#if defined(CONFIG_MALI400)
+extern int map_errcode( _mali_osk_errcode_t err );
+#endif
+
/* Module parameter to control log level */
int ump_debug_level = 2;
module_param(ump_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
MODULE_PARM_DESC(ump_debug_level, "Higher number, more dmesg output");
/* By default the module uses any available major, but it's possible to set it at load time to a specific number */
-int ump_major = 243;
+int ump_major = 0;
module_param(ump_major, int, S_IRUGO); /* r--r--r-- */
MODULE_PARM_DESC(ump_major, "Device major number");
@@ -92,9 +98,6 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
#endif
static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma);
-#if defined(CONFIG_VIDEO_UMP)
-extern int map_errcode( _mali_osk_errcode_t err );
-#endif
/* This variable defines the file operations this UMP device driver offer */
static struct file_operations ump_fops =
@@ -139,6 +142,7 @@ static int ump_initialize_module(void)
*/
static void ump_cleanup_module(void)
{
+/* MALI_SEC */
#ifdef CONFIG_ION_EXYNOS
if (ion_client_ump)
ion_client_destroy(ion_client_ump);
@@ -352,6 +356,7 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
case UMP_IOC_ALLOCATE :
err = ump_allocate_wrapper((u32 __user *)argument, session_data);
break;
+/* MALI_SEC */
#ifdef CONFIG_ION_EXYNOS
case UMP_IOC_ION_IMPORT:
err = ump_ion_import_wrapper((u32 __user *)argument, session_data);
@@ -400,7 +405,8 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
return err;
}
-#ifndef CONFIG_VIDEO_UMP
+/* MALI_SEC */
+#if !defined(CONFIG_MALI400)
int map_errcode( _mali_osk_errcode_t err )
{
switch(err)
@@ -429,6 +435,8 @@ static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma)
/* Validate the session data */
session_data = (struct ump_session_data *)filp->private_data;
+ /* MALI_SEC */
+ // original : if (NULL == session_data)
if (NULL == session_data || NULL == session_data->cookies_map->table->mappings)
{
MSG_ERR(("mmap() called without any session data available\n"));
@@ -474,6 +482,7 @@ EXPORT_SYMBOL(ump_dd_phys_blocks_get);
EXPORT_SYMBOL(ump_dd_size_get);
EXPORT_SYMBOL(ump_dd_reference_add);
EXPORT_SYMBOL(ump_dd_reference_release);
+/* MALI_SEC */
EXPORT_SYMBOL(ump_dd_meminfo_get);
EXPORT_SYMBOL(ump_dd_meminfo_set);
EXPORT_SYMBOL(ump_dd_handle_get_from_vaddr);
@@ -482,8 +491,7 @@ EXPORT_SYMBOL(ump_dd_handle_get_from_vaddr);
EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks);
/* Setup init and exit functions for this module */
-//module_init(ump_initialize_module);
-arch_initcall(ump_initialize_module);
+module_init(ump_initialize_module);
module_exit(ump_cleanup_module);
/* And some module informatio */
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h
index 4985bb7..4985bb7 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c
index 82c16cc..f42a320 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c
@@ -1,9 +1,9 @@
/*
- * 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.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -108,6 +108,7 @@ ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size)
backend->stat = block_allocator_stat;
backend->pre_allocate_physical_check = NULL;
backend->adjust_to_mali_phys = NULL;
+ /* MALI_SEC */
backend->get = NULL;
backend->set = NULL;
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.h
index ca8faae..fa4bdcc 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.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/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c
index 8f6a9b3..0cee2c8 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c
@@ -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.
@@ -77,6 +77,7 @@ ump_memory_backend * ump_os_memory_backend_create(const int max_allocation)
backend->stat = os_stat;
backend->pre_allocate_physical_check = NULL;
backend->adjust_to_mali_phys = NULL;
+ /* MALI_SEC */
backend->get = NULL;
backend->set = NULL;
@@ -136,20 +137,21 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
return 0; /* failure */
}
- while (left > 0)
+ while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max))
{
struct page * new_page;
if (is_cached)
{
- new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN );
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN);
} else
{
- new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD);
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
}
if (NULL == new_page)
{
- MSG_ERR(("UMP memory allocated: Out of Memory !!\n"));
+ /* MALI_SEC */
+ DBG_MSG(1, ("UMP memory allocated: Out of Memory !!\n"));
break;
}
@@ -183,6 +185,7 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
if (left)
{
DBG_MSG(1, ("Failed to allocate needed pages\n"));
+ /* MALI_SEC */
DBG_MSG(1, ("UMP memory allocated: %d kB Configured maximum OS memory usage: %d kB\n",
(pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.h
index 6f7e610..f924705 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_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/drivers/media/video/samsung/ump/linux/ump_memory_backend.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c
index d067cfe..fd1f555 100644
--- a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c
@@ -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.
@@ -56,6 +56,7 @@ ump_memory_backend* ump_memory_backend_create ( void )
DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size));
backend = ump_os_memory_backend_create(ump_memory_size);
}
+/* MALI_SEC */
#ifdef CONFIG_UMP_VCM_ALLOC
else if (2 == ump_backend)
{
diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c
index b117d99..ef1902e 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c
@@ -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/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c
index 8ae169a..5fd85a6 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c
@@ -23,6 +23,7 @@
#include <linux/module.h> /* kernel module definitions */
#include <linux/kernel.h>
#include <linux/mm.h>
+/* MALI_SEC */
#include <linux/sched.h>
#include <linux/slab.h>
@@ -149,7 +150,14 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descrip
vma->vm_private_data = vma_usage_tracker;
vma->vm_flags |= VM_IO;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
vma->vm_flags |= VM_RESERVED;
+#else
+ vma->vm_flags |= VM_DONTDUMP;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags |= VM_PFNMAP;
+#endif
+
if (0==descriptor->is_cached)
{
@@ -211,6 +219,7 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript
return retval;
}
+/* MALI_SEC */
static u32 _ump_osk_virt_to_phys_start(ump_dd_mem * mem, u32 start, u32 address, int *index)
{
int i;
@@ -231,6 +240,7 @@ static u32 _ump_osk_virt_to_phys_start(ump_dd_mem * mem, u32 start, u32 address,
return _MALI_OSK_ERR_FAULT;
}
+/* MALI_SEC */
static u32 _ump_osk_virt_to_phys_end(ump_dd_mem * mem, u32 start, u32 address, int *index)
{
int i;
@@ -251,6 +261,7 @@ static u32 _ump_osk_virt_to_phys_end(ump_dd_mem * mem, u32 start, u32 address, i
return _MALI_OSK_ERR_FAULT;
}
+/* MALI_SEC */
static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size)
{
int start_index, end_index;
@@ -299,6 +310,7 @@ static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 s
}
return;
}
+/* The end of MALI_SEC */
static void level1_cache_flush_all(void)
{
@@ -309,12 +321,14 @@ static void level1_cache_flush_all(void)
void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data )
{
int i;
+ /* MALI_SEC */
const void *start_v, *end_v;
/* Flush L1 using virtual address, the entire range in one go.
* Only flush if user space process has a valid write mapping on given address. */
if( (mem) && (virt!=NULL) && (access_ok(VERIFY_WRITE, virt, size)) )
{
+ /* MALI_SEC */
start_v = (void *)virt;
end_v = (void *)(start_v + size - 1);
/* There is no dmac_clean_range, so the L1 is always flushed,
@@ -324,6 +338,9 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
else
dmac_flush_range(start_v, end_v);
+ /* MALI ORIGINAL CODE */
+ //__cpuc_flush_dcache_area(virt, size);
+
DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v));
}
else
@@ -372,9 +389,14 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
/* Flush L2 using physical addresses, block for block. */
+ /* MALI_SEC */
if ((virt!=NULL) && (mem->size_bytes >= SZ_1M)) {
if (op == _UMP_UK_MSYNC_CLEAN)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
outer_clean_all();
+#else
+ outer_sync();
+#endif
else if ((op == _UMP_UK_MSYNC_INVALIDATE) || (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE))
outer_flush_all();
return;
@@ -447,6 +469,7 @@ void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk
return;
}
+/* MALI_SEC */
void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr)
{
struct mm_struct *mm = current->mm;
@@ -482,4 +505,3 @@ void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr)
DBG_MSG(3, ("Get handle: 0x%08lx\n", handle));
*mem = (ump_dd_mem*)handle;
}
-
diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c
index 3be6fed..12066eb 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c
@@ -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/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c
index a6691ed..977db9a 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c
@@ -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.
@@ -21,13 +21,14 @@
#include "ump_ukk.h"
#include "ump_kernel_common.h"
+/* MALI_SEC */
#if defined(CONFIG_ION_EXYNOS) || defined(CONFIG_DMA_SHARED_BUFFER)
#include <linux/scatterlist.h>
#include "ump_kernel_interface_ref_drv.h"
#include "mali_osk_list.h"
#ifdef CONFIG_ION_EXYNOS
#include <linux/ion.h>
-#include "../../../../../gpu/ion/ion_priv.h"
+#include "../../../../gpu/ion/ion_priv.h"
extern struct ion_device *ion_exynos;
extern struct ion_client *ion_client_ump;
#endif
@@ -89,6 +90,8 @@ int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * sessi
return 0; /* success */
}
+
+/* MALI_SEC */
#ifdef CONFIG_ION_EXYNOS
/*
* IOCTL operation; Import fd to UMP memory
@@ -256,6 +259,13 @@ int ump_dmabuf_import_wrapper(u32 __user *argument,
block_size = sizeof(ump_dd_physical_block) * npages;
blocks = (ump_dd_physical_block *)_mali_osk_malloc(block_size);
+
+ if (NULL == blocks) {
+ MSG_ERR(("Failed to allocate blocks\n"));
+ ret = -ENOMEM;
+ goto err_dmu_buf_unmap;
+ }
+
sgl = sgt->sgl;
while (i < npages) {
@@ -310,6 +320,7 @@ err_free_session:
_mali_osk_free(session);
err_free_block:
_mali_osk_free(blocks);
+err_dmu_buf_unmap:
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
err_dma_buf_detach:
dma_buf_detach(dma_buf, attach);
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.h
index 416a584..63ee98c 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.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.
@@ -27,10 +27,11 @@ extern "C"
int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+/* MALI_SEC */
#ifdef CONFIG_ION_EXYNOS
int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data);
#endif
-
+/* MALI_SEC */
#ifdef CONFIG_DMA_SHARED_BUFFER
int ump_dmabuf_import_wrapper(u32 __user *argument,
struct ump_session_data *session_data);
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c
index 780f311..780f311 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h
index e87a903..e87a903 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h
diff --git a/drivers/media/video/samsung/Kconfig b/drivers/media/video/samsung/Kconfig
index 7ae9e6a..4824144 100644
--- a/drivers/media/video/samsung/Kconfig
+++ b/drivers/media/video/samsung/Kconfig
@@ -17,8 +17,6 @@ if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
source "drivers/media/video/samsung/fimc/Kconfig"
source "drivers/media/video/samsung/tvout/Kconfig"
source "drivers/media/video/samsung/mfc5x/Kconfig"
- source "drivers/media/video/samsung/mali/Kconfig"
- source "drivers/media/video/samsung/ump/Kconfig"
endif
config VIDEO_FIMG2D
diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile
index e9905d2..5a46253 100644
--- a/drivers/media/video/samsung/Makefile
+++ b/drivers/media/video/samsung/Makefile
@@ -12,8 +12,6 @@ obj-$(CONFIG_VIDEO_FIMG2D3X) += fimg2d3x/
obj-$(CONFIG_VIDEO_FIMG2D4X) += fimg2d4x/
endif
-obj-$(CONFIG_VIDEO_UMP) += ump/
obj-$(CONFIG_VIDEO_TSI) += tsi/
-obj-$(CONFIG_VIDEO_MALI400MP) += mali/
EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/media/video/samsung/mali/Kbuild_module b/drivers/media/video/samsung/mali/Kbuild_module
deleted file mode 100644
index e865954..0000000
--- a/drivers/media/video/samsung/mali/Kbuild_module
+++ /dev/null
@@ -1,295 +0,0 @@
-#
-# Copyright (C) 2010-2011 ARM Limited. All rights reserved.
-#
-# This program is free software and is provided to you under the terms of the GNU General Public License version 2
-# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
-#
-# A copy of the licence is included with the program, and can also be obtained from Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-
-# This file is called by the Linux build system.
-
-OSKOS=linux
-
-# set up defaults if not defined by the user
-USING_UMP ?= 0
-USING_OS_MEMORY ?= 0
-USING_MALI_PMM_TESTSUITE ?= 0
-OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
-USING_PROFILING ?= 1
-USING_INTERNAL_PROFILING ?= 0
-DISABLE_PP0 ?= 0
-DISABLE_PP1 ?= 0
-DISABLE_PP2 ?= 0
-DISABLE_PP3 ?= 0
-PROFILING_SKIP_PP_JOBS ?= 0
-PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
-PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0
-TIMESTAMP ?= default
-BUILD ?= debug
-TARGET_PLATFORM ?= default
-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)
-
-# 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 -E "^[0-9]+" && 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)
-$(warning Current directory is $(shell pwd))
-$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists)
-else
-# Link arch to the selected arch-config directory
-$(shell [ -L $(DRIVER_DIR)/arch ] && rm $(DRIVER_DIR)/arch)
-$(shell ln -sf arch-$(CONFIG) $(DRIVER_DIR)/arch)
-$(shell touch $(DRIVER_DIR)/arch/config.h)
-endif
-
-# Set up our defines, which will be passed to gcc
-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_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 += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
-DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
-DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH)
-
-DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
-DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
-DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
-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.
-DEFINES += -DMALI_STATE_TRACKING=1
-else
-DEFINES += -DMALI_STATE_TRACKING=0
-endif
-DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
-
-MALI_PLATFORM_FILE = platform/$(TARGET_PLATFORM)/mali_platform.c
-
-
-ifdef CONFIG_PM
-ifdef CONFIG_PM_RUNTIME
- KERNEL_RUNTIME_PM_ENABLED = 1
-endif
-endif
-
-DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED)
-
-ifeq ($(BUILD), debug)
-DEFINES += -DDEBUG
-endif
-DEFINES += -DSVN_REV=$(SVN_REV)
-DEFINES += -DSVN_REV_STRING=\"$(SVN_REV)\"
-
-# Linux has its own mmap cleanup handlers (see mali_kernel_memory.c)
-DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
-
-ifeq ($(USING_UMP),1)
- DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1
- ccflags-y += -I$(DRIVER_DIR)/../../ump/include/ump
-else
- DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0
-endif
-
-# Use our defines when compiling
-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 \
- 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_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
-
-# Selecting files to compile by parsing the config file
-
-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
-endif
-
-mali-$(CONFIG_MALI400_GPU_UTILIZATION) += common/mali_kernel_utilization.o
-mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o
-
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI400PP),0)
- # Mali-400 PP in use
- ccflags-y += -DUSING_MALI400
-endif
-
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI300PP),0)
- # Mali-400 PP in use
- ccflags-y += -DUSING_MALI400
-endif
-
-ifneq ($(call submodule_enabled, $(DRIVER_DIR), MALI200),0)
- # Mali200 in use
- ccflags-y += -DUSING_MALI200
-endif
-
-# Always build in support for Mali L2 cache
-SRC += common/mali_l2_cache.c
-
-# 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
-
-
-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)
-
-VERSION_STRINGS += BUILD=$(shell echo $(BUILD) | tr a-z A-Z)
-VERSION_STRINGS += CPU=$(CPU)
-VERSION_STRINGS += USING_UMP=$(USING_UMP)
-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)
-VERSION_STRINGS += USING_GP2=$(call submodule_enabled, $(DRIVER_DIR), MALIGP2)
-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_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:
- @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(DRIVER_DIR)/__malidrv_build_info.c
diff --git a/drivers/media/video/samsung/mali/Kconfig b/drivers/media/video/samsung/mali/Kconfig
deleted file mode 100644
index 1736eed..0000000
--- a/drivers/media/video/samsung/mali/Kconfig
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-## S3C Multimedia Mali configuration
-##
-#
-# For Mali
-config VIDEO_MALI400MP
- bool "Enable MALI integration"
- depends on VIDEO_SAMSUNG
- default y
- ---help---
- This enables MALI integration in the multimedia device driver
-
-choice
-depends on VIDEO_MALI400MP
-prompt "MALI MEMORY OPTION"
-default MALI_OSMEM_ONLY
-config MALI_DED_ONLY
- bool "mali dedicated memory only"
- ---help---
- This enables MALI dedicated memory only option
-config MALI_DED_MMU
- bool "mali dedicated memory with mmu enable"
- ---help---
- This enables MALI dedicated memory with mmu enable option
-config MALI_OSMEM_ONLY
- bool "mali OS memory only"
- ---help---
- This enables MALI OS memory only option
-config MALI_DED_OSMEM
- bool "mali dedicated memory and OS memory"
- ---help---
- This enables MALI dedicated memory and OS memory option
-
-endchoice
-config MALI_MEM_SIZE
-int "Dedicated Memory Size"
- depends on VIDEO_MALI400MP && (MALI_DED_ONLY || MALI_DED_MMU || MALI_DED_OSMEM)
- default "128"
- ---help---
- This value is dedicated memory size of Mali GPU(unit is MByte).
-
-config MALI_R3P1_LSI
- bool "Uses the R3P1 as a kernel module"
- depends on VIDEO_MALI400MP
- default n
- ---help---
- This uses the r3p1 as a MALI kernel module
-
-
-# For DEBUG
-config VIDEO_MALI400MP_DEBUG
- bool "Enables debug messages"
- depends on VIDEO_MALI400MP
- default n
- help
- This enables Mali driver debug messages.
-
-config VIDEO_MALI400MP_DVFS
- bool "Enables DVFS"
- depends on VIDEO_MALI400MP && PM
- default y
- help
- This enables Mali driver DVFS.
diff --git a/drivers/media/video/samsung/mali/Kconfig_module b/drivers/media/video/samsung/mali/Kconfig_module
deleted file mode 100644
index dabb36e..0000000
--- a/drivers/media/video/samsung/mali/Kconfig_module
+++ /dev/null
@@ -1,30 +0,0 @@
-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/drivers/media/video/samsung/mali/Makefile b/drivers/media/video/samsung/mali/Makefile
deleted file mode 100644
index 3e25b61..0000000
--- a/drivers/media/video/samsung/mali/Makefile
+++ /dev/null
@@ -1,337 +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.
-#
-
-OSKOS :=linux
-FILES_PREFIX=
-MALI_INCLUDE_PREFIX := drivers/media/video/samsung/mali/
-KBUILDROOT =
-
-ifeq ($(CONFIG_MALI_DED_ONLY),y)
-USING_OS_MEMORY=0
-USING_MMU=0
-USING_DED=1
-endif
-
-ifeq ($(CONFIG_MALI_DED_MMU),y)
-USING_OS_MEMORY=0
-USING_MMU=1
-USING_DED=1
-endif
-
-ifeq ($(CONFIG_MALI_OSMEM_ONLY),y)
-USING_MMU=1
-USING_DED=0
-USING_OS_MEMORY=1
-endif
-
-ifeq ($(CONFIG_MALI_DED_OSMEM),y)
-USING_MMU=1
-USING_DED=1
-USING_OS_MEMORY=1
-endif
-
-ifeq ($(CONFIG_PM),y)
- USING_PMM = 1
-ifeq ($(CONFIG_PM_RUNTIME),y)
- KERNEL_RUNTIME_PM_ENABLED = 1
-endif
-endif
-
-ifeq ($(CONFIG_VIDEO_MALI400MP_DVFS),y)
-USING_GPU_UTILIZATION=1
-USING_MALI_DVFS_ENABLED=1
-endif
-
-ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y)
-BUILD=debug
-endif
-
-ifeq ($(CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING),y)
-USING_PROFILING=1
-USING_TRACEPOINTS=1
-endif
-
-# set up defaults if not defined by the user
-USE_UMPV2 ?= 0
-PANIC_ON_WATCHDOG_TIMEOUT ?= 1
-USING_MALI400 ?= 1
-USING_MMU ?= 1
-USING_DED ?= 0
-USING_UMP ?= 0
-ONLY_ZBT ?= 0
-USING_ZBT ?= 0
-USING_OS_MEMORY ?= 1
-USING_PMM ?= 0
-USING_MALI_RUN_TIME_PM ?= 0
-USING_MALI_PMM_TESTSUITE ?= 0
-USING_MALI_PMU ?= 0
-USING_GPU_UTILIZATION ?= 0
-OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
-USING_PROFILING ?= 0
-USING_INTERNAL_PROFILING ?= 0
-USING_TRACEPOINTS ?= 0
-USING_MALI_MAJOR_PREDEFINE = 1
-USING_MALI_DVFS_ENABLED ?= 1
-USING_MALI_PMM_EARLYSUSPEND ?= 0
-#USING_KERNEL_WITH_DMA_ALLOC_PHYS_PAGE ?= 0
-#CONFIG_MALI_MEM_SIZE ?= 512
-DISABLE_PP0 ?= 0
-DISABLE_PP1 ?= 0
-DISABLE_PP2 ?= 0
-DISABLE_PP3 ?= 0
-PROFILING_SKIP_PP_JOBS ?= 0
-PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
-PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH ?= 0
-TIMESTAMP ?= default
-BUILD ?= release
-TARGET_PLATFORM ?= default
-KERNEL_RUNTIME_PM_ENABLED ?= 0
-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
-
-# Get path to driver source from Linux build system
-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
-
-USING_MALI_SLP_GLOBAL_LOCK ?= 0
-
-#config validtion check
-ifeq ($(USING_OS_MEMORY),1)
- USING_MMU = 1
-endif
-
-# Check if a Mali Core sub module should be enabled, true or false returned
-#submodule_enabled = $(shell gcc $(DEFINES) -E $(FILES_PREFIX)/arch/config.h | grep type | grep -c $(2))
-
-# Inside the kernel build system
-
-# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak
--include ../../../arm_internal.mak
-
-# Set up our defines, which will be passed to gcc
-DEFINES += -DONLY_ZBT=$(ONLY_ZBT)
-DEFINES += -DUSING_ZBT=$(USING_ZBT)
-DEFINES += -DUSING_MMU=$(USING_MMU)
-DEFINES += -DUSING_OS_MEMORY=$(USING_OS_MEMORY)
-DEFINES += -DUSING_DED=$(USING_DED)
-DEFINES += -DUSING_UMP=$(USING_UMP)
-DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP
-DEFINES += -DUSING_MALI_PMU=$(USING_MALI_PMU)
-DEFINES += -DMALI_PMM_RUNTIME_JOB_CONTROL_ON=$(KERNEL_RUNTIME_PM_ENABLED)
-DEFINES += -DUSING_MALI_PMM=$(USING_PMM)
-DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
-DEFINES += -DCONFIG_MALI_MEM_SIZE=$(CONFIG_MALI_MEM_SIZE)
-DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP
-DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING)
-DEFINES += -DMALI_MAJOR_PREDEFINE=$(USING_MALI_MAJOR_PREDEFINE)
-DEFINES += -DMALI_DVFS_ENABLED=$(USING_MALI_DVFS_ENABLED)
-DEFINES += -DUSING_MALI_PMM_EARLYSUSPEND=$(USING_MALI_PMM_EARLYSUSPEND)
-DEFINES += -DMALI_STATE_TRACKING=0
-DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
-DEFINES += -DMALI_TRACEPOINTS_ENABLED=$(USING_TRACEPOINTS)
-DEFINES += -DDISABLE_PP0=$(DISABLE_PP0)
-DEFINES += -DDISABLE_PP1=$(DISABLE_PP1)
-DEFINES += -DDISABLE_PP2=$(DISABLE_PP2)
-DEFINES += -DDISABLE_PP3=$(DISABLE_PP3)
-DEFINES += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
-DEFINES += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
-DEFINES += -DPROFILING_PRINT_L2_HITRATE_ON_GP_FINISH=$(PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH)
-DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
-DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
-DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
-DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING)
-DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE)
-DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
-
-ifeq ($(BUILD),debug)
-DEFINES += -DDEBUG
-endif
-
-# Linux has its own mmap cleanup handlers (see mali_kernel_mem_mmu.o)
-DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
-
-# UMP
-ifeq ($(CONFIG_VIDEO_UMP),y)
- DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1
- EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)../ump/include
-else
- DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0
-endif
-
-# Target build file
-obj-$(CONFIG_VIDEO_UMP) += mali.o
-
-# Use our defines when compiling
-# MALI
-INCLUDES = \
- -I$(MALI_INCLUDE_PREFIX)\
- -I$(MALI_INCLUDE_PREFIX)include \
- -I$(MALI_INCLUDE_PREFIX)common \
- -I$(MALI_INCLUDE_PREFIX)linux \
- -I$(MALI_INCLUDE_PREFIX)platform\
- -I$(MALI_INCLUDE_PREFIX)regs
-
-EXTRA_CFLAGS += $(INCLUDES)\
- $(DEFINES)
-
-EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)linux/license/gpl
-EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)common/pmm
-
-# Source files which always are included in a build
-ifeq ($(CONFIG_VIDEO_UMP),y)
-OSKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_wait_queue.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_time.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.o
-else
-OSKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_locks.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_wait_queue.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_math.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_memory.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_misc.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_time.o \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.o
-endif #($(CONFIG_VIDEO_UMP),y)
-
-ifeq ($(CONFIG_CPU_EXYNOS4210),y)
- MALI_PLATFORM_DIR = platform/orion-m400
-else
- MALI_PLATFORM_DIR = platform/pegasus-m400
-endif #($(CONFIG_CPU_EXYNOS4210),y)
-
-MALI_PLATFORM_FILE=$(MALI_PLATFORM_DIR)/mali_platform.o
-UKKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.o \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.o \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_pp.o \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.o
-
-ifeq ($(USING_PROFILING),1)
-UKKFILES += \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.o
-endif
-
-mali-y := \
- common/mali_kernel_core.o \
- linux/mali_kernel_linux.o \
- common/mali_kernel_descriptor_mapping.o \
- common/mali_session.o \
- common/mali_device_pause_resume.o \
- common/mali_kernel_vsync.o \
- linux/mali_ukk_vsync.o \
- linux/mali_kernel_sysfs.o \
- common/mali_mmu.o \
- common/mali_mmu_page_directory.o \
- common/mali_memory.o \
- common/mali_kernel_memory_engine.o \
- common/mali_block_allocator.o \
- common/mali_kernel_mem_os.o \
- common/mali_mem_validation.o \
- common/mali_hw_core.o \
- common/mali_gp.o \
- common/mali_pp.o \
- common/mali_pp_job.o \
- common/mali_gp_job.o \
- common/mali_scheduler.o \
- common/mali_gp_scheduler.o \
- common/mali_pp_scheduler.o \
- common/mali_cluster.o \
- common/mali_group.o \
- common/mali_dlbu.o \
- common/mali_pm.o \
- common/mali_pmu.o \
- common/mali_user_settings_db.o \
- $(OSKOS)/mali_osk_pm.o \
- linux/mali_kernel_pm.o \
- linux/mali_pmu_power_up_down.o \
- $(MALI_PLATFORM_FILE) \
- $(OSKFILES) \
- $(UKKFILES)
-# __malidrv_build_info.c
-
-# Selecting files to compile by parsing the config file
-
-ifeq ($(USING_INTERNAL_PROFILING),1)
-PROFILING_BACKEND_SOURCES = \
- linux/mali_osk_profiling_internal.o \
- timestamp-$(TIMESTAMP)/mali_timestamp.o
-EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)timestamp-$(TIMESTAMP)
-else
-ifeq ($(USING_PROFILING),1)
-PROFILING_BACKEND_SOURCES = \
- linux/mali_osk_profiling_gator.o
-endif
-endif
-
-# Add the profiling sources
-mali-y += $(PROFILING_BACKEND_SOURCES)
-
-# Mali-400 PP in use
-ifeq ($(USING_MALI_PMM_TESTSUITE),1)
-EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)platform/mali_pmu_testing
-endif
-
-ifeq ($(USING_GPU_UTILIZATION),1)
-EXTRA_CFLAGS += -DCONFIG_MALI400_GPU_UTILIZATION=1
-
-mali-y += \
- common/mali_kernel_utilization.o
-endif
-
-ifeq ($(USING_MALI_DVFS_ENABLED),1)
-mali-y += $(MALI_PLATFORM_DIR)/mali_platform_dvfs.o
-endif #($(USING_MALI_DVFS_ENABLED),1)
-
-EXTRA_CFLAGS += -DUSING_MALI400
-
-# Mali Level2 cache in use
-EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE
-mali-y += common/mali_l2_cache.o
-
-# Mali SLP Global lock feature
-ifeq ($(USING_MALI_SLP_GLOBAL_LOCK),1)
-mali-y += \
- linux/mali_slp_global_lock.o
-endif
-
-
-ifeq ($(PANIC_ON_WATCHDOG_TIMEOUT),1)
- EXTRA_CFLAGS += -DUSING_KERNEL_PANIC
-endif
-
-# Get subversion revision number, fall back to 0000 if no svn info is available
-SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
-
-EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV)
-EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\"
-
diff --git a/drivers/media/video/samsung/mali/arch b/drivers/media/video/samsung/mali/arch
deleted file mode 120000
index 58ffbe7..0000000
--- a/drivers/media/video/samsung/mali/arch
+++ /dev/null
@@ -1 +0,0 @@
-arch-release \ No newline at end of file
diff --git a/drivers/media/video/samsung/mali/arch-debug b/drivers/media/video/samsung/mali/arch-debug
deleted file mode 120000
index 0ed0909..0000000
--- a/drivers/media/video/samsung/mali/arch-debug
+++ /dev/null
@@ -1 +0,0 @@
-arch-pegasus-m400/ \ No newline at end of file
diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h
deleted file mode 100644
index 73502a2..0000000
--- a/drivers/media/video/samsung/mali/arch-orion-m400/config.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the EB platform with ZBT memory enabled */
-/*zepplin added 2010.08.17 for orion configuration*/
-#define MALI_BASE_ADDR 0x13000000
-#define GP_ADDR MALI_BASE_ADDR
-#define L2_ADDR MALI_BASE_ADDR+0x1000
-#define PMU_ADDR MALI_BASE_ADDR+0x2000
-#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
-#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000
-#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000
-#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000
-#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000
-#define PP0_ADDR MALI_BASE_ADDR+0x8000
-#define PP1_ADDR MALI_BASE_ADDR+0xA000
-#define PP2_ADDR MALI_BASE_ADDR+0xC000
-#define PP3_ADDR MALI_BASE_ADDR+0xE000
-
-/*for mmu and os memory*/
-#define MEM_BASE_ADDR 0x40000000
-#define MEM_TOTAL_SIZE 0x40000000
-#define MEM_MALI_OS_SIZE 0x40000000
-
-/*for dedicated memory*/
-//#define MEM_MALI_BASE 0x58000000
-//#define MEM_MALI_SIZE 0x08000000
-#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024
-#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = GP_ADDR,
- .irq = IRQ_GP_3D,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = PP0_ADDR,
- .irq = IRQ_PP0_3D,
- .description = "Mali-400 PP 0",
- .mmu_id = 2
- },
- {
- .type = MALI400PP,
- .base = PP1_ADDR,
- .irq = IRQ_PP1_3D,
- .description = "Mali-400 PP 1",
- .mmu_id = 3
- },
- {
- .type = MALI400PP,
- .base = PP2_ADDR,
- .irq = IRQ_PP2_3D,
- .description = "Mali-400 PP 2",
- .mmu_id = 4
- },
- {
- .type = MALI400PP,
- .base = PP3_ADDR,
- .irq = IRQ_PP3_3D,
- .description = "Mali-400 PP 3",
- .mmu_id = 5
- },
-#if USING_MMU
- {
- .type = MMU,
- .base = GP_MMU_ADDR,
- .irq = IRQ_GPMMU_3D,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = PP0_MMU_ADDR,
- .irq = IRQ_PPMMU0_3D,
- .description = "Mali-400 MMU for PP 0",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = PP1_MMU_ADDR,
- .irq = IRQ_PPMMU1_3D,
- .description = "Mali-400 MMU for PP 1",
- .mmu_id = 3
- },
- {
- .type = MMU,
- .base = PP2_MMU_ADDR,
- .irq = IRQ_PPMMU2_3D,
- .description = "Mali-400 MMU for PP 2",
- .mmu_id = 4
- },
- {
- .type = MMU,
- .base = PP3_MMU_ADDR,
- .irq = IRQ_PPMMU3_3D,
- .description = "Mali-400 MMU for PP 3",
- .mmu_id = 5
- },
-#if USING_OS_MEMORY
- {
- .type = OS_MEMORY,
- .description = "System Memory",
- .size = MEM_MALI_OS_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
-#endif
-#if USING_DED /* Dedicated Memory */
- {
- .type = MEMORY,
- .description = "Dedicated Memory",
- .base = MEM_MALI_BASE,
- .size = MEM_MALI_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
- },
-#endif/* if USING_OS_MEMORY*/
- {
- .type = MEM_VALIDATION,
- .description = "Framebuffer Memory",
- .base = MEM_BASE_ADDR,
- .size = MEM_TOTAL_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
- },
-#else /* Not using MMU */
- {
- .type = MEMORY,
- .description = "Dedicated Memory",
- .base = MEM_MALI_BASE,
- .size = MEM_MALI_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
- },
-#endif
- {
- .type = MALI400L2,
- .base = L2_ADDR,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h
deleted file mode 100644
index e579526..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h
+++ /dev/null
@@ -1,85 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the PB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = PMU,
- .description = "Mali-300 PMU",
- .base = 0xC0002000,
- .irq = -1,
- .mmu_id = 0
-
- },
- {
- .type = MALI300GP,
- .description = "Mali-300 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI300PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-300 PP",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = -1,
- .description = "Mali-300 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = -1,
- .description = "Mali-300 MMU for PP",
- .mmu_id = 2
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = -0x50000000,
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xD0000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI300L2,
- .base = 0xC0001000,
- .description = "Mali-300 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h
deleted file mode 100644
index 3893d72..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h
+++ /dev/null
@@ -1,92 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the PB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
-
- {
- .type = PMU,
- .description = "Mali-400 PMU",
- .base = 0xC0002000,
- .irq = -1,
- .mmu_id = 0
- },
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-400 PP",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = -1,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = -1,
- .description = "Mali-400 MMU for PP",
- .mmu_id = 2
- },
- {
- .type = OS_MEMORY,
- .description = "OS Memory",
- .alloc_order = 10, /* Lowest preference for this memory */
- .size = 96 * 1024 * 1024, /* 96 MB */
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = 0,
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0x80000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI400L2,
- .base = 0xC0001000,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h
deleted file mode 100644
index 6d84ab1..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h
+++ /dev/null
@@ -1,85 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the PB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = PMU,
- .description = "Mali-400 PMU",
- .base = 0xC0002000,
- .irq = -1,
- .mmu_id = 0
-
- },
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-400 PP",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = -1,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = -1,
- .description = "Mali-400 MMU for PP",
- .mmu_id = 2
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = -0x50000000,
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xD0000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI400L2,
- .base = 0xC0001000,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h
deleted file mode 100644
index 568ac0a..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h
+++ /dev/null
@@ -1,77 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the PB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-400 PP",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = -1,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = -1,
- .description = "Mali-400 MMU for PP",
- .mmu_id = 2
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = -0x50000000,
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xD0000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI400L2,
- .base = 0xC0001000,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h
deleted file mode 100644
index 98b8059..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h
+++ /dev/null
@@ -1,91 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the PB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-400 PP 0",
- .mmu_id = 2
- },
- {
- .type = MALI400PP,
- .base = 0xc000A000,
- .irq = -1,
- .description = "Mali-400 PP 1",
- .mmu_id = 3
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = -1,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = -1,
- .description = "Mali-400 MMU for PP 0",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0005000,
- .irq = -1,
- .description = "Mali-400 MMU for PP 1",
- .mmu_id = 3
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = -0x50000000,
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xD0000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI400L2,
- .base = 0xC0001000,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h
deleted file mode 100644
index 7b10925..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h
+++ /dev/null
@@ -1,105 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the PB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-400 PP 0",
- .mmu_id = 2
- },
- {
- .type = MALI400PP,
- .base = 0xc000A000,
- .irq = -1,
- .description = "Mali-400 PP 1",
- .mmu_id = 3
- },
- {
- .type = MALI400PP,
- .base = 0xc000C000,
- .irq = -1,
- .description = "Mali-400 PP 2",
- .mmu_id = 4
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = 102,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 0",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0005000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 1",
- .mmu_id = 3
- },
- {
- .type = MMU,
- .base = 0xC0006000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 2",
- .mmu_id = 4
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = -0x50000000,
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xD0000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI400L2,
- .base = 0xC0001000,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h
deleted file mode 100644
index a15a6bd..0000000
--- a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h
+++ /dev/null
@@ -1,119 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the EB platform with ZBT memory enabled */
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = 0xC0000000,
- .irq = -1,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = 0xc0008000,
- .irq = -1,
- .description = "Mali-400 PP 0",
- .mmu_id = 2
- },
- {
- .type = MALI400PP,
- .base = 0xc000A000,
- .irq = -1,
- .description = "Mali-400 PP 1",
- .mmu_id = 3
- },
- {
- .type = MALI400PP,
- .base = 0xc000C000,
- .irq = -1,
- .description = "Mali-400 PP 2",
- .mmu_id = 4
- },
- {
- .type = MALI400PP,
- .base = 0xc000E000,
- .irq = -1,
- .description = "Mali-400 PP 3",
- .mmu_id = 5
- },
- {
- .type = MMU,
- .base = 0xC0003000,
- .irq = 102,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = 0xC0004000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 0",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = 0xC0005000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 1",
- .mmu_id = 3
- },
- {
- .type = MMU,
- .base = 0xC0006000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 2",
- .mmu_id = 4
- },
- {
- .type = MMU,
- .base = 0xC0007000,
- .irq = 102,
- .description = "Mali-400 MMU for PP 3",
- .mmu_id = 5
- },
- {
- .type = MEMORY,
- .description = "Mali SDRAM remapped to baseboard",
- .cpu_usage_adjust = -0x50000000,
- .alloc_order = 0, /* Highest preference for this memory */
- .base = 0xD0000000,
- .size = 0x10000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEMORY,
- .description = "Mali ZBT",
- .alloc_order = 5, /* Medium preference for this memory */
- .base = 0xe1000000,
- .size = 0x01000000,
- .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
- },
- {
- .type = MALI400L2,
- .base = 0xC0001000,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h
deleted file mode 100644
index d5196c3..0000000
--- a/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h
+++ /dev/null
@@ -1,154 +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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the EB platform with ZBT memory enabled */
-/*zepplin added 2010.08.17 for orion configuration*/
-#define MALI_BASE_ADDR 0x13000000
-#define GP_ADDR MALI_BASE_ADDR
-#define L2_ADDR MALI_BASE_ADDR+0x1000
-#define PMU_ADDR MALI_BASE_ADDR+0x2000
-#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
-#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000
-#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000
-#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000
-#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000
-#define PP0_ADDR MALI_BASE_ADDR+0x8000
-#define PP1_ADDR MALI_BASE_ADDR+0xA000
-#define PP2_ADDR MALI_BASE_ADDR+0xC000
-#define PP3_ADDR MALI_BASE_ADDR+0xE000
-
-/*for mmu and os memory*/
-#define MEM_BASE_ADDR 0x40000000
-#define MEM_TOTAL_SIZE 0x40000000
-#define MEM_MALI_OS_SIZE 0x40000000
-
-/*for dedicated memory*/
-//#define MEM_MALI_BASE 0x58000000
-//#define MEM_MALI_SIZE 0x08000000
-#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024
-#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = GP_ADDR,
- .irq = IRQ_GP_3D,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = PP0_ADDR,
- .irq = IRQ_PP0_3D,
- .description = "Mali-400 PP 0",
- .mmu_id = 2
- },
- {
- .type = MALI400PP,
- .base = PP1_ADDR,
- .irq = IRQ_PP1_3D,
- .description = "Mali-400 PP 1",
- .mmu_id = 3
- },
- {
- .type = MALI400PP,
- .base = PP2_ADDR,
- .irq = IRQ_PP2_3D,
- .description = "Mali-400 PP 2",
- .mmu_id = 4
- },
- {
- .type = MALI400PP,
- .base = PP3_ADDR,
- .irq = IRQ_PP3_3D,
- .description = "Mali-400 PP 3",
- .mmu_id = 5
- },
-#if USING_MMU
- {
- .type = MMU,
- .base = GP_MMU_ADDR,
- .irq = IRQ_GPMMU_3D,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = PP0_MMU_ADDR,
- .irq = IRQ_PPMMU0_3D,
- .description = "Mali-400 MMU for PP 0",
- .mmu_id = 2
- },
- {
- .type = MMU,
- .base = PP1_MMU_ADDR,
- .irq = IRQ_PPMMU1_3D,
- .description = "Mali-400 MMU for PP 1",
- .mmu_id = 3
- },
- {
- .type = MMU,
- .base = PP2_MMU_ADDR,
- .irq = IRQ_PPMMU2_3D,
- .description = "Mali-400 MMU for PP 2",
- .mmu_id = 4
- },
- {
- .type = MMU,
- .base = PP3_MMU_ADDR,
- .irq = IRQ_PPMMU3_3D,
- .description = "Mali-400 MMU for PP 3",
- .mmu_id = 5
- },
-#if USING_OS_MEMORY
- {
- .type = OS_MEMORY,
- .description = "System Memory",
- .size = MEM_MALI_OS_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
-#endif
-#if USING_DED /* Dedicated Memory */
- {
- .type = MEMORY,
- .description = "Dedicated Memory",
- .base = MEM_MALI_BASE,
- .size = MEM_MALI_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
- },
-#endif/* if USING_OS_MEMORY*/
- {
- .type = MEM_VALIDATION,
- .description = "memory validation",
- .base = MEM_BASE_ADDR,
- .size = MEM_TOTAL_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
- },
-#else /* Not using MMU */
- {
- .type = MEMORY,
- .description = "Dedicated Memory",
- .base = MEM_MALI_BASE,
- .size = MEM_MALI_SIZE,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
- },
-#endif
- {
- .type = MALI400L2,
- .base = L2_ADDR,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-release b/drivers/media/video/samsung/mali/arch-release
deleted file mode 120000
index 0ed0909..0000000
--- a/drivers/media/video/samsung/mali/arch-release
+++ /dev/null
@@ -1 +0,0 @@
-arch-pegasus-m400/ \ No newline at end of file
diff --git a/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h
deleted file mode 100644
index eb5da50..0000000
--- a/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h
+++ /dev/null
@@ -1,174 +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 __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 [] =
-{
- /* PMU */
- {
- .type = PMU,
- .base = MALI_BASE_ADDRESS + 0x02000,
- .description = "MALI PMU"
- },
- /* 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/drivers/media/video/samsung/mali/common/mali_cluster.c b/drivers/media/video/samsung/mali/common/mali_cluster.c
deleted file mode 100644
index f0fb2b6..0000000
--- a/drivers/media/video/samsung/mali/common/mali_cluster.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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/drivers/media/video/samsung/mali/common/mali_cluster.h b/drivers/media/video/samsung/mali/common/mali_cluster.h
deleted file mode 100644
index 33debdb..0000000
--- a/drivers/media/video/samsung/mali/common/mali_cluster.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h
deleted file mode 100644
index 6be75b0..0000000
--- a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h
+++ /dev/null
@@ -1,31 +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_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/drivers/media/video/samsung/mali/common/mali_gp.c b/drivers/media/video/samsung/mali/common/mali_gp.c
deleted file mode 100644
index 1624e46..0000000
--- a/drivers/media/video/samsung/mali/common/mali_gp.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * 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);
-
-#if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH
- {
- /* Read hits and Read misses*/
- mali_l2_cache_core_set_counter_src0(mali_l2_cache_core_get_glob_l2_core(0), 20);
- mali_l2_cache_core_set_counter_src1(mali_l2_cache_core_get_glob_l2_core(0), 21);
- }
-#endif
-
- /* 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 PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH
- {
- u32 src0, value0, src1, value1, sum, per_thousand, per_thousand_now, diff0, diff1;
- static u32 print_nr=0;
- static u32 prev0=0;
- static u32 prev1=0;
- if ( !(++print_nr&511) )
- {
- mali_l2_cache_core_get_counter_values(mali_l2_cache_core_get_glob_l2_core(0), &src0, &value0, &src1, &value1);
- MALI_DEBUG_ASSERT( src0==20 ); /* Read hits */
- MALI_DEBUG_ASSERT( src1==21 ); /* Read misses */
-
- sum = value0+value1;
- if ( sum > 1000000 )
- {
- per_thousand = value0 / (sum/1000);
- }
- else
- {
- per_thousand = (value0*1000) / (sum);
- }
- diff0 = value0-prev0;
- diff1 = value1-prev1;
-
- sum = diff0 + diff1 ;
- if ( sum > 1000000 )
- {
- per_thousand_now = diff0 / (sum/1000);
- }
- else
- {
- per_thousand_now = (diff0*1000) / (sum);
- }
-
- prev0=value0;
- prev1=value1;
- if (per_thousand_now<=1000)
- {
- MALI_DEBUG_PRINT(2, ("Mali L2: Read hits/misses: %d/%d = %d thousand_parts total, since previous: %d\n", value0, value1, per_thousand, per_thousand_now));
- }
-
- }
- }
-#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/drivers/media/video/samsung/mali/common/mali_gp.h b/drivers/media/video/samsung/mali/common/mali_gp.h
deleted file mode 100644
index 3175b75..0000000
--- a/drivers/media/video/samsung/mali/common/mali_gp.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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/drivers/media/video/samsung/mali/common/mali_gp_job.c b/drivers/media/video/samsung/mali/common/mali_gp_job.c
deleted file mode 100644
index abe1d93..0000000
--- a/drivers/media/video/samsung/mali/common/mali_gp_job.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
deleted file mode 100644
index f06d899..0000000
--- a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#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);
- if (NULL == gp_scheduler_lock)
- {
- return _MALI_OSK_ERR_NOMEM;
- }
-
- gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
- 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;
- }
-
-#if PROFILING_SKIP_PP_AND_GP_JOBS
-#warning GP jobs will not be executed
- mali_gp_scheduler_return_job_to_user(job, MALI_TRUE);
- return _MALI_OSK_ERR_OK;
-#endif
-
- 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/drivers/media/video/samsung/mali/common/mali_group.c b/drivers/media/video/samsung/mali/common/mali_group.c
deleted file mode 100644
index 94bf774..0000000
--- a/drivers/media/video/samsung/mali/common/mali_group.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * 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_GROUP_ACTIVATE_PD_STATUS_FAILED;
- 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/drivers/media/video/samsung/mali/common/mali_group.h b/drivers/media/video/samsung/mali/common/mali_group.h
deleted file mode 100644
index 3533d13..0000000
--- a/drivers/media/video/samsung/mali/common/mali_group.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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/drivers/media/video/samsung/mali/common/mali_kernel_core.c b/drivers/media/video/samsung/mali/common/mali_kernel_core.c
deleted file mode 100644
index 45e86d2..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_core.c
+++ /dev/null
@@ -1,980 +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_session.h"
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_ukk.h"
-#include "mali_kernel_core.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
-
-/** 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_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 u32 first_pp_offset = 0;
-
-#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */
-#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
-
-/* timer related */
-int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
-int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
-
-static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset)
-{
- int i;
- u32 addr = global_gpu_base_address + offset;
-
- for (i = 0; i < num_resources; i++)
- {
- if (type == arch_configuration[i].type && arch_configuration[i].base == addr)
- {
- return &(arch_configuration[i]);
- }
- }
-
- return NULL;
-}
-
-static u32 mali_count_resources(_mali_osk_resource_type_t type)
-{
- int i;
- u32 retval = 0;
-
- for (i = 0; i < num_resources; i++)
- {
- if (type == arch_configuration[i].type)
- {
- retval++;
- }
- }
-
- return retval;
-}
-
-
-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]);
- }
- }
- }
-
- 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;
- }
-
- 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;
-}
-
-static _mali_osk_errcode_t mali_parse_product_info(void)
-{
- _mali_osk_resource_t *first_pp_resource = 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"));
- }
-
- return _MALI_OSK_ERR_FAULT;
-}
-
-static void mali_delete_clusters(void)
-{
- u32 i;
- u32 number_of_clusters = mali_cluster_get_glob_num_clusters();
-
- for (i = 0; i < number_of_clusters; i++)
- {
- mali_cluster_delete(mali_cluster_get_global_cluster(i));
- }
-}
-
-static _mali_osk_errcode_t mali_create_cluster(_mali_osk_resource_t *resource)
-{
- if (NULL != resource)
- {
- struct mali_l2_cache_core *l2_cache;
-
- 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_DEBUG_PRINT(3, ("Found L2 cache %s, starting new cluster\n", resource->description));
-
- /*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;
- }
-
- 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_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;
- }
- }
-
- MALI_DEBUG_PRINT(3, ("Created cluster object\n"));
- return _MALI_OSK_ERR_OK;
-}
-
-static _mali_osk_errcode_t mali_parse_config_cluster(void)
-{
- if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
- {
- /* Create dummy cluster without L2 cache */
- return mali_create_cluster(NULL);
- }
- 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;
- }
-
- 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)
- {
- return ret;
- }
- }
- else
- {
- MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
- return _MALI_OSK_ERR_FAULT;
- }
-
- /* 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(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;
- }
- }
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-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)
-{
- struct mali_mmu_core *mmu;
- struct mali_group *group;
- struct mali_pp_core *pp;
-
- MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
-
- /* Create the MMU object */
- mmu = mali_mmu_create(resource_mmu);
- if (NULL == mmu)
- {
- 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))
- {
- /* 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());
- }
-
- if (NULL != resource_pp)
- {
- /* Create the PP core object inside this group */
- pp = mali_pp_create(resource_pp, group);
-
- if (NULL == pp)
- {
- /* 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);
- }
-
- 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());
-
- resource_gp = mali_find_resource(MALI_GP, 0x02000);
- resource_pp = mali_find_resource(MALI_PP, 0x00000);
- resource_mmu = mali_find_resource(MMU, 0x03000);
-
- 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)
- {
- _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;
- }
- }
- }
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-static _mali_osk_errcode_t mali_parse_config_pmu(void)
-{
- _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)
- {
- if (NULL == mali_pmu_create(resource_pmu, number_of_pp_cores, number_of_l2_caches))
- {
- err = _MALI_OSK_ERR_FAULT;
- }
- }
- return err;
-}
-
-static _mali_osk_errcode_t mali_parse_config_memory(void)
-{
- int i;
- _mali_osk_errcode_t ret;
-
- for(i = 0; i < num_resources; i++)
- {
- switch(arch_configuration[i].type)
- {
- 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;
-
- 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
-
- /* 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:
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_term();
-#endif
- mali_session_terminate();
-session_init_failed:
- return err;
-}
-
-void mali_terminate_subsystems(void)
-{
- struct mali_pmu_core *pmu;
-
- MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
-
- /* shut down subsystems in reverse order from startup */
-
- mali_pm_always_on(MALI_TRUE); /* Mali will be powered off once PM subsystem terminates */
-
-#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);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_term();
-#endif
-
- mali_session_terminate();
-}
-
-_mali_product_id_t mali_kernel_core_get_product_id(void)
-{
- return global_product_id;
-}
-
-void mali_kernel_core_wakeup(void)
-{
- 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);
- }
-}
-
-_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);
-
- /* check compatability */
- if ( args->version == _MALI_UK_API_VERSION )
- {
- args->compatible = 1;
- }
- else
- {
- args->compatible = 0;
- }
-
- args->version = _MALI_UK_API_VERSION; /* report our version */
-
- /* success regardless of being compatible or not */
- MALI_SUCCESS;
-}
-
-_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;
-
- /* check input */
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- 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;
- MALI_SUCCESS;
- }
-
- /* 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 */
- }
-
- /* 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);
-
- /* finished with the notification */
- _mali_osk_notification_delete( notification );
-
- 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;
-
- /* check input */
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- 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"));
- MALI_SUCCESS;
- }
-
- notification = _mali_osk_notification_create(args->type, 0);
- if ( NULL == notification)
- {
- 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 */
-}
-
-_mali_osk_errcode_t _mali_ukk_open(void **context)
-{
- struct mali_session_data *session_data;
-
- /* allocated struct to track this session */
- 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_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);
- }
-
- session_data->page_directory = mali_mmu_pagedir_alloc();
- if (NULL == session_data->page_directory)
- {
- _mali_osk_notification_queue_term(session_data->ioctl_queue);
- _mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- 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);
- }
-
- 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, MALI_CACHE_STANDARD);
- }
-
- if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session_data))
- {
- 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);
- }
-
- *context = (void*)session_data;
-
- /* Add session to the list of all sessions. */
- mali_session_add(session_data);
-
- MALI_DEBUG_PRINT(3, ("Session started\n"));
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t _mali_ukk_close(void **context)
-{
- struct mali_session_data *session;
- MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
- session = (struct mali_session_data *)*context;
-
- MALI_DEBUG_PRINT(3, ("Session ending\n"));
-
- /* Remove session from list of all sessions. */
- mali_session_remove(session);
-
- /* Abort queued and running jobs */
- mali_gp_scheduler_abort_session(session);
- mali_pp_scheduler_abort_session(session);
-
- /* 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);
-
- /* Free remaining memory allocated to this session */
- mali_memory_session_end(session);
-
- /* Free session data structures */
- mali_mmu_pagedir_free(session->page_directory);
- _mali_osk_notification_queue_term(session->ioctl_queue);
- _mali_osk_free(session);
-
- *context = NULL;
-
- MALI_DEBUG_PRINT(2, ("Session has ended\n"));
-
- MALI_SUCCESS;
-}
-
-#if MALI_STATE_TRACKING
-u32 _mali_kernel_core_dump_state(char* buf, u32 size)
-{
- 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/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c
deleted file mode 100644
index a374dbf..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c
+++ /dev/null
@@ -1,218 +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_utilization.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-/* Define how often to calculate and report GPU utilization, in milliseconds */
-#define MALI_GPU_UTILIZATION_TIMEOUT 1000
-
-static _mali_osk_lock_t *time_data_lock;
-
-static _mali_osk_atomic_t num_running_cores;
-
-static u64 period_start_time = 0;
-static u64 work_start_time = 0;
-static u64 accumulated_work_time = 0;
-
-static _mali_osk_timer_t *utilization_timer = NULL;
-static mali_bool timer_running = MALI_FALSE;
-
-
-static void calculate_gpu_utilization(void* arg)
-{
- u64 time_now;
- u64 time_period;
- u32 leading_zeroes;
- u32 shift_val;
- u32 work_normalized;
- u32 period_normalized;
- u32 utilization;
-
- _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
-
- if (accumulated_work_time == 0 && work_start_time == 0)
- {
- /* Don't reschedule timer, this will be started if new work arrives */
- timer_running = MALI_FALSE;
-
- _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
-
- /* No work done for this period, report zero usage */
- mali_gpu_utilization_handler(0);
-
- return;
- }
-
- time_now = _mali_osk_time_get_ns();
- time_period = time_now - period_start_time;
-
- /* If we are currently busy, update working period up to now */
- if (work_start_time != 0)
- {
- accumulated_work_time += (time_now - work_start_time);
- work_start_time = time_now;
- }
-
- /*
- * We have two 64-bit values, a dividend and a divisor.
- * To avoid dependencies to a 64-bit divider, we shift down the two values
- * equally first.
- * We shift the dividend up and possibly the divisor down, making the result X in 256.
- */
-
- /* Shift the 64-bit values down so they fit inside a 32-bit integer */
- leading_zeroes = _mali_osk_clz((u32)(time_period >> 32));
- shift_val = 32 - leading_zeroes;
- work_normalized = (u32)(accumulated_work_time >> shift_val);
- period_normalized = (u32)(time_period >> shift_val);
-
- /*
- * Now, we should report the usage in parts of 256
- * this means we must shift up the dividend or down the divisor by 8
- * (we could do a combination, but we just use one for simplicity,
- * but the end result should be good enough anyway)
- */
- if (period_normalized > 0x00FFFFFF)
- {
- /* The divisor is so big that it is safe to shift it down */
- period_normalized >>= 8;
- }
- else
- {
- /*
- * The divisor is so small that we can shift up the dividend, without loosing any data.
- * (dividend is always smaller than the divisor)
- */
- work_normalized <<= 8;
- }
-
- utilization = work_normalized / period_normalized;
-
- accumulated_work_time = 0;
- period_start_time = time_now; /* starting a new period */
-
- _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
-
- _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT));
-
-
- mali_gpu_utilization_handler(utilization);
-}
-
-_mali_osk_errcode_t mali_utilization_init(void)
-{
- time_data_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |
- _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_UTILIZATION);
-
- if (NULL == time_data_lock)
- {
- return _MALI_OSK_ERR_FAULT;
- }
-
- _mali_osk_atomic_init(&num_running_cores, 0);
-
- utilization_timer = _mali_osk_timer_init();
- if (NULL == utilization_timer)
- {
- _mali_osk_lock_term(time_data_lock);
- return _MALI_OSK_ERR_FAULT;
- }
- _mali_osk_timer_setcallback(utilization_timer, calculate_gpu_utilization, NULL);
-
- return _MALI_OSK_ERR_OK;
-}
-
-void mali_utilization_suspend(void)
-{
- if (NULL != utilization_timer)
- {
- _mali_osk_timer_del(utilization_timer);
- timer_running = MALI_FALSE;
- }
-}
-
-void mali_utilization_term(void)
-{
- if (NULL != utilization_timer)
- {
- _mali_osk_timer_del(utilization_timer);
- timer_running = MALI_FALSE;
- _mali_osk_timer_term(utilization_timer);
- utilization_timer = NULL;
- }
-
- _mali_osk_atomic_term(&num_running_cores);
-
- _mali_osk_lock_term(time_data_lock);
-}
-
-void mali_utilization_core_start(u64 time_now)
-{
- if (_mali_osk_atomic_inc_return(&num_running_cores) == 1)
- {
- /*
- * We went from zero cores working, to one core working,
- * we now consider the entire GPU for being busy
- */
-
- _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
-
- if (time_now < period_start_time)
- {
- /*
- * This might happen if the calculate_gpu_utilization() was able
- * to run between the sampling of time_now and us grabbing the lock above
- */
- time_now = period_start_time;
- }
-
- work_start_time = time_now;
- if (timer_running != MALI_TRUE)
- {
- timer_running = MALI_TRUE;
- period_start_time = work_start_time; /* starting a new period */
-
- _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
-
- _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT));
- }
- else
- {
- _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
- }
- }
-}
-
-void mali_utilization_core_end(u64 time_now)
-{
- if (_mali_osk_atomic_dec_return(&num_running_cores) == 0)
- {
- /*
- * No more cores are working, so accumulate the time we was busy.
- */
- _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
-
- if (time_now < work_start_time)
- {
- /*
- * This might happen if the calculate_gpu_utilization() was able
- * to run between the sampling of time_now and us grabbing the lock above
- */
- time_now = work_start_time;
- }
-
- accumulated_work_time += (time_now - work_start_time);
- work_start_time = 0;
-
- _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
- }
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.h b/drivers/media/video/samsung/mali/common/mali_mmu.h
deleted file mode 100644
index c7274b8..0000000
--- a/drivers/media/video/samsung/mali/common/mali_mmu.h
+++ /dev/null
@@ -1,55 +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_MMU_H__
-#define __MALI_MMU_H__
-
-#include "mali_osk.h"
-#include "mali_mmu_page_directory.h"
-
-/* Forward declaration from mali_group.h */
-struct mali_group;
-
-struct mali_mmu_core;
-
-_mali_osk_errcode_t mali_mmu_initialize(void);
-
-void mali_mmu_terminate(void);
-
-struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource);
-void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group);
-void mali_mmu_delete(struct mali_mmu_core *mmu);
-
-_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu);
-mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu);
-void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu);
-void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address);
-
-mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core* mmu, struct mali_page_directory *pagedir);
-void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu);
-void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* 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)
- */
-mali_bool mali_mmu_enable_stall(struct mali_mmu_core *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
- */
-void mali_mmu_disable_stall(struct mali_mmu_core *mmu);
-
-void mali_mmu_page_fault_done(struct mali_mmu_core *mmu);
-
-
-#endif /* __MALI_MMU_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pm.c b/drivers/media/video/samsung/mali/common/mali_pm.c
deleted file mode 100644
index 933e54e..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pm.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * 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_pm.h"
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_gp_scheduler.h"
-#include "mali_pp_scheduler.h"
-#include "mali_platform.h"
-#include "mali_kernel_utilization.h"
-#include "mali_kernel_core.h"
-#include "mali_group.h"
-
-#define MALI_PM_LIGHT_SLEEP_TIMEOUT 1000
-
-enum mali_pm_scheme
-{
- MALI_PM_SCHEME_DYNAMIC,
- MALI_PM_SCHEME_OS_SUSPENDED,
- MALI_PM_SCHEME_ALWAYS_ON
-};
-
-enum mali_pm_level
-{
- MALI_PM_LEVEL_1_ON,
- MALI_PM_LEVEL_2_STANDBY,
- MALI_PM_LEVEL_3_LIGHT_SLEEP,
- MALI_PM_LEVEL_4_DEEP_SLEEP
-};
-static _mali_osk_lock_t *mali_pm_lock_set_next_state;
-static _mali_osk_lock_t *mali_pm_lock_set_core_states;
-static _mali_osk_lock_t *mali_pm_lock_execute_state_change;
-static _mali_osk_irq_t *wq_irq;
-
-static _mali_osk_timer_t *idle_timer = NULL;
-static mali_bool idle_timer_running = MALI_FALSE;
-static u32 mali_pm_event_number = 0;
-
-static u32 num_active_gps = 0;
-static u32 num_active_pps = 0;
-
-static enum mali_pm_scheme current_scheme = MALI_PM_SCHEME_DYNAMIC;
-static enum mali_pm_level current_level = MALI_PM_LEVEL_1_ON;
-static enum mali_pm_level next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; /* Should be the state we go to when we go out of MALI_PM_SCHEME_ALWAYS_ON during init */
-
-
-
-static _mali_osk_errcode_t mali_pm_upper_half(void *data);
-static void mali_pm_bottom_half(void *data);
-static void mali_pm_powerup(void);
-static void mali_pm_powerdown(mali_power_mode power_mode);
-
-static void timeout_light_sleep(void* arg);
-#if 0
-/* Deep sleep timout not supported */
-static void timeout_deep_sleep(void* arg);
-#endif
-static u32 mali_pm_event_number_get(void);
-static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time );
-
-_mali_osk_errcode_t mali_pm_initialize(void)
-{
- mali_pm_lock_execute_state_change = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE);
-
- if (NULL != mali_pm_lock_execute_state_change )
- {
- mali_pm_lock_set_next_state = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ONELOCK| _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_LAST);
-
- if (NULL != mali_pm_lock_set_next_state)
- {
- mali_pm_lock_set_core_states = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_CORE_STATE);
-
- if (NULL != mali_pm_lock_set_core_states)
- {
- idle_timer = _mali_osk_timer_init();
- if (NULL != idle_timer)
- {
- wq_irq = _mali_osk_irq_init(_MALI_OSK_IRQ_NUMBER_PMM,
- mali_pm_upper_half,
- mali_pm_bottom_half,
- NULL,
- NULL,
- (void *)NULL,
- "Mali PM deferred work");
- if (NULL != wq_irq)
- {
- if (_MALI_OSK_ERR_OK == mali_platform_init())
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- _mali_osk_pm_dev_enable();
- mali_pm_powerup();
-#endif
- return _MALI_OSK_ERR_OK;
- }
-
- _mali_osk_irq_term(wq_irq);
- }
-
- _mali_osk_timer_del(idle_timer);
- _mali_osk_timer_term(idle_timer);
- }
- _mali_osk_lock_term(mali_pm_lock_set_core_states);
- }
- _mali_osk_lock_term(mali_pm_lock_set_next_state);
- }
- _mali_osk_lock_term(mali_pm_lock_execute_state_change);
- }
-
- return _MALI_OSK_ERR_FAULT;
-}
-
-void mali_pm_terminate(void)
-{
- mali_platform_deinit();
- _mali_osk_irq_term(wq_irq);
- _mali_osk_timer_del(idle_timer);
- _mali_osk_timer_term(idle_timer);
- _mali_osk_lock_term(mali_pm_lock_execute_state_change);
- _mali_osk_lock_term(mali_pm_lock_set_next_state);
- _mali_osk_lock_term(mali_pm_lock_set_core_states);
-}
-
-
-inline void mali_pm_lock(void)
-{
- _mali_osk_lock_wait(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW);
-}
-
-inline void mali_pm_unlock(void)
-{
- _mali_osk_lock_signal(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW);
-}
-
-inline void mali_pm_execute_state_change_lock(void)
-{
- _mali_osk_lock_wait(mali_pm_lock_execute_state_change,_MALI_OSK_LOCKMODE_RW);
-}
-
-inline void mali_pm_execute_state_change_unlock(void)
-{
- _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
-}
-
-static void mali_pm_powerup(void)
-{
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT(3, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n"));
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-#else
- /* Aquire our reference */
- _mali_osk_pm_dev_activate();
-#endif
- mali_group_power_on();
-}
-
-static void mali_pm_powerdown(mali_power_mode power_mode)
-{
- if ( (MALI_PM_LEVEL_1_ON == current_level) || (MALI_PM_LEVEL_2_STANDBY == current_level) )
- {
- mali_group_power_off();
- }
-
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
- mali_platform_power_mode_change(power_mode);
-#else
- _mali_osk_pm_dev_idle();
-
- if (MALI_POWER_MODE_DEEP_SLEEP == power_mode)
- {
- mali_platform_power_mode_change(power_mode);
- }
-#endif
-}
-
-mali_bool mali_pm_is_powered_on(void)
-{
- mali_bool is_on = MALI_TRUE;
-
- if( ! (MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme) )
- {
- is_on = MALI_FALSE;
- }
- else if ( ! (MALI_PM_LEVEL_1_ON == current_level || MALI_PM_LEVEL_2_STANDBY == current_level))
- {
- is_on = MALI_FALSE;
- }
- else if ( ! (MALI_PM_LEVEL_1_ON == next_level_dynamic || MALI_PM_LEVEL_2_STANDBY == next_level_dynamic))
- {
- is_on = MALI_FALSE;
- }
-
- return is_on;
-}
-
-MALI_DEBUG_CODE(
-static const char *state_as_string(enum mali_pm_level level)
-{
- switch(level)
- {
- case MALI_PM_LEVEL_1_ON:
- return "MALI_PM_LEVEL_1_ON";
- case MALI_PM_LEVEL_2_STANDBY:
- return "MALI_PM_LEVEL_2_STANDBY";
- case MALI_PM_LEVEL_3_LIGHT_SLEEP:
- return "MALI_PM_LEVEL_3_LIGHT_SLEEP";
- case MALI_PM_LEVEL_4_DEEP_SLEEP:
- return "MALI_PM_LEVEL_4_DEEP_SLEEP";
- default:
- return "UNKNOWN LEVEL";
- }
-});
-
-/* This could be used from another thread (work queue), if we need that */
-static void mali_pm_process_next(void)
-{
- enum mali_pm_level pm_level_to_set;
-
- _mali_osk_lock_wait(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
-
- pm_level_to_set = current_level;
-
- if (MALI_PM_SCHEME_DYNAMIC == current_scheme)
- {
- pm_level_to_set = next_level_dynamic;
-
- MALI_DEBUG_PRINT(4, ("Mali PM: Dynamic scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(pm_level_to_set)));
-
- if (current_level == pm_level_to_set)
- {
- goto end_function; /* early out, no change in power level */
- }
-
- /* Start timers according to new state, so we get STANDBY -> LIGHT_SLEEP -> DEEP_SLEEP */
-
- if (MALI_TRUE == idle_timer_running)
- {
- /* There is an existing timeout, so delete it */
- _mali_osk_timer_del(idle_timer);
- idle_timer_running = MALI_FALSE;
- }
-
- /* Making sure that we turn on through the platform file
- Since it was turned OFF directly through the platform file.
- This might lead to double turn-on, but the plaform file supports that.*/
- if ( current_level == MALI_PM_LEVEL_4_DEEP_SLEEP)
- {
- mali_pm_powerup();
- mali_kernel_core_wakeup();
-
- }
- if (MALI_PM_LEVEL_1_ON == pm_level_to_set)
- {
- if (MALI_PM_LEVEL_2_STANDBY != current_level)
- {
- /* We only need to do anything if we came from one of the sleeping states */
- mali_pm_powerup();
-
- /* Wake up Mali cores since we came from a sleep state */
- mali_kernel_core_wakeup();
- }
- }
- else if (MALI_PM_LEVEL_2_STANDBY == pm_level_to_set)
- {
- /* This is just an internal state, so we don't bother to report it to the platform file */
- idle_timer_running = MALI_TRUE;
- _mali_osk_timer_setcallback(idle_timer, timeout_light_sleep, (void*) mali_pm_event_number_get());
- _mali_osk_timer_add(idle_timer, _mali_osk_time_mstoticks(MALI_PM_LIGHT_SLEEP_TIMEOUT));
- }
- else if (MALI_PM_LEVEL_3_LIGHT_SLEEP == pm_level_to_set)
- {
- mali_pm_powerdown(MALI_POWER_MODE_LIGHT_SLEEP);
- }
- else if (MALI_PM_LEVEL_4_DEEP_SLEEP == pm_level_to_set)
- {
- MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n"));
- mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP);
- }
- }
- else if (MALI_PM_SCHEME_OS_SUSPENDED == current_scheme)
- {
- MALI_DEBUG_PRINT(4, ("Mali PM: OS scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_4_DEEP_SLEEP)));
-
- pm_level_to_set = MALI_PM_LEVEL_4_DEEP_SLEEP;
-
- if (current_level == pm_level_to_set)
- {
- goto end_function; /* early out, no change in power level */
- }
-
- /* Cancel any timers */
- if (MALI_TRUE == idle_timer_running)
- {
- /* There is an existing timeout, so delete it */
- _mali_osk_timer_del(idle_timer);
- idle_timer_running = MALI_FALSE;
- }
-
- MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n"));
- mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP);
- next_level_dynamic = current_level;
- }
- else if (MALI_PM_SCHEME_ALWAYS_ON == current_scheme)
- {
- MALI_DEBUG_PRINT(4, ("Mali PM: Always on scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_1_ON)));
-
- pm_level_to_set = MALI_PM_LEVEL_1_ON;
- if (current_level == pm_level_to_set)
- {
- goto end_function; /* early out, no change in power level */
- }
-
- MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n"));
- mali_pm_powerup();
- if (MALI_PM_LEVEL_2_STANDBY != current_level)
- {
- /* Wake up Mali cores since we came from a sleep state */
- mali_kernel_core_wakeup();
- }
- }
- else
- {
- MALI_PRINT_ERROR(("MALI PM: Illegal scheme"));
- }
-
- current_level = pm_level_to_set;
-
-end_function:
- _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
-
-}
-
-void mali_pm_always_on(mali_bool enable)
-{
- if (MALI_TRUE == enable)
- {
- /* The event is processed in current thread synchronously */
- mali_pm_event(MALI_PM_EVENT_SCHEME_ALWAYS_ON, MALI_FALSE, 0 );
- }
- else
- {
- /* The event is processed in current thread synchronously */
- mali_pm_event(MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, MALI_FALSE, 0 );
- }
-}
-
-static _mali_osk_errcode_t mali_pm_upper_half(void *data)
-{
- /* not used */
- return _MALI_OSK_ERR_OK;
-}
-
-static void mali_pm_bottom_half(void *data)
-{
- mali_pm_process_next();
-}
-
-static u32 mali_pm_event_number_get(void)
-{
- u32 retval;
-
- mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */
- retval = ++mali_pm_event_number;
- if (0==retval ) retval = ++mali_pm_event_number;
- mali_pm_unlock();
-
- return retval;
-}
-
-static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time )
-{
- mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */
- /* Only timer events should set this variable, all other events must set it to zero. */
- if ( 0 != timer_time )
- {
- MALI_DEBUG_ASSERT( (pm_event==MALI_PM_EVENT_TIMER_LIGHT_SLEEP) || (pm_event==MALI_PM_EVENT_TIMER_DEEP_SLEEP) );
- if ( mali_pm_event_number != timer_time )
- {
- /* In this case there have been processed newer events since the timer event was set up.
- If so we always ignore the timing event */
- mali_pm_unlock();
- return;
- }
- }
- else
- {
- /* Delete possible ongoing timers
- if ( (MALI_PM_LEVEL_2_STANDBY==current_level) || (MALI_PM_LEVEL_3_LIGHT_SLEEP==current_level) )
- {
- _mali_osk_timer_del(idle_timer);
- }
- */
- }
- mali_pm_event_number++;
- switch (pm_event)
- {
- case MALI_PM_EVENT_CORES_WORKING:
- next_level_dynamic = MALI_PM_LEVEL_1_ON;
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- break;
- case MALI_PM_EVENT_CORES_IDLE:
- next_level_dynamic = MALI_PM_LEVEL_2_STANDBY;
- /*MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );*/
- break;
- case MALI_PM_EVENT_TIMER_LIGHT_SLEEP:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- next_level_dynamic = MALI_PM_LEVEL_3_LIGHT_SLEEP;
- break;
- case MALI_PM_EVENT_TIMER_DEEP_SLEEP:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP;
- break;
- case MALI_PM_EVENT_OS_SUSPEND:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- current_scheme = MALI_PM_SCHEME_OS_SUSPENDED;
- next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; /* Dynamic scheme will go into level when we are resumed */
- break;
- case MALI_PM_EVENT_OS_RESUME:
- MALI_DEBUG_ASSERT(MALI_PM_SCHEME_OS_SUSPENDED == current_scheme );
- current_scheme = MALI_PM_SCHEME_DYNAMIC;
- break;
- case MALI_PM_EVENT_SCHEME_ALWAYS_ON:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
- current_scheme = MALI_PM_SCHEME_ALWAYS_ON;
- break;
- case MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL:
- MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme );
- current_scheme = MALI_PM_SCHEME_DYNAMIC;
- break;
- default:
- MALI_DEBUG_PRINT_ERROR(("Unknown next state."));
- mali_pm_unlock();
- return;
- }
- mali_pm_unlock();
-
- if (MALI_TRUE == schedule_work)
- {
- _mali_osk_irq_schedulework(wq_irq);
- }
- else
- {
- mali_pm_process_next();
- }
-}
-
-static void timeout_light_sleep(void* arg)
-{
- /* State change only if no newer power events have happend from the time in arg.
- Actual work will be scheduled on worker thread. */
- mali_pm_event(MALI_PM_EVENT_TIMER_LIGHT_SLEEP, MALI_TRUE, (u32) arg);
-}
-
-void mali_pm_core_event(enum mali_core_event core_event)
-{
- mali_bool transition_working = MALI_FALSE;
- mali_bool transition_idle = MALI_FALSE;
-
- _mali_osk_lock_wait(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW);
-
- switch (core_event)
- {
- case MALI_CORE_EVENT_GP_START:
- if (num_active_pps + num_active_gps == 0)
- {
- transition_working = MALI_TRUE;
- }
- num_active_gps++;
- break;
- case MALI_CORE_EVENT_GP_STOP:
- if (num_active_pps + num_active_gps == 1)
- {
- transition_idle = MALI_TRUE;
- }
- num_active_gps--;
- break;
- case MALI_CORE_EVENT_PP_START:
- if (num_active_pps + num_active_gps == 0)
- {
- transition_working = MALI_TRUE;
- }
- num_active_pps++;
- break;
- case MALI_CORE_EVENT_PP_STOP:
- if (num_active_pps + num_active_gps == 1)
- {
- transition_idle = MALI_TRUE;
- }
- num_active_pps--;
- break;
- }
-
- if (transition_working == MALI_TRUE)
- {
-#ifdef CONFIG_MALI400_GPU_UTILIZATION
- mali_utilization_core_start(_mali_osk_time_get_ns());
-#endif
- mali_pm_event(MALI_PM_EVENT_CORES_WORKING, MALI_FALSE, 0); /* process event in same thread */
- }
- else if (transition_idle == MALI_TRUE)
- {
-#ifdef CONFIG_MALI400_GPU_UTILIZATION
- mali_utilization_core_end(_mali_osk_time_get_ns());
-#endif
- mali_pm_event(MALI_PM_EVENT_CORES_IDLE, MALI_FALSE, 0); /* process event in same thread */
- }
-
- _mali_osk_lock_signal(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW);
-}
-
-void mali_pm_os_suspend(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS suspending...\n"));
-
- mali_gp_scheduler_suspend();
- mali_pp_scheduler_suspend();
- mali_pm_event(MALI_PM_EVENT_OS_SUSPEND, MALI_FALSE, 0); /* process event in same thread */
-
- MALI_DEBUG_PRINT(2, ("Mali PM: OS suspend completed\n"));
-}
-
-void mali_pm_os_resume(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS resuming...\n"));
-
- mali_pm_event(MALI_PM_EVENT_OS_RESUME, MALI_FALSE, 0); /* process event in same thread */
- mali_gp_scheduler_resume();
- mali_pp_scheduler_resume();
-
- MALI_DEBUG_PRINT(2, ("Mali PM: OS resume completed\n"));
-}
-
-void mali_pm_runtime_suspend(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime suspended\n"));
- mali_platform_power_mode_change(MALI_POWER_MODE_LIGHT_SLEEP);
-}
-
-void mali_pm_runtime_resume(void)
-{
- MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime resumed\n"));
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.c b/drivers/media/video/samsung/mali/common/mali_pmu.c
deleted file mode 100644
index 348b5dc..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pmu.c
+++ /dev/null
@@ -1,199 +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.
- */
-
-/**
- * @file mali_pmu.c
- * Mali driver functions for Mali 400 PMU hardware
- */
-#include "mali_hw_core.h"
-#include "mali_pmu.h"
-#include "mali_pp.h"
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-
-static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches);
-
-/** @brief MALI inbuilt PMU hardware info and PMU hardware has knowledge of cores power mask
- */
-struct mali_pmu_core
-{
- struct mali_hw_core hw_core;
- u32 mali_registered_cores_power_mask;
-};
-
-static struct mali_pmu_core *mali_global_pmu_core = NULL;
-
-/** @brief Register layout for hardware PMU
- */
-typedef enum {
- PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */
- PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */
- PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */
- PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */
- PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x10, /*< Size of register space */
-} pmu_reg_addr_mgmt_addr;
-
-struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches)
-{
- struct mali_pmu_core* pmu;
-
- MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core);
- MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n"));
-
- pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core));
- if (NULL != pmu)
- {
- pmu->mali_registered_cores_power_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches);
- if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE))
- {
- if (_MALI_OSK_ERR_OK == mali_pmu_reset(pmu))
- {
- mali_global_pmu_core = pmu;
- return pmu;
- }
- mali_hw_core_delete(&pmu->hw_core);
- }
- _mali_osk_free(pmu);
- }
-
- return NULL;
-}
-
-void mali_pmu_delete(struct mali_pmu_core *pmu)
-{
- MALI_DEBUG_ASSERT_POINTER(pmu);
-
- mali_hw_core_delete(&pmu->hw_core);
- _mali_osk_free(pmu);
- pmu = NULL;
-}
-
-_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu)
-{
- /* Don't use interrupts - just poll status */
- mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu)
-{
- u32 stat;
- u32 timeout;
-
- MALI_DEBUG_ASSERT_POINTER(pmu);
- MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 );
- MALI_DEBUG_PRINT( 4, ("Mali PMU: power down (0x%08X)\n", pmu->mali_registered_cores_power_mask) );
-
- mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->mali_registered_cores_power_mask);
-
- /* Wait for cores to be powered down (100 x 100us = 100ms) */
- timeout = 100;
- do
- {
- /* Get status of sleeping cores */
- stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
- stat &= pmu->mali_registered_cores_power_mask;
- if( stat == pmu->mali_registered_cores_power_mask ) break; /* All cores we wanted are now asleep */
- _mali_osk_time_ubusydelay(100);
- timeout--;
- } while( timeout > 0 );
-
- if( timeout == 0 )
- {
- return _MALI_OSK_ERR_TIMEOUT;
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu)
-{
- u32 stat;
- u32 timeout;
-
- MALI_DEBUG_ASSERT_POINTER(pmu);
- MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); /* Shouldn't be zero */
- MALI_DEBUG_PRINT( 4, ("Mali PMU: power up (0x%08X)\n", pmu->mali_registered_cores_power_mask) );
-
- mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, pmu->mali_registered_cores_power_mask);
-
- /* Wait for cores to be powered up (100 x 100us = 100ms) */
- timeout = 100;
- do
- {
- /* Get status of sleeping cores */
- stat = mali_hw_core_register_read(&pmu->hw_core,PMU_REG_ADDR_MGMT_STATUS);
- stat &= pmu->mali_registered_cores_power_mask;
- if( stat == 0 ) break; /* All cores we wanted are now awake */
- _mali_osk_time_ubusydelay(100);
- timeout--;
- } while( timeout > 0 );
-
- if( timeout == 0 )
- {
- return _MALI_OSK_ERR_TIMEOUT;
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-struct mali_pmu_core *mali_pmu_get_global_pmu_core(void)
-{
- return mali_global_pmu_core;
-}
-
-static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches)
-{
- u32 mask = 0;
-
- if (number_of_l2_caches == 1)
- {
- /* Mali-300 or Mali-400 */
- u32 i;
-
- /* GP */
- mask = 0x01;
-
- /* L2 cache */
- mask |= 0x01<<1;
-
- /* Set bit for each PP core */
- for (i = 0; i < number_of_pp_cores; i++)
- {
- mask |= 0x01<<(i+2);
- }
- }
- else if (number_of_l2_caches > 1)
- {
- /* Mali-450 */
-
- /* GP (including its L2 cache) */
- mask = 0x01;
-
- /* There is always at least one PP (including its L2 cache) */
- mask |= 0x01<<1;
-
- /* Additional PP cores in same L2 cache */
- if (number_of_pp_cores >= 2)
- {
- mask |= 0x01<<2;
- }
-
- /* Additional PP cores in a third L2 cache */
- if (number_of_pp_cores >= 5)
- {
- mask |= 0x01<<3;
- }
- }
-
- MALI_DEBUG_PRINT(4, ("Mali PMU: Power mask is 0x%08X (%u + %u)\n", mask, number_of_pp_cores, number_of_l2_caches));
-
- return mask;
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_pp.c b/drivers/media/video/samsung/mali/common/mali_pp.c
deleted file mode 100644
index 5549f82..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pp.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * 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_pp.h"
-#include "mali_hw_core.h"
-#include "mali_group.h"
-#include "mali_osk.h"
-#include "regs/mali_200_regs.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_core.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_osk_profiling.h"
-#endif
-
-/* See mali_gp.c file for description on how to handle the interrupt mask.
- * This is how to do it on PP: mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
- */
-
-#define MALI_MAX_NUMBER_OF_PP_CORES 8
-
-/**
- * Definition of the PP core struct
- * Used to track a PP core in the system.
- */
-struct mali_pp_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 */
- u32 core_id; /**< Unique core ID */
- struct mali_pp_job *running_job; /**< Current running (super) job */
- u32 running_sub_job; /**< Current running sub 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 pp_core_timed_out == MALI_TRUE */
- mali_bool core_timed_out; /**< if MALI_TRUE, this pp core has timed out; if MALI_FALSE, no timeout on this pp 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_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES];
-static u32 mali_global_num_pp_cores = 0;
-
-/* Interrupt handlers */
-static _mali_osk_errcode_t mali_pp_upper_half(void *data);
-static void mali_pp_bottom_half(void *data);
-static void mali_pp_irq_probe_trigger(void *data);
-static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
-static void mali_pp_post_process_job(struct mali_pp_core *core);
-static void mali_pp_timeout(void *data);
-
-struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group)
-{
- struct mali_pp_core* core = NULL;
-
- MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description));
- MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base));
-
- if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES)
- {
- MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n"));
- return NULL;
- }
-
- core = _mali_osk_malloc(sizeof(struct mali_pp_core));
- if (NULL != core)
- {
- core->group = group;
- core->core_id = mali_global_num_pp_cores;
- 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, MALI200_REG_SIZEOF_REGISTER_BANK))
- {
- _mali_osk_errcode_t ret;
-
- mali_group_lock(group);
- ret = mali_pp_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_pp_upper_half,
- mali_pp_bottom_half,
- mali_pp_irq_probe_trigger,
- mali_pp_irq_probe_ack,
- core,
- "mali_pp_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_pp_timeout, (void *)core);
-
- mali_global_pp_cores[mali_global_num_pp_cores] = core;
- mali_global_num_pp_cores++;
-
- return core;
- }
- else
- {
- MALI_PRINT_ERROR(("Failed to setup timeout timer for PP core %s\n", core->hw_core.description));
- /* Release IRQ handlers */
- _mali_osk_irq_term(core->irq);
- }
- }
- else
- {
- MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description));
- }
- }
- mali_hw_core_delete(&core->hw_core);
- }
-
- _mali_osk_free(core);
- }
- else
- {
- MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n"));
- }
-
- return NULL;
-}
-
-void mali_pp_delete(struct mali_pp_core *core)
-{
- u32 i;
-
- 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);
-
- /* Remove core from global list */
- for (i = 0; i < mali_global_num_pp_cores; i++)
- {
- if (mali_global_pp_cores[i] == core)
- {
- mali_global_pp_cores[i] = NULL;
- mali_global_num_pp_cores--;
- break;
- }
- }
-
- _mali_osk_free(core);
-}
-
-void mali_pp_stop_bus(struct mali_pp_core *core)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
- /* Will only send the stop bus command, and not wait for it to complete */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
-}
-
-_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
-{
- int i;
- const int request_loop_count = 20;
-
- MALI_DEBUG_ASSERT_POINTER(core);
- MALI_ASSERT_GROUP_LOCKED(core->group);
-
- /* Send the stop bus command. */
- mali_pp_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, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
- break;
- _mali_osk_time_ubusydelay(10);
- }
-
- if (request_loop_count == i)
- {
- MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
- return _MALI_OSK_ERR_FAULT;
- }
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
-{
- /* Bus must be stopped before calling this function */
- const int reset_finished_loop_count = 15;
- const u32 reset_invalid_value = 0xC0FFE000;
- const u32 reset_check_value = 0xC01A0000;
- int i;
-
- MALI_DEBUG_ASSERT_POINTER(core);
- MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
- MALI_ASSERT_GROUP_LOCKED(core->group);
-
- mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
-
- /* Set register to a bogus value. The register will be used to detect when reset is complete */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
-
- /* Force core to reset */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
-
- /* Wait for reset to be complete */
- for (i = 0; i < reset_finished_loop_count; i++)
- {
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
- if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW))
- {
- break;
- }
- _mali_osk_time_ubusydelay(10);
- }
-
- if (i == reset_finished_loop_count)
- {
- MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
- }
-
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */
- /* Re-enable interrupts */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
-
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
-{
- int i;
- const int request_loop_count = 20;
-
- MALI_DEBUG_ASSERT_POINTER(core);
- MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
- MALI_ASSERT_GROUP_LOCKED(core->group);
-
- mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
-
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
-
-#if defined(USING_MALI200)
-
- /* On Mali-200, stop the bus, then do a hard reset of the core */
-
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
- {
- break;
- }
- _mali_osk_time_ubusydelay(10);
- }
-
- if (request_loop_count == i)
- {
- MALI_PRINT_ERROR(("Mali PP: 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_pp_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, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
- {
- break;
- }
- _mali_osk_time_ubusydelay(10);
- }
-
- if (request_loop_count == i)
- {
- MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %s, Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
- return _MALI_OSK_ERR_FAULT;
- }
-#else
-#error "no supported mali core defined"
-#endif
-
- /* Re-enable interrupts */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
-
- return _MALI_OSK_ERR_OK;
-}
-
-void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job)
-{
- u32 *frame_registers = mali_pp_job_get_frame_registers(job);
- u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
- u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
- u32 *wb2_registers = mali_pp_job_get_wb2_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);
-
- mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, frame_registers, MALI200_NUM_REGS_FRAME);
- if (0 != sub_job)
- {
- /*
- * There are two frame registers which are different for each sub job.
- * For the first sub job, these are correctly represented in the frame register array,
- * but we need to patch these for all other sub jobs
- */
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job));
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job));
- }
-
- if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
- {
- mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, MALI200_NUM_REGS_WBx);
- }
-
- if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
- {
- mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, MALI200_NUM_REGS_WBx);
- }
-
- if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
- {
- mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, MALI200_NUM_REGS_WBx);
- }
-
- /* 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_src1_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, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
- }
- if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
- {
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
- }
- }
- else
- {
- /* Use HW counters from job object, if any */
- u32 perf_counter_flag = mali_pp_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_pp_job_get_perf_counter_src0(job);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
- }
-
- if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
- {
- core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
- }
- }
- }
-
- MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));
-
- /* Adding barrier to make sure all rester writes are finished */
- _mali_osk_write_mem_barrier();
-
- /* This is the command that starts the core. */
- mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
-
- /* Adding barrier to make sure previous rester writes is finished */
- _mali_osk_write_mem_barrier();
-
- /* Setup the timeout timer value and save the job id for the job running on the pp core */
- _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
- core->timeout_job_id = mali_pp_job_get_id(job);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job->frame_builder_id, job->flush_id, 0, 0, 0);
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), job->pid, job->tid, 0, 0, 0);
-#endif
-
- core->running_job = job;
- core->running_sub_job = sub_job;
-}
-
-u32 mali_pp_core_get_version(struct mali_pp_core *core)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
- return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION);
-}
-
-u32 mali_pp_core_get_id(struct mali_pp_core *core)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
- return core->core_id;
-}
-
-mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
-
- core->counter_src0 = counter;
- return MALI_TRUE;
-}
-
-mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
-
- core->counter_src1 = counter;
- return MALI_TRUE;
-}
-
-u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
- return core->counter_src0;
-}
-
-u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core)
-{
- MALI_DEBUG_ASSERT_POINTER(core);
- return core->counter_src1;
-}
-
-struct mali_pp_core* mali_pp_get_global_pp_core(u32 index)
-{
- if (MALI_MAX_NUMBER_OF_PP_CORES > index)
- {
- return mali_global_pp_cores[index];
- }
-
- return NULL;
-}
-
-u32 mali_pp_get_glob_num_pp_cores(void)
-{
- return mali_global_num_pp_cores;
-}
-
-u32 mali_pp_get_max_num_pp_cores(void)
-{
- return MALI_MAX_NUMBER_OF_PP_CORES;
-}
-
-/* ------------- interrupt handling below ------------------ */
-static _mali_osk_errcode_t mali_pp_upper_half(void *data)
-{
- struct mali_pp_core *core = (struct mali_pp_core *)data;
- u32 irq_readout;
-
- irq_readout = mali_hw_core_register_read(&core->hw_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_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id)|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_pp_bottom_half(void *data)
-{
- struct mali_pp_core *core = (struct mali_pp_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(), 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, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description));
-
- if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME)
- {
- mali_pp_post_process_job(core);
- MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
- mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED); /* Will release group lock */
- return;
- }
-
- /*
- * Now lets look at the possible error cases (IRQ indicating error or timeout)
- * END_OF_FRAME and HANG interrupts are not considered error.
- */
- irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG);
- if (0 != irq_errors)
- {
- mali_pp_post_process_job(core);
- MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n",
- irq_readout, core->hw_core.description));
- mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED); /* Will release group lock */
- return;
- }
- else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
- {
- if (core->timeout_job_id == mali_pp_job_get_id(core->running_job))
- {
- mali_pp_post_process_job(core);
- MALI_DEBUG_PRINT(2, ("Mali PP: Job %d timed out on core %s\n",
- mali_pp_job_get_id(core->running_job), core->hw_core.description));
- mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_TIMED_OUT); /* Will release group lock */
- }
- else
- {
- mali_group_unlock(core->group);
- }
- core->core_timed_out = MALI_FALSE;
- return;
- }
- else if (irq_readout & MALI200_REG_VAL_IRQ_HANG)
- {
- /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
- }
-
- /*
- * The only way to get here is if we got a HANG interrupt, which we ignore.
- * Re-enable interrupts and let core continue to run
- */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_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(), 0, 0, 0);
-#endif
-#endif
-}
-
-static void mali_pp_irq_probe_trigger(void *data)
-{
- struct mali_pp_core *core = (struct mali_pp_core *)data;
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
-}
-
-static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data)
-{
- struct mali_pp_core *core = (struct mali_pp_core *)data;
- u32 irq_readout;
-
- irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
- if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout)
- {
- mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_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_pp_post_process_job(struct mali_pp_core *core)
-{
- MALI_ASSERT_GROUP_LOCKED(core->group);
-
- if (NULL != core->running_job)
- {
- u32 val0 = 0;
- u32 val1 = 0;
-#if MALI_TIMELINE_PROFILING_ENABLED
- int counter_index = COUNTER_FP0_C0 + (2 * core->core_id);
-#endif
-
- if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
- {
- val0 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- if (mali_pp_job_get_perf_counter_flag(core->running_job) &&
- _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_pp_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_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, val0);
- }
- else
- {
- /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */
- mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE);
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_report_hw_counter(counter_index, val0);
-#endif
- }
-
- if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
- {
- val1 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
- if (mali_pp_job_get_perf_counter_flag(core->running_job) &&
- _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_pp_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_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, val1);
- }
- else
- {
- /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */
- mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE);
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
-#endif
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id),
- val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0);
-#endif
-
- /* We are no longer running a job... */
- core->running_job = NULL;
- _mali_osk_timer_del(core->timeout_timer);
- }
-}
-
-/* callback function for pp core timeout */
-static void mali_pp_timeout(void *data)
-{
- struct mali_pp_core * core = ((struct mali_pp_core *)data);
-
- MALI_DEBUG_PRINT(3, ("Mali PP: TIMEOUT callback \n"));
- core->core_timed_out = MALI_TRUE;
- _mali_osk_irq_schedulework(core->irq);
-}
-
-#if 0
-static void mali_pp_print_registers(struct mali_pp_core *core)
-{
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC)));
- MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
-}
-#endif
-
-#if 0
-void mali_pp_print_state(struct mali_pp_core *core)
-{
- MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) ));
-}
-#endif
-
-#if MALI_STATE_TRACKING
-u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size)
-{
- int n = 0;
-
- n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description);
-
- return n;
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_pp.h b/drivers/media/video/samsung/mali/common/mali_pp.h
deleted file mode 100644
index 9b425a0..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pp.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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_PP_H__
-#define __MALI_PP_H__
-
-#include "mali_osk.h"
-#include "mali_pp_job.h"
-
-struct mali_pp_core;
-struct mali_group;
-
-_mali_osk_errcode_t mali_pp_initialize(void);
-void mali_pp_terminate(void);
-
-struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t * resource, struct mali_group *group);
-void mali_pp_delete(struct mali_pp_core *core);
-
-void mali_pp_stop_bus(struct mali_pp_core *core);
-_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core);
-_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core);
-_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core);
-
-void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job);
-
-u32 mali_pp_core_get_version(struct mali_pp_core *core);
-
-u32 mali_pp_core_get_id(struct mali_pp_core *core);
-
-mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter);
-mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter);
-u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core);
-u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core);
-struct mali_pp_core* mali_pp_get_global_pp_core(u32 index);
-u32 mali_pp_get_glob_num_pp_cores(void);
-u32 mali_pp_get_max_num_pp_cores(void);
-/* Debug */
-u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size);
-
-#endif /* __MALI_PP_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.c b/drivers/media/video/samsung/mali/common/mali_pp_job.c
deleted file mode 100644
index 47b8a0a..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pp_job.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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_pp_job.h"
-#include "mali_osk.h"
-#include "mali_osk_list.h"
-#include "mali_kernel_common.h"
-#include "mali_uk_types.h"
-
-struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id)
-{
- struct mali_pp_job *job;
-
- if (args->num_cores > _MALI_PP_MAX_SUB_JOBS)
- {
- MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
- return NULL;
- }
-
- job = _mali_osk_malloc(sizeof(struct mali_pp_job));
- if (NULL != job)
- {
- u32 i;
- _mali_osk_list_init(&job->list);
- job->session = session;
- job->id = id;
- job->user_id = args->user_job_ptr;
- job->barrier = args->flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE;
- job->active_barrier = job->barrier;
- job->no_notification = args->flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE;
- _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers));
- _mali_osk_memcpy(job->frame_registers_addr_frame, args->frame_registers_addr_frame, sizeof(job->frame_registers_addr_frame));
- _mali_osk_memcpy(job->frame_registers_addr_stack, args->frame_registers_addr_stack, sizeof(job->frame_registers_addr_stack));
-
- /* Only copy write back registers for the units that are enabled */
- job->wb0_registers[0] = 0;
- job->wb1_registers[0] = 0;
- job->wb2_registers[0] = 0;
- if (args->wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
- {
- _mali_osk_memcpy(job->wb0_registers, args->wb0_registers, sizeof(job->wb0_registers));
- }
- if (args->wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
- {
- _mali_osk_memcpy(job->wb1_registers, args->wb1_registers, sizeof(job->wb1_registers));
- }
- if (args->wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
- {
- _mali_osk_memcpy(job->wb2_registers, args->wb2_registers, sizeof(job->wb2_registers));
- }
-
- job->perf_counter_flag = args->perf_counter_flag;
- job->perf_counter_src0 = args->perf_counter_src0;
- job->perf_counter_src1 = args->perf_counter_src1;
- for (i = 0; i < args->num_cores; i++)
- {
- job->perf_counter_value0[i] = 0;
- job->perf_counter_value1[i] = 0;
- }
- job->sub_job_count = args->num_cores;
- job->sub_jobs_started = 0;
- job->sub_jobs_completed = 0;
- job->sub_job_errors = 0;
-
- job->pid = _mali_osk_get_pid();
- job->tid = _mali_osk_get_tid();
- job->frame_builder_id = args->frame_builder_id;
- job->flush_id = args->flush_id;
-
- return job;
- }
-
- return NULL;
-}
-
-void mali_pp_job_delete(struct mali_pp_job *job)
-{
- _mali_osk_free(job);
-}
-
-_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
-{
- if ((0 == job->frame_registers[0]) || (0 == job->frame_registers[1]))
- {
- return _MALI_OSK_ERR_FAULT;
- }
- return _MALI_OSK_ERR_OK;
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
deleted file mode 100644
index a944055..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "mali_pp_scheduler.h"
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_osk_list.h"
-#include "mali_scheduler.h"
-#include "mali_pp.h"
-#include "mali_pp_job.h"
-#include "mali_group.h"
-#include "mali_cluster.h"
-
-/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
-#define MALI_MAX_NUMBER_OF_PP_GROUPS 8
-
-static mali_bool mali_pp_scheduler_is_suspended(void);
-
-enum mali_pp_slot_state
-{
- MALI_PP_SLOT_STATE_IDLE,
- MALI_PP_SLOT_STATE_WORKING,
-};
-
-/* A render slot is an entity which jobs can be scheduled onto */
-struct mali_pp_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_pp_slot_state state;
- struct mali_session_data *session;
-};
-
-static u32 pp_version = 0;
-static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */
-static struct mali_pp_slot slots[MALI_MAX_NUMBER_OF_PP_GROUPS];
-static u32 num_slots = 0;
-static u32 num_slots_idle = 0;
-
-/* Variables to allow safe pausing of the scheduler */
-static _mali_osk_wait_queue_t *pp_scheduler_working_wait_queue = NULL;
-static u32 pause_count = 0;
-
-static _mali_osk_lock_t *pp_scheduler_lock = NULL;
-/* Contains tid of thread that locked the scheduler or 0, if not locked */
-MALI_DEBUG_CODE(static u32 pp_scheduler_lock_owner = 0);
-
-_mali_osk_errcode_t mali_pp_scheduler_initialize(void)
-{
- u32 i;
-
- _MALI_OSK_INIT_LIST_HEAD(&job_queue);
-
- pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
- if (NULL == pp_scheduler_lock)
- {
- return _MALI_OSK_ERR_NOMEM;
- }
-
- pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
- if (NULL == pp_scheduler_working_wait_queue)
- {
- _mali_osk_lock_term(pp_scheduler_lock);
- return _MALI_OSK_ERR_NOMEM;
- }
-
- /* Find all the available PP 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_pp_core *pp_core = mali_group_get_pp_core(group);
- if (NULL != pp_core)
- {
- if (0 == pp_version)
- {
- /* Retrieve PP version from first avaiable PP core */
- pp_version = mali_pp_core_get_version(pp_core);
- }
- slots[num_slots].group = group;
- slots[num_slots].state = MALI_PP_SLOT_STATE_IDLE;
- slots[num_slots].session = NULL;
- num_slots++;
- num_slots_idle++;
- }
- group_id++;
- group = mali_cluster_get_group(curr_cluster, group_id);
- }
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-void mali_pp_scheduler_terminate(void)
-{
- _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
- _mali_osk_lock_term(pp_scheduler_lock);
-}
-
-MALI_STATIC_INLINE void mali_pp_scheduler_lock(void)
-{
- if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
- {
- /* Non-interruptable lock failed: this should never happen. */
- MALI_DEBUG_ASSERT(0);
- }
- MALI_DEBUG_PRINT(5, ("Mali PP scheduler: PP scheduler lock taken\n"));
- MALI_DEBUG_ASSERT(0 == pp_scheduler_lock_owner);
- MALI_DEBUG_CODE(pp_scheduler_lock_owner = _mali_osk_get_tid());
-}
-
-MALI_STATIC_INLINE void mali_pp_scheduler_unlock(void)
-{
- MALI_DEBUG_PRINT(5, ("Mali PP scheduler: Releasing PP scheduler lock\n"));
- MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
- MALI_DEBUG_CODE(pp_scheduler_lock_owner = 0);
- _mali_osk_lock_signal(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
-}
-
-#ifdef DEBUG
-MALI_STATIC_INLINE void mali_pp_scheduler_assert_locked(void)
-{
- MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
-}
-#define MALI_ASSERT_PP_SCHEDULER_LOCKED() mali_pp_scheduler_assert_locked()
-#else
-#define MALI_ASSERT_PP_SCHEDULER_LOCKED()
-#endif
-
-static mali_bool mali_pp_scheduler_session_has_running_jobs(struct mali_session_data *session)
-{
- u32 i;
-
- MALI_ASSERT_PP_SCHEDULER_LOCKED();
-
- if (num_slots_idle == num_slots)
- {
- return MALI_FALSE;
- }
-
- for (i = 0; i < num_slots; i++)
- {
- if (MALI_PP_SLOT_STATE_WORKING == slots[i].state)
- {
- if (slots[i].session == session)
- {
- return MALI_TRUE;
- }
- }
- }
-
- return MALI_FALSE;
-}
-
-static void mali_pp_scheduler_schedule(void)
-{
- u32 i;
- struct mali_pp_job *job;
-#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
- struct mali_session_data * session;
-#endif
-
- MALI_ASSERT_PP_SCHEDULER_LOCKED();
-
- if (0 < pause_count || 0 == num_slots_idle || _mali_osk_list_empty(&job_queue))
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
- pause_count, num_slots_idle));
- return; /* Nothing to do, so early out */
- }
-
-
-#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP
- if ( num_slots_idle < num_slots )
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started, since only %d/%d cores are available\n", num_slots_idle,num_slots));
- return;
- }
-#endif
-
-#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
- /* Finding initial session for the PP cores */
- job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
- session = job->session;
- if ( num_slots != num_slots_idle )
- {
- for (i = 0; (i < num_slots) ; i++)
- {
- if ( slots[i].state == MALI_PP_SLOT_STATE_IDLE )
- {
- continue;
- }
- session = mali_group_get_session(slots[i].group);
- break;
- }
- }
-#endif
-
- for (i = 0; (i < num_slots) && (0 < num_slots_idle); i++)
- {
- u32 sub_job;
-
- if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */
- {
- break; /* No more jobs to schedule, so early out */
- }
-
- if (MALI_PP_SLOT_STATE_IDLE != slots[i].state)
- {
- continue;
- }
-
- job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
- MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job)); /* All jobs on the job_queue should have unstarted sub jobs */
-
- if (MALI_TRUE == mali_pp_job_has_active_barrier(job))
- {
- if (MALI_TRUE == mali_pp_scheduler_session_has_running_jobs(mali_pp_job_get_session(job)))
- {
- /* There is already a running job from this session, so we need to enforce the barrier */
- return;
- }
- else
- {
- /* Barrier is now enforced, update job object so we don't delay execution of sub-jobs */
- mali_pp_job_barrier_enforced(job);
- }
- }
-
- #if MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED
- if ( (0==job->sub_jobs_started) && (num_slots_idle < num_slots) && (job->sub_job_count > num_slots_idle))
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job with %d subjobs not started, since only %d/%d cores are available\n", job->sub_job_count, num_slots_idle,num_slots));
- return;
- }
- #endif
-
- #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
- if ( job->session != session )
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started since existing job is from another application\n"));
- return;
- }
- #endif
-
- sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
-
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Starting job %u (0x%08X) part %u/%u\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job)));
- if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slots[i].group, job, sub_job))
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job)));
-
- /* Mark this sub job as started */
- mali_pp_job_mark_sub_job_started(job, sub_job);
-
- /* Mark slot as busy */
- slots[i].state = MALI_PP_SLOT_STATE_WORKING;
- slots[i].session = mali_pp_job_get_session(job);
- num_slots_idle--;
-
- if (!mali_pp_job_has_unstarted_sub_jobs(job))
- {
- /*
- * All sub jobs have now started for this job, remove this job from the job queue.
- * The job will now only be referred to by the slots which are running it.
- * The last slot to complete will make sure it is returned to user space.
- */
- _mali_osk_list_del(&job->list);
-#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP
- MALI_DEBUG_PRINT(6, ("Mali PP scheduler: Skip scheduling more jobs when MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP is set.\n"));
- return;
-#endif
- }
- }
- else
- {
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n"));
- return;
- }
- }
-}
-
-static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job)
-{
- if (MALI_FALSE == mali_pp_job_use_no_notification(job))
- {
- _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s));
- if (NULL != notobj)
- {
- u32 i;
- u32 sub_jobs = mali_pp_job_get_sub_job_count(job);
- mali_bool success = mali_pp_job_was_success(job);
-
- _mali_uk_pp_job_finished_s *jobres = notobj->result_buffer;
- _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
- jobres->user_job_ptr = mali_pp_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;
- }
-
- for (i = 0; i < sub_jobs; i++)
- {
- jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i);
- jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i);
- }
-
- mali_session_send_notification(mali_pp_job_get_session(job), notobj);
- }
- else
- {
- MALI_PRINT_ERROR(("Mali PP scheduler: Unable to allocate notification object\n"));
- }
- }
-
- mali_pp_job_delete(job);
-}
-
-void mali_pp_scheduler_do_schedule(void)
-{
- mali_pp_scheduler_lock();
-
- mali_pp_scheduler_schedule();
-
- mali_pp_scheduler_unlock();
-}
-
-void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
-{
- u32 i;
- mali_bool job_is_done;
-
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job), success ? "success" : "failure"));
-
- mali_pp_scheduler_lock();
-
- /* Find slot which was running this job */
- for (i = 0; i < num_slots; i++)
- {
- if (slots[i].group == group)
- {
- MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slots[i].state);
- slots[i].state = MALI_PP_SLOT_STATE_IDLE;
- slots[i].session = NULL;
- num_slots_idle++;
- mali_pp_job_mark_sub_job_completed(job, success);
- }
- }
-
- /* If paused, then this was the last job, so wake up sleeping workers */
- if (pause_count > 0)
- {
- /* Wake up sleeping workers. Their wake-up condition is that
- * num_slots == num_slots_idle, so unless we are done working, no
- * threads will actually be woken up.
- */
- _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
- }
- else
- {
- mali_pp_scheduler_schedule();
- }
-
- job_is_done = mali_pp_job_is_complete(job);
-
- mali_pp_scheduler_unlock();
-
- if (job_is_done)
- {
- /* Send notification back to user space */
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for job %u (0x%08X)\n", mali_pp_job_get_id(job), job));
- mali_pp_scheduler_return_job_to_user(job);
- }
-}
-
-void mali_pp_scheduler_suspend(void)
-{
- mali_pp_scheduler_lock();
- pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
- mali_pp_scheduler_unlock();
-
- /*mali_pp_scheduler_working_lock();*/
- /* We have now aquired the working lock, which means that we have successfully paused the scheduler */
- /*mali_pp_scheduler_working_unlock();*/
-
- /* go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
- * mali_pp_scheduler_suspended() function will be called. This will return true
- * iff state is idle and pause_count > 0, so if the core is active this
- * will not do anything.
- */
- _mali_osk_wait_queue_wait_event(pp_scheduler_working_wait_queue, mali_pp_scheduler_is_suspended);
-}
-
-void mali_pp_scheduler_resume(void)
-{
- mali_pp_scheduler_lock();
- pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
- if (0 == pause_count)
- {
- mali_pp_scheduler_schedule();
- }
- mali_pp_scheduler_unlock();
-}
-
-_mali_osk_errcode_t _mali_ukk_pp_start_job(_mali_uk_pp_start_job_s *args)
-{
- struct mali_session_data *session;
- struct mali_pp_job *job;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_DEBUG_ASSERT_POINTER(args->ctx);
-
- session = (struct mali_session_data*)args->ctx;
-
- job = mali_pp_job_create(session, args, mali_scheduler_get_new_id());
- if (NULL == job)
- {
- return _MALI_OSK_ERR_NOMEM;
- }
-
- if (_MALI_OSK_ERR_OK != mali_pp_job_check(job))
- {
- /* Not a valid job, return to user immediately */
- mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
- mali_pp_scheduler_return_job_to_user(job); /* This will also delete the job object */
- return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
- }
-
-#if PROFILING_SKIP_PP_JOBS || PROFILING_SKIP_PP_AND_GP_JOBS
-#warning PP jobs will not be executed
- mali_pp_scheduler_return_job_to_user(job);
- return _MALI_OSK_ERR_OK;
-#endif
-
- mali_pp_scheduler_lock();
-
- _mali_osk_list_addtail(&job->list, &job_queue);
-
- MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n", mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
-
- mali_pp_scheduler_schedule();
-
- mali_pp_scheduler_unlock();
-
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores(_mali_uk_get_pp_number_of_cores_s *args)
-{
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_DEBUG_ASSERT_POINTER(args->ctx);
- args->number_of_cores = num_slots;
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t _mali_ukk_get_pp_core_version(_mali_uk_get_pp_core_version_s *args)
-{
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_DEBUG_ASSERT_POINTER(args->ctx);
- args->version = pp_version;
- return _MALI_OSK_ERR_OK;
-}
-
-void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
-{
- struct mali_session_data *session;
- struct mali_pp_job *job;
- struct mali_pp_job *tmp;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_DEBUG_ASSERT_POINTER(args->ctx);
-
- session = (struct mali_session_data*)args->ctx;
-
- mali_pp_scheduler_lock();
-
- /* Check queue for jobs that match */
- _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list)
- {
- if (mali_pp_job_get_session(job) == session &&
- mali_pp_job_get_frame_builder_id(job) == (u32)args->fb_id &&
- mali_pp_job_get_flush_id(job) == (u32)args->flush_id)
- {
- if (args->wbx & _MALI_UK_PP_JOB_WB0)
- {
- mali_pp_job_disable_wb0(job);
- }
- if (args->wbx & _MALI_UK_PP_JOB_WB1)
- {
- mali_pp_job_disable_wb1(job);
- }
- if (args->wbx & _MALI_UK_PP_JOB_WB2)
- {
- mali_pp_job_disable_wb2(job);
- }
- break;
- }
- }
-
- mali_pp_scheduler_unlock();
-}
-
-void mali_pp_scheduler_abort_session(struct mali_session_data *session)
-{
- struct mali_pp_job *job, *tmp;
- int i;
-
- mali_pp_scheduler_lock();
- MALI_DEBUG_PRINT(3, ("Mali PP 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_pp_job, list)
- {
- if (mali_pp_job_get_session(job) == session)
- {
- _mali_osk_list_del(&(job->list));
-
- if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) )
- {
- /* The job is in the render pipeline, we can not delete it yet. */
- /* It will be deleted in the mali_group_abort_session() call below */
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in queue\n", job));
- continue;
- }
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Removing PP job 0x%08x from queue\n", job));
- mali_pp_job_delete(job);
- }
- }
-
- mali_pp_scheduler_unlock();
-
- /* Abort running jobs from this session */
- for (i = 0; i < num_slots; i++)
- {
- struct mali_group *group = slots[i].group;
-
- MALI_DEBUG_PRINT(5, ("PP sched abort: Looking at group 0x%08x\n", group));
-
- if (MALI_PP_SLOT_STATE_WORKING == slots[i].state)
- {
- MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborting session 0x%08x from group 0x%08x\n", session, group));
-
- mali_group_abort_session(group, session);
- }
- }
-}
-
-static mali_bool mali_pp_scheduler_is_suspended(void)
-{
- mali_bool ret;
-
- mali_pp_scheduler_lock();
- ret = pause_count > 0 && num_slots == num_slots_idle;
- mali_pp_scheduler_unlock();
-
- return ret;
-}
-
-#if MALI_STATE_TRACKING
-u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
-{
- int n = 0;
- int i;
-
- n += _mali_osk_snprintf(buf + n, size - n, "PP:\n");
- n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
- n += _mali_osk_snprintf(buf + n, size - n, "\n");
-
- for (i = 0; i < num_slots; i++)
- {
- n += mali_group_dump_state(slots[i].group, buf + n, size - n);
- n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", slots[i].state);
- }
-
- return n;
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
deleted file mode 100644
index 48eb3bd..0000000
--- a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __MALI_PP_SCHEDULER_H__
-#define __MALI_PP_SCHEDULER_H__
-
-#include "mali_osk.h"
-#include "mali_cluster.h"
-#include "mali_pp_job.h"
-
-_mali_osk_errcode_t mali_pp_scheduler_initialize(void);
-void mali_pp_scheduler_terminate(void);
-
-void mali_pp_scheduler_do_schedule(void);
-void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success);
-
-void mali_pp_scheduler_suspend(void);
-void mali_pp_scheduler_resume(void);
-
-/** @brief Abort all PP jobs from session running or queued
- *
- * This functions aborts all PP jobs from the specified session. Queued jobs are removed from the queue and jobs
- * currently running on a core will be aborted.
- *
- * @param session Pointer to session whose jobs should be aborted
- */
-void mali_pp_scheduler_abort_session(struct mali_session_data *session);
-
-u32 mali_pp_scheduler_dump_state(char *buf, u32 size);
-
-#endif /* __MALI_PP_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h
deleted file mode 100644
index 7c78947..0000000
--- a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h
+++ /dev/null
@@ -1,28 +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_UTGARD_H__
-#define __MALI_UTGARD_H__
-
-/** @brief MALI GPU power down using MALI in-built PMU
- *
- * called to power down all cores
- */
-int mali_pmu_powerdown(void);
-
-
-/** @brief MALI GPU power up using MALI in-built PMU
- *
- * called to power up all cores
- */
-int mali_pmu_powerup(void);
-
-#endif /* __MALI_UTGARD_H__ */
-
diff --git a/drivers/media/video/samsung/mali/linux/mali_dma_buf.c b/drivers/media/video/samsung/mali/linux/mali_dma_buf.c
deleted file mode 100644
index 4dd711f..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_dma_buf.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/fs.h> /* file system operations */
-#include <asm/uaccess.h> /* user space access */
-#include <linux/dma-buf.h>
-#include <linux/scatterlist.h>
-#include <linux/rbtree.h>
-
-#include "mali_ukk.h"
-#include "mali_osk.h"
-#include "mali_kernel_common.h"
-#include "mali_session.h"
-#include "mali_kernel_linux.h"
-
-#include "mali_kernel_memory_engine.h"
-#include "mali_memory.h"
-
-#include "mali_kernel_sysfs.h"
-
-
-struct mali_dma_buf_attachment {
- struct dma_buf *buf;
- struct dma_buf_attachment *attachment;
- struct sg_table *sgt;
- _mali_osk_atomic_t ref;
- struct rb_node rb_node;
-};
-
-static struct rb_root mali_dma_bufs = RB_ROOT;
-static DEFINE_SPINLOCK(mali_dma_bufs_lock);
-
-static inline struct mali_dma_buf_attachment *mali_dma_buf_lookup(struct rb_root *root, struct dma_buf *target)
-{
- struct rb_node *node = root->rb_node;
- struct mali_dma_buf_attachment *res;
-
- spin_lock(&mali_dma_bufs_lock);
- while (node)
- {
- res = rb_entry(node, struct mali_dma_buf_attachment, rb_node);
-
- if (target < res->buf) node = node->rb_left;
- else if (target > res->buf) node = node->rb_right;
- else
- {
- _mali_osk_atomic_inc(&res->ref);
- spin_unlock(&mali_dma_bufs_lock);
- return res;
- }
- }
- spin_unlock(&mali_dma_bufs_lock);
-
- return NULL;
-}
-
-static void mali_dma_buf_add(struct rb_root *root, struct mali_dma_buf_attachment *new)
-{
- struct rb_node **node = &root->rb_node;
- struct rb_node *parent = NULL;
- struct mali_dma_buf_attachment *res;
-
- spin_lock(&mali_dma_bufs_lock);
- while (*node)
- {
- parent = *node;
- res = rb_entry(*node, struct mali_dma_buf_attachment, rb_node);
-
- if (new->buf < res->buf) node = &(*node)->rb_left;
- else node = &(*node)->rb_right;
- }
-
- rb_link_node(&new->rb_node, parent, node);
- rb_insert_color(&new->rb_node, &mali_dma_bufs);
-
- spin_unlock(&mali_dma_bufs_lock);
-
- return;
-}
-
-
-static void mali_dma_buf_release(void *ctx, void *handle)
-{
- struct mali_dma_buf_attachment *mem;
- u32 ref;
-
- mem = (struct mali_dma_buf_attachment *)handle;
-
- MALI_DEBUG_ASSERT_POINTER(mem);
- MALI_DEBUG_ASSERT_POINTER(mem->attachment);
- MALI_DEBUG_ASSERT_POINTER(mem->buf);
-
- spin_lock(&mali_dma_bufs_lock);
- ref = _mali_osk_atomic_dec_return(&mem->ref);
-
- MALI_DEBUG_ASSERT(ref >= 0);
-
- if (0 == ref)
- {
- rb_erase(&mem->rb_node, &mali_dma_bufs);
- spin_unlock(&mali_dma_bufs_lock);
-
- MALI_DEBUG_ASSERT(0 == _mali_osk_atomic_read(&mem->ref));
-
- dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
-
- dma_buf_detach(mem->buf, mem->attachment);
- dma_buf_put(mem->buf);
-
- _mali_osk_free(mem);
- }
- else
- {
- spin_unlock(&mali_dma_bufs_lock);
- }
-}
-
-/* Callback from memory engine which will map into Mali virtual address space */
-static mali_physical_memory_allocation_result mali_dma_buf_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
-{
- struct mali_session_data *session;
- struct mali_page_directory *pagedir;
- struct mali_dma_buf_attachment *mem;
- struct scatterlist *sg;
- int i;
- u32 virt;
-
- MALI_DEBUG_ASSERT_POINTER(ctx);
- MALI_DEBUG_ASSERT_POINTER(engine);
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT_POINTER(offset);
- MALI_DEBUG_ASSERT_POINTER(alloc_info);
-
- /* Mapping dma-buf with an offset is not supported. */
- MALI_DEBUG_ASSERT(0 == *offset);
-
- virt = descriptor->mali_address;
- session = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
- pagedir = mali_session_get_page_directory(session);
-
- MALI_DEBUG_ASSERT_POINTER(session);
-
- mem = (struct mali_dma_buf_attachment *)ctx;
-
- MALI_DEBUG_ASSERT_POINTER(mem);
-
- mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL);
- if (IS_ERR_OR_NULL(mem->sgt))
- {
- MALI_PRINT_ERROR(("Failed to map dma-buf attachment\n"));
- return MALI_MEM_ALLOC_INTERNAL_FAILURE;
- }
-
- for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i)
- {
- u32 size = sg_dma_len(sg);
- dma_addr_t phys = sg_dma_address(sg);
-
- /* sg must be page aligned. */
- MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
-
- mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_CACHE_STANDARD);
-
- virt += size;
- *offset += size;
- }
-
- if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
- {
- u32 guard_phys;
- MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n"));
-
- guard_phys = sg_dma_address(mem->sgt->sgl);
- mali_mmu_pagedir_update(mali_session_get_page_directory(session), virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_CACHE_STANDARD);
- }
-
- MALI_DEBUG_ASSERT(*offset == descriptor->size);
-
- alloc_info->ctx = NULL;
- alloc_info->handle = mem;
- alloc_info->next = NULL;
- alloc_info->release = mali_dma_buf_release;
-
- return MALI_MEM_ALLOC_FINISHED;
-}
-
-int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg)
-{
- mali_physical_memory_allocator external_memory_allocator;
- struct dma_buf *buf;
- struct mali_dma_buf_attachment *mem;
- _mali_uk_attach_dma_buf_s args;
- mali_memory_allocation *descriptor;
- int md;
- int fd;
-
- /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s)))
- {
- return -EFAULT;
- }
-
-
- fd = args.mem_fd;
-
- buf = dma_buf_get(fd);
- if (IS_ERR_OR_NULL(buf))
- {
- MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd));
- return PTR_RET(buf);
- }
-
- /* Currently, mapping of the full buffer are supported. */
- if (args.size != buf->size)
- {
- MALI_DEBUG_PRINT(2, ("dma-buf size doesn't match mapping size.\n"));
- dma_buf_put(buf);
- return -EINVAL;
- }
-
-
- mem = mali_dma_buf_lookup(&mali_dma_bufs, buf);
- if (NULL == mem)
- {
- /* dma-buf is not already attached to Mali */
- mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
- if (NULL == mem)
- {
- MALI_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n"));
- dma_buf_put(mem->buf);
- return -ENOMEM;
- }
- _mali_osk_atomic_init(&mem->ref, 1);
- mem->buf = buf;
-
- mem->attachment = dma_buf_attach(mem->buf, mali_device);
- if (NULL == mem->attachment)
- {
- MALI_DEBUG_PRINT(2, ("Failed to attach to dma-buf %d\n", fd));
- dma_buf_put(mem->buf);
- _mali_osk_free(mem);
- return -EFAULT;
- }
-
- mali_dma_buf_add(&mali_dma_bufs, mem);
- }
- else
- {
- /* dma-buf is already attached to Mali */
- /* Give back the reference we just took, mali_dma_buf_lookup grabbed a new reference for us. */
- dma_buf_put(buf);
- }
-
- /* Map dma-buf into this session's page tables */
-
- /* Set up Mali memory descriptor */
- descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
- if (NULL == descriptor)
- {
- MALI_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd));
- mali_dma_buf_release(NULL, mem);
- return -ENOMEM;
- }
-
- descriptor->size = args.size;
- descriptor->mapping = NULL;
- descriptor->mali_address = args.mali_address;
- descriptor->mali_addr_mapping_info = (void*)session;
- descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
- descriptor->lock = session->memory_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 );
-
- /* Get descriptor mapping for memory. */
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md))
- {
- MALI_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd));
- _mali_osk_free(descriptor);
- mali_dma_buf_release(NULL, mem);
- return -EFAULT;
- }
-
- external_memory_allocator.allocate = mali_dma_buf_commit;
- external_memory_allocator.allocate_page_table_block = NULL;
- external_memory_allocator.ctx = mem;
- external_memory_allocator.name = "DMA-BUF Memory";
- external_memory_allocator.next = NULL;
-
- /* Map memory into session's Mali virtual address space. */
- _mali_osk_lock_wait(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
- if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(mali_mem_get_memory_engine(), descriptor, &external_memory_allocator, NULL))
- {
- _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd));
- mali_descriptor_mapping_free(session->descriptor_mapping, md);
- mali_dma_buf_release(NULL, mem);
- return -ENOMEM;
- }
- _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
-
- /* Return stuff to user space */
- if (0 != put_user(md, &user_arg->cookie))
- {
- /* Roll back */
- MALI_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd));
- mali_descriptor_mapping_free(session->descriptor_mapping, md);
- mali_dma_buf_release(NULL, mem);
- return -EFAULT;
- }
-
- return 0;
-}
-
-int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg)
-{
- _mali_uk_release_dma_buf_s args;
- mali_memory_allocation *descriptor;
-
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s)) )
- {
- return -EFAULT;
- }
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args.cookie, (void**)&descriptor))
- {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release dma-buf\n", args.cookie));
- return -EINVAL;
- }
-
- descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args.cookie);
-
- if (NULL != descriptor)
- {
- _mali_osk_lock_wait( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
-
- /* Will call back to mali_dma_buf_release() which will release the dma-buf attachment. */
- mali_allocation_engine_release_memory(mali_mem_get_memory_engine(), descriptor);
-
- _mali_osk_lock_signal( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
-
- _mali_osk_free(descriptor);
- }
-
- /* Return the error that _mali_ukk_map_external_ump_mem produced */
- return 0;
-}
-
-int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
-{
- _mali_uk_dma_buf_get_size_s args;
- int fd;
- struct dma_buf *buf;
-
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s)) )
- {
- return -EFAULT;
- }
-
- /* Do DMA-BUF stuff */
- fd = args.mem_fd;
-
- buf = dma_buf_get(fd);
- if (IS_ERR_OR_NULL(buf))
- {
- MALI_DEBUG_PRINT(2, ("Failed to get dma-buf from fd: %d\n", fd));
- return PTR_RET(buf);
- }
-
- if (0 != put_user(buf->size, &user_arg->size))
- {
- dma_buf_put(buf);
- return -EFAULT;
- }
-
- dma_buf_put(buf);
-
- return 0;
-}
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c
deleted file mode 100644
index 4639d55..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c
+++ /dev/null
@@ -1,268 +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.
- */
-
-/**
- * @file mali_kernel_pm.c
- * Linux Power Management integration
- */
-
-#include <linux/sched.h>
-#include <linux/platform_device.h>
-#include <linux/version.h>
-#include <asm/current.h>
-#include <linux/suspend.h>
-#include <linux/module.h>
-#ifdef CONFIG_PM_RUNTIME
-#include <linux/pm_runtime.h>
-#endif
-#include "mali_osk.h"
-#include "mali_uk_types.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_license.h"
-#include "mali_linux_pm.h"
-#include "mali_pm.h"
-#include "mali_platform.h"
-
-#if ! MALI_LICENSE_IS_GPL
-#undef CONFIG_PM_RUNTIME
-#endif
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-extern void set_mali_parent_power_domain(struct platform_device* dev);
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-static int mali_probe(struct platform_device *pdev);
-static int mali_remove(struct platform_device *pdev);
-
-#ifdef CONFIG_PM_RUNTIME
-static int mali_runtime_suspend(struct device *dev);
-static int mali_runtime_resume(struct device *dev);
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
-static int mali_os_suspend(struct platform_device *pdev, pm_message_t state);
-static int mali_os_resume(struct platform_device *pdev);
-#else
-static int mali_os_suspend(struct device *dev);
-static int mali_os_resume(struct device *dev);
-#endif
-
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
-static const struct dev_pm_ops mali_dev_pm_ops =
-{
-#ifdef CONFIG_PM_RUNTIME
- .runtime_suspend = mali_runtime_suspend,
- .runtime_resume = mali_runtime_resume,
- .runtime_idle = NULL,
-#else
- .suspend = mali_os_suspend,
- .resume = mali_os_resume,
-#endif
- .freeze = mali_os_suspend,
- .poweroff = mali_os_suspend,
- .thaw = mali_os_resume,
- .restore = mali_os_resume,
-};
-#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
-struct pm_ext_ops mali_ext_pm_operations =
-{
- .base =
- {
- .freeze = mali_os_suspend,
- .thaw = mali_os_resume,
- .poweroff = mali_os_suspend,
- .restore = mali_os_resume,
- },
-};
-#endif
-
-
-static struct platform_driver mali_plat_driver =
-{
- .probe = mali_probe,
- .remove = mali_remove,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
- .suspend = mali_os_suspend,
- .resume = mali_os_resume,
- .pm = &mali_ext_pm_operations,
-#endif
-
- .driver =
- {
- .name = "mali_dev",
- .owner = THIS_MODULE,
-#if MALI_LICENSE_IS_GPL
- .bus = &platform_bus_type,
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
- .pm = &mali_dev_pm_ops,
-#endif
- },
-};
-
-#ifdef CONFIG_PM_RUNTIME
-static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy);
-
-static struct notifier_block mali_pwr_notif_block =
-{
- .notifier_call = mali_pwr_suspend_notifier
-};
-#endif
-
-/** This function is called when platform device is unregistered. This function
- * is necessary when the platform device is unregistered.
- */
-static void _mali_release_pm(struct device *device)
-{
-}
-struct platform_device mali_gpu_device =
-{
- .name = "mali_dev",
- .id = 0,
- .dev.release = _mali_release_pm
-};
-
-/** This function is called when the device is probed */
-static int mali_probe(struct platform_device *pdev)
-{
- return 0;
-}
-
-static int mali_remove(struct platform_device *pdev)
-{
-#ifdef CONFIG_PM_RUNTIME
- pm_runtime_disable(&pdev->dev);
-#endif
- return 0;
-}
-
-#ifdef CONFIG_PM_RUNTIME
-static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy)
-{
- switch (event)
- {
- case PM_SUSPEND_PREPARE:
- MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n"));
- mali_pm_os_suspend();
- break;
- case PM_POST_SUSPEND:
- MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n"));
- mali_pm_os_resume();
- break;
- default:
- break;
- }
- return 0;
-}
-#endif
-
-
-#ifdef CONFIG_PM_RUNTIME
-
-static int mali_runtime_suspend(struct device *dev)
-{
- MALI_DEBUG_PRINT(3, ("mali_runtime_suspend() called\n"));
- mali_pm_runtime_suspend();
- return 0; /* all ok */
-}
-
-static int mali_runtime_resume(struct device *dev)
-{
- MALI_DEBUG_PRINT(3, ("mali_runtime_resume() called\n"));
- mali_pm_runtime_resume();
- return 0; /* all ok */
-}
-
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
-
-static int mali_os_suspend(struct platform_device *pdev, pm_message_t state)
-{
- MALI_DEBUG_PRINT(3, ("mali_os_suspend(old) called\n"));
- mali_pm_os_suspend();
- return 0; /* all ok */
-}
-
-static int mali_os_resume(struct platform_device *pdev)
-{
- MALI_DEBUG_PRINT(3, ("mali_os_resume(old) called\n"));
- mali_pm_os_resume();
- return 0; /* all ok */
-}
-
-#else
-
-static int mali_os_suspend(struct device *dev)
-{
- MALI_DEBUG_PRINT(3, ("mali_os_suspend(new) called\n"));
- mali_pm_os_suspend();
- return 0; /* all ok */
-}
-
-static int mali_os_resume(struct device *dev)
-{
- MALI_DEBUG_PRINT(3, ("mali_os_resume(new) called\n"));
- mali_pm_os_resume();
- return 0; /* all ok */
-}
-
-#endif
-
-/** This function is called when Mali GPU device is initialized
- */
-int _mali_dev_platform_register(void)
-{
- int err;
-
-#ifdef CONFIG_PM_RUNTIME
- set_mali_parent_power_domain((void *)&mali_gpu_device);
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
- err = register_pm_notifier(&mali_pwr_notif_block);
- if (err)
- {
- return err;
- }
-#endif
-
-#if MALI_LICENSE_IS_GPL
- err = platform_device_register(&mali_gpu_device);
- if (!err)
- {
- err = platform_driver_register(&mali_plat_driver);
- if (err)
- {
-#ifdef CONFIG_PM_RUNTIME
- unregister_pm_notifier(&mali_pwr_notif_block);
-#endif
- platform_device_unregister(&mali_gpu_device);
- }
- }
-#endif
-
- return err;
-}
-
-/** This function is called when Mali GPU device is unloaded
- */
-void _mali_dev_platform_unregister(void)
-{
-#ifdef CONFIG_PM_RUNTIME
- unregister_pm_notifier(&mali_pwr_notif_block);
-#endif
-
-#if MALI_LICENSE_IS_GPL
- platform_driver_unregister(&mali_plat_driver);
- platform_device_unregister(&mali_gpu_device);
-#endif
-}
-
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h
deleted file mode 100644
index 6ef7270..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h
+++ /dev/null
@@ -1,17 +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_PM_H__
-#define __MALI_KERNEL_PM_H__
-
-int _mali_dev_platform_register(void);
-void _mali_dev_platform_unregister(void);
-
-#endif /* __MALI_KERNEL_PM_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h
deleted file mode 100644
index 10f633e..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h
+++ /dev/null
@@ -1,50 +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_LINUX_PM_H__
-#define __MALI_LINUX_PM_H__
-
-#ifdef CONFIG_PM
-/* Number of power states supported for making power up and down */
-typedef enum
-{
- _MALI_DEVICE_SUSPEND, /* Suspend */
- _MALI_DEVICE_RESUME, /* Resume */
- _MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */
-} _mali_device_power_states;
-
-/* Number of DVFS events */
-typedef enum
-{
- _MALI_DVFS_PAUSE_EVENT = _MALI_DEVICE_MAX_POWER_STATES, /* DVFS Pause event */
- _MALI_DVFS_RESUME_EVENT, /* DVFS Resume event */
- _MALI_MAX_DEBUG_OPERATIONS,
-} _mali_device_dvfs_events;
-
-extern _mali_device_power_states mali_device_state;
-extern _mali_device_power_states mali_dvfs_device_state;
-extern _mali_osk_lock_t *lock;
-extern short is_wake_up_needed;
-extern int timeout_fired;
-extern struct platform_device mali_gpu_device;
-
-/* dvfs pm thread */
-extern struct task_struct *dvfs_pm_thread;
-
-/* Power management thread */
-extern struct task_struct *pm_thread;
-
-int mali_device_suspend(u32 event_id, struct task_struct **pwr_mgmt_thread);
-int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread);
-int mali_get_ospmm_thread_state(void);
-
-#endif /* CONFIG_PM */
-#endif /* __MALI_LINUX_PM_H___ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h
deleted file mode 100644
index 7d811bd..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h
+++ /dev/null
@@ -1,32 +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_LINUX_PM_TESTSUITE_H__
-#define __MALI_LINUX_PM_TESTSUITE_H__
-
-#if MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM)
-
-typedef enum
-{
- _MALI_DEVICE_PMM_TIMEOUT_EVENT,
- _MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS,
- _MALI_DEVICE_PMM_REGISTERED_CORES,
- _MALI_DEVICE_MAX_PMM_EVENTS
-
-} _mali_device_pmm_recording_events;
-
-extern unsigned int mali_timeout_event_recording_on;
-extern unsigned int mali_job_scheduling_events_recording_on;
-extern unsigned int pwr_mgmt_status_reg;
-extern unsigned int is_mali_pmm_testsuite_enabled;
-extern unsigned int is_mali_pmu_present;
-
-#endif /* MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) */
-
-#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c
deleted file mode 100644
index ddfe564..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c
+++ /dev/null
@@ -1,266 +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.
- */
-
-/**
- * @file mali_osk_irq.c
- * Implementation of the OS abstraction layer for the kernel device driver
- */
-
-#include <linux/slab.h> /* For memory allocation */
-#include <linux/workqueue.h>
-#include <linux/version.h>
-
-#include "mali_osk.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_license.h"
-#include "mali_kernel_linux.h"
-#include "linux/interrupt.h"
-
-typedef struct _mali_osk_irq_t_struct
-{
- u32 irqnum;
- void *data;
- _mali_osk_irq_uhandler_t uhandler;
- _mali_osk_irq_bhandler_t bhandler;
- struct work_struct work_queue_irq_handle; /* Workqueue for the bottom half of the IRQ-handling. This job is activated when this core gets an IRQ.*/
-} mali_osk_irq_object_t;
-
-#if MALI_LICENSE_IS_GPL
-static struct workqueue_struct *pmm_wq = NULL;
-struct workqueue_struct *mali_wq = NULL;
-#endif
-
-typedef void (*workqueue_func_t)(void *);
-typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
-static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/
-
-#if defined(INIT_DELAYED_WORK)
-static void irq_handler_bottom_half ( struct work_struct *work );
-#else
-static void irq_handler_bottom_half ( void * input );
-#endif
-
-/**
- * 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 */
-
-_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, _mali_osk_irq_bhandler_t bhandler, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *data, const char *description )
-{
- mali_osk_irq_object_t *irq_object;
-
- irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL);
- if (NULL == irq_object) return NULL;
-
-#if MALI_LICENSE_IS_GPL
- if (NULL == mali_wq)
- {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
- mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0);
-#else
- mali_wq = create_workqueue("mali");
-#endif
- if(NULL == mali_wq)
- {
- MALI_PRINT_ERROR(("Unable to create Mali workqueue\n"));
- kfree(irq_object);
- return NULL;
- }
- }
-#endif
-
- /* workqueue API changed in 2.6.20, support both versions: */
-#if defined(INIT_DELAYED_WORK)
- /* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */
- INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half);
-#else
- /* Old syntax: INIT_WORK( struct work_struct *work, void (*function)(void *), void *data) */
- INIT_WORK( &irq_object->work_queue_irq_handle, irq_handler_bottom_half, irq_object);
-#endif /* defined(INIT_DELAYED_WORK) */
-
- if (-1 == irqnum)
- {
- /* Probe for IRQ */
- if ( (NULL != trigger_func) && (NULL != ack_func) )
- {
- unsigned long probe_count = 3;
- _mali_osk_errcode_t err;
- int irq;
-
- MALI_DEBUG_PRINT(2, ("Probing for irq\n"));
-
- do
- {
- unsigned long mask;
-
- mask = probe_irq_on();
- trigger_func(data);
-
- _mali_osk_time_ubusydelay(5);
-
- irq = probe_irq_off(mask);
- err = ack_func(data);
- }
- while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--);
-
- if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1;
- else irqnum = irq;
- }
- else irqnum = -1; /* no probe functions, fault */
-
- if (-1 != irqnum)
- {
- /* found an irq */
- MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum));
- }
- else
- {
- MALI_DEBUG_PRINT(2, ("Probe for irq failed\n"));
- }
- }
-
- irq_object->irqnum = irqnum;
- irq_object->uhandler = uhandler;
- irq_object->bhandler = bhandler;
- irq_object->data = data;
-
- /* Is this a real IRQ handler we need? */
- if (irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM)
- {
- if (-1 == irqnum)
- {
- MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description));
- kfree(irq_object);
- return NULL;
- }
-
- if (0 != request_irq(irqnum, irq_handler_upper_half, IRQF_SHARED, description, irq_object))
- {
- MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description));
- kfree(irq_object);
- return NULL;
- }
- }
-
-#if MALI_LICENSE_IS_GPL
- if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum )
- {
- pmm_wq = create_singlethread_workqueue("mali-pmm-wq");
- }
-#endif
-
- return irq_object;
-}
-
-void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq )
-{
- mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
-#if MALI_LICENSE_IS_GPL
- if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
- {
- queue_work( pmm_wq,&irq_object->work_queue_irq_handle );
- }
- else
- {
- queue_work(mali_wq, &irq_object->work_queue_irq_handle);
- }
-#else
- schedule_work(&irq_object->work_queue_irq_handle);
-#endif
-}
-
-void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq )
-{
-#if MALI_LICENSE_IS_GPL
- if (NULL != irq)
- {
- mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
- if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
- {
- flush_workqueue(pmm_wq);
- }
- else
- {
- flush_workqueue(mali_wq);
- }
- }
- else
- {
- flush_workqueue(mali_wq);
- }
-#endif
-}
-
-void _mali_osk_irq_term( _mali_osk_irq_t *irq )
-{
- mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
-
-#if MALI_LICENSE_IS_GPL
- if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
- {
- flush_workqueue(pmm_wq);
- destroy_workqueue(pmm_wq);
- }
-#endif
- free_irq(irq_object->irqnum, irq_object);
- kfree(irq_object);
- flush_scheduled_work();
-}
-
-
-/** This function is called directly in interrupt context from the OS just after
- * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel.
- * It is registered one of these function for each mali core. When an interrupt
- * arrives this function will be called equal times as registered mali cores.
- * That means that we only check one mali core in one function call, and the
- * core we check for each turn is given by the \a dev_id variable.
- * If we detect an pending interrupt on the given core, we mask the interrupt
- * out by settging the core's IRQ_MASK register to zero.
- * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority
- * work queue job.
- */
-static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/
-{
- mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id;
-
- if (irq_object->uhandler(irq_object->data) == _MALI_OSK_ERR_OK)
- {
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
-}
-
-/* Is executed when an interrupt occur on one core */
-/* workqueue API changed in 2.6.20, support both versions: */
-#if defined(INIT_DELAYED_WORK)
-static void irq_handler_bottom_half ( struct work_struct *work )
-#else
-static void irq_handler_bottom_half ( void * input )
-#endif
-{
- mali_osk_irq_object_t *irq_object;
-
-#if defined(INIT_DELAYED_WORK)
- irq_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_irq_object_t, work_queue_irq_handle);
-#else
- if ( NULL == input )
- {
- MALI_PRINT_ERROR(("IRQ: Null pointer! Illegal!"));
- return; /* Error */
- }
- irq_object = (mali_osk_irq_object_t *) input;
-#endif
-
- irq_object->bhandler(irq_object->data);
-}
-
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
deleted file mode 100644
index 06cb215..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
+++ /dev/null
@@ -1,34 +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.
- */
-
-/**
- * @file mali_osk_mali.c
- * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
- */
-#include <linux/kernel.h>
-#include <asm/uaccess.h>
-#include <mach/irqs.h>
-
-#include "mali_kernel_common.h" /* MALI_xxx macros */
-#include "mali_osk.h" /* kernel side OS functions */
-#include "mali_uk_types.h"
-#include "arch/config.h" /* contains the configuration of the arch we are compiling for */
-
-_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources )
-{
- *num_resources = sizeof(arch_configuration) / sizeof(arch_configuration[0]);
- *arch_config = arch_configuration;
- return _MALI_OSK_ERR_OK;
-}
-
-void _mali_osk_resources_term( _mali_osk_resource_t **arch_config, u32 num_resources )
-{
- /* Nothing to do */
-}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c
deleted file mode 100644
index 491a603..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c
+++ /dev/null
@@ -1,83 +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.
- */
-
-/**
- * @file mali_osk_pm.c
- * Implementation of the callback functions from common power management
- */
-
-#include <linux/sched.h>
-
-#ifdef CONFIG_PM_RUNTIME
-#include <linux/pm_runtime.h>
-#endif /* CONFIG_PM_RUNTIME */
-#include <linux/platform_device.h>
-#include "mali_platform.h"
-#include "mali_osk.h"
-#include "mali_uk_types.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_license.h"
-#include "mali_linux_pm.h"
-#include "mali_kernel_license.h"
-
-#if ! MALI_LICENSE_IS_GPL
-#undef CONFIG_PM_RUNTIME
-#endif
-
-extern struct platform_device mali_gpu_device;
-
-#ifdef CONFIG_PM_RUNTIME
-static mali_bool have_runtime_reference = MALI_FALSE;
-#endif
-
-void _mali_osk_pm_dev_enable(void)
-{
-#ifdef CONFIG_PM_RUNTIME
- pm_runtime_enable(&(mali_gpu_device.dev));
-#endif
-}
-
-/* NB: Function is not thread safe */
-_mali_osk_errcode_t _mali_osk_pm_dev_idle(void)
-{
-#ifdef CONFIG_PM_RUNTIME
- if (MALI_TRUE == have_runtime_reference)
- {
- int err;
- err = pm_runtime_put_sync(&(mali_gpu_device.dev));
- if (0 > err)
- {
- MALI_PRINT_ERROR(("OSK PM: pm_runtime_put_sync() returned error code %d\n", err));
- return _MALI_OSK_ERR_FAULT;
- }
- have_runtime_reference = MALI_FALSE;
- }
-#endif
- return _MALI_OSK_ERR_OK;
-}
-
-/* NB: Function is not thread safe */
-_mali_osk_errcode_t _mali_osk_pm_dev_activate(void)
-{
-#ifdef CONFIG_PM_RUNTIME
- if (MALI_TRUE != have_runtime_reference)
- {
- int err;
- err = pm_runtime_get_sync(&(mali_gpu_device.dev));
- if (0 > err)
- {
- MALI_PRINT_ERROR(("OSK PM: pm_runtime_get_sync() returned error code %d\n", err));
- return _MALI_OSK_ERR_FAULT;
- }
- have_runtime_reference = MALI_TRUE;
- }
-#endif
- return _MALI_OSK_ERR_OK;
-}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c
deleted file mode 100644
index 2df935d..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_ukk.h"
-#include "mali_timestamp.h"
-#include "mali_osk_profiling.h"
-#include "mali_user_settings_db.h"
-
-typedef struct mali_profiling_entry
-{
- u64 timestamp;
- u32 event_id;
- u32 data[5];
-} mali_profiling_entry;
-
-
-typedef enum mali_profiling_state
-{
- MALI_PROFILING_STATE_UNINITIALIZED,
- MALI_PROFILING_STATE_IDLE,
- MALI_PROFILING_STATE_RUNNING,
- MALI_PROFILING_STATE_RETURN,
-} mali_profiling_state;
-
-static _mali_osk_lock_t *lock = NULL;
-static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
-static mali_profiling_entry* profile_entries = NULL;
-static u32 profile_entry_count = 0;
-static _mali_osk_atomic_t profile_insert_index;
-static _mali_osk_atomic_t profile_entries_written;
-
-_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
-{
- profile_entries = NULL;
- profile_entry_count = 0;
- _mali_osk_atomic_init(&profile_insert_index, 0);
- _mali_osk_atomic_init(&profile_entries_written, 0);
-
- lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
- if (NULL == lock)
- {
- return _MALI_OSK_ERR_FAULT;
- }
-
- prof_state = MALI_PROFILING_STATE_IDLE;
-
- if (MALI_TRUE == auto_start)
- {
- u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
-
- mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
- if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
- {
- return _MALI_OSK_ERR_FAULT;
- }
- }
-
- return _MALI_OSK_ERR_OK;
-}
-
-void _mali_osk_profiling_term(void)
-{
- prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
-
- /* wait for all elements to be completely inserted into array */
- while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written))
- {
- /* do nothing */;
- }
-
- if (NULL != profile_entries)
- {
- _mali_osk_vfree(profile_entries);
- profile_entries = NULL;
- }
-
- if (NULL != lock)
- {
- _mali_osk_lock_term(lock);
- lock = NULL;
- }
-}
-
-inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit)
-{
- _mali_osk_errcode_t ret;
-
- mali_profiling_entry *new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry));
-
- if(NULL == new_profile_entries)
- {
- return _MALI_OSK_ERR_NOMEM;
- }
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_IDLE)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_vfree(new_profile_entries);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- if (*limit > MALI_PROFILING_MAX_BUFFER_ENTRIES)
- {
- *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
- }
-
- profile_entries = new_profile_entries;
- profile_entry_count = *limit;
-
- ret = _mali_timestamp_reset();
-
- if (ret == _MALI_OSK_ERR_OK)
- {
- prof_state = MALI_PROFILING_STATE_RUNNING;
- }
- else
- {
- _mali_osk_vfree(profile_entries);
- profile_entries = NULL;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return ret;
-}
-
-inline void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
-{
- if (prof_state == MALI_PROFILING_STATE_RUNNING)
- {
- u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) % profile_entry_count;
-
- profile_entries[cur_index].timestamp = _mali_timestamp_get();
- profile_entries[cur_index].event_id = event_id;
- profile_entries[cur_index].data[0] = data0;
- profile_entries[cur_index].data[1] = data1;
- profile_entries[cur_index].data[2] = data2;
- profile_entries[cur_index].data[3] = data3;
- profile_entries[cur_index].data[4] = data4;
-
- /* If event is "leave API function", add current memory usage to the event
- * as data point 4. This is used in timeline profiling to indicate how
- * much memory was used when leaving a function. */
- if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC))
- {
- profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage();
- }
-
- _mali_osk_atomic_inc(&profile_entries_written);
- }
-}
-
-inline void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value)
-{
- /* Not implemented */
-}
-
-void _mali_osk_profiling_report_sw_counters(u32 *counters)
-{
- /* Not implemented */
-}
-
-inline _mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_RUNNING)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- /* go into return state (user to retreive events), no more events will be added after this */
- prof_state = MALI_PROFILING_STATE_RETURN;
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
-
- /* wait for all elements to be completely inserted into array */
- while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written))
- {
- /* do nothing */;
- }
-
- *count = _mali_osk_atomic_read(&profile_insert_index);
- if(*count>profile_entry_count) *count=profile_entry_count;
-
- return _MALI_OSK_ERR_OK;
-}
-
-inline u32 _mali_osk_profiling_get_count(void)
-{
- u32 retval = 0;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if (prof_state == MALI_PROFILING_STATE_RETURN)
- {
- retval = _mali_osk_atomic_read(&profile_entries_written);
- if(retval>profile_entry_count) retval = profile_entry_count;
- }
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
-
- return retval;
-}
-
-inline _mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if(index<profile_entry_count)
- {
- u32 idx = index;
- if(_mali_osk_atomic_read(&profile_insert_index)>=profile_entry_count)
- {
- idx = (index + _mali_osk_atomic_read(&profile_insert_index)) % profile_entry_count;
- }
-
- if (prof_state != MALI_PROFILING_STATE_RETURN)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- if (idx >= _mali_osk_atomic_read(&profile_entries_written))
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_FAULT;
- }
-
- *timestamp = profile_entries[idx].timestamp;
- *event_id = profile_entries[idx].event_id;
- data[0] = profile_entries[idx].data[0];
- data[1] = profile_entries[idx].data[1];
- data[2] = profile_entries[idx].data[2];
- data[3] = profile_entries[idx].data[3];
- data[4] = profile_entries[idx].data[4];
- }
- else
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_FAULT;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_OK;
-}
-
-inline _mali_osk_errcode_t _mali_osk_profiling_clear(void)
-{
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (prof_state != MALI_PROFILING_STATE_RETURN)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
- }
-
- prof_state = MALI_PROFILING_STATE_IDLE;
- profile_entry_count = 0;
- _mali_osk_atomic_init(&profile_insert_index, 0);
- _mali_osk_atomic_init(&profile_entries_written, 0);
- if (NULL != profile_entries)
- {
- _mali_osk_vfree(profile_entries);
- profile_entries = NULL;
- }
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_OK;
-}
-
-mali_bool _mali_osk_profiling_is_recording(void)
-{
- return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
-}
-
-mali_bool _mali_osk_profiling_have_recording(void)
-{
- return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
-{
- return _mali_osk_profiling_start(&args->limit);
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args)
-{
- /* Always add process and thread identificator in the first two data elements for events from user space */
- _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]);
- return _MALI_OSK_ERR_OK;
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args)
-{
- return _mali_osk_profiling_stop(&args->count);
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args)
-{
- return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data);
-}
-
-_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args)
-{
- return _mali_osk_profiling_clear();
-}
-
-_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args)
-{
- _mali_osk_profiling_report_sw_counters(args->counters);
- return _MALI_OSK_ERR_OK;
-}
-
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
deleted file mode 100644
index 83ee906..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
+++ /dev/null
@@ -1,130 +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.
- */
-
-/**
- * @file mali_osk_specific.h
- * Defines per-OS Kernel level specifics, such as unusual workarounds for
- * certain OSs.
- */
-
-#ifndef __MALI_OSK_SPECIFIC_H__
-#define __MALI_OSK_SPECIFIC_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define MALI_STATIC_INLINE static inline
-#define MALI_NON_STATIC_INLINE inline
-
-#ifdef __cplusplus
-}
-#endif
-
-/** The list of events supported by the Mali DDK. */
-typedef enum
-{
- /* Vertex processor activity */
- ACTIVITY_VP = 0,
-
- /* Fragment processor activity */
- ACTIVITY_FP0,
- ACTIVITY_FP1,
- ACTIVITY_FP2,
- ACTIVITY_FP3,
-
- /* L2 cache counters */
- COUNTER_L2_C0,
- COUNTER_L2_C1,
-
- /* Vertex processor counters */
- COUNTER_VP_C0,
- COUNTER_VP_C1,
-
- /* Fragment processor counters */
- COUNTER_FP0_C0,
- COUNTER_FP0_C1,
- COUNTER_FP1_C0,
- COUNTER_FP1_C1,
- COUNTER_FP2_C0,
- COUNTER_FP2_C1,
- COUNTER_FP3_C0,
- COUNTER_FP3_C1,
-
- /*
- * If more hardware counters are added, the _mali_osk_hw_counter_table
- * below should also be updated.
- */
-
- /* EGL software counters */
- COUNTER_EGL_BLIT_TIME,
-
- /* GLES software counters */
- COUNTER_GLES_DRAW_ELEMENTS_CALLS,
- COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
- COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
- COUNTER_GLES_DRAW_ARRAYS_CALLS,
- COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
- COUNTER_GLES_DRAW_POINTS,
- COUNTER_GLES_DRAW_LINES,
- COUNTER_GLES_DRAW_LINE_LOOP,
- COUNTER_GLES_DRAW_LINE_STRIP,
- COUNTER_GLES_DRAW_TRIANGLES,
- COUNTER_GLES_DRAW_TRIANGLE_STRIP,
- COUNTER_GLES_DRAW_TRIANGLE_FAN,
- COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
- COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
- COUNTER_GLES_UPLOAD_TEXTURE_TIME,
- COUNTER_GLES_UPLOAD_VBO_TIME,
- COUNTER_GLES_NUM_FLUSHES,
- COUNTER_GLES_NUM_VSHADERS_GENERATED,
- COUNTER_GLES_NUM_FSHADERS_GENERATED,
- COUNTER_GLES_VSHADER_GEN_TIME,
- COUNTER_GLES_FSHADER_GEN_TIME,
- COUNTER_GLES_INPUT_TRIANGLES,
- COUNTER_GLES_VXCACHE_HIT,
- COUNTER_GLES_VXCACHE_MISS,
- COUNTER_GLES_VXCACHE_COLLISION,
- COUNTER_GLES_CULLED_TRIANGLES,
- COUNTER_GLES_CULLED_LINES,
- COUNTER_GLES_BACKFACE_TRIANGLES,
- COUNTER_GLES_GBCLIP_TRIANGLES,
- COUNTER_GLES_GBCLIP_LINES,
- COUNTER_GLES_TRIANGLES_DRAWN,
- COUNTER_GLES_DRAWCALL_TIME,
- COUNTER_GLES_TRIANGLES_COUNT,
- COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
- COUNTER_GLES_STRIP_TRIANGLES_COUNT,
- COUNTER_GLES_FAN_TRIANGLES_COUNT,
- COUNTER_GLES_LINES_COUNT,
- COUNTER_GLES_INDEPENDENT_LINES_COUNT,
- COUNTER_GLES_STRIP_LINES_COUNT,
- COUNTER_GLES_LOOP_LINES_COUNT,
-
- /* Framebuffer capture pseudo-counter */
- COUNTER_FILMSTRIP,
-
- NUMBER_OF_EVENTS
-} _mali_osk_counter_id;
-
-#define FIRST_ACTIVITY_EVENT ACTIVITY_VP
-#define LAST_ACTIVITY_EVENT ACTIVITY_FP3
-
-#define FIRST_HW_COUNTER COUNTER_L2_C0
-#define LAST_HW_COUNTER COUNTER_FP3_C1
-
-#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME
-#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT
-
-#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP
-#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP
-
-#endif /* __MALI_OSK_SPECIFIC_H__ */
diff --git a/drivers/media/video/samsung/mali/platform/default/mali_platform.c b/drivers/media/video/samsung/mali/platform/default/mali_platform.c
deleted file mode 100644
index d966f25..0000000
--- a/drivers/media/video/samsung/mali/platform/default/mali_platform.c
+++ /dev/null
@@ -1,43 +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.
- */
-
-/**
- * @file mali_platform.c
- * Platform specific Mali driver functions for a default platform
- */
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-
-_mali_osk_errcode_t mali_platform_init(void)
-{
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_deinit(void)
-{
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
-{
- MALI_SUCCESS;
-}
-
-void mali_gpu_utilization_handler(u32 utilization)
-{
-}
-
-void set_mali_parent_power_domain(void* dev)
-{
-}
-
-
diff --git a/drivers/media/video/samsung/mali/platform/mali_platform.h b/drivers/media/video/samsung/mali/platform/mali_platform.h
deleted file mode 100644
index 888f57a..0000000
--- a/drivers/media/video/samsung/mali/platform/mali_platform.h
+++ /dev/null
@@ -1,153 +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.
- */
-
-/**
- * @file mali_platform.h
- * Platform specific Mali driver functions
- */
-
-#ifndef __MALI_PLATFORM_H__
-#define __MALI_PLATFORM_H__
-
-#include "mali_osk.h"
-
-#ifdef CONFIG_CPU_EXYNOS4210
-#define MALI_DVFS_STEPS 3
-#else
-#define MALI_DVFS_STEPS 5
-#endif
-
-/* @Enable or Disable Mali GPU Bottom Lock feature */
-#define MALI_GPU_BOTTOM_LOCK 1
-
-#define MALI_VOLTAGE_LOCK 1
-
-/* @Enable or Disable the CPU frequency lock when the GPU clock is 440 Mhz */
-#define CPUFREQ_LOCK_DURING_440 0
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @brief description of power change reasons
- */
-typedef enum mali_power_mode_tag
-{
- MALI_POWER_MODE_ON, /**< Power Mali on */
- MALI_POWER_MODE_LIGHT_SLEEP, /**< Mali has been idle for a short time, or runtime PM suspend */
- MALI_POWER_MODE_DEEP_SLEEP, /**< Mali has been idle for a long time, or OS suspend */
-} mali_power_mode;
-
-/** @brief Platform specific setup and initialisation of MALI
- *
- * This is called from the entrypoint of the driver to initialize the platform
- *
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_platform_init(void);
-
-/** @brief Platform specific deinitialisation of MALI
- *
- * This is called on the exit of the driver to terminate the platform
- *
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_platform_deinit(void);
-
-/** @brief Platform specific powerdown sequence of MALI
- *
- * Notification from the Mali device driver stating the new desired power mode.
- * MALI_POWER_MODE_ON must be obeyed, while the other modes are optional.
- * @param power_mode defines the power modes
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode);
-
-
-/** @brief Platform specific handling of GPU utilization data
- *
- * When GPU utilization data is enabled, this function will be
- * periodically called.
- *
- * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
- */
-void mali_gpu_utilization_handler(u32 utilization);
-
-/** @brief Setting the power domain of MALI
- *
- * This function sets the power domain of MALI if Linux run time power management is enabled
- *
- * @param dev Reference to struct platform_device (defined in linux) used by MALI GPU
- */
-//void set_mali_parent_power_domain(void* dev);
-void mali_utilization_suspend(void);
-
-#ifdef CONFIG_REGULATOR
-int mali_regulator_get_usecount(void);
-void mali_regulator_disable(void);
-void mali_regulator_enable(void);
-void mali_regulator_set_voltage(int min_uV, int max_uV);
-#endif
-mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz);
-unsigned long mali_clk_get_rate(void);
-void mali_clk_put(mali_bool binc_mali_clk);
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-_mali_osk_errcode_t mali_platform_powerdown(u32 cores);
-_mali_osk_errcode_t mali_platform_powerup(u32 cores);
-#endif
-
-
-#if USING_MALI_PMM
-#if MALI_POWER_MGMT_TEST_SUITE
-/** @brief function to get status of individual cores
- *
- * This function is used by power management test suite to get the status of powered up/down the number
- * of cores
- * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
- */
-u32 pmu_get_power_up_down_info(void);
-#endif
-#endif
-
-#if MALI_DVFS_ENABLED
-mali_bool init_mali_dvfs_status(int step);
-void deinit_mali_dvfs_status(void);
-mali_bool mali_dvfs_handler(u32 utilization);
-int mali_dvfs_is_running(void);
-void mali_dvfs_late_resume(void);
-int get_mali_dvfs_control_status(void);
-mali_bool set_mali_dvfs_current_step(unsigned int step);
-void mali_default_step_set(int step, mali_bool boostup);
-int change_dvfs_tableset(int change_clk, int change_step);
-#ifdef CONFIG_CPU_EXYNOS4210
-#if MALI_GPU_BOTTOM_LOCK
-int mali_dvfs_bottom_lock_push(void);
-int mali_dvfs_bottom_lock_pop(void);
-#endif
-#else
-int mali_dvfs_bottom_lock_push(int lock_step);
-int mali_dvfs_bottom_lock_pop(void);
-#endif
-#endif
-
-int mali_dvfs_get_vol(int step);
-
-#if MALI_VOLTAGE_LOCK
-int mali_voltage_lock_push(int lock_vol);
-int mali_voltage_lock_pop(void);
-int mali_voltage_lock_init(void);
-int mali_vol_get_from_table(int vol);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c
deleted file mode 100644
index cb95dc6..0000000
--- a/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c
+++ /dev/null
@@ -1,66 +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.
- */
-
-/**
- * @file mali_platform.c
- * Platform specific Mali driver functions for a default platform
- */
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-#include "mali_pmu.h"
-#include "linux/mali/mali_utgard.h"
-
-static u32 bPowerOff = 1;
-
-_mali_osk_errcode_t mali_platform_init(void)
-{
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_deinit(void)
-{
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
-{
- switch (power_mode)
- {
- case MALI_POWER_MODE_ON:
- if (bPowerOff == 1)
- {
- mali_pmu_powerup();
- bPowerOff = 0;
- }
- break;
- case MALI_POWER_MODE_LIGHT_SLEEP:
- case MALI_POWER_MODE_DEEP_SLEEP:
-
- if (bPowerOff == 0)
- {
- mali_pmu_powerdown();
- bPowerOff = 1;
- }
-
- break;
- }
- MALI_SUCCESS;
-}
-
-void mali_gpu_utilization_handler(u32 utilization)
-{
-}
-
-void set_mali_parent_power_domain(void* dev)
-{
-}
-
-
diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
deleted file mode 100644
index 119831d..0000000
--- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
+++ /dev/null
@@ -1,656 +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.
- */
-
-/**
- * @file mali_platform.c
- * Platform specific Mali driver functions for a default platform
- */
-#include <linux/version.h>
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-#include "mali_linux_pm.h"
-
-#if USING_MALI_PMM
-#include "mali_pm.h"
-#endif
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#include <plat/pd.h>
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-
-#include <asm/io.h>
-#include <mach/regs-pmu.h>
-
-#define EXTXTALCLK_NAME "ext_xtal"
-#define VPLLSRCCLK_NAME "vpll_src"
-#define FOUTVPLLCLK_NAME "fout_vpll"
-#define SCLVPLLCLK_NAME "sclk_vpll"
-#define GPUMOUT1CLK_NAME "mout_g3d1"
-
-#define MPLLCLK_NAME "mout_mpll"
-#define GPUMOUT0CLK_NAME "mout_g3d0"
-#define GPUCLK_NAME "sclk_g3d"
-#define CLK_DIV_STAT_G3D 0x1003C62C
-#define CLK_DESC "clk-divider-status"
-
-static struct clk *ext_xtal_clock = 0;
-static struct clk *vpll_src_clock = 0;
-static struct clk *fout_vpll_clock = 0;
-static struct clk *sclk_vpll_clock = 0;
-
-static struct clk *mpll_clock = 0;
-static struct clk *mali_parent_clock = 0;
-static struct clk *mali_clock = 0;
-
-int mali_gpu_clk = 160;
-static unsigned int GPU_MHZ = 1000000;
-#ifdef CONFIG_S5PV310_ASV
-int mali_gpu_vol = 1100000; /* 1.10V for ASV */
-#else
-int mali_gpu_vol = 1100000; /* 1.10V */
-#endif
-
-#if MALI_DVFS_ENABLED
-#define MALI_DVFS_DEFAULT_STEP 0 // 134Mhz default
-#endif
-
-int gpu_power_state;
-static int bPoweroff;
-
-#ifdef CONFIG_REGULATOR
-struct regulator {
- struct device *dev;
- struct list_head list;
- int uA_load;
- int min_uV;
- int max_uV;
- char *supply_name;
- struct device_attribute dev_attr;
- struct regulator_dev *rdev;
-};
-
-struct regulator *g3d_regulator=NULL;
-#endif
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
-extern struct platform_device s5pv310_device_pd[];
-#else
-extern struct platform_device exynos4_device_pd[];
-#endif
-#endif
-
-mali_io_address clk_register_map=0;
-
-#if MALI_GPU_BOTTOM_LOCK
-_mali_osk_lock_t *mali_dvfs_lock;
-#else
-static _mali_osk_lock_t *mali_dvfs_lock;
-#endif
-
-#ifdef CONFIG_REGULATOR
-int mali_regulator_get_usecount(void)
-{
- struct regulator_dev *rdev;
-
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_get_usecount : g3d_regulator is null\n"));
- return 0;
- }
- rdev = g3d_regulator->rdev;
- return rdev->use_count;
-}
-
-void mali_regulator_disable(void)
-{
- bPoweroff = 1;
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
- return;
- }
- regulator_disable(g3d_regulator);
- MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount()));
-}
-
-void mali_regulator_enable(void)
-{
- bPoweroff = 0;
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
- return;
- }
- regulator_enable(g3d_regulator);
- MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount()));
-}
-
-void mali_regulator_set_voltage(int min_uV, int max_uV)
-{
- int voltage;
-
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
- return;
- }
- MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS,
- min_uV, max_uV, 0, 0, 0);
-#endif
-
- regulator_set_voltage(g3d_regulator,min_uV,max_uV);
- voltage = regulator_get_voltage(g3d_regulator);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS,
- voltage, 0, 1, 0, 0);
-#endif
- mali_gpu_vol = voltage;
- MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol));
-
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-}
-#endif
-
-unsigned long mali_clk_get_rate(void)
-{
- return clk_get_rate(mali_clock);
-}
-
-mali_bool mali_clk_get(mali_bool bis_vpll)
-{
- if (bis_vpll == MALI_TRUE)
- {
- if (ext_xtal_clock == NULL)
- {
- ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
- if (IS_ERR(ext_xtal_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (vpll_src_clock == NULL)
- {
- vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
- if (IS_ERR(vpll_src_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (fout_vpll_clock == NULL)
- {
- fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
- if (IS_ERR(fout_vpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (sclk_vpll_clock == NULL)
- {
- sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
- if (IS_ERR(sclk_vpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_parent_clock == NULL)
- {
- mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
-
- if (IS_ERR(mali_parent_clock)) {
- MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
- return MALI_FALSE;
- }
- }
- }
- else // mpll
- {
- if (mpll_clock == NULL)
- {
- mpll_clock = clk_get(NULL,MPLLCLK_NAME);
-
- if (IS_ERR(mpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_parent_clock == NULL)
- {
- mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
-
- if (IS_ERR(mali_parent_clock)) {
- MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
- return MALI_FALSE;
- }
- }
- }
-
- // mali clock get always.
- if (mali_clock == NULL)
- {
- mali_clock = clk_get(NULL, GPUCLK_NAME);
-
- if (IS_ERR(mali_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
- return MALI_FALSE;
- }
- }
-
- return MALI_TRUE;
-}
-
-void mali_clk_put(mali_bool binc_mali_clock)
-{
- if (mali_parent_clock)
- {
- clk_put(mali_parent_clock);
- mali_parent_clock = 0;
- }
-
- if (mpll_clock)
- {
- clk_put(mpll_clock);
- mpll_clock = 0;
- }
-
- if (sclk_vpll_clock)
- {
- clk_put(sclk_vpll_clock);
- sclk_vpll_clock = 0;
- }
-
- if (fout_vpll_clock)
- {
- clk_put(fout_vpll_clock);
- fout_vpll_clock = 0;
- }
-
- if (vpll_src_clock)
- {
- clk_put(vpll_src_clock);
- vpll_src_clock = 0;
- }
-
- if (ext_xtal_clock)
- {
- clk_put(ext_xtal_clock);
- ext_xtal_clock = 0;
- }
-
- if (binc_mali_clock == MALI_TRUE && mali_clock)
- {
- clk_put(mali_clock);
- mali_clock = 0;
- }
-
-}
-
-
-mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz)
-{
- unsigned long rate = 0;
- mali_bool bis_vpll = MALI_FALSE;
-
-#ifdef CONFIG_VPLL_USE_FOR_TVENC
- bis_vpll = MALI_TRUE;
-#endif
-
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
- if (mali_clk_get(bis_vpll) == MALI_FALSE)
- return MALI_FALSE;
-
- rate = (unsigned long)clk * (unsigned long)mhz;
- MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz ));
-
- if (bis_vpll)
- {
- clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ);
- clk_set_parent(vpll_src_clock, ext_xtal_clock);
- clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
-
- clk_set_parent(mali_parent_clock, sclk_vpll_clock);
- clk_set_parent(mali_clock, mali_parent_clock);
- }
- else
- {
- clk_set_parent(mali_parent_clock, mpll_clock);
- clk_set_parent(mali_clock, mali_parent_clock);
- }
-
- if (clk_enable(mali_clock) < 0)
- return MALI_FALSE;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ,
- rate, 0, 0, 0, 0);
-#endif
-
- clk_set_rate(mali_clock, rate);
- rate = clk_get_rate(mali_clock);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ,
- rate, 0, 0, 0, 0);
-#endif
-
- if (bis_vpll)
- mali_gpu_clk = (int)(rate / mhz);
- else
- mali_gpu_clk = (int)((rate + 500000) / mhz);
-
- GPU_MHZ = mhz;
- MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk));
-
- mali_clk_put(MALI_FALSE);
-
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
- return MALI_TRUE;
-}
-
-static mali_bool init_mali_clock(void)
-{
- mali_bool ret = MALI_TRUE;
-
- gpu_power_state = 0;
-
- if (mali_clock != 0)
- return ret; // already initialized
-
- mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
- | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
- if (mali_dvfs_lock == NULL)
- return _MALI_OSK_ERR_FAULT;
-
- if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE)
- {
- ret = MALI_FALSE;
- goto err_clock_get;
- }
-
- MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock));
-
-
-#ifdef CONFIG_REGULATOR
-#if USING_MALI_PMM
- g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d");
-#else
- g3d_regulator = regulator_get(NULL, "vdd_g3d");
-#endif
-
- if (IS_ERR(g3d_regulator))
- {
- MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
- ret = MALI_FALSE;
- goto err_regulator;
- }
-
- regulator_enable(g3d_regulator);
- MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount()));
- mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
-#endif
-
- MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n"));
- MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__));
- MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__));
-
- mali_clk_put(MALI_FALSE);
-
- return MALI_TRUE;
-
-
-#ifdef CONFIG_REGULATOR
-err_regulator:
- regulator_put(g3d_regulator);
-#endif
-
-err_clock_get:
- mali_clk_put(MALI_TRUE);
-
- return ret;
-}
-
-static mali_bool deinit_mali_clock(void)
-{
- if (mali_clock == 0)
- return MALI_TRUE;
-
-#ifdef CONFIG_REGULATOR
- if (g3d_regulator)
- {
- regulator_put(g3d_regulator);
- g3d_regulator=NULL;
- }
-#endif
-
- mali_clk_put(MALI_TRUE);
-
- return MALI_TRUE;
-}
-
-
-static _mali_osk_errcode_t enable_mali_clocks(void)
-{
- int err;
- err = clk_enable(mali_clock);
- MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
-
- // set clock rate
- mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t disable_mali_clocks(void)
-{
- clk_disable(mali_clock);
- MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
-
- MALI_SUCCESS;
-}
-
-void set_mali_parent_power_domain(struct platform_device* dev)
-{
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
- dev->dev.parent = &s5pv310_device_pd[PD_G3D].dev;
-#else
- dev->dev.parent = &exynos4_device_pd[PD_G3D].dev;
-#endif
-
-#endif
-}
-
-_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
-{
- if (bpower_on)
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT(3,("_mali_osk_pm_dev_activate \n"));
- _mali_osk_pm_dev_activate();
-#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- void __iomem *status;
- u32 timeout;
- __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_PMU_G3D_CONF);
- status = S5P_PMU_G3D_CONF + 0x4;
-
- timeout = 10;
- while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
- != S5P_INT_LOCAL_PWR_EN) {
- if (timeout == 0) {
- MALI_PRINTF(("Power domain enable failed.\n"));
- return -ETIMEDOUT;
- }
- timeout--;
- _mali_osk_time_ubusydelay(100);
- }
-#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- }
- else
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT( 4,("_mali_osk_pm_dev_idle\n"));
- _mali_osk_pm_dev_idle();
-
-#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- void __iomem *status;
- u32 timeout;
- __raw_writel(0, S5P_PMU_G3D_CONF);
-
- status = S5P_PMU_G3D_CONF + 0x4;
- /* Wait max 1ms */
- timeout = 10;
- while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
- {
- if (timeout == 0) {
- MALI_PRINTF(("Power domain disable failed.\n" ));
- return -ETIMEDOUT;
- }
- timeout--;
- _mali_osk_time_ubusydelay( 100);
- }
-#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_init()
-{
- MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
-#if MALI_DVFS_ENABLED
- if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
- if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP))
- MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
-#endif
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_deinit()
-{
- deinit_mali_clock();
-
-#if MALI_DVFS_ENABLED
- deinit_mali_dvfs_status();
- if (clk_register_map )
- {
- _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
- clk_register_map=0;
- }
-#endif
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_powerdown(u32 cores)
-{
- MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores));
-
- if (gpu_power_state != 0) // power down after state is 0
- {
- gpu_power_state = gpu_power_state & (~cores);
- if (gpu_power_state == 0)
- {
- MALI_DEBUG_PRINT( 3,("disable clock\n"));
- disable_mali_clocks();
- }
- }
- else
- {
- MALI_PRINT(("mali_platform_powerdown gpu_power_state == 0 and cores %x \n", cores));
- }
-
- bPoweroff=1;
-
-
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_powerup(u32 cores)
-{
- MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores));
-
- if (gpu_power_state == 0) // power up only before state is 0
- {
- gpu_power_state = gpu_power_state | cores;
-
- if (gpu_power_state != 0)
- {
- MALI_DEBUG_PRINT(4,("enable clock \n"));
- enable_mali_clocks();
- }
- }
- else
- {
- gpu_power_state = gpu_power_state | cores;
- }
-
- bPoweroff=0;
-
-
- MALI_SUCCESS;
-}
-
-void mali_gpu_utilization_handler(u32 utilization)
-{
- if (bPoweroff==0)
- {
-#if MALI_DVFS_ENABLED
- if(!mali_dvfs_handler(utilization))
- MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
-#endif
- }
-}
-
-#if MALI_POWER_MGMT_TEST_SUITE
-u32 pmu_get_power_up_down_info(void)
-{
- return 4095;
-}
-
-#endif
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
-{
- MALI_SUCCESS;
-}
-
diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c
deleted file mode 100644
index 4efa759..0000000
--- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c
+++ /dev/null
@@ -1,448 +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.
- */
-
-/**
- * @file mali_platform_dvfs.c
- * Platform specific Mali driver dvfs functions
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-
-#include <asm/io.h>
-
-#ifdef CONFIG_CPU_FREQ
-#include <mach/asv.h>
-#include <mach/regs-pmu.h>
-#define EXYNOS4_ASV_ENABLED
-#endif
-
-#include "mali_device_pause_resume.h"
-#include <linux/workqueue.h>
-
-#define MALI_DVFS_WATING 10 // msec
-
-static int bMaliDvfsRun=0;
-
-#if MALI_GPU_BOTTOM_LOCK
-static _mali_osk_atomic_t bottomlock_status;
-#endif
-
-typedef struct mali_dvfs_tableTag{
- unsigned int clock;
- unsigned int freq;
- unsigned int vol;
-}mali_dvfs_table;
-
-typedef struct mali_dvfs_statusTag{
- unsigned int currentStep;
- mali_dvfs_table * pCurrentDvfs;
-
-}mali_dvfs_currentstatus;
-
-typedef struct mali_dvfs_thresholdTag{
- unsigned int downthreshold;
- unsigned int upthreshold;
-}mali_dvfs_threshold_table;
-
-typedef struct mali_dvfs_staycount{
- unsigned int staycount;
-}mali_dvfs_staycount_table;
-
-mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={
- /*step 0*/{1},
- /*step 1*/{1},
- /*step 2*/{1} };
-
-/*dvfs threshold*/
-mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
- /*step 0*/{((int)((255*0)/100)) ,((int)((255*85)/100))},
- /*step 1*/{((int)((255*75)/100)) ,((int)((255*85)/100))},
- /*step 2*/{((int)((255*75)/100)) ,((int)((255*100)/100))} };
-
-/*dvfs status*/
-mali_dvfs_currentstatus maliDvfsStatus;
-int mali_dvfs_control=0;
-
-/*dvfs table*/
-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
-#ifdef CONFIG_EXYNOS4210_1400MHZ_SUPPORT
- /*step 0*/{134 ,1000000 , 950000},
-#else
- /*step 0*/{100 ,1000000 , 950000},
-#endif
- /*step 1*/{160 ,1000000 , 950000},
- /*step 2*/{267 ,1000000 ,1000000} };
-
-#ifdef EXYNOS4_ASV_ENABLED
-
-#define ASV_8_LEVEL 8
-#define ASV_5_LEVEL 5
-
-static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = {
- /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */
- {1000000, 1000000, 1100000}, /* S */
- {1000000, 1000000, 1100000}, /* A */
- { 950000, 950000, 1000000}, /* B */
- { 950000, 950000, 1000000}, /* C */
- { 950000, 950000, 950000}, /* D */
-};
-
-static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = {
- /* L3 (100/134MHz) L2(160MHz), L1(267MHz) */
- {1000000, 1000000, 1100000}, /* SS */
- {1000000, 1000000, 1100000}, /* A1 */
- {1000000, 1000000, 1100000}, /* A2 */
- { 950000, 950000, 1000000}, /* B1 */
- { 950000, 950000, 1000000}, /* B2 */
- { 950000, 950000, 1000000}, /* C1 */
- { 950000, 950000, 1000000}, /* C2 */
- { 950000, 950000, 950000}, /* D1 */
-};
-#endif
-
-static u32 mali_dvfs_utilization = 255;
-
-static void mali_dvfs_work_handler(struct work_struct *w);
-
-static struct workqueue_struct *mali_dvfs_wq = 0;
-extern mali_io_address clk_register_map;
-
-#if MALI_GPU_BOTTOM_LOCK
-extern _mali_osk_lock_t *mali_dvfs_lock;
-#endif
-
-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
-
-static unsigned int get_mali_dvfs_status(void)
-{
- return maliDvfsStatus.currentStep;
-}
-
-#if MALI_GPU_BOTTOM_LOCK
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-int get_mali_dvfs_control_status(void)
-{
- return mali_dvfs_control;
-}
-
-mali_bool set_mali_dvfs_current_step(unsigned int step)
-{
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- maliDvfsStatus.currentStep = step;
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- return MALI_TRUE;
-}
-#endif
-#endif
-
-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
-{
- u32 validatedStep=step;
-
-#ifdef CONFIG_REGULATOR
- if (mali_regulator_get_usecount()==0) {
- MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n"));
- return MALI_FALSE;
- }
-#endif
-
- if (boostup) {
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
- } else {
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
- }
-
- maliDvfsStatus.currentStep = validatedStep;
- /*for future use*/
- maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
-
- return MALI_TRUE;
-}
-
-static void mali_platform_wating(u32 msec)
-{
- /*sample wating
- change this in the future with proper check routine.
- */
- unsigned int read_val;
- while(1) {
- read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
- if ((read_val & 0x8000)==0x0000) break;
-
- _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218
- }
- /* _mali_osk_time_ubusydelay(msec*1000);*/
-}
-
-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
-{
-
- MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
-
- if (!set_mali_dvfs_status(step, boostup)) {
- MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
- return MALI_FALSE;
- }
-
- /*wait until clock and voltage is stablized*/
- mali_platform_wating(MALI_DVFS_WATING); /*msec*/
-
- return MALI_TRUE;
-}
-
-static unsigned int decideNextStatus(unsigned int utilization)
-{
- unsigned int level=0; // 0:stay, 1:up
-
- if (!mali_dvfs_control) {
-#if MALI_GPU_BOTTOM_LOCK
- if (_mali_osk_atomic_read(&bottomlock_status) > 0)
- level = 1; /* or bigger */
- else
-#endif
- switch(maliDvfsStatus.currentStep)
- {
- case 0:
- if( utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold)
- level=1;
- else
- level = maliDvfsStatus.currentStep;
- break;
- case 1:
- if( utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold)
- level=2;
- else if( utilization <
- (mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold*mali_dvfs[maliDvfsStatus.currentStep-1].clock)/
- mali_dvfs[maliDvfsStatus.currentStep].clock)
- level=0;
- else
- level = maliDvfsStatus.currentStep;
- break;
- case 2:
- if( utilization <
- (mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold*mali_dvfs[maliDvfsStatus.currentStep-1].clock)/
- mali_dvfs[maliDvfsStatus.currentStep].clock)
- level=1;
- else
- level = maliDvfsStatus.currentStep;
- break;
- }
- }
- else
- {
- if((mali_dvfs_control == 1)||(( mali_dvfs_control > 3) && (mali_dvfs_control < mali_dvfs[0].clock+1)))
- {
- level=0;
- }
- else if((mali_dvfs_control == 2)||(( mali_dvfs_control > mali_dvfs[0].clock) && (mali_dvfs_control < mali_dvfs[1].clock+1)))
- {
- level=1;
- }
- else
- {
- level=2;
- }
- }
-
- return level;
-}
-
-#ifdef EXYNOS4_ASV_ENABLED
-static mali_bool mali_dvfs_table_update(void)
-{
- unsigned int exynos_result_of_asv_group;
- unsigned int target_asv;
- unsigned int i;
- exynos_result_of_asv_group = exynos_result_of_asv & 0xf;
- target_asv = exynos_result_of_asv >> 28;
- MALI_PRINT(("exynos_result_of_asv_group = 0x%x, target_asv = 0x%x\n", exynos_result_of_asv_group, target_asv));
-
- if (target_asv == 0x8) { //SUPPORT_1400MHZ
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs[i].vol = asv_3d_volt_5_table[exynos_result_of_asv_group][i];
- MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol));
- }
- } else if (target_asv == 0x4){ //SUPPORT_1200MHZ
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs[i].vol = asv_3d_volt_8_table[exynos_result_of_asv_group][i];
- MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol));
- }
- }
-
- return MALI_TRUE;
-
-}
-#endif
-
-static mali_bool mali_dvfs_status(u32 utilization)
-{
- unsigned int nextStatus = 0;
- unsigned int curStatus = 0;
- mali_bool boostup = MALI_FALSE;
-#ifdef EXYNOS4_ASV_ENABLED
- static mali_bool asv_applied = MALI_FALSE;
-#endif
- static int stay_count = 0; // to prevent frequent switch
-
- MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization));
-#ifdef EXYNOS4_ASV_ENABLED
- if (asv_applied == MALI_FALSE) {
- mali_dvfs_table_update();
- change_mali_dvfs_status(0,0);
- asv_applied = MALI_TRUE;
-
- return MALI_TRUE;
- }
-#endif
-
- /*decide next step*/
- curStatus = get_mali_dvfs_status();
- nextStatus = decideNextStatus(utilization);
-
- MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
-
- /*if next status is same with current status, don't change anything*/
- if ((curStatus!=nextStatus && stay_count==0)) {
- /*check if boost up or not*/
- if (nextStatus > maliDvfsStatus.currentStep)
- boostup = 1;
-
- /*change mali dvfs status*/
- if (!change_mali_dvfs_status(nextStatus,boostup)) {
- MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
- return MALI_FALSE;
- }
- stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount;
- } else {
- if (stay_count>0)
- stay_count--;
- }
-
- return MALI_TRUE;
-}
-
-
-
-int mali_dvfs_is_running(void)
-{
- return bMaliDvfsRun;
-}
-
-
-
-void mali_dvfs_late_resume(void)
-{
- // set the init clock as low when resume
- set_mali_dvfs_status(0,0);
-}
-
-
-static void mali_dvfs_work_handler(struct work_struct *w)
-{
- bMaliDvfsRun=1;
-
- MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
-
- if (!mali_dvfs_status(mali_dvfs_utilization))
- MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
-
- bMaliDvfsRun=0;
-}
-
-
-mali_bool init_mali_dvfs_status(int step)
-{
- /*default status
- add here with the right function to get initilization value.
- */
- if (!mali_dvfs_wq)
- mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
-
-#if MALI_GPU_BOTTOM_LOCK
- _mali_osk_atomic_init(&bottomlock_status, 0);
-#endif
-
- /*add a error handling here*/
- maliDvfsStatus.currentStep = step;
-
- return MALI_TRUE;
-}
-
-void deinit_mali_dvfs_status(void)
-{
-#if MALI_GPU_BOTTOM_LOCK
- _mali_osk_atomic_term(&bottomlock_status);
-#endif
-
- if (mali_dvfs_wq)
- destroy_workqueue(mali_dvfs_wq);
- mali_dvfs_wq = NULL;
-}
-
-mali_bool mali_dvfs_handler(u32 utilization)
-{
- mali_dvfs_utilization = utilization;
- queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work);
-
- /*add error handle here*/
- return MALI_TRUE;
-}
-
-void mali_default_step_set(int step, mali_bool boostup)
-{
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-
- if (maliDvfsStatus.currentStep == 1)
- set_mali_dvfs_status(step, boostup);
-}
-
-#if MALI_GPU_BOTTOM_LOCK
-int mali_dvfs_bottom_lock_push(void)
-{
- int prev_status = _mali_osk_atomic_read(&bottomlock_status);
-
- if (prev_status < 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for push"));
- return -1;
- }
-
- if (prev_status == 0) {
- mali_regulator_set_voltage(mali_dvfs[1].vol, mali_dvfs[1].vol);
- mali_clk_set_rate(mali_dvfs[1].clock, mali_dvfs[1].freq);
- set_mali_dvfs_current_step(1);
- }
-
- return _mali_osk_atomic_inc_return(&bottomlock_status);
-}
-
-int mali_dvfs_bottom_lock_pop(void)
-{
- if (_mali_osk_atomic_read(&bottomlock_status) <= 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for pop"));
- return -1;
- }
-
- return _mali_osk_atomic_dec_return(&bottomlock_status);
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
deleted file mode 100644
index a08bc97..0000000
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
+++ /dev/null
@@ -1,801 +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.
- */
-
-/**
- * @file mali_platform.c
- * Platform specific Mali driver functions for a default platform
- */
-#include <linux/version.h>
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-#include "mali_linux_pm.h"
-
-#if USING_MALI_PMM
-#include "mali_pm.h"
-#endif
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#include <plat/pd.h>
-#endif
-
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
-#include "mali_osk_profiling.h"
-unsigned long gFreq = 366;
-int gVolt = 5000;
-#endif
-
-#include <asm/io.h>
-#include <mach/regs-pmu.h>
-
-#define EXTXTALCLK_NAME "ext_xtal"
-#define VPLLSRCCLK_NAME "vpll_src"
-#define FOUTVPLLCLK_NAME "fout_vpll"
-#define SCLVPLLCLK_NAME "sclk_vpll"
-#define GPUMOUT1CLK_NAME "mout_g3d1"
-
-#define MPLLCLK_NAME "mout_mpll"
-#define GPUMOUT0CLK_NAME "mout_g3d0"
-#define GPUCLK_NAME "sclk_g3d"
-#define CLK_DIV_STAT_G3D 0x1003C62C
-#define CLK_DESC "clk-divider-status"
-
-#define MALI_BOTTOMLOCK_VOL 900000
-
-typedef struct mali_runtime_resumeTag{
- int clk;
- int vol;
-}mali_runtime_resume_table;
-
-mali_runtime_resume_table mali_runtime_resume = {266, 900000};
-
-/* lock/unlock CPU freq by Mali */
-extern int cpufreq_lock_by_mali(unsigned int freq);
-extern void cpufreq_unlock_by_mali(void);
-
-/* start of modification by skkim */
-extern mali_bool init_mali_dvfs_status(int step);
-extern void deinit_mali_dvfs_status(void);
-extern mali_bool mali_dvfs_handler(u32 utilization);
-extern int get_mali_dvfs_control_status(void);
-extern mali_bool set_mali_dvfs_current_step(unsigned int step);
-/* end of modification by skkim */
-
-static struct clk *ext_xtal_clock = 0;
-static struct clk *vpll_src_clock = 0;
-static struct clk *fout_vpll_clock = 0;
-static struct clk *sclk_vpll_clock = 0;
-
-static struct clk *mpll_clock = 0;
-static struct clk *mali_parent_clock = 0;
-static struct clk *mali_clock = 0;
-
-
-static unsigned int GPU_MHZ = 1000000;
-
-int mali_gpu_clk = 266;
-int mali_gpu_vol = 900000;
-
-#if MALI_DVFS_ENABLED
-#define MALI_DVFS_DEFAULT_STEP 1
-#endif
-#if MALI_VOLTAGE_LOCK
-int mali_lock_vol = 0;
-static _mali_osk_atomic_t voltage_lock_status;
-static mali_bool mali_vol_lock_flag = 0;
-#endif
-
-int gpu_power_state;
-static int bPoweroff;
-
-#ifdef CONFIG_REGULATOR
-struct regulator {
- struct device *dev;
- struct list_head list;
- int uA_load;
- int min_uV;
- int max_uV;
- char *supply_name;
- struct device_attribute dev_attr;
- struct regulator_dev *rdev;
-};
-
-struct regulator *g3d_regulator=NULL;
-#endif
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
-extern struct platform_device s5pv310_device_pd[];
-#else
-extern struct platform_device exynos4_device_pd[];
-#endif
-#endif
-
-mali_io_address clk_register_map=0;
-
-_mali_osk_lock_t *mali_dvfs_lock = 0;
-
-#ifdef CONFIG_REGULATOR
-int mali_regulator_get_usecount(void)
-{
- struct regulator_dev *rdev;
-
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_get_usecount : g3d_regulator is null\n"));
- return 0;
- }
- rdev = g3d_regulator->rdev;
- return rdev->use_count;
-}
-
-void mali_regulator_disable(void)
-{
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
- return;
- }
- regulator_disable(g3d_regulator);
- MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount()));
- bPoweroff = 1;
-}
-
-void mali_regulator_enable(void)
-{
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
- return;
- }
- regulator_enable(g3d_regulator);
- MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount()));
- bPoweroff = 0;
-}
-
-void mali_regulator_set_voltage(int min_uV, int max_uV)
-{
- int voltage;
-#if !MALI_DVFS_ENABLED
- min_uV = mali_gpu_vol;
- max_uV = mali_gpu_vol;
-#endif
-#if MALI_VOLTAGE_LOCK
- if (mali_vol_lock_flag == MALI_FALSE) {
- if (min_uV < MALI_BOTTOMLOCK_VOL || max_uV < MALI_BOTTOMLOCK_VOL) {
- min_uV = MALI_BOTTOMLOCK_VOL;
- max_uV = MALI_BOTTOMLOCK_VOL;
- }
- } else if (_mali_osk_atomic_read(&voltage_lock_status) > 0 ) {
- if (min_uV < mali_lock_vol || max_uV < mali_lock_vol) {
-#if MALI_DVFS_ENABLED
- int mali_vol_get;
- mali_vol_get = mali_vol_get_from_table(mali_lock_vol);
- if (mali_vol_get) {
- min_uV = mali_vol_get;
- max_uV = mali_vol_get;
- }
-#else
- min_uV = mali_lock_vol;
- max_uV = mali_lock_vol;
-#endif
- }
- }
-#endif
-
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
- if( IS_ERR_OR_NULL(g3d_regulator) )
- {
- MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
- return;
- }
-
- MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
-
- regulator_set_voltage(g3d_regulator,min_uV,max_uV);
- voltage = regulator_get_voltage(g3d_regulator);
-
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- gVolt = voltage/1000;
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_GPU |
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, gFreq, gVolt,
- 0, 0, 0);
-#endif
-
- mali_gpu_vol = voltage;
- MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol));
-
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-}
-#endif
-
-unsigned long mali_clk_get_rate(void)
-{
- return clk_get_rate(mali_clock);
-}
-
-mali_bool mali_clk_get(mali_bool bis_vpll)
-{
- if (bis_vpll == MALI_TRUE)
- {
- if (ext_xtal_clock == NULL)
- {
- ext_xtal_clock = clk_get(NULL,EXTXTALCLK_NAME);
- if (IS_ERR(ext_xtal_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source ext_xtal_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (vpll_src_clock == NULL)
- {
- vpll_src_clock = clk_get(NULL,VPLLSRCCLK_NAME);
- if (IS_ERR(vpll_src_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source vpll_src_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (fout_vpll_clock == NULL)
- {
- fout_vpll_clock = clk_get(NULL,FOUTVPLLCLK_NAME);
- if (IS_ERR(fout_vpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source fout_vpll_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (sclk_vpll_clock == NULL)
- {
- sclk_vpll_clock = clk_get(NULL,SCLVPLLCLK_NAME);
- if (IS_ERR(sclk_vpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source sclk_vpll_clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_parent_clock == NULL)
- {
- mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
-
- if (IS_ERR(mali_parent_clock)) {
- MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
- return MALI_FALSE;
- }
- }
- }
- else // mpll
- {
- if (mpll_clock == NULL)
- {
- mpll_clock = clk_get(NULL,MPLLCLK_NAME);
-
- if (IS_ERR(mpll_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source mpll clock\n"));
- return MALI_FALSE;
- }
- }
-
- if (mali_parent_clock == NULL)
- {
- mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
-
- if (IS_ERR(mali_parent_clock)) {
- MALI_PRINT( ( "MALI Error : failed to get source mali parent clock\n"));
- return MALI_FALSE;
- }
- }
- }
-
- // mali clock get always.
- if (mali_clock == NULL)
- {
- mali_clock = clk_get(NULL, GPUCLK_NAME);
-
- if (IS_ERR(mali_clock)) {
- MALI_PRINT( ("MALI Error : failed to get source mali clock\n"));
- return MALI_FALSE;
- }
- }
-
- return MALI_TRUE;
-}
-
-void mali_clk_put(mali_bool binc_mali_clock)
-{
- if (mali_parent_clock)
- {
- clk_put(mali_parent_clock);
- mali_parent_clock = 0;
- }
-
- if (mpll_clock)
- {
- clk_put(mpll_clock);
- mpll_clock = 0;
- }
-
- if (sclk_vpll_clock)
- {
- clk_put(sclk_vpll_clock);
- sclk_vpll_clock = 0;
- }
-
- if (fout_vpll_clock)
- {
- clk_put(fout_vpll_clock);
- fout_vpll_clock = 0;
- }
-
- if (vpll_src_clock)
- {
- clk_put(vpll_src_clock);
- vpll_src_clock = 0;
- }
-
- if (ext_xtal_clock)
- {
- clk_put(ext_xtal_clock);
- ext_xtal_clock = 0;
- }
-
- if (binc_mali_clock == MALI_TRUE && mali_clock)
- {
- clk_put(mali_clock);
- mali_clock = 0;
- }
-
-}
-
-
-mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz)
-{
- unsigned long rate = 0;
- mali_bool bis_vpll = MALI_TRUE;
-
-#ifndef CONFIG_VPLL_USE_FOR_TVENC
- bis_vpll = MALI_TRUE;
-#endif
-
-#if !MALI_DVFS_ENABLED
- clk = mali_gpu_clk;
-#endif
- trace_printk("SPI_GPUFREQ_%uMHz\n", mali_gpu_clk);
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
- if (mali_clk_get(bis_vpll) == MALI_FALSE)
- return MALI_FALSE;
-
- rate = (unsigned long)clk * (unsigned long)mhz;
- MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz ));
-
- if (bis_vpll)
- {
- clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ);
- clk_set_parent(vpll_src_clock, ext_xtal_clock);
- clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
-
- clk_set_parent(mali_parent_clock, sclk_vpll_clock);
- clk_set_parent(mali_clock, mali_parent_clock);
- }
- else
- {
- clk_set_parent(mali_parent_clock, mpll_clock);
- clk_set_parent(mali_clock, mali_parent_clock);
- }
-
- if (clk_enable(mali_clock) < 0)
- return MALI_FALSE;
-
-
- clk_set_rate(mali_clock, rate);
- rate = clk_get_rate(mali_clock);
-
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- gFreq = rate/1000000;
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_GPU |
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
- gFreq, gVolt, 0, 0, 0);
-#endif
-
- if (bis_vpll)
- mali_gpu_clk = (int)(rate / mhz);
- else
- mali_gpu_clk = (int)((rate + 500000) / mhz);
-
- GPU_MHZ = mhz;
- MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk));
-
- mali_clk_put(MALI_FALSE);
-
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
-
- return MALI_TRUE;
-}
-
-static mali_bool init_mali_clock(void)
-{
- mali_bool ret = MALI_TRUE;
-
- if (mali_clock != 0)
- return ret; // already initialized
-
- mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
- | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
- if (mali_dvfs_lock == NULL)
- return _MALI_OSK_ERR_FAULT;
-
- if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE)
- {
- ret = MALI_FALSE;
- goto err_clock_get;
- }
-
- MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock));
-
-
-#ifdef CONFIG_REGULATOR
-#if USING_MALI_PMM
- g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d");
-#else
- g3d_regulator = regulator_get(NULL, "vdd_g3d");
-#endif
-
- if (IS_ERR(g3d_regulator))
- {
- MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n"));
- ret = MALI_FALSE;
- goto err_regulator;
- }
-
- regulator_enable(g3d_regulator);
-
- MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount()));
- mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
-#endif
-
- MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n"));
-
- MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__));
- MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__));
-
- mali_clk_put(MALI_FALSE);
-
- gpu_power_state=0;
- bPoweroff=1;
-
- return MALI_TRUE;
-#ifdef CONFIG_REGULATOR
-err_regulator:
- regulator_put(g3d_regulator);
-#endif
-
-err_clock_get:
- mali_clk_put(MALI_TRUE);
-
- return ret;
-}
-
-static mali_bool deinit_mali_clock(void)
-{
- if (mali_clock == 0)
- return MALI_TRUE;
-
-#ifdef CONFIG_REGULATOR
- if (g3d_regulator)
- {
- regulator_put(g3d_regulator);
- g3d_regulator=NULL;
- }
-#endif
-
- mali_clk_put(MALI_TRUE);
-
- return MALI_TRUE;
-}
-static _mali_osk_errcode_t enable_mali_clocks(void)
-{
- int err;
- err = clk_enable(mali_clock);
- MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
-
- mali_runtime_resume.vol = mali_dvfs_get_vol(MALI_DVFS_DEFAULT_STEP);
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if MALI_DVFS_ENABLED
- // set clock rate
- if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk)
- mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
- else {
- mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
- mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
- set_mali_dvfs_current_step(MALI_DVFS_DEFAULT_STEP);
- }
-#if CPUFREQ_LOCK_DURING_440
- /* lock/unlock CPU freq by Mali */
- if (mali_gpu_clk >= 440)
- err = cpufreq_lock_by_mali(1200);
-#endif
-#else
- mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
- mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
-#endif
-#else
- mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
-#endif
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t disable_mali_clocks(void)
-{
- clk_disable(mali_clock);
- MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
-
-#if MALI_DVFS_ENABLED && CPUFREQ_LOCK_DURING_440
- /* lock/unlock CPU freq by Mali */
- cpufreq_unlock_by_mali();
-#endif
- MALI_SUCCESS;
-}
-
-void set_mali_parent_power_domain(struct platform_device* dev)
-{
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
- dev->dev.parent = &s5pv310_device_pd[PD_G3D].dev;
-#else
- dev->dev.parent = &exynos4_device_pd[PD_G3D].dev;
-#endif
-#endif
-}
-
-_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
-{
- if (bpower_on)
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT(3,("_mali_osk_pmm_dev_activate \n"));
- _mali_osk_pm_dev_activate();
-#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- void __iomem *status;
- u32 timeout;
- __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_PMU_G3D_CONF);
- status = S5P_PMU_G3D_CONF + 0x4;
-
- timeout = 10;
- while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
- != S5P_INT_LOCAL_PWR_EN) {
- if (timeout == 0) {
- MALI_PRINTF(("Power domain enable failed.\n"));
- return -ETIMEDOUT;
- }
- timeout--;
- _mali_osk_time_ubusydelay(100);
- }
-#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- }
- else
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- MALI_DEBUG_PRINT( 4,("_mali_osk_pmm_dev_idle\n"));
- _mali_osk_pm_dev_idle();
-#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- void __iomem *status;
- u32 timeout;
- __raw_writel(0, S5P_PMU_G3D_CONF);
-
- status = S5P_PMU_G3D_CONF + 0x4;
- /* Wait max 1ms */
- timeout = 10;
- while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
- {
- if (timeout == 0) {
- MALI_PRINTF(("Power domain disable failed.\n" ));
- return -ETIMEDOUT;
- }
- timeout--;
- _mali_osk_time_ubusydelay( 100);
- }
-#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_init()
-{
- MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
-#if MALI_VOLTAGE_LOCK
- _mali_osk_atomic_init(&voltage_lock_status, 0);
-#endif
-#if MALI_DVFS_ENABLED
- if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
- if(!init_mali_dvfs_status(MALI_DVFS_DEFAULT_STEP))
- MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
-#endif
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_deinit()
-{
- deinit_mali_clock();
-#if MALI_VOLTAGE_LOCK
- _mali_osk_atomic_term(&voltage_lock_status);
-#endif
-#if MALI_DVFS_ENABLED
- deinit_mali_dvfs_status();
- if (clk_register_map )
- {
- _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
- clk_register_map=0;
- }
-#endif
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_powerdown(u32 cores)
-{
- trace_printk("SPI_GPU_PWR Idle\n");
- MALI_DEBUG_PRINT(3,("power down is called in mali_platform_powerdown state %x core %x \n", gpu_power_state, cores));
-
- if (gpu_power_state != 0) // power down after state is 0
- {
- gpu_power_state = gpu_power_state & (~cores);
- if (gpu_power_state == 0)
- {
- MALI_DEBUG_PRINT( 3,("disable clock\n"));
- disable_mali_clocks();
- }
- }
- else
- {
- MALI_PRINT(("mali_platform_powerdown gpu_power_state == 0 and cores %x \n", cores));
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_platform_powerup(u32 cores)
-{
- trace_printk("SPI_GPU_PWR Start\n");
- MALI_DEBUG_PRINT(3,("power up is called in mali_platform_powerup state %x core %x \n", gpu_power_state, cores));
-
- if (gpu_power_state == 0) // power up only before state is 0
- {
- gpu_power_state = gpu_power_state | cores;
-
- if (gpu_power_state != 0)
- {
- MALI_DEBUG_PRINT(4,("enable clock \n"));
- enable_mali_clocks();
- }
- }
- else
- {
- gpu_power_state = gpu_power_state | cores;
- }
-
- MALI_SUCCESS;
-}
-
-void mali_gpu_utilization_handler(u32 utilization)
-{
- if (bPoweroff==0)
- {
-#if MALI_DVFS_ENABLED
- if(!mali_dvfs_handler(utilization))
- MALI_DEBUG_PRINT(1,( "error on mali dvfs status in utilization\n"));
-#endif
- }
-}
-
-#if MALI_POWER_MGMT_TEST_SUITE
-u32 pmu_get_power_up_down_info(void)
-{
- return 4095;
-}
-
-#endif
-
-_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
-{
- switch (power_mode)
- {
- case MALI_POWER_MODE_ON:
- MALI_DEBUG_PRINT(1, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", bPoweroff ? "powering on" : "already on"));
- if (bPoweroff == 1)
- {
- /** If run time power management is used, donot call this function */
-#ifndef CONFIG_PM_RUNTIME
- g3d_power_domain_control(1);
-#endif
-
- MALI_DEBUG_PRINT(4,("enable clock \n"));
- enable_mali_clocks();
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
-#endif
- //MALI_PRINTF(("Mali Platform powered up"));
- gpu_power_state=1;
- bPoweroff=0;
- }
- break;
- case MALI_POWER_MODE_LIGHT_SLEEP:
- case MALI_POWER_MODE_DEEP_SLEEP:
- MALI_DEBUG_PRINT(1, ("Mali platform: Got %s event, %s\n",
- power_mode == MALI_POWER_MODE_LIGHT_SLEEP ? "MALI_POWER_MODE_LIGHT_SLEEP" : "MALI_POWER_MODE_DEEP_SLEEP",
- bPoweroff ? "already off" : "powering off"));
- if (bPoweroff == 0)
- {
- disable_mali_clocks();
-#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
- _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU|MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, 0, 0, 0, 0, 0);
-#endif
-
-#ifndef CONFIG_PM_RUNTIME
- g3d_power_domain_control(0);
-#endif
-
- //MALI_PRINTF(("Mali Platform powered down"));
- gpu_power_state=0;
- bPoweroff=1;
- }
-
- break;
- }
- MALI_SUCCESS;
-}
-
-#if MALI_VOLTAGE_LOCK
-int mali_voltage_lock_push(int lock_vol)
-{
- int prev_status = _mali_osk_atomic_read(&voltage_lock_status);
-
- if (prev_status < 0) {
- MALI_PRINT(("gpu voltage lock status is not valid for push\n"));
- return -1;
- }
- if (prev_status == 0) {
- mali_lock_vol = lock_vol;
- if (mali_gpu_vol < mali_lock_vol)
- mali_regulator_set_voltage(mali_lock_vol, mali_lock_vol);
- } else {
- MALI_PRINT(("gpu voltage lock status is already pushed, current lock voltage : %d\n", mali_lock_vol));
- return -1;
- }
-
- return _mali_osk_atomic_inc_return(&voltage_lock_status);
-}
-
-int mali_voltage_lock_pop(void)
-{
- if (_mali_osk_atomic_read(&voltage_lock_status) <= 0) {
- MALI_PRINT(("gpu voltage lock status is not valid for pop\n"));
- return -1;
- }
- return _mali_osk_atomic_dec_return(&voltage_lock_status);
-}
-
-int mali_voltage_lock_init(void)
-{
- mali_vol_lock_flag = MALI_TRUE;
-
- MALI_SUCCESS;
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
deleted file mode 100644
index cc1164e..0000000
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
+++ /dev/null
@@ -1,847 +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.
- */
-
-/**
- * @file mali_platform_dvfs.c
- * Platform specific Mali driver dvfs functions
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-
-#include <asm/io.h>
-
-#include "mali_device_pause_resume.h"
-#include <linux/workqueue.h>
-
-#define MAX_MALI_DVFS_STEPS 5
-#define MALI_DVFS_WATING 10 // msec
-
-#ifdef CONFIG_CPU_FREQ
-#include <mach/asv.h>
-#define EXYNOS4_ASV_ENABLED
-#endif
-
-#include <plat/cpu.h>
-
-static int bMaliDvfsRun=0;
-
-static _mali_osk_atomic_t bottomlock_status;
-int bottom_lock_step = 0;
-
-typedef struct mali_dvfs_tableTag{
- unsigned int clock;
- unsigned int freq;
- unsigned int vol;
-}mali_dvfs_table;
-
-typedef struct mali_dvfs_statusTag{
- unsigned int currentStep;
- mali_dvfs_table * pCurrentDvfs;
-
-}mali_dvfs_currentstatus;
-
-typedef struct mali_dvfs_thresholdTag{
- unsigned int downthreshold;
- unsigned int upthreshold;
-}mali_dvfs_threshold_table;
-
-typedef struct mali_dvfs_staycount{
- unsigned int staycount;
-}mali_dvfs_staycount_table;
-
-typedef struct mali_dvfs_stepTag{
- int clk;
- int vol;
-}mali_dvfs_step;
-
-mali_dvfs_step step[MALI_DVFS_STEPS]={
- /*step 0 clk*/ {160, 875000},
-#if (MALI_DVFS_STEPS > 1)
- /*step 1 clk*/ {266, 900000},
-#if (MALI_DVFS_STEPS > 2)
- /*step 2 clk*/ {350, 950000},
-#if (MALI_DVFS_STEPS > 3)
- /*step 3 clk*/ {440, 1025000},
-#if (MALI_DVFS_STEPS > 4)
- /*step 4 clk*/ {533, 1075000}
-#endif
-#endif
-#endif
-#endif
-};
-
-mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={
- /*step 0*/{0},
-#if (MALI_DVFS_STEPS > 1)
- /*step 1*/{0},
-#if (MALI_DVFS_STEPS > 2)
- /*step 2*/{0},
-#if (MALI_DVFS_STEPS > 3)
- /*step 3*/{0},
-#if (MALI_DVFS_STEPS > 4)
- /*step 4*/{0}
-#endif
-#endif
-#endif
-#endif
-};
-
-/* dvfs information */
-// L0 = 533Mhz, 1.075V
-// L1 = 440Mhz, 1.025V
-// L2 = 350Mhz, 0.95V
-// L3 = 266Mhz, 0.90V
-// L4 = 160Mhz, 0.875V
-
-int step0_clk = 160;
-int step0_vol = 875000;
-#if (MALI_DVFS_STEPS > 1)
-int step1_clk = 266;
-int step1_vol = 900000;
-int step0_up = 70;
-int step1_down = 62;
-#if (MALI_DVFS_STEPS > 2)
-int step2_clk = 350;
-int step2_vol = 950000;
-int step1_up = 90;
-int step2_down = 85;
-#if (MALI_DVFS_STEPS > 3)
-int step3_clk = 440;
-int step3_vol = 1025000;
-int step2_up = 90;
-int step3_down = 85;
-#if (MALI_DVFS_STEPS > 4)
-int step4_clk = 533;
-int step4_vol = 1075000;
-int step3_up = 90;
-int step4_down = 95;
-#endif
-#endif
-#endif
-#endif
-
-mali_dvfs_table mali_dvfs_all[MAX_MALI_DVFS_STEPS]={
- {160 ,1000000 , 875000},
- {266 ,1000000 , 900000},
- {350 ,1000000 , 950000},
- {440 ,1000000 , 1025000},
- {533 ,1000000 , 1075000} };
-
-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
- {160 ,1000000 , 875000},
-#if (MALI_DVFS_STEPS > 1)
- {266 ,1000000 , 900000},
-#if (MALI_DVFS_STEPS > 2)
- {350 ,1000000 , 950000},
-#if (MALI_DVFS_STEPS > 3)
- {440 ,1000000 ,1025000},
-#if (MALI_DVFS_STEPS > 4)
- {533 ,1000000 ,1075000}
-#endif
-#endif
-#endif
-#endif
-};
-
-mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
- {0 , 70},
-#if (MALI_DVFS_STEPS > 1)
- {62 , 90},
-#if (MALI_DVFS_STEPS > 2)
- {85 , 90},
-#if (MALI_DVFS_STEPS > 3)
- {85 ,90},
-#if (MALI_DVFS_STEPS > 4)
- {95 ,100}
-#endif
-#endif
-#endif
-#endif
-};
-
-#ifdef EXYNOS4_ASV_ENABLED
-#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */
-#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */
-
-static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
- { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */
-#if (MALI_DVFS_STEPS > 1)
- { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */
-#if (MALI_DVFS_STEPS > 2)
- { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */
-#if (MALI_DVFS_STEPS > 3)
- { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */
-#endif
-#endif
-#endif
-};
-
-static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
- { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */
-#if (MALI_DVFS_STEPS > 1)
- { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */
-#if (MALI_DVFS_STEPS > 2)
- { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */
-#if (MALI_DVFS_STEPS > 3)
- { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */
-#endif
-#endif
-#endif
-};
-
-static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = {
- { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000}, /* L4(160Mhz) */
-#if (MALI_DVFS_STEPS > 1)
- { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 862500}, /* L3(266Mhz) */
-#if (MALI_DVFS_STEPS > 2)
- { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 925000, 912500}, /* L2(350Mhz) */
-#if (MALI_DVFS_STEPS > 3)
- { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500, 975000}, /* L1(440Mhz) */
-#if (MALI_DVFS_STEPS > 4)
- { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(600Mhz) */
-#endif
-#endif
-#endif
-#endif
-};
-#endif /* ASV_LEVEL */
-
-/*dvfs status*/
-mali_dvfs_currentstatus maliDvfsStatus;
-int mali_dvfs_control=0;
-
-static u32 mali_dvfs_utilization = 255;
-
-static void mali_dvfs_work_handler(struct work_struct *w);
-
-static struct workqueue_struct *mali_dvfs_wq = 0;
-extern mali_io_address clk_register_map;
-extern _mali_osk_lock_t *mali_dvfs_lock;
-
-int mali_runtime_resumed = -1;
-
-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
-
-/* lock/unlock CPU freq by Mali */
-#include <linux/types.h>
-#include <mach/cpufreq.h>
-
-atomic_t mali_cpufreq_lock;
-
-int cpufreq_lock_by_mali(unsigned int freq)
-{
-#ifdef CONFIG_EXYNOS4_CPUFREQ
-/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */
- unsigned int level;
-
- if (atomic_read(&mali_cpufreq_lock) == 0) {
- if (exynos_cpufreq_get_level(freq * 1000, &level)) {
- printk(KERN_ERR
- "Mali: failed to get cpufreq level for %dMHz",
- freq);
- return -EINVAL;
- }
-
- if (exynos_cpufreq_lock(DVFS_LOCK_ID_G3D, level)) {
- printk(KERN_ERR
- "Mali: failed to cpufreq lock for L%d", level);
- return -EINVAL;
- }
-
- atomic_set(&mali_cpufreq_lock, 1);
- printk(KERN_DEBUG "Mali: cpufreq locked on <%d>%dMHz\n", level,
- freq);
- }
-#endif
- return 0;
-}
-
-void cpufreq_unlock_by_mali(void)
-{
-#ifdef CONFIG_EXYNOS4_CPUFREQ
-/* #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_ARCH_EXYNOS4) */
- if (atomic_read(&mali_cpufreq_lock) == 1) {
- exynos_cpufreq_lock_free(DVFS_LOCK_ID_G3D);
- atomic_set(&mali_cpufreq_lock, 0);
- printk(KERN_DEBUG "Mali: cpufreq locked off\n");
- }
-#endif
-}
-
-static unsigned int get_mali_dvfs_status(void)
-{
- return maliDvfsStatus.currentStep;
-}
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-int get_mali_dvfs_control_status(void)
-{
- return mali_dvfs_control;
-}
-
-mali_bool set_mali_dvfs_current_step(unsigned int step)
-{
- _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- maliDvfsStatus.currentStep = step % MAX_MALI_DVFS_STEPS;
- if (step >= MAX_MALI_DVFS_STEPS)
- mali_runtime_resumed = maliDvfsStatus.currentStep;
- _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- return MALI_TRUE;
-}
-#endif
-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
-{
- u32 validatedStep=step;
- int err;
-
-#ifdef CONFIG_REGULATOR
- if (mali_regulator_get_usecount() == 0) {
- MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n"));
- return MALI_FALSE;
- }
-#endif
-
- if (boostup) {
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
- } else {
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
-#endif
- }
-
-#ifdef EXYNOS4_ASV_ENABLED
- if (samsung_rev() < EXYNOS4412_REV_2_0) {
- if (mali_dvfs[step].clock == 160)
- exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
- else
- exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
- }
-#endif
-
-
- set_mali_dvfs_current_step(validatedStep);
- /*for future use*/
- maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
-
-#if CPUFREQ_LOCK_DURING_440
- /* lock/unlock CPU freq by Mali */
- if (mali_dvfs[step].clock == 440)
- err = cpufreq_lock_by_mali(1200);
- else
- cpufreq_unlock_by_mali();
-#endif
-
- return MALI_TRUE;
-}
-
-static void mali_platform_wating(u32 msec)
-{
- /*sample wating
- change this in the future with proper check routine.
- */
- unsigned int read_val;
- while(1) {
- read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
- if ((read_val & 0x8000)==0x0000) break;
- _mali_osk_time_ubusydelay(100); // 1000 -> 100 : 20101218
- }
- /* _mali_osk_time_ubusydelay(msec*1000);*/
-}
-
-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
-{
-
- MALI_DEBUG_PRINT(1, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
-
- if (!set_mali_dvfs_status(step, boostup)) {
- MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
- return MALI_FALSE;
- }
-
- /*wait until clock and voltage is stablized*/
- mali_platform_wating(MALI_DVFS_WATING); /*msec*/
-
- return MALI_TRUE;
-}
-
-#ifdef EXYNOS4_ASV_ENABLED
-extern unsigned int exynos_result_of_asv;
-
-static mali_bool mali_dvfs_table_update(void)
-{
- unsigned int i;
- unsigned int step_num = MALI_DVFS_STEPS;
-
- if(samsung_rev() < EXYNOS4412_REV_2_0)
- step_num = MALI_DVFS_STEPS - 1;
-
- if(soc_is_exynos4412()) {
- if (exynos_armclk_max == 1000000) {
- MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
- }
- } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) {
- MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000;
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol));
- }
- } else if (samsung_rev() >= EXYNOS4412_REV_2_0) {
- MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
- }
- } else {
- MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- for (i = 0; i < step_num; i++) {
- mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv];
- MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
- }
- }
- }
-
- return MALI_TRUE;
-}
-#endif
-
-static unsigned int decideNextStatus(unsigned int utilization)
-{
- static unsigned int level = 0; // 0:stay, 1:up
- static int mali_dvfs_clk = 0;
-
- if (mali_runtime_resumed >= 0) {
- level = mali_runtime_resumed;
- mali_runtime_resumed = -1;
- }
-
- if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold
- <= mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) {
- MALI_PRINT(("upthreadshold is smaller than downthreshold: %d < %d\n",
- mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold,
- mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold));
- return level;
- }
-
- if (!mali_dvfs_control && level == maliDvfsStatus.currentStep) {
- if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) &&
- level < MALI_DVFS_STEPS - 1) {
- level++;
- if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
- level=get_mali_dvfs_status();
- }
- }
- if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) &&
- level > 0) {
- level--;
- }
- } else if (mali_dvfs_control == 999) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[i].clock;
- }
-#ifdef EXYNOS4_ASV_ENABLED
- mali_dvfs_table_update();
-#endif
- i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs[i].clock = step[i].clk;
- }
- mali_dvfs_control = 0;
- level = 0;
-
- step0_clk = step[0].clk;
- change_dvfs_tableset(step0_clk, 0);
-#if (MALI_DVFS_STEPS > 1)
- step1_clk = step[1].clk;
- change_dvfs_tableset(step1_clk, 1);
-#if (MALI_DVFS_STEPS > 2)
- step2_clk = step[2].clk;
- change_dvfs_tableset(step2_clk, 2);
-#if (MALI_DVFS_STEPS > 3)
- step3_clk = step[3].clk;
- change_dvfs_tableset(step3_clk, 3);
-#if (MALI_DVFS_STEPS > 4)
- step4_clk = step[4].clk;
- change_dvfs_tableset(step4_clk, 4);
-#endif
-#endif
-#endif
-#endif
- } else if (mali_dvfs_control != mali_dvfs_clk && mali_dvfs_control != 999) {
- if (mali_dvfs_control < mali_dvfs_all[1].clock && mali_dvfs_control > 0) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[0].clock;
- }
- maliDvfsStatus.currentStep = 0;
- } else if (mali_dvfs_control < mali_dvfs_all[2].clock && mali_dvfs_control >= mali_dvfs_all[1].clock) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[1].clock;
- }
- maliDvfsStatus.currentStep = 1;
- } else if (mali_dvfs_control < mali_dvfs_all[3].clock && mali_dvfs_control >= mali_dvfs_all[2].clock) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[2].clock;
- }
- maliDvfsStatus.currentStep = 2;
- } else if (mali_dvfs_control < mali_dvfs_all[4].clock && mali_dvfs_control >= mali_dvfs_all[3].clock) {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[3].clock;
- }
- maliDvfsStatus.currentStep = 3;
- } else {
- int i = 0;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- step[i].clk = mali_dvfs_all[4].clock;
- }
- maliDvfsStatus.currentStep = 4;
- }
- step0_clk = step[0].clk;
- change_dvfs_tableset(step0_clk, 0);
-#if (MALI_DVFS_STEPS > 1)
- step1_clk = step[1].clk;
- change_dvfs_tableset(step1_clk, 1);
-#if (MALI_DVFS_STEPS > 2)
- step2_clk = step[2].clk;
- change_dvfs_tableset(step2_clk, 2);
-#if (MALI_DVFS_STEPS > 3)
- step3_clk = step[3].clk;
- change_dvfs_tableset(step3_clk, 3);
-#if (MALI_DVFS_STEPS > 4)
- step4_clk = step[4].clk;
- change_dvfs_tableset(step4_clk, 4);
-#endif
-#endif
-#endif
-#endif
- level = maliDvfsStatus.currentStep;
- }
-
- mali_dvfs_clk = mali_dvfs_control;
-
- if (_mali_osk_atomic_read(&bottomlock_status) > 0) {
- if (level < bottom_lock_step)
- level = bottom_lock_step;
- }
-
- return level;
-}
-
-static mali_bool mali_dvfs_status(u32 utilization)
-{
- unsigned int nextStatus = 0;
- unsigned int curStatus = 0;
- mali_bool boostup = MALI_FALSE;
- static int stay_count = 0;
-#ifdef EXYNOS4_ASV_ENABLED
- static mali_bool asv_applied = MALI_FALSE;
-#endif
-
- MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization));
-#ifdef EXYNOS4_ASV_ENABLED
- if (asv_applied == MALI_FALSE) {
- mali_dvfs_table_update();
- change_mali_dvfs_status(1, 0);
- asv_applied = MALI_TRUE;
-
- return MALI_TRUE;
- }
-#endif
-
- /*decide next step*/
- curStatus = get_mali_dvfs_status();
- nextStatus = decideNextStatus(utilization);
-
- MALI_DEBUG_PRINT(1, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
-
- /*if next status is same with current status, don't change anything*/
- if ((curStatus != nextStatus && stay_count == 0)) {
- /*check if boost up or not*/
- if (nextStatus > maliDvfsStatus.currentStep) boostup = 1;
-
- /*change mali dvfs status*/
- if (!change_mali_dvfs_status(nextStatus,boostup)) {
- MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
- return MALI_FALSE;
- }
- stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount;
- } else {
- if (stay_count > 0)
- stay_count--;
- }
-
- return MALI_TRUE;
-}
-
-
-
-int mali_dvfs_is_running(void)
-{
- return bMaliDvfsRun;
-
-}
-
-
-
-void mali_dvfs_late_resume(void)
-{
- // set the init clock as low when resume
- set_mali_dvfs_status(0,0);
-}
-
-
-static void mali_dvfs_work_handler(struct work_struct *w)
-{
- int change_clk = 0;
- int change_step = 0;
- bMaliDvfsRun=1;
-
- /* dvfs table change when clock was changed */
- if (step0_clk != mali_dvfs[0].clock) {
- MALI_PRINT(("::: step0_clk change to %d Mhz\n", step0_clk));
- change_clk = step0_clk;
- change_step = 0;
- step0_clk = change_dvfs_tableset(change_clk, change_step);
- }
-#if (MALI_DVFS_STEPS > 1)
- if (step1_clk != mali_dvfs[1].clock) {
- MALI_PRINT(("::: step1_clk change to %d Mhz\n", step1_clk));
- change_clk = step1_clk;
- change_step = 1;
- step1_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step0_up != mali_dvfs_threshold[0].upthreshold) {
- MALI_PRINT(("::: step0_up change to %d %\n", step0_up));
- mali_dvfs_threshold[0].upthreshold = step0_up;
- }
- if (step1_down != mali_dvfs_threshold[1].downthreshold) {
- MALI_PRINT((":::step1_down change to %d %\n", step1_down));
- mali_dvfs_threshold[1].downthreshold = step1_down;
- }
-#if (MALI_DVFS_STEPS > 2)
- if (step2_clk != mali_dvfs[2].clock) {
- MALI_PRINT(("::: step2_clk change to %d Mhz\n", step2_clk));
- change_clk = step2_clk;
- change_step = 2;
- step2_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step1_up != mali_dvfs_threshold[1].upthreshold) {
- MALI_PRINT((":::step1_up change to %d %\n", step1_up));
- mali_dvfs_threshold[1].upthreshold = step1_up;
- }
- if (step2_down != mali_dvfs_threshold[2].downthreshold) {
- MALI_PRINT((":::step2_down change to %d %\n", step2_down));
- mali_dvfs_threshold[2].downthreshold = step2_down;
- }
-#if (MALI_DVFS_STEPS > 3)
- if (step3_clk != mali_dvfs[3].clock) {
- MALI_PRINT(("::: step3_clk change to %d Mhz\n", step3_clk));
- change_clk = step3_clk;
- change_step = 3;
- step3_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step2_up != mali_dvfs_threshold[2].upthreshold) {
- MALI_PRINT((":::step2_up change to %d %\n", step2_up));
- mali_dvfs_threshold[2].upthreshold = step2_up;
- }
- if (step3_down != mali_dvfs_threshold[3].downthreshold) {
- MALI_PRINT((":::step3_down change to %d %\n", step3_down));
- mali_dvfs_threshold[3].downthreshold = step3_down;
- }
-#if (MALI_DVFS_STEPS > 4)
- if (step4_clk != mali_dvfs[4].clock) {
- MALI_PRINT(("::: step4_clk change to %d Mhz\n", step4_clk));
- change_clk = step4_clk;
- change_step = 4;
- step4_clk = change_dvfs_tableset(change_clk, change_step);
- }
- if (step3_up != mali_dvfs_threshold[3].upthreshold) {
- MALI_PRINT((":::step3_up change to %d %\n", step3_up));
- mali_dvfs_threshold[3].upthreshold = step3_up;
- }
- if (step4_down != mali_dvfs_threshold[4].downthreshold) {
- MALI_PRINT((":::step4_down change to %d %\n", step4_down));
- mali_dvfs_threshold[4].downthreshold = step4_down;
- }
-#endif
-#endif
-#endif
-#endif
-
-
-#ifdef DEBUG
- mali_dvfs[0].vol = step0_vol;
- mali_dvfs[1].vol = step1_vol;
- mali_dvfs[2].vol = step2_vol;
- mali_dvfs[3].vol = step3_vol;
- mali_dvfs[4].vol = step4_vol;
-#endif
- MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
-
- if (!mali_dvfs_status(mali_dvfs_utilization))
- MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler"));
-
- bMaliDvfsRun=0;
-}
-
-mali_bool init_mali_dvfs_status(int step)
-{
- /*default status
- add here with the right function to get initilization value.
- */
- if (!mali_dvfs_wq)
- mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
-
- _mali_osk_atomic_init(&bottomlock_status, 0);
-
- /*add a error handling here*/
- set_mali_dvfs_current_step(step);
-
- return MALI_TRUE;
-}
-
-void deinit_mali_dvfs_status(void)
-{
- if (mali_dvfs_wq)
- destroy_workqueue(mali_dvfs_wq);
-
- _mali_osk_atomic_term(&bottomlock_status);
-
- mali_dvfs_wq = NULL;
-}
-
-mali_bool mali_dvfs_handler(u32 utilization)
-{
- mali_dvfs_utilization = utilization;
- queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work);
-
- /*add error handle here*/
- return MALI_TRUE;
-}
-
-int change_dvfs_tableset(int change_clk, int change_step)
-{
- int err;
-
- if (change_clk < mali_dvfs_all[1].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[0].clock;
- } else if (change_clk < mali_dvfs_all[2].clock && change_clk >= mali_dvfs_all[1].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[1].clock;
- } else if (change_clk < mali_dvfs_all[3].clock && change_clk >= mali_dvfs_all[2].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[2].clock;
- } else if (change_clk < mali_dvfs_all[4].clock && change_clk >= mali_dvfs_all[3].clock) {
- mali_dvfs[change_step].clock = mali_dvfs_all[3].clock;
- } else {
- mali_dvfs[change_step].clock = mali_dvfs_all[4].clock;
- }
-
- MALI_PRINT((":::mali dvfs step %d clock and voltage = %d Mhz, %d V\n",change_step, mali_dvfs[change_step].clock, mali_dvfs[change_step].vol));
-
- if (maliDvfsStatus.currentStep == change_step) {
-#ifdef CONFIG_REGULATOR
- /*change the voltage*/
- mali_regulator_set_voltage(mali_dvfs[change_step].vol, mali_dvfs[change_step].vol);
-#endif
- /*change the clock*/
- mali_clk_set_rate(mali_dvfs[change_step].clock, mali_dvfs[change_step].freq);
-
-#if CPUFREQ_LOCK_DURING_440
- /* lock/unlock CPU freq by Mali */
- if (mali_dvfs[change_step].clock == 440)
- err = cpufreq_lock_by_mali(1200);
- else
- cpufreq_unlock_by_mali();
-#endif
- }
-
- return mali_dvfs[change_step].clock;
-}
-
-void mali_default_step_set(int step, mali_bool boostup)
-{
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-
- if (maliDvfsStatus.currentStep == 1)
- set_mali_dvfs_status(step, boostup);
-}
-
-int mali_dvfs_bottom_lock_push(int lock_step)
-{
- int prev_status = _mali_osk_atomic_read(&bottomlock_status);
-
- if (prev_status < 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for push\n"));
- return -1;
- }
- if (bottom_lock_step < lock_step) {
- bottom_lock_step = lock_step;
- if (get_mali_dvfs_status() < lock_step) {
- mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol);
- mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq);
- set_mali_dvfs_current_step(lock_step);
- }
- }
- return _mali_osk_atomic_inc_return(&bottomlock_status);
-}
-
-int mali_dvfs_bottom_lock_pop(void)
-{
- int prev_status = _mali_osk_atomic_read(&bottomlock_status);
- if (prev_status <= 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for pop\n"));
- return -1;
- } else if (prev_status == 1) {
- bottom_lock_step = 0;
- MALI_PRINT(("gpu bottom lock release\n"));
- }
-
- return _mali_osk_atomic_dec_return(&bottomlock_status);
-}
-
-int mali_dvfs_get_vol(int step)
-{
- step = step % MAX_MALI_DVFS_STEPS;
- MALI_DEBUG_ASSERT(step<MAX_MALI_DVFS_STEPS);
-
- return mali_dvfs[step].vol;
-}
-
-#if MALI_VOLTAGE_LOCK
-int mali_vol_get_from_table(int vol)
-{
- int i;
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- if (mali_dvfs[i].vol >= vol)
- return mali_dvfs[i].vol;
- }
- MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol));
- return 0;
-}
-#endif
diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig
deleted file mode 100644
index 9d8e5e6..0000000
--- a/drivers/media/video/samsung/ump/Kconfig
+++ /dev/null
@@ -1,58 +0,0 @@
-
-#
-## S3C Multimedia Mali configuration
-##
-#
-# For UMP
-config VIDEO_UMP
- bool "Enable UMP(Unified Memory Provider)"
- default y
- ---help---
- This enables UMP memory provider
-
-config UMP_VCM_ALLOC
- depends on VIDEO_UMP && VCM
- default y
- bool "Enable ump-vcm(virtual contiguous memory) memory"
- help
- Use VCM(virtual-contiguous-memory) to allocate physical memory.
-
-
-config UMP_R3P1_LSI
- bool "Uses the R3P1 as a ump module"
- depends on VIDEO_UMP
- default n
- ---help---
- This uses the r3p1 as a UMP kernel module
-
-choice
-depends on VIDEO_UMP
-prompt "UMP MEMEMORY OPTION"
-default UMP_OSMEM_ONLY
-config UMP_DED_ONLY
- bool "ump dedicated memory only"
- ---help---
- This enables UMP dedicated memory only option
-config UMP_OSMEM_ONLY
- bool "ump OS memory only"
- ---help---
- This enables UMP OS memory only option
-config UMP_VCM_ONLY
- bool "ump VCM memory"
- ---help---
- This enables UMP VCM memory only option
-
-endchoice
-config UMP_MEM_SIZE
-int "UMP Memory Size"
- depends on VIDEO_UMP
- default "512"
- ---help---
- This value is dedicated memory size of UMP (unit is MByte).
-# For UMP_DEBUG
-config VIDEO_UMP_DEBUG
- bool "Enables debug messages"
- depends on VIDEO_UMP
- default n
- help
- This enables UMP driver debug messages.
diff --git a/drivers/media/video/samsung/ump/Kconfig_module b/drivers/media/video/samsung/ump/Kconfig_module
deleted file mode 100644
index 3ae316c..0000000
--- a/drivers/media/video/samsung/ump/Kconfig_module
+++ /dev/null
@@ -1,16 +0,0 @@
-config UMP
- tristate "UMP support"
- depends on ARM
- ---help---
- This enables support for the UMP memory allocation and sharing API.
-
- To compile this driver as a module, choose M here: the module will be
- called ump.
-
-config UMP_DEBUG
- bool "Enable extra debug in UMP"
- depends on UMP
- default y
- ---help---
- This enabled extra debug checks and messages in UMP.
-
diff --git a/drivers/media/video/samsung/ump/Makefile b/drivers/media/video/samsung/ump/Makefile
deleted file mode 100644
index 3a1aac0..0000000
--- a/drivers/media/video/samsung/ump/Makefile
+++ /dev/null
@@ -1,93 +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.
-#
-
-ifeq ($(CONFIG_UMP_DED_ONLY),y)
-UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE)
-USING_MEMORY=0
-endif
-
-ifeq ($(CONFIG_UMP_OSMEM_ONLY),y)
-UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE)
-USING_MEMORY=1
-endif
-
-ifeq ($(CONFIG_UMP_VCM_ONLY),y)
-UMP_MEM_SIZE= $(CONFIG_UMP_MEM_SIZE)
-USING_MEMORY=2
-endif
-
-
-# For UMP Debug
-ifeq ($(CONFIG_VIDEO_UMP_DEBUG),y)
-DEFINES += -DDEBUG
-endif
-
-# Set up our defines, which will be passed to gcc
-DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER
-DEFINES += -DUSING_MEMORY=$(USING_MEMORY)
-DEFINES += -DUMP_MEM_SIZE=$(UMP_MEM_SIZE)
-DEFINES += -DMALI_STATE_TRACKING=1
-
-UDD_FILE_PREFIX := drivers/media/video/samsung/ump/
-KBUILDROOT =
-
-# linux build system integration
-
-obj-$(CONFIG_VIDEO_UMP) += ump.o
-
-# 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
-
-INCLUDES += \
- -I$(UDD_FILE_PREFIX)\
- -I$(UDD_FILE_PREFIX)common\
- -I$(UDD_FILE_PREFIX)linux\
- -I$(UDD_FILE_PREFIX)include\
- -I$(UDD_FILE_PREFIX)linux/license/gpl/\
- -I$(UDD_FILE_PREFIX)../mali/common\
- -I$(UDD_FILE_PREFIX)../mali/linux
-
-OSKFILES+=\
- $(KBUILDROOT)../mali/linux/mali_osk_atomics.o \
- $(KBUILDROOT)../mali/linux/mali_osk_locks.o \
- $(KBUILDROOT)../mali/linux/mali_osk_math.o \
- $(KBUILDROOT)../mali/linux/mali_osk_memory.o \
- $(KBUILDROOT)../mali/linux/mali_osk_misc.o
-
-ump-y := \
- $(KBUILDROOT)linux/ump_kernel_linux.o \
- $(KBUILDROOT)linux/ump_kernel_memory_backend_os.o \
- $(KBUILDROOT)linux/ump_kernel_memory_backend_dedicated.o \
- $(KBUILDROOT)linux/ump_memory_backend.o \
- $(KBUILDROOT)linux/ump_ukk_wrappers.o \
- $(KBUILDROOT)linux/ump_ukk_ref_wrappers.o \
- $(KBUILDROOT)linux/ump_osk_atomics.o \
- $(KBUILDROOT)linux/ump_osk_low_level_mem.o \
- $(KBUILDROOT)linux/ump_osk_misc.o \
- $(KBUILDROOT)common/ump_kernel_common.o \
- $(KBUILDROOT)common/ump_kernel_descriptor_mapping.o \
- $(KBUILDROOT)common/ump_kernel_api.o \
- $(KBUILDROOT)common/ump_kernel_ref_drv.o\
- $(OSKFILES)
-
-ump-$(CONFIG_UMP_VCM_ALLOC) += \
- $(KBUILDROOT)linux/ump_kernel_memory_backend_vcm.o \
-
-EXTRA_CFLAGS += $(INCLUDES) \
- $(DEFINES)
-
-
-# Get subversion revision number, fall back to 0000 if no svn info is available
-SVN_REV:=$(shell ((svnversion | grep -E "^[0-9]+" && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
-
-EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV)
-EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\"
-
diff --git a/drivers/media/video/samsung/ump/arch b/drivers/media/video/samsung/ump/arch
deleted file mode 120000
index 58ffbe7..0000000
--- a/drivers/media/video/samsung/ump/arch
+++ /dev/null
@@ -1 +0,0 @@
-arch-release \ No newline at end of file
diff --git a/drivers/media/video/samsung/ump/arch-debug b/drivers/media/video/samsung/ump/arch-debug
deleted file mode 120000
index 0ed0909..0000000
--- a/drivers/media/video/samsung/ump/arch-debug
+++ /dev/null
@@ -1 +0,0 @@
-arch-pegasus-m400/ \ No newline at end of file
diff --git a/drivers/media/video/samsung/ump/arch-release b/drivers/media/video/samsung/ump/arch-release
deleted file mode 120000
index 0ed0909..0000000
--- a/drivers/media/video/samsung/ump/arch-release
+++ /dev/null
@@ -1 +0,0 @@
-arch-pegasus-m400/ \ No newline at end of file
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
deleted file mode 100644
index 46797ea..0000000
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
+++ /dev/null
@@ -1,290 +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.
- */
-
-/* create by boojin.kim@samsung.com */
-/* needed to detect kernel version specific code */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-#include <linux/semaphore.h>
-#else /* pre 2.6.26 the file was in the arch specific location */
-#include <asm/semaphore.h>
-#endif
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/atomic.h>
-#include <linux/vmalloc.h>
-#include <asm/cacheflush.h>
-#include "ump_kernel_common.h"
-#include "ump_kernel_memory_backend.h"
-#include "ump_kernel_interface_ref_drv.h"
-#include "ump_kernel_memory_backend_vcm.h"
-#include "../common/ump_uk_types.h"
-#include <linux/vcm-drv.h>
-#include <plat/s5p-vcm.h>
-#include <linux/dma-mapping.h>
-
-#define UMP_REF_DRV_UK_VCM_DEV_G2D 12
-
-typedef struct ump_vcm {
- struct vcm *vcm;
- struct vcm_res *vcm_res;
- unsigned int dev_id;
-} ump_vcm;
-
-typedef struct vcm_allocator {
- struct semaphore mutex;
- u32 num_vcm_blocks;
-} vcm_allocator;
-
-static void ump_vcm_free(void* ctx, ump_dd_mem * descriptor);
-static int ump_vcm_allocate(void* ctx, ump_dd_mem * descriptor);
-static void *vcm_res_get(ump_dd_mem *mem, void* args);
-static void vcm_attr_set(ump_dd_mem *mem, void* args);
-static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor);
-static void vcm_memory_backend_destroy(ump_memory_backend * backend);
-
-
-/*
- * Create VCM memory backend
- */
-ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation)
-{
- ump_memory_backend * backend;
- vcm_allocator * info;
-
- info = kmalloc(sizeof(vcm_allocator), GFP_KERNEL);
- if (NULL == info)
- {
- return NULL;
- }
-
- info->num_vcm_blocks = 0;
-
-
- sema_init(&info->mutex, 1);
-
- backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL);
- if (NULL == backend)
- {
- kfree(info);
- return NULL;
- }
-
- backend->ctx = info;
- backend->allocate = ump_vcm_allocate;
- backend->release = ump_vcm_free;
- backend->shutdown = vcm_memory_backend_destroy;
- backend->pre_allocate_physical_check = NULL;
- backend->adjust_to_mali_phys = NULL;
-
- backend->get = vcm_res_get;
- backend->set = vcm_attr_set;
-
-
- return backend;
-}
-
-/*
- * Destroy specified VCM memory backend
- */
-static void vcm_memory_backend_destroy(ump_memory_backend * backend)
-{
- vcm_allocator * info = (vcm_allocator*)backend->ctx;
-#if 0
- DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated));
-#endif
- kfree(info);
- kfree(backend);
-}
-
-/*
- * Allocate UMP memory
- */
-static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor)
-{
- int ret; /* success */
- vcm_allocator *info;
- struct ump_vcm *ump_vcm;
-
- BUG_ON(!descriptor);
- BUG_ON(!ctx);
-
- info = (vcm_allocator*)ctx;
-
- ump_vcm = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL);
- if (NULL == ump_vcm)
- {
- return 0;
- }
-
- ump_vcm->dev_id = (int)descriptor->backend_info & ~UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE;
-
- if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_NONE) { /* None */
- ump_vcm->dev_id = UMP_REF_DRV_UK_VCM_DEV_G2D; /* this ID is G2D */
- }
- else if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR) { /* Physical Linear */
- return 0;
- }
- else { /* Other VCM */
- ump_vcm->dev_id -= 2;
- }
-
- DBG_MSG(5, ("Device ID for VCM : %d\n", ump_vcm->dev_id));
- ump_vcm->vcm = vcm_find_vcm(ump_vcm->dev_id);
-
- if (!ump_vcm->vcm)
- {
- return 0;
- }
- descriptor->backend_info = (void*)ump_vcm;
-
- if (down_interruptible(&info->mutex)) {
- DBG_MSG(1, ("Failed to get mutex in ump_vcm_allocate\n"));
- return 0; /* failure */
- }
-
- ret = vcm_mem_allocator(info, descriptor);
- up(&info->mutex);
-
- return ret; /* success */
-}
-
-static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor)
-{
- unsigned long num_blocks;
- int i;
- struct vcm_phys *phys;
- struct vcm_phys_part *part;
- int size_total = 0;
- struct ump_vcm *ump_vcm;
-
- ump_vcm = (struct ump_vcm*)descriptor->backend_info;
-
- ump_vcm->vcm_res =
- vcm_make_binding(ump_vcm->vcm, descriptor->size_bytes,
- ump_vcm->dev_id, 0);
-
- phys = ump_vcm->vcm_res->phys;
- part = phys->parts;
- num_blocks = phys->count;
-
- DBG_MSG(5,
- ("Allocating page array. Size: %lu, VCM Reservation : 0x%x\n",
- phys->count * sizeof(ump_dd_physical_block),
- ump_vcm->vcm_res->start));
-
- /* Now, make a copy of the block information supplied by the user */
- descriptor->block_array =
- (ump_dd_physical_block *) vmalloc(sizeof(ump_dd_physical_block) *
- num_blocks);
-
- if (NULL == descriptor->block_array) {
- vfree(descriptor->block_array);
- DBG_MSG(1, ("Could not allocate a mem handle for function.\n"));
- return 0; /* failure */
- }
-
- for (i = 0; i < num_blocks; i++) {
- descriptor->block_array[i].addr = part->start;
- descriptor->block_array[i].size = part->size;
-
- dmac_unmap_area(phys_to_virt(part->start), part->size, DMA_FROM_DEVICE);
- outer_inv_range(part->start, part->start + part->size);
-
- ++part;
- size_total += descriptor->block_array[i].size;
- DBG_MSG(6,
- ("UMP memory created with VCM. addr 0x%x, size: 0x%x\n",
- descriptor->block_array[i].addr,
- descriptor->block_array[i].size));
- }
-
- descriptor->size_bytes = size_total;
- descriptor->nr_blocks = num_blocks;
- descriptor->ctx = NULL;
-
- info->num_vcm_blocks += num_blocks;
- return 1;
-}
-
-/*
- * Free specified UMP memory
- */
-static void ump_vcm_free(void *ctx, ump_dd_mem * descriptor)
-{
- struct ump_vcm *ump_vcm;
- vcm_allocator *info;
-
- BUG_ON(!descriptor);
- BUG_ON(!ctx);
-
- ump_vcm = (struct ump_vcm*)descriptor->backend_info;
- info = (vcm_allocator*)ctx;
-
- BUG_ON(descriptor->nr_blocks > info->num_vcm_blocks);
-
- if (down_interruptible(&info->mutex)) {
- DBG_MSG(1, ("Failed to get mutex in ump_vcm_free\n"));
- return;
- }
-
- DBG_MSG(5, ("Releasing %lu VCM pages\n", descriptor->nr_blocks));
-
- info->num_vcm_blocks -= descriptor->nr_blocks;
-
- up(&info->mutex);
-
- DBG_MSG(6, ("Freeing physical page by VCM\n"));
- vcm_destroy_binding(ump_vcm->vcm_res);
- ump_vcm->vcm = NULL;
- ump_vcm->vcm_res = NULL;
-
- kfree(ump_vcm);
- vfree(descriptor->block_array);
-}
-
-static void *vcm_res_get(ump_dd_mem *mem, void *args)
-{
- struct ump_vcm *ump_vcm;
- enum vcm_dev_id vcm_id;
-
- ump_vcm = (struct ump_vcm*)mem->backend_info;
- vcm_id = (enum vcm_dev_id)args;
-
- if (vcm_reservation_in_vcm
- (vcm_find_vcm(vcm_id), ump_vcm->vcm_res)
- == S5PVCM_RES_NOT_IN_VCM)
- return NULL;
- else
- return ump_vcm->vcm_res;
-}
-
-static void vcm_attr_set(ump_dd_mem *mem, void *args)
-{
- struct ump_vcm *ump_vcm, *ump_vcmh;
-
- ump_vcm = (struct ump_vcm*)args;
-
- ump_vcmh = kmalloc(sizeof(struct ump_vcm), GFP_KERNEL);
- if (NULL == ump_vcmh)
- {
- return;
- }
-
- ump_vcmh->dev_id = ump_vcm->dev_id;
- ump_vcmh->vcm = ump_vcm->vcm;
- ump_vcmh->vcm_res = ump_vcm->vcm_res;
-
- mem->backend_info= (void*)ump_vcmh;
-
- return;
-}
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
deleted file mode 100644
index c1ead0d..0000000
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
+++ /dev/null
@@ -1,22 +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.
- */
-
-/**
- * @file ump_kernel_memory_backend_vcm.h
- */
-
-#ifndef __UMP_KERNEL_MEMORY_BACKEND_VCM_H__
-#define __UMP_KERNEL_MEMORY_BACKEND_VCM_H__
-
-#include "ump_kernel_memory_backend.h"
-
-ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation);
-
-#endif /* __UMP_KERNEL_MEMORY_BACKEND_VCM_H__ */