From c28265764ec6ad9995eb0c761a376ffc9f141fcd Mon Sep 17 00:00:00 2001 From: codeworkx Date: Mon, 17 Sep 2012 17:53:57 +0200 Subject: applied patches from i9305 jb sources, updated mali to r3p0 Change-Id: Iec4bc4e2fb59e2cf5b4d25568a644d4e3719565e --- drivers/media/Makefile | 2 +- drivers/media/video/Kconfig | 10 +- drivers/media/video/Makefile | 4 + drivers/media/video/isx012.c | 1021 +- drivers/media/video/isx012.h | 108 +- drivers/media/video/isx012_regs.h | 1862 +-- drivers/media/video/m5mo.c | 41 +- drivers/media/video/m5mo.h | 1 + drivers/media/video/m9mo.c | 11797 ++++++++++++++---- drivers/media/video/m9mo.h | 230 +- drivers/media/video/s5c73m3.c | 208 +- drivers/media/video/s5c73m3.h | 26 +- drivers/media/video/s5k5bbgx.c | 1738 +++ drivers/media/video/s5k5bbgx.h | 117 + drivers/media/video/s5k5bbgx_setfile.h | 12066 +++++++++++++++++++ drivers/media/video/s5k5ccgx.c | 143 +- drivers/media/video/s5k5ccgx.h | 38 +- drivers/media/video/samsung/Makefile | 19 + drivers/media/video/samsung/fimc/Kconfig | 9 + drivers/media/video/samsung/fimc/fimc.h | 42 +- drivers/media/video/samsung/fimc/fimc_capture.c | 376 +- drivers/media/video/samsung/fimc/fimc_capture_u1.c | 45 - drivers/media/video/samsung/fimc/fimc_dev.c | 334 +- drivers/media/video/samsung/fimc/fimc_dev_u1.c | 26 +- drivers/media/video/samsung/fimc/fimc_output.c | 92 +- drivers/media/video/samsung/fimc/fimc_regs.c | 7 + drivers/media/video/samsung/fimc/fimc_v4l2.c | 130 + .../video/samsung/fimg2d3x-exynos4/fimg2d_dev.c | 35 +- .../media/video/samsung/fimg2d4x-exynos4/fimg2d.h | 12 + .../video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c | 9 +- .../video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c | 17 +- .../video/samsung/fimg2d4x-exynos4/fimg2d_cache.c | 87 + .../video/samsung/fimg2d4x-exynos4/fimg2d_cache.h | 10 + .../video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c | 64 +- .../video/samsung/fimg2d4x-exynos4/fimg2d_drv.c | 64 +- drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h | 44 +- drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c | 29 +- drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h | 5 + drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c | 103 +- drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h | 2 +- drivers/media/video/samsung/mali/Kconfig | 10 +- drivers/media/video/samsung/mali/Makefile | 207 +- drivers/media/video/samsung/mali/Makefile.common | 59 - drivers/media/video/samsung/mali/Makefile_module | 89 + drivers/media/video/samsung/mali/arch | 1 - .../media/video/samsung/mali/arch-debug/config.h | 154 + .../video/samsung/mali/arch-orion-m400/config.h | 154 - .../samsung/mali/arch-pb-virtex5-m300/config.h | 85 + .../mali/arch-pb-virtex5-m400-1-direct/config.h | 92 + .../mali/arch-pb-virtex5-m400-1-pmu/config.h | 85 + .../samsung/mali/arch-pb-virtex5-m400-1/config.h | 77 + .../samsung/mali/arch-pb-virtex5-m400-2/config.h | 91 + .../samsung/mali/arch-pb-virtex5-m400-3/config.h | 105 + .../samsung/mali/arch-pb-virtex5-m400-4/config.h | 119 + .../video/samsung/mali/arch-pegasus-m400/config.h | 154 + .../media/video/samsung/mali/arch-release/config.h | 154 + .../samsung/mali/arch-ve-virtex6-m450-8/config.h | 168 + drivers/media/video/samsung/mali/arch/config.h | 154 + .../samsung/mali/common/mali_block_allocator.c | 6 +- .../media/video/samsung/mali/common/mali_cluster.c | 218 + .../media/video/samsung/mali/common/mali_cluster.h | 44 + .../samsung/mali/common/mali_device_pause_resume.c | 46 + .../samsung/mali/common/mali_device_pause_resume.h | 31 + .../media/video/samsung/mali/common/mali_dlbu.c | 285 + .../media/video/samsung/mali/common/mali_dlbu.h | 45 + drivers/media/video/samsung/mali/common/mali_gp.c | 693 ++ drivers/media/video/samsung/mali/common/mali_gp.h | 46 + .../media/video/samsung/mali/common/mali_gp_job.c | 49 + .../media/video/samsung/mali/common/mali_gp_job.h | 131 + .../video/samsung/mali/common/mali_gp_scheduler.c | 438 + .../video/samsung/mali/common/mali_gp_scheduler.h | 30 + .../media/video/samsung/mali/common/mali_group.c | 841 ++ .../media/video/samsung/mali/common/mali_group.h | 146 + .../media/video/samsung/mali/common/mali_hw_core.c | 46 + .../media/video/samsung/mali/common/mali_hw_core.h | 71 + .../video/samsung/mali/common/mali_kernel_GP2.c | 1493 --- .../samsung/mali/common/mali_kernel_MALI200.c | 1304 -- .../video/samsung/mali/common/mali_kernel_common.h | 5 +- .../video/samsung/mali/common/mali_kernel_core.c | 1359 ++- .../video/samsung/mali/common/mali_kernel_core.h | 127 +- .../mali/common/mali_kernel_descriptor_mapping.c | 15 +- .../mali/common/mali_kernel_descriptor_mapping.h | 6 +- .../video/samsung/mali/common/mali_kernel_gp.h | 21 - .../samsung/mali/common/mali_kernel_l2_cache.c | 517 - .../samsung/mali/common/mali_kernel_l2_cache.h | 25 - .../video/samsung/mali/common/mali_kernel_mem.h | 17 - .../samsung/mali/common/mali_kernel_mem_buddy.c | 1427 --- .../samsung/mali/common/mali_kernel_mem_mmu.c | 3157 ----- .../samsung/mali/common/mali_kernel_mem_mmu.h | 75 - .../video/samsung/mali/common/mali_kernel_mem_os.c | 26 +- .../mali/common/mali_kernel_memory_engine.c | 26 +- .../mali/common/mali_kernel_memory_engine.h | 5 +- .../video/samsung/mali/common/mali_kernel_pp.h | 21 - .../samsung/mali/common/mali_kernel_profiling.c | 364 - .../samsung/mali/common/mali_kernel_profiling.h | 127 - .../samsung/mali/common/mali_kernel_rendercore.c | 2031 ---- .../samsung/mali/common/mali_kernel_rendercore.h | 565 - .../mali/common/mali_kernel_session_manager.h | 19 - .../samsung/mali/common/mali_kernel_subsystem.h | 107 - .../samsung/mali/common/mali_kernel_utilization.c | 56 +- .../samsung/mali/common/mali_kernel_utilization.h | 2 +- .../video/samsung/mali/common/mali_kernel_vsync.c | 32 +- .../video/samsung/mali/common/mali_l2_cache.c | 398 + .../video/samsung/mali/common/mali_l2_cache.h | 43 + .../samsung/mali/common/mali_mem_validation.c | 71 + .../samsung/mali/common/mali_mem_validation.h | 19 + .../media/video/samsung/mali/common/mali_memory.c | 1321 ++ .../media/video/samsung/mali/common/mali_memory.h | 80 + drivers/media/video/samsung/mali/common/mali_mmu.c | 619 + drivers/media/video/samsung/mali/common/mali_mmu.h | 55 + .../samsung/mali/common/mali_mmu_page_directory.c | 459 + .../samsung/mali/common/mali_mmu_page_directory.h | 83 + drivers/media/video/samsung/mali/common/mali_osk.h | 158 +- .../video/samsung/mali/common/mali_osk_list.h | 2 +- .../video/samsung/mali/common/mali_osk_mali.h | 32 +- .../video/samsung/mali/common/mali_osk_profiling.h | 147 + drivers/media/video/samsung/mali/common/mali_pm.c | 547 + drivers/media/video/samsung/mali/common/mali_pm.h | 56 + drivers/media/video/samsung/mali/common/mali_pmu.c | 199 + drivers/media/video/samsung/mali/common/mali_pmu.h | 70 + drivers/media/video/samsung/mali/common/mali_pp.c | 710 ++ drivers/media/video/samsung/mali/common/mali_pp.h | 47 + .../media/video/samsung/mali/common/mali_pp_job.c | 92 + .../media/video/samsung/mali/common/mali_pp_job.h | 255 + .../video/samsung/mali/common/mali_pp_scheduler.c | 542 + .../video/samsung/mali/common/mali_pp_scheduler.h | 38 + .../video/samsung/mali/common/mali_scheduler.c | 36 + .../video/samsung/mali/common/mali_scheduler.h | 21 + .../media/video/samsung/mali/common/mali_session.c | 47 + .../media/video/samsung/mali/common/mali_session.h | 65 + .../video/samsung/mali/common/mali_uk_types.h | 1176 -- drivers/media/video/samsung/mali/common/mali_ukk.h | 184 +- .../samsung/mali/common/mali_user_settings_db.c | 88 + .../samsung/mali/common/mali_user_settings_db.h | 40 + .../media/video/samsung/mali/common/pmm/mali_pmm.c | 1024 -- .../media/video/samsung/mali/common/pmm/mali_pmm.h | 348 - .../video/samsung/mali/common/pmm/mali_pmm_pmu.c | 350 - .../video/samsung/mali/common/pmm/mali_pmm_pmu.h | 86 - .../samsung/mali/common/pmm/mali_pmm_policy.c | 243 - .../samsung/mali/common/pmm/mali_pmm_policy.h | 155 - .../mali/common/pmm/mali_pmm_policy_alwayson.c | 80 - .../mali/common/pmm/mali_pmm_policy_alwayson.h | 62 - .../mali/common/pmm/mali_pmm_policy_jobcontrol.c | 470 - .../mali/common/pmm/mali_pmm_policy_jobcontrol.h | 80 - .../video/samsung/mali/common/pmm/mali_pmm_state.c | 716 -- .../video/samsung/mali/common/pmm/mali_pmm_state.h | 290 - .../samsung/mali/common/pmm/mali_pmm_system.h | 61 - .../samsung/mali/include/linux/mali/mali_utgard.h | 28 + .../mali/include/linux/mali/mali_utgard_counters.h | 264 + .../mali/include/linux/mali/mali_utgard_ioctl.h | 80 + .../linux/mali/mali_utgard_profiling_events.h | 121 + .../mali/include/linux/mali/mali_utgard_uk_types.h | 1133 ++ .../samsung/mali/linux/mali_device_pause_resume.c | 72 - .../samsung/mali/linux/mali_device_pause_resume.h | 19 - .../video/samsung/mali/linux/mali_kernel_ioctl.h | 13 +- .../video/samsung/mali/linux/mali_kernel_linux.c | 227 +- .../video/samsung/mali/linux/mali_kernel_linux.h | 8 +- .../video/samsung/mali/linux/mali_kernel_pm.c | 681 +- .../video/samsung/mali/linux/mali_kernel_pm.h | 5 +- .../video/samsung/mali/linux/mali_kernel_sysfs.c | 1007 +- .../video/samsung/mali/linux/mali_kernel_sysfs.h | 2 +- .../media/video/samsung/mali/linux/mali_linux_pm.h | 7 +- .../samsung/mali/linux/mali_linux_pm_testsuite.h | 13 +- .../video/samsung/mali/linux/mali_linux_trace.h | 132 +- .../video/samsung/mali/linux/mali_osk_indir_mmap.h | 2 +- .../media/video/samsung/mali/linux/mali_osk_irq.c | 84 +- .../video/samsung/mali/linux/mali_osk_locks.c | 109 +- .../samsung/mali/linux/mali_osk_low_level_mem.c | 31 +- .../media/video/samsung/mali/linux/mali_osk_mali.c | 21 +- .../video/samsung/mali/linux/mali_osk_memory.c | 2 +- .../media/video/samsung/mali/linux/mali_osk_misc.c | 5 +- .../samsung/mali/linux/mali_osk_notification.c | 25 +- .../media/video/samsung/mali/linux/mali_osk_pm.c | 204 +- .../video/samsung/mali/linux/mali_osk_profiling.c | 47 - .../samsung/mali/linux/mali_osk_profiling_gator.c | 262 + .../mali/linux/mali_osk_profiling_internal.c | 308 + .../video/samsung/mali/linux/mali_osk_specific.h | 102 +- .../video/samsung/mali/linux/mali_osk_timers.c | 4 +- .../video/samsung/mali/linux/mali_osk_wait_queue.c | 73 + .../samsung/mali/linux/mali_pmu_power_up_down.c | 65 + .../samsung/mali/linux/mali_profiling_events.h | 17 + .../media/video/samsung/mali/linux/mali_uk_types.h | 19 + .../media/video/samsung/mali/linux/mali_ukk_core.c | 24 +- .../media/video/samsung/mali/linux/mali_ukk_gp.c | 21 +- .../media/video/samsung/mali/linux/mali_ukk_mem.c | 81 +- .../media/video/samsung/mali/linux/mali_ukk_pp.c | 49 +- .../video/samsung/mali/linux/mali_ukk_profiling.c | 63 +- .../video/samsung/mali/linux/mali_ukk_vsync.c | 4 +- .../video/samsung/mali/linux/mali_ukk_wrappers.h | 14 +- .../samsung/mali/platform/default/mali_platform.c | 4 +- .../video/samsung/mali/platform/mali_platform.h | 36 +- .../mali_platform_pmu_testing/mali_platform.c | 66 + .../mali/platform/orion-m400/mali_platform.c | 2 +- .../mali/platform/orion-m400/mali_platform_dvfs.c | 415 +- .../mali/platform/pegasus-m400/mali_platform.c | 118 +- .../platform/pegasus-m400/mali_platform_dvfs.c | 175 +- drivers/media/video/samsung/mali/readme.txt | 28 + .../media/video/samsung/mali/regs/mali_200_regs.h | 32 +- .../media/video/samsung/mali/regs/mali_gp_regs.h | 27 +- .../mali/timestamp-arm11-cc/mali_timestamp.c | 2 +- .../mali/timestamp-arm11-cc/mali_timestamp.h | 2 +- .../mali/timestamp-default/mali_timestamp.c | 2 +- .../mali/timestamp-default/mali_timestamp.h | 2 +- drivers/media/video/samsung/tvout/Kconfig | 10 + drivers/media/video/samsung/tvout/hw_if/hdcp.c | 20 +- drivers/media/video/samsung/tvout/hw_if/hdmi.c | 56 +- drivers/media/video/samsung/tvout/hw_if/hw_if.h | 26 + drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c | 76 +- drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c | 89 +- drivers/media/video/samsung/tvout/s5p_tvout.c | 38 +- .../video/samsung/tvout/s5p_tvout_common_lib.h | 10 + drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h | 4 +- drivers/media/video/samsung/tvout/s5p_tvout_fb.c | 16 +- drivers/media/video/samsung/tvout/s5p_tvout_hpd.c | 80 +- drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c | 115 +- drivers/media/video/samsung/tvout/s5p_vp_ctrl.c | 20 +- drivers/media/video/samsung/ump/Kconfig | 5 +- drivers/media/video/samsung/ump/Makefile | 18 +- drivers/media/video/samsung/ump/Makefile.common | 19 +- drivers/media/video/samsung/ump/Makefile_backup | 80 - drivers/media/video/samsung/ump/Makefile_module | 119 + drivers/media/video/samsung/ump/arch | 1 - .../media/video/samsung/ump/arch-debug/config.h | 22 + .../samsung/ump/arch-marcopolo-vega1-m400/config.h | 18 - .../ump/arch-marcopolo-vega1-m400/config.h.org | 87 - .../video/samsung/ump/arch-orion-m400/config.h | 14 +- .../video/samsung/ump/arch-pb-virtex5/config.h | 4 +- .../video/samsung/ump/arch-pegasus-m400/config.h | 22 + .../media/video/samsung/ump/arch-release/config.h | 22 + drivers/media/video/samsung/ump/arch/config.h | 22 + .../video/samsung/ump/common/ump_kernel_api.c | 229 +- .../video/samsung/ump/common/ump_kernel_common.c | 15 +- .../video/samsung/ump/common/ump_kernel_common.h | 14 +- .../ump/common/ump_kernel_descriptor_mapping.c | 35 +- .../ump/common/ump_kernel_descriptor_mapping.h | 6 +- .../samsung/ump/common/ump_kernel_memory_backend.h | 7 +- .../video/samsung/ump/common/ump_kernel_ref_drv.c | 13 +- .../video/samsung/ump/common/ump_kernel_types.h | 24 +- drivers/media/video/samsung/ump/common/ump_osk.h | 11 +- .../media/video/samsung/ump/common/ump_uk_types.h | 75 +- drivers/media/video/samsung/ump/common/ump_ukk.h | 14 +- .../samsung/ump/include/ump_kernel_interface.h | 6 +- .../ump/include/ump_kernel_interface_ref_drv.h | 6 +- .../samsung/ump/include/ump_kernel_interface_vcm.h | 6 +- .../samsung/ump/include/ump_kernel_platform.h | 6 +- .../ump/linux/license/gpl/ump_kernel_license.h | 6 +- drivers/media/video/samsung/ump/linux/ump_ioctl.h | 16 +- .../video/samsung/ump/linux/ump_kernel_linux.c | 36 +- .../video/samsung/ump/linux/ump_kernel_linux.h | 12 +- .../linux/ump_kernel_memory_backend_dedicated.c | 19 +- .../linux/ump_kernel_memory_backend_dedicated.h | 7 +- .../ump/linux/ump_kernel_memory_backend_os.c | 16 +- .../ump/linux/ump_kernel_memory_backend_os.h | 7 +- .../ump/linux/ump_kernel_memory_backend_vcm.c | 24 +- .../ump/linux/ump_kernel_memory_backend_vcm.h | 6 +- .../video/samsung/ump/linux/ump_memory_backend.c | 7 +- .../video/samsung/ump/linux/ump_osk_atomics.c | 6 +- .../samsung/ump/linux/ump_osk_low_level_mem.c | 213 +- .../media/video/samsung/ump/linux/ump_osk_misc.c | 6 +- .../video/samsung/ump/linux/ump_ukk_ref_wrappers.c | 6 +- .../video/samsung/ump/linux/ump_ukk_ref_wrappers.h | 6 +- .../video/samsung/ump/linux/ump_ukk_wrappers.c | 143 +- .../video/samsung/ump/linux/ump_ukk_wrappers.h | 10 +- drivers/media/video/slp_db8131m.c | 796 ++ drivers/media/video/slp_db8131m.h | 100 + drivers/media/video/slp_db8131m_setfile.h | 2264 ++++ drivers/media/video/slp_s5c73m3.c | 3415 ++++++ drivers/media/video/slp_s5c73m3.h | 516 + drivers/media/video/slp_s5k4ecgx.c | 2335 ++++ drivers/media/video/slp_s5k4ecgx.h | 195 + drivers/media/video/slp_s5k4ecgx_setfile.h | 7308 +++++++++++ drivers/media/video/sr200pc20m.h | 8 - drivers/media/video/sr200pc20m_regs-s2plus.h | 4168 ------- drivers/media/video/v4l2-ioctl.c | 4 + 274 files changed, 61722 insertions(+), 28463 deletions(-) create mode 100644 drivers/media/video/s5k5bbgx.c create mode 100644 drivers/media/video/s5k5bbgx.h create mode 100644 drivers/media/video/s5k5bbgx_setfile.h delete mode 100644 drivers/media/video/samsung/mali/Makefile.common create mode 100644 drivers/media/video/samsung/mali/Makefile_module delete mode 120000 drivers/media/video/samsung/mali/arch create mode 100644 drivers/media/video/samsung/mali/arch-debug/config.h delete mode 100644 drivers/media/video/samsung/mali/arch-orion-m400/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h create mode 100644 drivers/media/video/samsung/mali/arch-pegasus-m400/config.h create mode 100644 drivers/media/video/samsung/mali/arch-release/config.h create mode 100644 drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h create mode 100644 drivers/media/video/samsung/mali/arch/config.h create mode 100644 drivers/media/video/samsung/mali/common/mali_cluster.c create mode 100644 drivers/media/video/samsung/mali/common/mali_cluster.h create mode 100644 drivers/media/video/samsung/mali/common/mali_device_pause_resume.c create mode 100644 drivers/media/video/samsung/mali/common/mali_device_pause_resume.h create mode 100644 drivers/media/video/samsung/mali/common/mali_dlbu.c create mode 100644 drivers/media/video/samsung/mali/common/mali_dlbu.h create mode 100644 drivers/media/video/samsung/mali/common/mali_gp.c create mode 100644 drivers/media/video/samsung/mali/common/mali_gp.h create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_job.c create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_job.h create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_scheduler.c create mode 100644 drivers/media/video/samsung/mali/common/mali_gp_scheduler.h create mode 100644 drivers/media/video/samsung/mali/common/mali_group.c create mode 100644 drivers/media/video/samsung/mali/common/mali_group.h create mode 100644 drivers/media/video/samsung/mali/common/mali_hw_core.c create mode 100644 drivers/media/video/samsung/mali/common/mali_hw_core.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_GP2.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_gp.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_pp.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_profiling.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_profiling.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_session_manager.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h create mode 100644 drivers/media/video/samsung/mali/common/mali_l2_cache.c create mode 100644 drivers/media/video/samsung/mali/common/mali_l2_cache.h create mode 100644 drivers/media/video/samsung/mali/common/mali_mem_validation.c create mode 100644 drivers/media/video/samsung/mali/common/mali_mem_validation.h create mode 100644 drivers/media/video/samsung/mali/common/mali_memory.c create mode 100644 drivers/media/video/samsung/mali/common/mali_memory.h create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu.c create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu.h create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c create mode 100644 drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h create mode 100644 drivers/media/video/samsung/mali/common/mali_osk_profiling.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pm.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pm.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pmu.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pmu.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pp.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pp.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_job.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_job.h create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_scheduler.c create mode 100644 drivers/media/video/samsung/mali/common/mali_pp_scheduler.h create mode 100644 drivers/media/video/samsung/mali/common/mali_scheduler.c create mode 100644 drivers/media/video/samsung/mali/common/mali_scheduler.h create mode 100644 drivers/media/video/samsung/mali/common/mali_session.c create mode 100644 drivers/media/video/samsung/mali/common/mali_session.h delete mode 100644 drivers/media/video/samsung/mali/common/mali_uk_types.h create mode 100644 drivers/media/video/samsung/mali/common/mali_user_settings_db.c create mode 100644 drivers/media/video/samsung/mali/common/mali_user_settings_db.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm.c delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h delete mode 100644 drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h create mode 100644 drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c delete mode 100644 drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h delete mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c create mode 100644 drivers/media/video/samsung/mali/linux/mali_profiling_events.h create mode 100644 drivers/media/video/samsung/mali/linux/mali_uk_types.h create mode 100644 drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c create mode 100644 drivers/media/video/samsung/mali/readme.txt delete mode 100644 drivers/media/video/samsung/ump/Makefile_backup create mode 100644 drivers/media/video/samsung/ump/Makefile_module delete mode 120000 drivers/media/video/samsung/ump/arch create mode 100644 drivers/media/video/samsung/ump/arch-debug/config.h delete mode 100644 drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h delete mode 100755 drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org create mode 100644 drivers/media/video/samsung/ump/arch-pegasus-m400/config.h create mode 100644 drivers/media/video/samsung/ump/arch-release/config.h create mode 100644 drivers/media/video/samsung/ump/arch/config.h create mode 100644 drivers/media/video/slp_db8131m.c create mode 100644 drivers/media/video/slp_db8131m.h create mode 100644 drivers/media/video/slp_db8131m_setfile.h create mode 100644 drivers/media/video/slp_s5c73m3.c create mode 100644 drivers/media/video/slp_s5c73m3.h create mode 100644 drivers/media/video/slp_s5k4ecgx.c create mode 100644 drivers/media/video/slp_s5k4ecgx.h create mode 100644 drivers/media/video/slp_s5k4ecgx_setfile.h delete mode 100644 drivers/media/video/sr200pc20m_regs-s2plus.h (limited to 'drivers/media') diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 01d6967..7f8a1cc 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -13,4 +13,4 @@ obj-y += common/ rc/ video/ obj-$(CONFIG_VIDEO_DEV) += radio/ obj-$(CONFIG_DVB_CORE) += dvb/ obj-$(CONFIG_TDMB) += tdmb/ -obj-$(CONFIG_ISDBT_FC8100) += isdbt/ +obj-$(CONFIG_ISDBT) += isdbt/ diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 8298e84..aeedd90 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -442,7 +442,7 @@ endchoice config VIDEO_S5K4E5 tristate "S5K4E5 supporting camera driver" - depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS + depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS ---help--- This driver supports S5K4E5 sensor. choice @@ -478,7 +478,7 @@ endchoice config VIDEO_S5K6A3 tristate "S5K6A3 supporting camera driver" - depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS + depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS ---help--- This driver supports S5K6A3 sensor. choice @@ -530,6 +530,12 @@ config VIDEO_S5K5BAFX ---help--- This driver supports S5K5BAFX SoC camera module +config VIDEO_S5K5BBGX + tristate "S5K5BBGX supporting camera driver" + depends on I2C && VIDEO_V4L2 && TARGET_LOCALE_NA && VIDEO_FIMC_MIPI + ---help--- + This driver supports S5K5BBGX SoC camera module + config VIDEO_S5K5CCGX_COMMON tristate "S5K5CCGX supporting camera driver" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 805f5fd..1ad29ec 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -81,6 +81,7 @@ ifeq ($(CONFIG_MACH_PX),y) obj-$(CONFIG_VIDEO_S5K5BAFX) += s5k5bafx-v2.o else obj-$(CONFIG_VIDEO_S5K5BAFX) += s5k5bafx.o +obj-$(CONFIG_VIDEO_S5K5BBGX) += s5k5bbgx.o endif obj-$(CONFIG_VIDEO_S5K5CCGX_COMMON) += s5k5ccgx.o obj-$(CONFIG_VIDEO_SR200PC20) += sr200pc20-p2.o @@ -91,6 +92,9 @@ obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3.o obj-$(CONFIG_VIDEO_ISX012) += isx012.o obj-$(CONFIG_VIDEO_S5C73M3_SPI) += s5c73m3_spi.o +obj-$(CONFIG_VIDEO_SLP_S5C73M3) += slp_s5c73m3.o +obj-$(CONFIG_VIDEO_SLP_S5K4ECGX) += slp_s5k4ecgx.o +obj-$(CONFIG_VIDEO_SLP_DB8131M) += slp_db8131m.o obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o diff --git a/drivers/media/video/isx012.c b/drivers/media/video/isx012.c index ff2cbb0..8223d58 100644 --- a/drivers/media/video/isx012.c +++ b/drivers/media/video/isx012.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * - change date: 2012.04.25 + * - change date: 2012.06.28 */ #include "isx012.h" #include @@ -23,9 +23,15 @@ #define isx012_writeb(sd, addr, data) isx012_i2c_write(sd, addr, data, 1) #define isx012_writew(sd, addr, data) isx012_i2c_write(sd, addr, data, 2) #define isx012_writel(sd, addr, data) isx012_i2c_write(sd, addr, data, 4) +#define isx012_wait_ae_stable_af(sd) isx012_wait_ae_stable(sd, true, false) +#define isx012_wait_ae_stable_preview(sd) isx012_wait_ae_stable(sd, false, true) +#define isx012_wait_ae_stable_cap(sd) isx012_wait_ae_stable(sd, false, false) + +static int dbg_level; static const struct isx012_fps isx012_framerates[] = { { I_FPS_0, FRAME_RATE_AUTO }, + { I_FPS_7, FRAME_RATE_7}, { I_FPS_15, FRAME_RATE_15 }, { I_FPS_25, FRAME_RATE_25 }, { I_FPS_30, FRAME_RATE_30 }, @@ -48,6 +54,7 @@ static const struct isx012_framesize isx012_preview_frmsizes[] = { static const struct isx012_framesize isx012_capture_frmsizes[] = { { CAPTURE_SZ_VGA, 640, 480 }, + { CAPTURE_SZ_960_720, 960, 720 }, { CAPTURE_SZ_W1MP, 1536, 864 }, { CAPTURE_SZ_2MP, 1600, 1200 }, { CAPTURE_SZ_W2MP, 2048, 1152 }, @@ -112,6 +119,9 @@ static const struct isx012_regs reg_datas = { ISX012_REGSET(IMAGE_EFFECT_SEPIA, isx012_Effect_Sepia), ISX012_REGSET(IMAGE_EFFECT_NEGATIVE, ISX012_Effect_Negative), + ISX012_REGSET(IMAGE_EFFECT_SOLARIZE, isx012_Effect_Solar), + ISX012_REGSET(IMAGE_EFFECT_SKETCH, isx012_Effect_Sketch), + ISX012_REGSET(IMAGE_EFFECT_POINT_COLOR_3, isx012_Effect_Pastel), }, .white_balance = { ISX012_REGSET(WHITE_BALANCE_AUTO, isx012_WB_Auto), @@ -162,14 +172,13 @@ static const struct isx012_regs reg_datas = { ISX012_REGSET(SHARPNESS_PLUS_1, isx012_Sharpness_Plus_1), ISX012_REGSET(SHARPNESS_PLUS_2, isx012_Sharpness_Plus_2), }, - .fps = { ISX012_REGSET(I_FPS_0, isx012_fps_auto), + ISX012_REGSET(I_FPS_7, isx012_fps_7fix), ISX012_REGSET(I_FPS_15, isx012_fps_15fix), ISX012_REGSET(I_FPS_25, isx012_fps_25fix), ISX012_REGSET(I_FPS_30, isx012_fps_30fix), }, - .preview_size = { ISX012_REGSET(PREVIEW_SZ_320x240, isx012_320_Preview), ISX012_REGSET(PREVIEW_SZ_VGA, isx012_640_Preview), @@ -179,21 +188,10 @@ static const struct isx012_regs reg_datas = { }, .capture_size = { ISX012_REGSET(CAPTURE_SZ_VGA, isx012_VGA_Capture), + ISX012_REGSET(CAPTURE_SZ_960_720, isx012_960_720_Capture), ISX012_REGSET(CAPTURE_SZ_3MP, isx012_3M_Capture), ISX012_REGSET(CAPTURE_SZ_5MP, isx012_5M_Capture), }, -#if 0 /* DSLIM: Should be implemented */ - .preview_return = ISX012_REGSET_TABLE(s5k5ccgx_preview_return), - - .ae_lock_on = - ISX012_REGSET_TABLE(s5k5ccgx_ae_lock), - .ae_lock_off = - ISX012_REGSET_TABLE(s5k5ccgx_ae_unlock), - .awb_lock_on = - ISX012_REGSET_TABLE(s5k5ccgx_awb_lock), - .awb_lock_off = - ISX012_REGSET_TABLE(s5k5ccgx_awb_unlock), -#endif /* AF */ .af_window_reset = ISX012_REGSET_TABLE(ISX012_AF_Window_Reset), @@ -211,11 +209,11 @@ static const struct isx012_regs reg_datas = { .flash_ae_line = ISX012_REGSET_TABLE(ISX012_Flash_AELINE), .flash_on = ISX012_REGSET_TABLE(ISX012_Flash_ON), .flash_off = ISX012_REGSET_TABLE(ISX012_Flash_OFF), + .ae_manual = ISX012_REGSET_TABLE(ISX012_ae_manual_mode), + .flash_fast_ae_awb = ISX012_REGSET_TABLE(ISX012_flash_fast_ae_awb), .init_reg = ISX012_REGSET_TABLE(ISX012_Init_Reg), -#if 0 /* DSLIM: Should be implemented */ - .get_esd_status = ISX012_REGSET_TABLE(s5k5ccgx_get_esd_reg), -#endif + /* Camera mode */ .preview_mode = ISX012_REGSET_TABLE(ISX012_Preview_Mode), .capture_mode = ISX012_REGSET_TABLE(ISX012_Capture_Mode), @@ -252,13 +250,16 @@ static void msleep_debug(u32 msecs, bool dbg_on) { u32 delta_halfrange; /* in us unit */ + if (unlikely(!msecs)) + return; + if (dbg_on) cam_dbg("delay for %dms\n", msecs); - if (msecs <= 5) + if (msecs <= 7) delta_halfrange = 100; else - delta_halfrange = 500; + delta_halfrange = 300; if (msecs <= 20) usleep_range((msecs * 1000 - delta_halfrange), @@ -358,7 +359,15 @@ static int isx012_define_table(void) printk(KERN_DEBUG "isx012_define_table start!\n"); start = strstr(isx012_regs_table, "aeoffset_table"); + if (!start) { + cam_err("%s: can not find %s", __func__, "aeoffset_table"); + return -ENOENT; + } end = strstr(start, "};"); + if (!end) { + cam_err("%s: can not find %s end", __func__, "aeoffset_table"); + return -ENOENT; + } /* Find table */ index_2 = 0; @@ -440,7 +449,15 @@ static int isx012_define_read(char *name, int len_size) //printk(KERN_DEBUG "isx012_define_read start!\n"); start = strstr(isx012_regs_table, name); + if (!start) { + cam_err("%s: can not find %s", __func__, name); + return -ENOENT; + } end = strstr(start, "tuning"); + if (!end) { + cam_err("%s: can not find %s", __func__, "tuning"); + return -ENOENT; + } reg = strstr(start," "); @@ -690,7 +707,7 @@ static int isx012_i2c_read(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); u8 buf[16] = {0,}; struct i2c_msg msg[2]; - int err, retry = 3; + int err, retry = 5; if (unlikely(!client->adapter)) { @@ -724,7 +741,7 @@ static int isx012_i2c_read(struct v4l2_subdev *sd, msleep_debug(POLL_TIME_MS, false); } while (retry-- > 0); - CHECK_ERR_COND_MSG(err != 2, -EIO, "I2C does not working\n"); + CHECK_ERR_COND_MSG(err != 2, -EIO, "I2C does not work\n"); #ifdef CONFIG_CAM_I2C_LITTLE_ENDIAN if (len == 1) @@ -819,7 +836,7 @@ static int isx012_i2c_write(struct v4l2_subdev *sd, msleep_debug(POLL_TIME_MS, false); } while (retry_count-- > 0); - CHECK_ERR_COND_MSG(err != 1, -EIO, "I2C does not working\n"); + CHECK_ERR_COND_MSG(err != 1, -EIO, "I2C does not work\n"); return 0; } @@ -975,8 +992,7 @@ static int isx012_is_om_changed(struct v4l2_subdev *sd) for (cnt1 = 0; cnt1 < ISX012_CNT_OM_CHECK; cnt1++) { err = isx012_readb(sd, REG_INTSTS, &val); - if (unlikely(err)) - cam_err("om changed: error, readb cnt=%d\n", cnt1); + CHECK_ERR_MSG(err, "om changed: error, readb cnt=%d\n", cnt1); if ((val & REG_INTBIT_OM) == REG_INTBIT_OM) { status &= ~0x01; @@ -988,8 +1004,7 @@ static int isx012_is_om_changed(struct v4l2_subdev *sd) for (cnt2 = 0; cnt2 < ISX012_CNT_OM_CHECK; cnt2++) { err = isx012_writeb(sd, REG_INTCLR, REG_INTBIT_OM); err |= isx012_readb(sd, REG_INTSTS, &val); - if (unlikely(err)) - cam_err("om changed: error, rw cnt=%d\n", cnt2); + CHECK_ERR_MSG(err, "om changed: clear error, rw\n"); if ((val & REG_INTBIT_OM) == 0) { status &= ~0x02; @@ -998,13 +1013,13 @@ static int isx012_is_om_changed(struct v4l2_subdev *sd) msleep_debug(5, false); } - cam_dbg("om changed: sucess. int cnt=%d, clr cnt=%d\n", cnt1, cnt2); - if (unlikely(status)) { cam_err("om changed: error, fail 0x%X\n", status); return -EAGAIN; } + cam_dbg("om changed: int cnt=%d, clr cnt=%d\n", cnt1, cnt2); + return 0; } @@ -1032,8 +1047,9 @@ static int isx012_is_cm_changed(struct v4l2_subdev *sd) for (cnt2 = 0; cnt2 < ISX012_CNT_CM_CHECK; cnt2++) { err = isx012_writeb(sd, REG_INTCLR, REG_INTBIT_CM); - CHECK_ERR_MSG(err, "cm changed: error, writeb\n"); - isx012_readb(sd, REG_INTSTS, &val); + err |= isx012_readb(sd, REG_INTSTS, &val); + CHECK_ERR_MSG(err, "cm changed: clear error, rw\n"); + if ((val & REG_INTBIT_CM) == 0) { status &= ~0x02; break; @@ -1042,24 +1058,27 @@ static int isx012_is_cm_changed(struct v4l2_subdev *sd) msleep_debug(5, false); } - cam_dbg("cm changed: int cnt=%d, clr cnt=%d\n", cnt1, cnt2); - if (unlikely(status)) { cam_err("cm changed: error, fail 0x%X\n", status); return -EAGAIN; } + cam_dbg("cm changed: int cnt=%d, clr cnt=%d\n", cnt1, cnt2); + return 0; } static inline int isx012_transit_preview_mode(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); - int err = -EIO; - err = isx012_set_from_table(sd, "preview_mode", + isx012_restore_sensor_flash(sd); + + if (state->exposure.ae_lock || state->wb.awb_lock) + cam_info("Restore user ae(awb)-lock...\n"); + + return isx012_set_from_table(sd, "preview_mode", &state->regs->preview_mode, 1, 0); - return err; } /** @@ -1078,11 +1097,11 @@ static inline int isx012_transit_half_mode(struct v4l2_subdev *sd) if (state->scene_mode == SCENE_MODE_NIGHTSHOT && state->light_level >= LUX_LEVEL_LOW) { cam_info("half_mode: night lowlux\n"); - state->lowlux_night = 1; + state->capture.lowlux_night = 1; err = isx012_set_from_table(sd, "night_halfrelease_mode", &state->regs->halfrelease_mode_night, 1, 0); } else { - state->lowlux_night = 0; + state->capture.lowlux_night = 0; err = isx012_set_from_table(sd, "halfrelease", &state->regs->halfrelease_mode, 1, 0); } @@ -1096,11 +1115,8 @@ static inline int isx012_transit_capture_mode(struct v4l2_subdev *sd) struct isx012_state *state = to_state(sd); int err = -EIO; - if (state->lowlux_night) { + if (state->capture.lowlux_night) { cam_info("capture_mode: night lowlux\n"); -#if !defined(CONFIG_NEW_STREAM_DELAY) - state->lowlux_night = 0; -#endif err = isx012_set_from_table(sd, "capture_mode_night", &state->regs->capture_mode_night, 1, 0); } else @@ -1260,7 +1276,7 @@ static void isx012_frame_checker(struct work_struct *work) if (((u8)val & ISX012_INTSRC_VINT) == ISX012_INTSRC_VINT) { ++int_cnt; - cam_info("frame INT %d (cnt=%d)\n", int_cnt, cnt); + cam_info("frame_INT %d (cnt=%d)\n", int_cnt, cnt); if (int_cnt >= 2) { state->frame_check = false; return; @@ -1279,7 +1295,7 @@ static void isx012_frame_checker(struct work_struct *work) return; } - msleep_debug(10, false); + msleep_debug(3, false); } cam_err("frame INT Not occured!\n"); @@ -1330,7 +1346,7 @@ static void isx012_stop_frame_checker(struct v4l2_subdev *sd) /** * isx012_is_hwflash_on - check whether flash device is on * - * Refer to state->flash_on to check whether flash is in use in driver. + * Refer to state->flash.on to check whether flash is in use in driver. */ static inline int isx012_is_hwflash_on(struct v4l2_subdev *sd) { @@ -1352,7 +1368,7 @@ static int isx012_flash_en(struct v4l2_subdev *sd, s32 mode, s32 onoff) { struct isx012_state *state = to_state(sd); - if (unlikely(state->ignore_flash)) { + if (unlikely(state->flash.ignore_flash)) { cam_warn("WARNING, we ignore flash command.\n"); return 0; } @@ -1368,7 +1384,7 @@ static int isx012_flash_en(struct v4l2_subdev *sd, s32 mode, s32 onoff) * isx012_flash_torch - turn flash on/off as torch for preflash, recording * @onoff: ISX012_FLASH_ON or ISX012_FLASH_OFF * - * This func set state->flash_on properly. + * This func set state->flash.on properly. */ static inline int isx012_flash_torch(struct v4l2_subdev *sd, s32 onoff) { @@ -1376,7 +1392,7 @@ static inline int isx012_flash_torch(struct v4l2_subdev *sd, s32 onoff) int err = 0; err = isx012_flash_en(sd, ISX012_FLASH_MODE_MOVIE, onoff); - state->flash_on = (onoff == ISX012_FLASH_ON) ? 1 : 0; + state->flash.on = (onoff == ISX012_FLASH_ON) ? 1 : 0; return err; } @@ -1393,9 +1409,7 @@ static inline int isx012_flash_oneshot(struct v4l2_subdev *sd, s32 onoff) int err = 0; err = isx012_flash_en(sd, ISX012_FLASH_MODE_NORMAL, onoff); - - /* The flash_on here is only used for EXIF */ - state->flash_on = (onoff == ISX012_FLASH_ON) ? 1 : 0; + state->flash.on = (onoff == ISX012_FLASH_ON) ? 1 : 0; return err; } @@ -1441,7 +1455,8 @@ static void isx012_set_framesize(struct v4l2_subdev *sd, cam_dbg("%s: Requested Res %dx%d\n", __func__, width, height); - found_frmsize = (preview ? &state->preview : &state->capture); + found_frmsize = preview ? + &state->preview.frmsize : &state->capture.frmsize; for (i = 0; i < num_frmsize; i++) { if ((frmsizes[i].width == width) && @@ -1538,9 +1553,19 @@ static int isx012_set_exposure(struct v4l2_subdev *sd, s32 val) static inline u32 isx012_get_light_level(struct v4l2_subdev *sd, u32 *light_level) { - isx012_readb(sd, REG_USER_GAINLEVEL_NOW, light_level); + struct isx012_state *state = to_state(sd); + u32 val_lsb = 0, val_msb = 0; + + if (state->iso == ISO_AUTO) + isx012_readb(sd, REG_USER_GAINLEVEL_NOW, light_level); + else { + isx012_readw(sd, REG_SHT_TIME_OUT_L, &val_lsb); + isx012_readw(sd, REG_SHT_TIME_OUT_H, &val_msb); + + *light_level = (val_msb << 16) | (val_lsb & 0xFFFF); + } - cam_trace("X, light level = 0x%X", *light_level); + cam_trace("X, iso = %d, light level = 0x%X", state->iso, *light_level); return 0; } @@ -1549,19 +1574,23 @@ static inline u32 isx012_get_light_level(struct v4l2_subdev *sd, static int isx012_set_capture_size(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); + u32 width, height; - if (unlikely(!state->capture)) { + if (unlikely(!state->capture.frmsize)) { cam_warn("warning, capture resolution not set\n"); - state->capture = isx012_get_framesize(isx012_capture_frmsizes, + state->capture.frmsize = isx012_get_framesize( + isx012_capture_frmsizes, ARRAY_SIZE(isx012_capture_frmsizes), - CAPTURE_SZ_3MP); + CAPTURE_SZ_5MP); } - cam_dbg("set capture size(%dx%d)\n", - state->capture->width, state->capture->height); + width = state->capture.frmsize->width; + height = state->capture.frmsize->height; + + cam_dbg("set capture size(%dx%d)\n", width, height); - isx012_writew(sd, REG_HSIZE_CAP, state->capture->width); - isx012_writew(sd, REG_VSIZE_CAP, state->capture->height); + isx012_writew(sd, REG_HSIZE_CAP, width); + isx012_writew(sd, REG_VSIZE_CAP, height); return 0; } @@ -1571,7 +1600,7 @@ static int isx012_set_sensor_mode(struct v4l2_subdev *sd, s32 val) { struct isx012_state *state = to_state(sd); - cam_trace("mode=%d\n", val); /*DSLIM*/ + cam_trace("mode=%d\n", val); switch (val) { case SENSOR_MOVIE: @@ -1640,6 +1669,7 @@ static int isx012_set_ae_lock(struct v4l2_subdev *sd, s32 lock, bool force) isx012_readb(sd, REG_CPUEXT, &val); val |= REG_CPUEXT_AE_HOLD; isx012_writeb(sd, REG_CPUEXT, val); + state->exposure.ae_lock = 1; cam_info("AE lock by user\n"); break; @@ -1651,8 +1681,9 @@ static int isx012_set_ae_lock(struct v4l2_subdev *sd, s32 lock, bool force) isx012_readb(sd, REG_CPUEXT, &val); val &= ~REG_CPUEXT_AE_HOLD; isx012_writeb(sd, REG_CPUEXT, val); + state->exposure.ae_lock = 0; - cam_info("AE unlock by user\n"); + cam_info("AE unlock\n"); break; default: @@ -1675,6 +1706,7 @@ static int isx012_set_awb_lock(struct v4l2_subdev *sd, s32 lock, bool force) isx012_readb(sd, REG_CPUEXT, &val); val |= REG_CPUEXT_AWB_HOLD; isx012_writeb(sd, REG_CPUEXT, val); + state->wb.awb_lock = 1; cam_info("AWB lock by user\n"); break; @@ -1686,8 +1718,9 @@ static int isx012_set_awb_lock(struct v4l2_subdev *sd, s32 lock, bool force) isx012_readb(sd, REG_CPUEXT, &val); val &= ~REG_CPUEXT_AWB_HOLD; isx012_writeb(sd, REG_CPUEXT, val); + state->wb.awb_lock = 0; - cam_info("AWB unlock by user\n"); + cam_info("AWB unlock\n"); break; default: @@ -1776,8 +1809,8 @@ static int isx012_pre_sensor_flash(struct v4l2_subdev *sd) /* read preview AE scale */ isx012_readw(sd, REG_USER_AESCL_AUTO, - &state->exposure.ae_offset.ae_auto); - isx012_readw(sd, REG_ERRSCL_AUTO, &state->exposure.ae_offset.ersc_auto); + &state->flash.ae_offset.ae_auto); + isx012_readw(sd, REG_ERRSCL_AUTO, &state->flash.ae_offset.ersc_auto); if (state->wb.mode == WHITE_BALANCE_AUTO) isx012_writeb(sd, REG_AWB_SN1, 0x00); @@ -1808,28 +1841,45 @@ static int isx012_post_sensor_flash(struct v4l2_subdev *sd) isx012_writeb(sd, REG_VPARA_TRG, 0x01); + state->flash.ae_flash_lock = 0; + state->capture.ae_manual_mode = 0; + return 0; } +static inline int isx012_restore_sensor_flash(struct v4l2_subdev *sd) +{ + struct isx012_state *state = to_state(sd); + + if (!state->flash.ae_flash_lock) + return 0; + + cam_info("Flash is locked. Unlocking...\n"); + return isx012_post_sensor_flash(sd); +} + static int isx012_set_ae_gainoffset(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); - s16 ae_diff, ae_offset; + s16 ae_diff, ae_offset = 0; u16 ae_auto, ae_now; s16 ersc_auto, ersc_now; + u16 ae_ofsetval, ae_maxdiff; - ae_auto = (u16)state->exposure.ae_offset.ae_auto; - ae_now = (u16)state->exposure.ae_offset.ae_now; - ersc_auto = (u16)state->exposure.ae_offset.ersc_auto; - ersc_now = (u16)state->exposure.ae_offset.ersc_now; + ae_auto = (u16)state->flash.ae_offset.ae_auto; + ae_now = (u16)state->flash.ae_offset.ae_now; + ersc_auto = (u16)state->flash.ae_offset.ersc_auto; + ersc_now = (u16)state->flash.ae_offset.ersc_now; + ae_ofsetval = (u16)state->flash.ae_offset.ae_ofsetval; + ae_maxdiff = (u16)state->flash.ae_offset.ae_maxdiff; ae_diff = (ae_now + ersc_now) - (ae_auto + ersc_auto); if (ae_diff < 0) ae_diff = 0; if (ersc_now < 0) { - if (ae_diff >= AE_MAXDIFF) - ae_offset = -AE_OFSETVAL - ersc_now; + if (ae_diff >= ae_maxdiff) + ae_offset = -ae_ofsetval - ersc_now; else { #ifdef CONFIG_LOAD_FILE ae_offset = -gtable_buf[ae_diff / 10] - ersc_now; @@ -1838,21 +1888,100 @@ static int isx012_set_ae_gainoffset(struct v4l2_subdev *sd) #endif } } else { - if (ae_diff >= AE_MAXDIFF) - ae_offset = -AE_OFSETVAL; + if (ae_diff >= ae_maxdiff) + ae_offset = -ae_ofsetval; else { #ifdef CONFIG_LOAD_FILE - ae_offset = -gtable_buf[ae_offset / 10]; + ae_offset = -gtable_buf[ae_diff / 10]; #else - ae_offset = -aeoffset_table[ae_offset / 10]; + ae_offset = -aeoffset_table[ae_diff / 10]; #endif } } + /* cam_info("[ae_gainoffset] ae_offset(%d), ae_diff(%d):" + " (ae_now(%d) + ersc_now(%d)) - (ae_auto(%d) + ersc_auto(%d))", + ae_offset, ae_diff, ae_now, ersc_now, ae_auto, ersc_auto); */ isx012_writew(sd, REG_CAP_GAINOFFSET, ae_offset); return 0; } +static int isx012_wait_ae_stable(struct v4l2_subdev *sd, + bool af_doing, bool long_wait) +{ + struct isx012_state *state = to_state(sd); + u32 val = 0, mode = 0; + int count; + int max_1st, max_2nd; + + if (af_doing || long_wait) + max_1st = max_2nd = ISX012_CNT_AE_STABLE; + else { + max_1st = 20; /* 200ms + alpha */ + max_2nd = 70; /* 700ms + alpha */ + } + + /* 1st: go to Half mode */ + for (count = 0; count < max_1st; count++) { + if (af_doing && (state->focus.start == AUTO_FOCUS_OFF)) + goto cancel_out; + + isx012_readb(sd, REG_MODESEL_FIX, &mode); + if ((u8)mode == 0x01) + break; + + msleep_debug(10, false); + } + + if (count >= max_1st) + cam_info("check_ae_stable: fail to check modesel_fix\n\n"); + else + cam_dbg("check_ae_stable: 1st check count=%d\n", count); + + /* 2nd: check move_sts */ + for (count = 0; count < max_2nd; count++) { + if (af_doing && (state->focus.start == AUTO_FOCUS_OFF)) + goto cancel_out; + + isx012_readb(sd, REG_HALF_MOVE_STS, &val); + if ((u8)val == 0x00) + break; + + msleep_debug(10, false); + } + + if (count >= max_2nd) + cam_info("check_ae_stable: fail to check half_move_sts\n\n"); + else + cam_dbg("check_ae_stable: 2nd check count=%d\n", count); + + return 0; + +cancel_out: + cam_info("check_ae_stable: AF is cancelled(%s)\n", + mode == 0x01 ? "1st" : "2nd"); + return 1; +} + +static bool isx012_check_flash_fire(struct v4l2_subdev *sd, u32 light_level) +{ + struct isx012_state *state = to_state(sd); + + if (state->iso == ISO_AUTO) { + if (light_level < state->lux_level_flash) + goto flash_off; + } else if (light_level < state->shutter_level_flash) + goto flash_off; + + /* Flash on */ + return true; + +flash_off: + isx012_restore_sensor_flash(sd); + + return false; +} + static int isx012_cancel_af(struct v4l2_subdev *sd, bool flash) { struct isx012_state *state = to_state(sd); @@ -1867,17 +1996,14 @@ static int isx012_cancel_af(struct v4l2_subdev *sd, bool flash) if (flash) isx012_post_sensor_flash(sd); - isx012_return_focus(sd); - return 0; } /* PX: Prepare AF Flash */ -static int isx012_af_start_preflash(struct v4l2_subdev *sd, u32 touch) +static int isx012_af_start_preflash(struct v4l2_subdev *sd, + u32 touch, u32 flash_mode) { struct isx012_state *state = to_state(sd); - u32 val = 0; - int count; bool flash = false; cam_trace("E\n"); @@ -1885,16 +2011,18 @@ static int isx012_af_start_preflash(struct v4l2_subdev *sd, u32 touch) if (state->sensor_mode == SENSOR_MOVIE) return 0; - cam_dbg("Start SINGLE AF, flash mode %d\n", state->flash_mode); + cam_dbg("Start SINGLE AF, touch %d, flash mode %d\n", + touch, flash_mode); - state->focus.preflash = PREFLASH_OFF; + state->flash.preflash = PREFLASH_OFF; state->light_level = LUX_LEVEL_MAX; /* We unlock AE, AWB if not going to capture mode after AF * for market app. */ if (state->focus.lock) { + cam_warn("Focus is locked. Unlocking...\n"); isx012_writeb(sd, REG_MODESEL, 0x0); - msleep_debug(200, true); + msleep_debug(200, false); state->focus.lock = 0; } @@ -1904,77 +2032,32 @@ static int isx012_af_start_preflash(struct v4l2_subdev *sd, u32 touch) isx012_get_light_level(sd, &state->light_level); - switch (state->flash_mode) { + switch (flash_mode) { case FLASH_MODE_AUTO: - if (state->light_level < state->lux_level_flash) { - /* flash not needed */ + if (!isx012_check_flash_fire(sd, state->light_level)) break; - } case FLASH_MODE_ON: flash = true; - state->focus.preflash = PREFLASH_ON; + state->flash.preflash = PREFLASH_ON; isx012_pre_sensor_flash(sd); isx012_flash_torch(sd, ISX012_FLASH_ON); break; case FLASH_MODE_OFF: - break; - default: + isx012_restore_sensor_flash(sd); break; } - /* Check AE-stable */ - if (flash) { - for (count = 0; count < ISX012_CNT_AE_STABLE; count++) { - if (state->focus.start == AUTO_FOCUS_OFF) { - cam_info("af_start_preflash: " - "AF is cancelled!\n"); - state->focus.status = AF_RESULT_CANCELLED; - goto cancel_out; - } - - isx012_readb(sd, REG_MODESEL_FIX, &val); - if ((u8)val == 0x01) - break; - - msleep_debug(10, false); - } - if (count >= ISX012_CNT_AE_STABLE) - cam_info("start preflash: fail to check modesel_fix\n\n\n"); - else - cam_dbg("start preflash: 1st check count=%d\n", count); - - for (count = 0; count < ISX012_CNT_AE_STABLE; count++) { - if (state->focus.start == AUTO_FOCUS_OFF) { - cam_info("af_start_preflash: " - "AF is cancelled!\n"); - state->focus.status = AF_RESULT_CANCELLED; - goto cancel_out; - } - - isx012_readb(sd, REG_HALF_MOVE_STS, &val); - if ((u8)val == 0x00) - break; - - msleep_debug(10, false); - } - if (count >= ISX012_CNT_AE_STABLE) - cam_info("start preflash: fail to check half_move_sts\n\n\n"); - else - cam_dbg("start preflash: 2nd check count=%d\n", count); - } - -cancel_out: - /* If AF cancel, finish pre-flash process. */ - if (state->focus.status == AF_RESULT_CANCELLED) { - if (flash) { - isx012_flash_torch(sd, ISX012_FLASH_OFF); - state->focus.preflash = PREFLASH_NONE; - } + if (flash && isx012_wait_ae_stable_af(sd)) { + /* Cancel AF */ + state->focus.status = AF_RESULT_CANCELLED; + isx012_flash_torch(sd, ISX012_FLASH_OFF); + state->flash.preflash = PREFLASH_NONE; isx012_cancel_af(sd, flash); + isx012_return_focus(sd); } cam_trace("X\n"); @@ -1984,22 +2067,22 @@ cancel_out: static int isx012_do_af(struct v4l2_subdev *sd, u32 touch) { struct isx012_state *state = to_state(sd); - u32 read_value = 0, ae_scl = 0; + u32 read_value = 0; u32 count = 0; - bool flash = false; + bool flash = false, success = false; cam_trace("E\n"); /* We do not go to half-release mode if setting FLASH_ON. * And note that flash variable should only be set to true * in camera mode. */ - if (state->focus.preflash == PREFLASH_ON) + if (state->flash.preflash == PREFLASH_ON) flash = true; if (state->sensor_mode == SENSOR_MOVIE) { isx012_set_from_table(sd, "af_camcorder_start", &state->regs->af_camcorder_start, 1, 0); - } else + } else if (!flash) isx012_transit_half_mode(sd); /* Check the result of AF */ @@ -2021,26 +2104,23 @@ static int isx012_do_af(struct v4l2_subdev *sd, u32 touch) if (unlikely(count >= AF_SEARCH_COUNT)) { cam_warn("warning, AF check failed. val=0x%X\n\n", read_value); isx012_writeb(sd, REG_INTCLR, 0x10); - state->focus.status = AF_RESULT_FAILED; goto check_fail; } isx012_writeb(sd, REG_INTCLR, 0x10); isx012_readb(sd, REG_AF_RESUNT, &read_value); if ((u8)read_value == 0x01) - state->focus.status = AF_RESULT_SUCCESS; - else { - state->focus.status = AF_RESULT_FAILED; + success = true; + else af_dbg("AF Fail. AF_RESULT reg=0x%X\n", (u8)read_value); - } check_fail: if (flash) { isx012_readw(sd, REG_ERRSCL_NOW, - &state->exposure.ae_offset.ersc_now); + &state->flash.ae_offset.ersc_now); isx012_readw(sd, REG_USER_AESCL_NOW, - &state->exposure.ae_offset.ae_now); - isx012_readw(sd, REG_AESCL, &ae_scl); + &state->flash.ae_offset.ae_now); + isx012_readw(sd, REG_AESCL, &state->flash.ae_scl); } if (touch) @@ -2050,38 +2130,46 @@ check_fail: isx012_set_from_table(sd, "af_saf_off", &state->regs->af_saf_off, 1, 0); - msleep_debug(66, true); /* Wait 1V time(66ms) */ + /* Remove the exising below 66ms delay: + * many delays have been added to _saf_off recently*/ + /* msleep_debug(66, true);*/ /* Wait 1V time(66ms) */ if (state->focus.start == AUTO_FOCUS_OFF) { - cam_dbg("do_af: AF is cancelled 02\n"); + cam_dbg("do_af: AF is cancelled\n"); state->focus.status = AF_RESULT_CANCELLED; goto cancel_out; } if (flash) { isx012_writew(sd, REG_MANOUTGAIN, - (u16)ae_scl - AE_SCL_SUBRACT_VALUE); + (u16)(state->flash.ae_scl - AE_SCL_SUBRACT_VALUE)); isx012_set_ae_gainoffset(sd); isx012_flash_torch(sd, ISX012_FLASH_OFF); - state->focus.ae_manual_mode = touch ? 1 : 0; + state->capture.ae_manual_mode = touch ? 1 : 0; } cancel_out: if (state->focus.status == AF_RESULT_CANCELLED) { - cam_dbg("Single AF cancelled.\n"); + cam_info("Single AF cancelled\n"); if (flash) { isx012_flash_torch(sd, ISX012_FLASH_OFF); - state->focus.preflash = PREFLASH_NONE; + state->flash.preflash = PREFLASH_NONE; } isx012_cancel_af(sd, flash); + isx012_return_focus(sd); } else { if (state->sensor_mode == SENSOR_MOVIE) isx012_return_focus(sd); state->focus.start = AUTO_FOCUS_OFF; - cam_dbg("Single AF finished(0x%X)\n", state->focus.status); + state->focus.status = success ? + AF_RESULT_SUCCESS : AF_RESULT_FAILED; + cam_info("Single AF finished(0x%X)\n", state->focus.status); + if (!touch) state->focus.lock = 1; /* fix me */ + if (flash) + state->flash.ae_flash_lock = 1; } return 0; @@ -2093,8 +2181,8 @@ static int isx012_set_af(struct v4l2_subdev *sd, s32 val) struct isx012_state *state = to_state(sd); int err = 0; - cam_info("%s: %s, focus mode %d\n", __func__, - val ? "start" : "stop", state->focus.mode); + cam_info("set_af: %s, focus %d, touch %d\n", + val ? "start" : "stop", state->focus.mode, state->focus.touch); if (unlikely((u32)val >= AUTO_FOCUS_MAX)) { cam_err("%s: error, invalid value(%d)\n", __func__, val); @@ -2121,11 +2209,41 @@ static int isx012_set_af(struct v4l2_subdev *sd, s32 val) return 0; } +static int isx012_start_af(struct v4l2_subdev *sd) +{ + struct isx012_state *state = to_state(sd); + int err = 0; + u32 touch, flash_mode; + + mutex_lock(&state->af_lock); + touch = state->focus.touch; + state->focus.touch = 0; + + flash_mode = state->flash.mode; + + if (state->sensor_mode == SENSOR_CAMERA) { + err = isx012_af_start_preflash(sd, touch, flash_mode); + if (unlikely(err)) + goto out; + + if (state->focus.status == AF_RESULT_CANCELLED) + goto out; + } + + isx012_do_af(sd, touch); + +out: + mutex_unlock(&state->af_lock); + + return 0; +} + /* PX: Stop AF */ static int isx012_stop_af(struct v4l2_subdev *sd, s32 touch) { struct isx012_state *state = to_state(sd); int err = 0; + bool flash; cam_trace("E\n"); /* mutex_lock(&state->af_lock); */ @@ -2133,18 +2251,17 @@ static int isx012_stop_af(struct v4l2_subdev *sd, s32 touch) switch (state->focus.status) { case AF_RESULT_FAILED: case AF_RESULT_SUCCESS: - cam_dbg("Stop AF, focus mode %d, AF result %d\n", + cam_info("Stop AF, focus mode %d, AF result %d\n", state->focus.mode, state->focus.status); - if (state->focus.mode == FOCUS_MODE_MACRO) - isx012_set_from_table(sd, "cancel_af_macro", - &state->regs->cancel_af_macro, 1, 0); - else - isx012_set_from_table(sd, "cancel_af_normal", - &state->regs->cancel_af_normal, 1, 0); + flash = ((state->flash.preflash == PREFLASH_ON) || + state->flash.ae_flash_lock) ? 1 : 0; + + isx012_cancel_af(sd, flash); state->focus.status = AF_RESULT_CANCELLED; - state->focus.preflash = PREFLASH_NONE; + state->flash.preflash = PREFLASH_NONE; + state->focus.lock = 0; break; case AF_RESULT_CANCELLED: @@ -2158,17 +2275,9 @@ static int isx012_stop_af(struct v4l2_subdev *sd, s32 touch) break; } -#if 0 - if (!touch) { - /* We move lens to default position if af is cancelled.*/ - err = isx012_return_focus(sd); - if (unlikely(err)) { - cam_err("%s: error, fail to af_norma_mode (%d)\n", - __func__, err); - goto err_out; - } - } -#endif + if (state->focus.touch) + state->focus.touch = 0; + /* mutex_unlock(&state->af_lock); */ cam_trace("X\n"); return 0; @@ -2182,28 +2291,8 @@ static void isx012_af_worker(struct work_struct *work) { struct isx012_state *state = container_of(work, \ struct isx012_state, af_work); - struct v4l2_subdev *sd = &state->sd; - int err = -EINVAL; - u32 touch; - mutex_lock(&state->af_lock); - touch = state->focus.touch; - - if (state->sensor_mode == SENSOR_CAMERA) { - err = isx012_af_start_preflash(sd, touch); - if (unlikely(err)) - goto out; - - if (state->focus.status == AF_RESULT_CANCELLED) - goto out; - } - - isx012_do_af(sd, touch); - -out: - state->focus.touch = 0; - mutex_unlock(&state->af_lock); - return; + isx012_start_af(&state->sd); } /* PX: Set focus mode */ @@ -2214,7 +2303,7 @@ static int isx012_set_focus_mode(struct v4l2_subdev *sd, s32 val) u32 cancel = 0; u8 focus_mode = (u8)val; - cam_dbg("%s val =%d(0x%X)\n", __func__, val, val); + cam_info("set_focus_mode %d(0x%X)\n", val, val); if (state->focus.mode == val) return 0; @@ -2274,9 +2363,9 @@ static int isx012_set_af_window(struct v4l2_subdev *sd) struct isx012_state *state = to_state(sd); const s32 mapped_x = state->focus.pos_x; const s32 mapped_y = state->focus.pos_y; - const u32 preview_width = state->preview->width; - const u32 preview_height = state->preview->height; - const u32 preview_ratio = FRM_RATIO(state->preview); + const u32 preview_width = state->preview.frmsize->width; + const u32 preview_height = state->preview.frmsize->height; + const u32 preview_ratio = FRM_RATIO(state->preview.frmsize); u32 start_x, start_y; u32 ratio_width, ratio_height; struct isx012_rect window = {0, 0, 0, 0}; @@ -2318,9 +2407,11 @@ static int isx012_set_af_window(struct v4l2_subdev *sd) isx012_writew(sd, 0x6A56, window.height); isx012_set_from_table(sd, "af_winddow_set", &state->regs->af_winddow_set, 1, 0); + + state->focus.touch = 1; mutex_unlock(&state->af_lock); - cam_dbg("AF window position completed.\n"); + cam_info("AF window position completed.\n"); cam_trace("X\n"); return 0; @@ -2331,10 +2422,8 @@ static int isx012_set_touch_af(struct v4l2_subdev *sd, s32 val) struct isx012_state *state = to_state(sd); int err = -EIO; - cam_trace("%s, x=%d y=%d\n", val ? "start" : "stop", - state->focus.pos_x, state->focus.pos_y); - - state->focus.touch = val; + cam_info("set_touch (%d, %d)\n", + state->focus.pos_x, state->focus.pos_y); if (val) { if (mutex_is_locked(&state->af_lock)) { @@ -2345,7 +2434,8 @@ static int isx012_set_touch_af(struct v4l2_subdev *sd, s32 val) err = queue_work(state->workqueue, &state->af_win_work); if (likely(!err)) cam_warn("WARNING, AF window is still processing\n"); - } + } else + cam_err("%s: invalid val(%d)\n", __func__, val); cam_trace("X\n"); return 0; @@ -2425,54 +2515,113 @@ static int isx012_init_regs(struct v4l2_subdev *sd) } #endif -static int isx012_wait_steamoff(struct v4l2_subdev *sd) +static inline int isx012_do_wait_steamoff(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); struct isx012_stream_time *stream_time = &state->stream_time; s32 elapsed_msec = 0; + u32 val = 0; + int err = 0, count; cam_trace("E\n"); - if (unlikely(!(state->pdata->is_mipi & state->need_wait_streamoff))) - return 0; - do_gettimeofday(&stream_time->curr_time); elapsed_msec = GET_ELAPSED_TIME(stream_time->curr_time, \ stream_time->before_time) / 1000; - if (state->pdata->streamoff_delay > elapsed_msec) { - cam_info("stream-off: %dms + %dms\n", elapsed_msec, - state->pdata->streamoff_delay - elapsed_msec); - msleep_debug(state->pdata->streamoff_delay - elapsed_msec, - true); - } else - cam_info("stream-off: %dms\n", elapsed_msec); + for (count = 0; count < ISX012_CNT_STREAMOFF; count++) { + err = isx012_readb(sd, 0x00DC, &val); + CHECK_ERR_MSG(err, "wait_steamoff: error, readb\n") + + if ((val & 0x04) == 0) { + cam_dbg("wait_steamoff: %dms + cnt(%d)\n", + elapsed_msec, count); + break; + } + + /* cam_info("wait_steamoff: val = 0x%X\n", val);*/ + msleep_debug(2, false); + } + + if (unlikely(count >= ISX012_CNT_STREAMOFF)) + cam_info("wait_steamoff: time-out!\n\n"); state->need_wait_streamoff = 0; return 0; } -static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd) +static inline int isx012_fast_capture_switch(struct v4l2_subdev *sd) +{ + u32 val = 0; + int err = 0, count; + + cam_trace("EX\n"); + + for (count = 0; count < ISX012_CNT_STREAMOFF; count++) { + err = isx012_readb(sd, 0x00DC, &val); + CHECK_ERR_MSG(err, "fast_capture_switch: error, readb\n") + + if ((val & 0x03) == 0x02) { + cam_dbg("fast_capture_switch: cnt(%d)\n", count); + break; + } + + /* cam_info("wait_steamoff: val = 0x%X\n", val);*/ + msleep_debug(2, false); + } + + if (unlikely(count >= ISX012_CNT_STREAMOFF)) + cam_info("fast_capture_switch: time-out!\n\n"); + + return 0; +} + +static int isx012_wait_steamoff(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); - cam_info("STREAM %s\n", (cmd == STREAM_STOP) ? "STOP" : "START"); + if (unlikely(!state->pdata->is_mipi)) + return 0; + + if (state->need_wait_streamoff) { + isx012_do_wait_steamoff(sd); + state->need_wait_streamoff = 0; + } else if (state->format_mode == V4L2_PIX_FMT_MODE_CAPTURE) + isx012_fast_capture_switch(sd); + + cam_trace("EX\n"); + + return 0; +} + +static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd) +{ + struct isx012_state *state = to_state(sd); if (cmd == STREAM_STOP) { - isx012_writeb(sd, 0x00BF, 0x01); +#if !defined(CONFIG_VIDEO_IMPROVE_STREAMOFF) + state->capture.pre_req = 0; +#endif + if (!((state->runmode == RUNMODE_RUNNING) + && state->capture.pre_req)) { + isx012_writeb(sd, 0x00BF, 0x01); + state->need_wait_streamoff = 1; + cam_info("STREAM STOP\n"); + } + #ifdef CONFIG_DEBUG_NO_FRAME isx012_stop_frame_checker(sd); #endif -#ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF do_gettimeofday(&state->stream_time.before_time); - state->need_wait_streamoff = 1; -#else - msleep_debug(150, true); + +#if !defined(CONFIG_VIDEO_IMPROVE_STREAMOFF) + isx012_wait_steamoff(sd); #endif } else { isx012_writeb(sd, 0x00BF, 0x00); + cam_info("STREAM START\n"); return 0; } @@ -2480,39 +2629,31 @@ static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd) case RUNMODE_CAPTURING: cam_dbg("Capture Stop!\n"); state->runmode = RUNMODE_CAPTURING_STOP; + state->capture.ready = 0; + state->capture.lowlux_night = 0; -#ifdef CONFIG_NEW_STREAM_DELAY - if (state->lowlux_night) { - state->pdata->streamoff_delay = 400; - state->lowlux_night = 0; - } else - state->pdata->streamoff_delay = 150; -#endif - /* We turn flash off if one shot flash is still on. */ + /* We turn flash off if one-shot flash is still on. */ if (isx012_is_hwflash_on(sd)) isx012_flash_oneshot(sd, ISX012_FLASH_OFF); + else + state->flash.on = 0; - if (state->focus.preflash == PREFLASH_ON) + if (state->flash.preflash == PREFLASH_ON) isx012_post_sensor_flash(sd); break; case RUNMODE_RUNNING: cam_dbg("Preview Stop!\n"); state->runmode = RUNMODE_RUNNING_STOP; -#ifdef CONFIG_NEW_STREAM_DELAY - if (state->scene_mode == SCENE_MODE_NIGHTSHOT) - state->pdata->streamoff_delay = 150; - else - state->pdata->streamoff_delay = 66; -#endif + if (state->capture.pre_req) { + isx012_prepare_fast_capture(sd); + state->capture.pre_req = 0; + } break; case RUNMODE_RECORDING: state->runmode = RUNMODE_RECORDING_STOP; -#ifdef CONFIG_NEW_STREAM_DELAY - state->pdata->streamoff_delay = 66; -#endif break; default: @@ -2531,7 +2672,7 @@ static int isx012_set_flash_mode(struct v4l2_subdev *sd, s32 val) /* if (state->sensor_mode == SENSOR_MOVIE && !state->recording) return 0;*/ - if (state->flash_mode == val) { + if (state->flash.mode == val) { cam_dbg("the same flash mode=%d\n", val); return 0; } @@ -2539,11 +2680,11 @@ static int isx012_set_flash_mode(struct v4l2_subdev *sd, s32 val) if (val == FLASH_MODE_TORCH) isx012_flash_torch(sd, ISX012_FLASH_ON); - if ((state->flash_mode == FLASH_MODE_TORCH) + if ((state->flash.mode == FLASH_MODE_TORCH) && (val == FLASH_MODE_OFF)) isx012_flash_torch(sd, ISX012_FLASH_OFF); - state->flash_mode = val; + state->flash.mode = val; cam_dbg("Flash mode = %d\n", val); return 0; } @@ -2603,21 +2744,32 @@ retry: switch (val) { case ISO_AUTO: case ISO_50: + state->shutter_level_flash = 0xB52A; + break; + case ISO_100: + state->shutter_level_flash = 0x9DBA; + break; + case ISO_200: + state->shutter_level_flash = 0x864A; + break; + case ISO_400: - isx012_set_from_table(sd, "iso", - state->regs->iso, ARRAY_SIZE(state->regs->iso), - val); + state->shutter_level_flash = 0x738A; break; default: cam_err("set_iso: error, not supported (%d)\n", val); val = ISO_AUTO; goto retry; - break; } + isx012_set_from_table(sd, "iso", state->regs->iso, + ARRAY_SIZE(state->regs->iso), val); + + state->iso = val; + cam_trace("X\n"); return 0; } @@ -2641,7 +2793,9 @@ static inline void isx012_get_exif_flash(struct v4l2_subdev *sd, { struct isx012_state *state = to_state(sd); - switch (state->flash_mode) { + *flash = 0; + + switch (state->flash.mode) { case FLASH_MODE_OFF: *flash |= EXIF_FLASH_MODE_SUPPRESSION; break; @@ -2659,12 +2813,8 @@ static inline void isx012_get_exif_flash(struct v4l2_subdev *sd, break; } - if (state->flash_on) { + if (state->flash.on) *flash |= EXIF_FLASH_FIRED; - if (state->sensor_mode == SENSOR_CAMERA) - state->flash_on = 0; - } - } /* PX: */ @@ -2672,14 +2822,21 @@ static int isx012_get_exif(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); u32 exposure_time = 0; + u32 int_dec, integer; /* exposure time */ state->exif.exp_time_den = 0; isx012_get_exif_exptime(sd, &exposure_time); - /*WARN(!exposure_time, "WARNING: exposure time is 0\n");*/ - if (exposure_time) + if (exposure_time) { state->exif.exp_time_den = 1000 * 1000 / exposure_time; - else + + int_dec = (1000 * 1000) * 10 / exposure_time; + integer = state->exif.exp_time_den * 10; + + /* Round off */ + if ((int_dec - integer) > 5) + state->exif.exp_time_den += 1; + } else state->exif.exp_time_den = 0; /* iso */ @@ -2695,20 +2852,51 @@ static int isx012_get_exif(struct v4l2_subdev *sd) return 0; } +/* for debugging */ +static int isx012_check_preview_status(struct v4l2_subdev *sd) +{ + u32 reg_val1 = 0; + u32 reg_val4 = 0; + u32 reg_val7 = 0; + u32 reg_val11 = 0; + + /* AE SN */ + isx012_readb(sd, REG_AE_SN1, ®_val1); + isx012_readb(sd, REG_AE_SN4, ®_val4); + isx012_readb(sd, REG_AE_SN7, ®_val7); + isx012_readb(sd, REG_AE_SN11, ®_val11); + + cam_info("AE_SN[0x%X, 0x%X, 0x%X, 0x%X]" + , reg_val1, reg_val4, reg_val7, reg_val11); + + return 0; +} + static int isx012_set_preview_size(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); + u32 width, height; - if (!state->update_frmsize) + if (!state->preview.update_frmsize) return 0; - cam_dbg("set preview size(%dx%d)\n", - state->preview->width, state->preview->height); + if (unlikely(!state->preview.frmsize)) { + cam_warn("warning, preview resolution not set\n"); + state->preview.frmsize = isx012_get_framesize( + isx012_preview_frmsizes, + ARRAY_SIZE(isx012_preview_frmsizes), + PREVIEW_SZ_XGA); + } - isx012_writew(sd, REG_HSIZE_MONI, state->preview->width); - isx012_writew(sd, REG_VSIZE_MONI, state->preview->height); + width = state->preview.frmsize->width; + height = state->preview.frmsize->height; - state->update_frmsize = 0; + cam_dbg("set preview size(%dx%d)\n", width, height); + + isx012_writew(sd, REG_HSIZE_MONI, width); + isx012_writew(sd, REG_VSIZE_MONI, height); + + state->preview.update_frmsize = 0; return 0; } @@ -2718,7 +2906,7 @@ static int isx012_start_preview(struct v4l2_subdev *sd) struct isx012_state *state = to_state(sd); int err = -EINVAL; - cam_dbg("Camera Preview start, runmode = %d\n", state->runmode); + cam_info("Camera Preview start, runmode = %d\n", state->runmode); if ((state->runmode == RUNMODE_NOTREADY) || (state->runmode == RUNMODE_CAPTURING)) { @@ -2727,9 +2915,18 @@ static int isx012_start_preview(struct v4l2_subdev *sd) } state->focus.status = AF_RESULT_NONE; - state->focus.preflash = PREFLASH_NONE; + state->flash.preflash = PREFLASH_NONE; state->focus.touch = 0; + /* Do fast-AE before preview mode if needed */ + if (state->preview.fast_ae) { + cam_info("Fast AE for preview\n"); + isx012_set_from_table(sd, "flash_fast_ae_awb", + &state->regs->flash_fast_ae_awb, 1, 0); + isx012_wait_ae_stable_preview(sd); + state->preview.fast_ae = 0; + } + /* Set movie mode if needed. */ isx012_transit_movie_mode(sd); @@ -2745,8 +2942,11 @@ static int isx012_start_preview(struct v4l2_subdev *sd) err = isx012_transit_preview_mode(sd); CHECK_ERR_MSG(err, "preview_mode(%d)\n", err); + isx012_check_preview_status(sd); + err = isx012_is_cm_changed(sd); CHECK_ERR(err); + isx012_control_stream(sd, STREAM_START); #ifdef CONFIG_DEBUG_NO_FRAME @@ -2763,55 +2963,62 @@ static int isx012_start_preview(struct v4l2_subdev *sd) return 0; } -static int isx012_start_video_preview(struct v4l2_subdev *sd) +static int isx012_set_capture(struct v4l2_subdev *sd) { struct isx012_state *state = to_state(sd); - int err = -EINVAL; + int err = 0; + u32 lux = 0, ae_scl; - cam_dbg("Video Preview start, runmode = %d (Not Implemented)\n", - state->runmode); - return err; -} + if (unlikely((state->flash.preflash == PREFLASH_ON) && + (state->flash.mode == FLASH_MODE_OFF))) + isx012_post_sensor_flash(sd); -static int isx012_start_capture(struct v4l2_subdev *sd) -{ - struct isx012_state *state = to_state(sd); - int err = -ENODEV, count; - u32 lux = 0, val = 0; + if (state->capture.ae_manual_mode) { + /* Check whether fast-AE for preview is needed after capture */ + isx012_readw(sd, REG_AESCL, &ae_scl); + cam_dbg("set_capture: pre ae_scl = %d, ae_scl = %d\n", + state->flash.ae_scl, ae_scl); + if (abs(state->flash.ae_scl - ae_scl) >= AESCL_DIFF_FASTAE) + state->preview.fast_ae = 1; - cam_trace("E\n"); + isx012_set_from_table(sd, "ae_manual_mode", + &state->regs->ae_manual, 1, 0); + } /* Set capture size */ err = isx012_set_capture_size(sd); CHECK_ERR_MSG(err, "fail to set capture size (%d)\n", err); - if (state->focus.ae_manual_mode) { - isx012_writeb(sd, REG_AE_SN1, 0x02); - isx012_writeb(sd, REG_AE_SN4, 0x02); - isx012_writeb(sd, REG_AE_SN7, 0x02); - isx012_writeb(sd, REG_AE_SN11, 0x02); - - msleep_debug(66, true); /* Wait 1v time(66ms) */ - } - /* Set flash */ - switch (state->flash_mode) { + switch (state->flash.mode) { case FLASH_MODE_AUTO: - /* 3rd party App could do capturing without AF. So we check - * whether AF is executed before capture and turn on flash - * if needed. But we do not consider low-light capture of Market - * App. */ - if (state->focus.preflash == PREFLASH_NONE) { + /* 3rd party App could do capturing without AF.*/ + if (state->flash.preflash == PREFLASH_NONE) { isx012_get_light_level(sd, &lux); - if (lux < state->lux_level_flash) + if (!isx012_check_flash_fire(sd, lux)) break; - } else if (state->focus.preflash == PREFLASH_OFF) - break; + } else if (state->flash.preflash == PREFLASH_OFF) { + /* we re-check lux if capture after touch-AF*/ + if (!state->focus.lock) { + isx012_get_light_level(sd, &lux); + if (!isx012_check_flash_fire(sd, lux)) + break; + } else + break; + } /* We do not break. */ case FLASH_MODE_ON: isx012_flash_oneshot(sd, ISX012_FLASH_ON); - /* We here don't need to set state->flash_on to 1 */ + + if (unlikely(state->flash.preflash != PREFLASH_ON)) { + cam_warn("warning: Flash capture without preflash!!\n\n"); + isx012_set_from_table(sd, "flash_fast_ae_awb", + &state->regs->flash_fast_ae_awb, 1, 0); + isx012_wait_ae_stable_cap(sd); + state->flash.awb_delay = 0; + } else + state->flash.awb_delay = 210; break; case FLASH_MODE_OFF: @@ -2819,36 +3026,78 @@ static int isx012_start_capture(struct v4l2_subdev *sd) break; } - /* Set here lowlux_night field for night shot of 3rd party App. - * Refer to comments of above switch() statements */ - /* Transit to capture mode */ err = isx012_transit_capture_mode(sd); CHECK_ERR_MSG(err, "fail to capture_mode (%d)\n", err); - err = isx012_is_cm_changed(sd); + return 0; +} + +static int isx012_prepare_fast_capture(struct v4l2_subdev *sd) +{ + struct isx012_state *state = to_state(sd); + int err = 0; + + cam_info("prepare_fast_capture\n"); + + state->req_fmt.width = (state->capture.pre_req >> 16); + state->req_fmt.height = (state->capture.pre_req & 0xFFFF); + isx012_set_framesize(sd, isx012_capture_frmsizes, + ARRAY_SIZE(isx012_capture_frmsizes), false); + + err = isx012_set_capture(sd); CHECK_ERR(err); - isx012_control_stream(sd, STREAM_START); + state->capture.ready = 1; + + return 0; +} + +static int isx012_start_capture(struct v4l2_subdev *sd) +{ + struct isx012_state *state = to_state(sd); + int err = -ENODEV, count; + u32 val = 0; + u32 night_delay; + + cam_info("start_capture\n"); + + if (!state->capture.ready) { + err = isx012_set_capture(sd); + CHECK_ERR(err); + + err = isx012_is_cm_changed(sd); + CHECK_ERR(err); + + isx012_control_stream(sd, STREAM_START); + night_delay = 500; + } else + night_delay = 700; /* for completely skipping 1 frame. */ #ifdef CONFIG_DEBUG_NO_FRAME isx012_start_frame_checker(sd); #endif - if (state->focus.preflash == PREFLASH_ON) { - msleep_debug(210, true); + if (state->flash.on && (state->wb.mode == WHITE_BALANCE_AUTO)) { + msleep_debug(state->flash.awb_delay, true); + for (count = 0; count < ISX012_CNT_CAPTURE_AWB; count++) { isx012_readb(sd, REG_AWBSTS, &val); - if ((val & 0x06) != 0) { - cam_trace("AWB stable. cnt=%d\n", count); + if ((val & 0x06) != 0) break; - } + msleep_debug(30, false); } + + if (unlikely(count >= ISX012_CNT_CAPTURE_AWB)) + cam_warn("start_capture: fail to check awb\n"); } state->runmode = RUNMODE_CAPTURING; + if (state->capture.lowlux_night) + msleep_debug(night_delay, true); + /* Get EXIF */ isx012_get_exif(sd); @@ -2872,12 +3121,13 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd, state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE; if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { - previous_index = state->preview ? state->preview->index : -1; + previous_index = state->preview.frmsize ? + state->preview.frmsize->index : -1; isx012_set_framesize(sd, isx012_preview_frmsizes, ARRAY_SIZE(isx012_preview_frmsizes), true); - if (previous_index != state->preview->index) - state->update_frmsize = 1; + if (previous_index != state->preview.frmsize->index) + state->preview.update_frmsize = 1; } else { /* * In case of image capture mode, @@ -2888,8 +3138,8 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd, /* for maket app. * Samsung camera app does not use unmatched ratio.*/ - if (unlikely(FRM_RATIO(state->preview) - != FRM_RATIO(state->capture))) { + if (unlikely(FRM_RATIO(state->preview.frmsize) + != FRM_RATIO(state->capture.frmsize))) { cam_warn("%s: warning, capture ratio " \ "is different with preview ratio\n", __func__); @@ -2926,7 +3176,7 @@ static int isx012_try_mbus_fmt(struct v4l2_subdev *sd, for (i = 0; i < num_entries; i++) { if (capture_fmts[i].code == fmt->code && capture_fmts[i].colorspace == fmt->colorspace) { - cam_dbg("%s: match found, returning 0\n", __func__); + cam_info("%s: match found, returning 0\n", __func__); return 0; } } @@ -2948,23 +3198,23 @@ static int isx012_enum_framesizes(struct v4l2_subdev *sd, * this returns the default camera resolution (VGA) */ if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { - if (unlikely(state->preview == NULL)) { + if (unlikely(state->preview.frmsize == NULL)) { cam_err("%s: error\n", __func__); return -EFAULT; } fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = state->preview->width; - fsize->discrete.height = state->preview->height; + fsize->discrete.width = state->preview.frmsize->width; + fsize->discrete.height = state->preview.frmsize->height; } else { - if (unlikely(state->capture == NULL)) { + if (unlikely(state->capture.frmsize == NULL)) { cam_err("%s: error\n", __func__); return -EFAULT; } fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = state->capture->width; - fsize->discrete.height = state->capture->height; + fsize->discrete.width = state->capture.frmsize->width; + fsize->discrete.height = state->capture.frmsize->height; } return 0; @@ -3082,7 +3332,7 @@ static int isx012_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int isx012_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct isx012_state *state = to_state(sd); - int err = -ENOIOCTLCMD; + int err = 0; if (!state->initialized && ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE) { cam_warn("%s: WARNING, camera not initialized. ID = %d(0x%X)\n", @@ -3188,11 +3438,20 @@ static int isx012_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) err = isx012_set_iso(sd, ctrl->value); break; + case V4L2_CID_CAMERA_CAPTURE_MODE: + if (RUNMODE_RUNNING == state->runmode) + state->capture.pre_req = ctrl->value; + + break; + + case V4L2_CID_CAMERA_ANTI_BANDING: + break; + case V4L2_CID_CAMERA_FRAME_RATE: default: cam_err("%s: WARNING, unknown Ctrl-ID 0x%x\n", __func__, ctrl->id); - err = 0; /* we return no error. */ + /* we return no error. */ break; } @@ -3263,14 +3522,14 @@ static int isx012_s_stream(struct v4l2_subdev *sd, int enable) case STREAM_MODE_MOVIE_ON: cam_info("movie on"); state->recording = 1; - if (state->flash_mode != FLASH_MODE_OFF) + if (state->flash.mode != FLASH_MODE_OFF) isx012_flash_torch(sd, ISX012_FLASH_ON); break; case STREAM_MODE_MOVIE_OFF: cam_info("movie off"); state->recording = 0; - if (state->flash_on) + if (state->flash.on) isx012_flash_torch(sd, ISX012_FLASH_OFF); break; @@ -3457,7 +3716,7 @@ static int isx012_post_poweron(struct v4l2_subdev *sd) isx012_Sensor_Calibration(sd); cam_dbg("calibration complete!\n"); - cam_dbg("POWER ON END\n\n"); + cam_info("POWER ON END\n\n"); return 0; } @@ -3473,7 +3732,7 @@ static void isx012_init_parameter(struct v4l2_subdev *sd) state->light_level = LUX_LEVEL_MAX; /* Set update_frmsize to 1 for case of power reset */ - state->update_frmsize = 1; + state->preview.update_frmsize = 1; /* Initialize focus field for case of init after power reset. */ memset(&state->focus, 0, sizeof(state->focus)); @@ -3482,6 +3741,17 @@ static void isx012_init_parameter(struct v4l2_subdev *sd) state->frame_check = false; #endif state->lux_level_flash = LUX_LEVEL_FLASH_ON; + state->shutter_level_flash = 0x0; + +#ifdef CONFIG_LOAD_FILE + state->flash.ae_offset.ae_ofsetval = + isx012_define_read("AE_OFSETVAL", 4); + state->flash.ae_offset.ae_maxdiff = + isx012_define_read("AE_MAXDIFF", 4); +#else + state->flash.ae_offset.ae_ofsetval = AE_OFSETVAL; + state->flash.ae_offset.ae_maxdiff = AE_MAXDIFF; +#endif } static int isx012_init(struct v4l2_subdev *sd, u32 val) @@ -3489,10 +3759,11 @@ static int isx012_init(struct v4l2_subdev *sd, u32 val) struct isx012_state *state = to_state(sd); int err = -EINVAL; - cam_dbg("%s: start\n", __func__); + cam_info("init: start v08(%s)\n", __DATE__); #ifdef CONFIG_LOAD_FILE err = isx012_regs_table_init(); + CHECK_ERR_MSG(err, "loading setfile fail!\n"); #endif err = isx012_post_poweron(sd); CHECK_ERR_MSG(err, "power-on fail!\n"); @@ -3558,22 +3829,22 @@ static int isx012_s_config(struct v4l2_subdev *sd, else state->freq = state->pdata->freq; - state->preview = state->capture = NULL; + state->preview.frmsize = state->capture.frmsize = NULL; state->sensor_mode = SENSOR_CAMERA; state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; state->fps = 0; state->req_fps = -1; /* Initialize the independant HW module like flash here */ - state->flash_mode = FLASH_MODE_OFF; - state->flash_on = 0; + state->flash.mode = FLASH_MODE_OFF; + state->flash.on = 0; for (i = 0; i < ARRAY_SIZE(isx012_ctrls); i++) isx012_ctrls[i].value = isx012_ctrls[i].default_value; #ifdef ISX012_SUPPORT_FLASH if (isx012_is_hwflash_on(sd)) - state->ignore_flash = 1; + state->flash.ignore_flash = 1; #endif state->regs = ®_datas; @@ -3672,7 +3943,7 @@ static int isx012_remove(struct i2c_client *client) * to preventing Market App from controlling improperly flash. * It isn't necessary in case that you power flash down * in power routine to turn camera off.*/ - if (unlikely(state->flash_on && !state->ignore_flash)) + if (unlikely(state->flash.on && !state->flash.ignore_flash)) isx012_flash_torch(sd, ISX012_FLASH_OFF); v4l2_device_unregister_subdev(sd); @@ -3685,6 +3956,83 @@ static int isx012_remove(struct i2c_client *client) return 0; } +static int is_sysdev(struct device *dev, void *str) +{ + return !strcmp(dev_name(dev), (char *)str) ? 1 : 0; +} + +ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + char temp_buf[60] = {0,}; + + sprintf(buf, "Log Level: "); + if (dbg_level & CAMDBG_LEVEL_TRACE) { + sprintf(temp_buf, "trace "); + strcat(buf, temp_buf); + } + + if (dbg_level & CAMDBG_LEVEL_DEBUG) { + sprintf(temp_buf, "debug "); + strcat(buf, temp_buf); + } + + if (dbg_level & CAMDBG_LEVEL_INFO) { + sprintf(temp_buf, "info "); + strcat(buf, temp_buf); + } + + sprintf(temp_buf, "\n - warn and error level is always on\n\n"); + strcat(buf, temp_buf); + + return strlen(buf); +} + +ssize_t cam_loglevel_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + printk(KERN_DEBUG "CAM buf=%s, count=%d\n", buf, count); + + if (strstr(buf, "trace")) + dbg_level |= CAMDBG_LEVEL_TRACE; + else + dbg_level &= ~CAMDBG_LEVEL_TRACE; + + if (strstr(buf, "debug")) + dbg_level |= CAMDBG_LEVEL_DEBUG; + else + dbg_level &= ~CAMDBG_LEVEL_DEBUG; + + if (strstr(buf, "info")) + dbg_level |= CAMDBG_LEVEL_INFO; + + return count; +} + +static DEVICE_ATTR(loglevel, 0664, cam_loglevel_show, cam_loglevel_store); + +static int isx012_create_dbglogfile(struct class *cls) +{ + struct device *dev; + int err; + + dbg_level |= CAMDBG_LEVEL_DEFAULT; + + dev = class_find_device(cls, NULL, "rear", is_sysdev); + if (unlikely(!dev)) { + pr_info("[ISX012] can not find rear device\n"); + return 0; + } + + err = device_create_file(dev, &dev_attr_loglevel); + if (unlikely(err < 0)) { + pr_err("cam_init: failed to create device file, %s\n", + dev_attr_loglevel.attr.name); + } + + return 0; +} + static const struct i2c_device_id isx012_id[] = { { ISX012_DRIVER_NAME, 0 }, {} @@ -3703,6 +4051,7 @@ static int __init v4l2_i2c_drv_init(void) { pr_info("%s: %s called\n", __func__, ISX012_DRIVER_NAME); /* dslim*/ isx012_create_file(camera_class); + isx012_create_dbglogfile(camera_class); return i2c_add_driver(&v4l2_i2c_driver); } diff --git a/drivers/media/video/isx012.h b/drivers/media/video/isx012.h index 9e34992..5e65195 100644 --- a/drivers/media/video/isx012.h +++ b/drivers/media/video/isx012.h @@ -9,7 +9,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * - change date: 2012.04.17 12 + * - change date: 2012.06.28 */ #ifndef __ISX012_H__ @@ -35,12 +35,11 @@ #define CONFIG_CAM_YUV_CAPTURE #define CONFIG_CAM_I2C_LITTLE_ENDIAN /* #define CONFIG_LOAD_FILE */ /* for tuning */ -#define CONFIG_DEBUG_NO_FRAME -#define CONFIG_NEW_STREAM_DELAY +/* #define CONFIG_DEBUG_NO_FRAME */ /** Debuging Feature **/ -#define CONFIG_CAM_DEBUG -#define CONFIG_CAM_TRACE /* Enable it with CONFIG_CAM_DEBUG */ +/* #define CONFIG_CAM_DEBUG */ +/* #define CONFIG_CAM_TRACE */ /* Enable it with CONFIG_CAM_DEBUG */ /* #define CONFIG_CAM_AF_DEBUG *//* Enable it with CONFIG_CAM_DEBUG */ /* #define DEBUG_WRITE_REGS */ /***********************************/ @@ -63,6 +62,16 @@ module_param_named(debug_mask, isx012_debug_mask, uint, S_IWUSR | S_IRUGO); #endif #define TAG_NAME "["ISX012_DRIVER_NAME"]"" " + +/* Define debug level */ +#define CAMDBG_LEVEL_ERR (1 << 0) +#define CAMDBG_LEVEL_WARN (1 << 1) +#define CAMDBG_LEVEL_INFO (1 << 2) +#define CAMDBG_LEVEL_DEBUG (1 << 3) +#define CAMDBG_LEVEL_TRACE (1 << 4) +#define CAMDBG_LEVEL_DEFAULT \ + (CAMDBG_LEVEL_ERR | CAMDBG_LEVEL_WARN | CAMDBG_LEVEL_INFO) + #define cam_err(fmt, ...) \ printk(KERN_ERR TAG_NAME fmt, ##__VA_ARGS__) #define cam_warn(fmt, ...) \ @@ -76,7 +85,7 @@ module_param_named(debug_mask, isx012_debug_mask, uint, S_IWUSR | S_IRUGO); #else #define cam_dbg(fmt, ...) \ do { \ - if (*to_state(sd)->dbg_level & CAMDBG_LEVEL_DEBUG) \ + if (dbg_level & CAMDBG_LEVEL_DEBUG) \ printk(KERN_DEBUG TAG_NAME fmt, ##__VA_ARGS__); \ } while (0) #endif @@ -86,7 +95,7 @@ module_param_named(debug_mask, isx012_debug_mask, uint, S_IWUSR | S_IRUGO); #else #define cam_trace(fmt, ...) \ do { \ - if (*to_state(sd)->dbg_level & CAMDBG_LEVEL_TRACE) \ + if (dbg_level & CAMDBG_LEVEL_TRACE) \ printk(KERN_DEBUG TAG_NAME "%s: " fmt, \ __func__, ##__VA_ARGS__); \ } while (0) @@ -214,6 +223,7 @@ enum isx012_preview_frame_size { enum isx012_capture_frame_size { CAPTURE_SZ_VGA = 0, /* 640x480 */ + CAPTURE_SZ_960_720, CAPTURE_SZ_W1MP, /* 1536x864. Samsung-defined */ CAPTURE_SZ_2MP, /* UXGA - 1600x1200 */ CAPTURE_SZ_W2MP, /* 2048x1152. Samsung-defined */ @@ -350,18 +360,31 @@ struct isx012_gps_info { s32 gps_timeStamp; }; +struct isx012_preview { + const struct isx012_framesize *frmsize; + u32 update_frmsize:1; + u32 fast_ae:1; +}; + +struct isx012_capture { + const struct isx012_framesize *frmsize; + u32 pre_req; /* for fast capture */ + u32 ae_manual_mode:1; + u32 lowlux_night:1; + u32 ready:1; /* for fast capture */ +}; + +/* Focus struct */ struct isx012_focus { enum v4l2_focusmode mode; enum af_result_status status; - enum preflash_status preflash; u32 pos_x; u32 pos_y; u32 start:1; /* enum v4l2_auto_focus*/ u32 touch:1; - u32 lock:1; /* fix me */ - u32 ae_manual_mode:1; + u32 lock:1; /* set if single AF is done */ }; /* struct for sensor specific data */ @@ -370,16 +393,30 @@ struct isx012_ae_gain_offset { u32 ae_now; u32 ersc_auto; u32 ersc_now; + + u32 ae_ofsetval; + u32 ae_maxdiff; }; -/* Exposure */ -struct isx012_exposure { +/* Flash struct */ +struct isx012_flash { struct isx012_ae_gain_offset ae_offset; - s32 val; + enum v4l2_flash_mode mode; + enum preflash_status preflash; + u32 awb_delay; + u32 ae_scl; /* for back-up */ + u32 on:1; /* flash on/off */ + u32 ignore_flash:1; + u32 ae_flash_lock:1; +}; + +/* Exposure struct */ +struct isx012_exposure { + s32 val; /* exposure value */ u32 ae_lock:1; }; -/* White Balance */ +/* White Balance struct */ struct isx012_whitebalance { enum v4l2_wb_mode mode; /* wb mode */ u32 awb_lock:1; @@ -396,8 +433,8 @@ struct isx012_exif { /* EXIF - flash filed */ #define EXIF_FLASH_FIRED (0x01) -#define EXIF_FLASH_MODE_FIRING (0x01) -#define EXIF_FLASH_MODE_SUPPRESSION (0x01 << 1) +#define EXIF_FLASH_MODE_FIRING (0x01 << 3) +#define EXIF_FLASH_MODE_SUPPRESSION (0x02 << 3) #define EXIF_FLASH_MODE_AUTO (0x03 << 3) struct isx012_stream_time { @@ -486,17 +523,13 @@ struct isx012_regs { struct regset_table sharpness[SHARPNESS_MAX]; struct regset_table fps[I_FPS_MAX]; struct regset_table preview_return; - struct regset_table ae_lock_on; - struct regset_table ae_lock_off; - struct regset_table awb_lock_on; - struct regset_table awb_lock_off; -#ifdef CONFIG_VIDEO_ISX012_P8 - struct regset_table set_lowlight_cap; -#endif + /* Flash */ struct regset_table flash_ae_line; struct regset_table flash_on; struct regset_table flash_off; + struct regset_table flash_fast_ae_awb; + struct regset_table ae_manual; /* AF */ struct regset_table af_normal_mode; @@ -534,9 +567,10 @@ struct isx012_state { struct isx012_platform_data *pdata; struct v4l2_subdev sd; struct v4l2_pix_format req_fmt; - const struct isx012_framesize *preview; - const struct isx012_framesize *capture; + struct isx012_preview preview; + struct isx012_capture capture; struct isx012_focus focus; + struct isx012_flash flash; struct isx012_exposure exposure; struct isx012_whitebalance wb; struct isx012_exif exif; @@ -556,8 +590,8 @@ struct isx012_state { enum runmode runmode; enum v4l2_sensor_mode sensor_mode; enum v4l2_pix_format_mode format_mode; - enum v4l2_flash_mode flash_mode; enum v4l2_scene_mode scene_mode; + enum v4l2_iso_mode iso; s32 vt_mode; s32 req_fps; @@ -566,18 +600,15 @@ struct isx012_state { u32 one_frame_delay_ms; u32 light_level; /* light level */ u32 lux_level_flash; + u32 shutter_level_flash; u8 *dbg_level; #ifdef CONFIG_DEBUG_NO_FRAME bool frame_check; #endif u32 recording:1; u32 hd_videomode:1; - u32 flash_on:1; - u32 ignore_flash:1; - u32 update_frmsize:1; u32 need_wait_streamoff:1; u32 initialized:1; - u32 lowlux_night:1; }; static inline struct isx012_state *to_state(struct v4l2_subdev *sd) @@ -585,6 +616,10 @@ static inline struct isx012_state *to_state(struct v4l2_subdev *sd) return container_of(sd, struct isx012_state, sd); } +static inline int isx012_restore_sensor_flash(struct v4l2_subdev *sd); +static int isx012_set_capture(struct v4l2_subdev *sd); +static int isx012_prepare_fast_capture(struct v4l2_subdev *sd); + extern struct class *camera_class; extern int isx012_create_file(struct class *cls); @@ -615,14 +650,15 @@ extern int isx012_create_file(struct class *cls); #define LUX_LEVEL_FLASH_ON 0x2B /* Count for loop */ -#define ISX012_CNT_CAPTURE_FRM 100 +#define ISX012_CNT_CAPTURE_FRM 330 #define ISX012_CNT_CLEAR_VINT 20 #define ISX012_CNT_AE_STABLE 100 /* for checking MODESEL_FIX */ -#define ISX012_CNT_CAPTURE_AWB 8 +#define ISX012_CNT_CAPTURE_AWB 3 /* 8 -> 3 */ #define ISX012_CNT_OM_CHECK 30 -#define ISX012_CNT_CM_CHECK 180 /* 160 -> 180 */ +#define ISX012_CNT_CM_CHECK 280 /* 160 -> 180 */ +#define ISX012_CNT_STREAMOFF 300 -#define AF_SEARCH_COUNT 80 +#define AF_SEARCH_COUNT 200 #define AE_STABLE_SEARCH_COUNT 7 /* Sensor AF first,second window size. @@ -631,6 +667,10 @@ extern int isx012_create_file(struct class *cls); #define DEFAULT_WINDOW_HEIGHT 80 #define AF_PRECISION 100 +/* diff value fior fast AE in preview */ +#define AESCL_DIFF_FASTAE 1000 + + /* * Register Address Definition */ diff --git a/drivers/media/video/isx012_regs.h b/drivers/media/video/isx012_regs.h index 4e05dbf..fa8de0c 100644 --- a/drivers/media/video/isx012_regs.h +++ b/drivers/media/video/isx012_regs.h @@ -9,14 +9,14 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * Change Date: 2012.04.19 + * Change Date: 2012.06.28 */ #ifndef __ISX012_REGS_H__ #define __ISX012_REGS_H__ #define AE_OFSETVAL 3450 //for tuning // max 5.1times -#define AE_MAXDIFF 5000 //for tuning // max =< 5000 +#define AE_MAXDIFF 4000 //for tuning // max =< 5000 #define GLOWLIGHT_DEFAULT 0x002B //for tuning #define GLOWLIGHT_ISO50 0xB52A //for tuning #define GLOWLIGHT_ISO100 0x9DBA //for tuning @@ -83,7 +83,6 @@ const uint16_t aeoffset_table[] = { // normal 4.6times static const isx012_regset_t ISX012_Init_Reg[] = { -//ISX012_Initial_Setting_sensor_111218_V3.08.ini// ///////////////////////////////////// //AF driver setting//³»ºÎ AF driver// ///////////////////////////////////// @@ -254,7 +253,7 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x6616,0x01,0x01}, // AF_DIRECTBACK_F :On=1 {0x661B,0x03,0x01}, // AF_OPDDATA_SAVE : {0x661C,0x00,0x01}, // AF_MONOTONY_POS : -{0x663E,0x01,0x01}, // AF_SEARCH_SECOND_DIR : +{0x663E,0x00,0x01}, // AF_SEARCH_SECOND_DIR : {0x663F,0x01,0x01}, // AF_DIRECTBACK_SECOND_F : {0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F : AF off½Ã zero positionÀ¸·Î °¥Áö(01) ÇöÀ§Ä¡¿¡ ÀÖÀ»Áö(00) Á¤ÇÔ {0x6675,0x01,0x01}, // CAP_AF_CANCEL_F : 1·Î ¼³Á¤½Ã capture¸ðµå¿¡¼­ AFÀÚµ¿ ĵ½½ @@ -273,9 +272,9 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x664C,0xFF,0x01}, // AF_UPRATE_ON_PEAK_DETECT_HBPF : {0x665A,0x00C8,0x02}, // AF_LENSPOS_ON_AFNG : {0x665C,0x0018,0x02}, // AF_DRV_AMOUNT_TONEAR_F : -{0x665E,0x0004,0x02}, // AF_DRV_AMOUNT_TONEAR_S : +{0x665E,0x0003,0x02}, // AF_DRV_AMOUNT_TONEAR_S : {0x6660,0x0018,0x02}, // AF_DRV_AMOUNT_TOFAR_F : -{0x6662,0x0004,0x02}, // AF_DRV_AMOUNT_TOFAR_S : +{0x6662,0x0003,0x02}, // AF_DRV_AMOUNT_TOFAR_S : {0x6666,0x00C8,0x02}, // AF_AREA_LOW_TYPE1 : {0x6668,0x02BC,0x02}, // AF_AREA_HIGH_TYPE1 : {0x669A,0x01F4,0x02}, // AF_OPD_MONOTONYUP_HBPF_TH : @@ -290,10 +289,10 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x6706,0x0003,0x02}, // AF_LVD_HBPF_RATE1_2ND : {0x6708,0x0003,0x02}, // AF_LVD_HBPF_RATE2_2ND : {0x670A,0x00,0x01}, // AF_LVD_HBPF_SHIFT_2ND : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : //chooys add -{0x6677,0x00,0x01}, /* AF_SEND_PARTITION : Use=1 */ +{0x6677,0x00,0x01}, // AF_SEND_PARTITION : Use=1 {0x6678,0x20,0x01}, // AF_SENDNUM_ALL {0x6679,0x01,0x01}, // AF_SENDNUM_UP {0x667A,0x01,0x01}, // AF_SENDNUM_DOWN @@ -304,6 +303,9 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x660E,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN {0x6610,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX +{0x66E4,0xC8,0x01}, +{0x66E5,0xC8,0x01}, + //AF opd window setting {0x6A30,0x044E,0x02}, // AF_OPD0_HDELAY : {0x6A32,0x02E5,0x02}, // AF_OPD0_VDELAY : @@ -321,14 +323,14 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x6A4A,0x00C9,0x02}, // AF_OPD3_VDELAY : {0x6A4C,0x01AE,0x02}, // AF_OPD3_HVALID : {0x6A4E,0x01AE,0x02}, // AF_OPD3_VVALID : -{0x6A50,0x048A,0x02}, // AF_OPD4_HDELAY : -{0x6A52,0x0321,0x02}, // AF_OPD4_VDELAY : -{0x6A54,0x015F,0x02}, // AF_OPD4_HVALID : -{0x6A56,0x015F,0x02}, // AF_OPD4_VVALID : -{0x6A58,0x04BA,0x02}, // AF_OPD5_HDELAY : -{0x6A5A,0x02E4,0x02}, // AF_OPD5_VDELAY : -{0x6A5C,0x00F0,0x02}, // AF_OPD5_HVALID : -{0x6A5E,0x0276,0x02}, // AF_OPD5_VVALID : +{0x6A50,0x04C6,0x02}, // AF_OPD4_HDELAY : +{0x6A52,0x035D,0x02}, // AF_OPD4_VDELAY : +{0x6A54,0x00E6,0x02}, // AF_OPD4_HVALID : +{0x6A56,0x00E6,0x02}, // AF_OPD4_VVALID : +{0x6A58,0x048A,0x02}, // AF_OPD5_HDELAY : +{0x6A5A,0x0321,0x02}, // AF_OPD5_VDELAY : +{0x6A5C,0x015F,0x02}, // AF_OPD5_HVALID : +{0x6A5E,0x015F,0x02}, // AF_OPD5_VVALID : {0x6A60,0x04B4,0x02}, // AF_OPD6_HDELAY : {0x6A62,0x0579,0x02}, // AF_OPD6_VDELAY : {0x6A64,0x0118,0x02}, // AF_OPD6_HVALID : @@ -337,24 +339,24 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY : {0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID : {0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID : -{0x6A70,0x04C6,0x02}, // AF_OPD8_HDELAY : -{0x6A72,0x0493,0x02}, // AF_OPD8_VDELAY : -{0x6A74,0x00E6,0x02}, // AF_OPD8_HVALID : -{0x6A76,0x00E6,0x02}, // AF_OPD8_VVALID : -{0x6A78,0x048A,0x02}, // AF_OPD9_HDELAY : -{0x6A7A,0x0457,0x02}, // AF_OPD9_VDELAY : -{0x6A7C,0x015F,0x02}, // AF_OPD9_HVALID : -{0x6A7E,0x015F,0x02}, // AF_OPD9_VVALID : -{0x6A80,0x05,0x01}, // AF_OPD1A_WEIGHT : -{0x6A81,0x04,0x01}, // AF_OPD1B_WEIGHT : -{0x6A82,0x03,0x01}, // AF_OPD2A_WEIGHT : +{0x6A70,0x021D,0x02}, // AF_OPD8_HDELAY : +{0x6A72,0x02F5,0x02}, // AF_OPD8_VDELAY : +{0x6A74,0x01AE,0x02}, // AF_OPD8_HVALID : +{0x6A76,0x01AE,0x02}, // AF_OPD8_VVALID : +{0x6A78,0x06A4,0x02}, // AF_OPD9_HDELAY : +{0x6A7A,0x02F5,0x02}, // AF_OPD9_VDELAY : +{0x6A7C,0x01AE,0x02}, // AF_OPD9_HVALID : +{0x6A7E,0x01AE,0x02}, // AF_OPD9_VVALID : +{0x6A80,0x06,0x01}, // AF_OPD1A_WEIGHT : +{0x6A81,0x05,0x01}, // AF_OPD1B_WEIGHT : +{0x6A82,0x02,0x01}, // AF_OPD2A_WEIGHT : {0x6A83,0x02,0x01}, // AF_OPD2B_WEIGHT : {0x6A84,0x08,0x01}, // AF_OPD3A_WEIGHT : {0x6A85,0x07,0x01}, // AF_OPD3B_WEIGHT : -{0x6A86,0x03,0x01}, // AF_OPD4A_WEIGHT : -{0x6A87,0x02,0x01}, // AF_OPD4B_WEIGHT : -{0x6A88,0x00,0x01}, // AF_OPD5A_WEIGHT : -{0x6A89,0x00,0x01}, // AF_OPD5B_WEIGHT : +{0x6A86,0x04,0x01}, // AF_OPD4A_WEIGHT : +{0x6A87,0x03,0x01}, // AF_OPD4B_WEIGHT : +{0x6A88,0x01,0x01}, // AF_OPD5A_WEIGHT : +{0x6A89,0x01,0x01}, // AF_OPD5B_WEIGHT : //lee haknoh add @@ -384,7 +386,7 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x0328,0x52,0x01}, // SHTCTRLTIME2_TYPE1 : {0x0329,0x23,0x01}, // AGCGAIN2_TYPE1 : {0x032A,0x3E,0x01}, // SHTCTRLTIME3_TYPE1 : -{0x032B,0x42,0x01}, // AGCGAIN3_TYPE1 : +{0x032B,0x3F,0x01}, // AGCGAIN3_TYPE1 : // normal preview AE line {0x032C,0x7C,0x01}, // SHTCTRLTIME1_TYPE2 @@ -392,7 +394,7 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x032E,0x7C,0x01}, // SHTCTRLTIME2_TYPE2 {0x032F,0x3D,0x01}, // AGCGAIN2_TYPE2 {0x0330,0x3E,0x01}, // SHTCTRLTIME3_TYPE2 -{0x0331,0x42,0x01}, // AGCGAIN3_TYPE2 +{0x0331,0x3F,0x01}, // AGCGAIN3_TYPE2 // flash ae line {0x0332,0x42,0x01}, // SHTCTRLTIME1_TYPE3 : @@ -403,7 +405,7 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x0337,0x3C,0x01}, // AGCGAIN3_TYPE3 : //sports ae line -{0x0338,0x01,0x01}, // SHTCTRLTIME1_TYPE4 +{0x0338,0x00,0x01}, // SHTCTRLTIME1_TYPE4 {0x0339,0x14,0x01}, // AGCGAIN1_TYPE4 {0x033A,0x21,0x01}, // SHTCTRLTIME2_TYPE4 {0x033B,0x19,0x01}, // AGCGAIN2_TYPE4 @@ -424,7 +426,7 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x0346,0xFF,0x01}, // SHTCTRLTIME2_TYPE6 : {0x0347,0x00,0x01}, // AGCGAIN2_TYPE6 : {0x0348,0xFA,0x01}, // SHTCTRLTIME3_TYPE6 : -{0x0349,0x3D,0x01}, // AGCGAIN3_TYPE6 : +{0x0349,0x3B,0x01}, // AGCGAIN3_TYPE6 : // fire mode line {0x0356,0x01,0x01}, // SHTCTRLTIME1_TYPE9 : @@ -1084,9 +1086,9 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x6E92,0x0000,0x02}, // IBYHUE4_POS1 : {0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 : {0x6E96,0x0000,0x02}, // IBYHUE1_POS2 : -{0x6E98,0xFFF8,0x02}, // IRYHUE1_POS2 : +{0x6E98,0xFFF5,0x02}, // IRYHUE1_POS2 : {0x6E9A,0xFFFD,0x02}, // IBYHUE2_POS2 : -{0x6E9C,0xFFF8,0x02}, // IRYHUE2_POS2 : +{0x6E9C,0xFFF5,0x02}, // IRYHUE2_POS2 : {0x6E9E,0xFFFD,0x02}, // IBYHUE3_POS2 : {0x6EA0,0xFFEE,0x02}, // IRYHUE3_POS2 : {0x6EA2,0x0000,0x02}, // IBYHUE4_POS2 : @@ -2369,22 +2371,8 @@ static const isx012_regset_t ISX012_Init_Reg[] = {0x62A4,0x92,0x01}, // IN_LUMST : 146 {0x62A5,0x9C,0x01}, // OUT_LUMST : 156 -//SHD TH -{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2 -{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2 -{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2 -{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2 -{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB -{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB -{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB -{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB - -//PreWB_offset (for SHD2) -{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : -//PreWB_offset (for SHD3) -{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB : -{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB : -{0x005E,0xA6A6,0x02}, /* for ESD check */ +//ISO output setting +{0x5E3F,0x00,0x01}, // ISOSENS_OUT_SEL : }; // ISX012-0 @@ -2861,6 +2849,11 @@ static const isx012_regset_t ISX012_Preview_SizeSetting[] = static const isx012_regset_t ISX012_Preview_Mode[] = { +{0x5000,0x00,0x01}, /* CPUEXT, added by SAMSUNG TN */ +{0x5E32,0x0F,0x01}, /* for Fast-AE reset */ +{0x5E3D,0x0A,0x01}, /* for Fast-AE reset */ +{0x0181,0x00,0x01}, // CAP_HALF_AE_CTRL + {0x0089,0x00,0x01}, //OUTFMT_MONI {0x0083,0x01,0x01}, //SENSMODE_MONI {0x0086,0x02,0x01}, //FPSTYPE_MONI @@ -4068,9 +4061,9 @@ static const isx012_regset_t ISX012_Camcorder_Mode_OFF[] = { static const isx012_regset_t ISX012_Halfrelease_Mode[] = { -{0x00B1,0x01,0x01}, //AF_RESTART_F +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF {0x00B3,0x00,0x01}, //AFMODE_HREL : -{0xFFFF,0x21,0x01},//$wait, 33 +{0xFFFF,0x42,0x01},//$wait, 66 {0x0081,0x01,0x01}, //MODESEL }; @@ -4083,14 +4076,8 @@ static const isx012_regset_t ISX012_Barcode_SAF[] = static const isx012_regset_t ISX012_Lowlux_night_Halfrelease_Mode[] = { -/*++ Disable mipi high clock */ -#if 0 -/* {0x6A9E,0x0AE0,0x02},*/ /* HMAX_1_1*/ -/* {0x00AC,0x02,0x01},*/ /* */ -#endif -/*-- Disable mipi high clock */ -{0x660E,0x09,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN -{0x6610,0x09,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX +{0x660E,0x04,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN +{0x6610,0x04,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX {0x664A,0x01,0x01}, // AF_DROPN_ON_PEAK_DETECT : {0x6640,0x01,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND : {0x0289,0x21,0x01}, //AWB_SN8 @@ -4147,7 +4134,7 @@ static const isx012_regset_t ISX012_AF_Macro_ON[] = static const isx012_regset_t ISX012_AF_SAF[] = { -{0x00B1,0x01,0x01}, //AF_RESTART_F +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF {0x00B3,0x00,0x01}, //AFMODE_HREL : {0xFFFF,0x21,0x01},//$wait, 33 {0x0081,0x01,0x01}, //MODESEL @@ -4155,16 +4142,16 @@ static const isx012_regset_t ISX012_AF_SAF[] = static const isx012_regset_t ISX012_AF_SAF_OFF[] = { +{0xFFFF,0x42,0x01},//$wait, 66 {0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF {0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF -{0xFFFF,0x21,0x01}, //$wait,33 }; static const isx012_regset_t ISX012_AF_TouchSAF_OFF[] = { +{0xFFFF,0x42,0x01},//$wait, 66 {0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF {0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF -{0xFFFF,0x21,0x01}, //$wait,33 {0x0081,0x00,0x01}, //MODESEL }; @@ -4215,24 +4202,24 @@ static const isx012_regset_t ISX012_AF_Window_Reset[] = {0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY : {0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID : {0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID : -{0x6A70,0x04C6,0x02}, // AF_OPD8_HDELAY : -{0x6A72,0x0493,0x02}, // AF_OPD8_VDELAY : -{0x6A74,0x00E6,0x02}, // AF_OPD8_HVALID : -{0x6A76,0x00E6,0x02}, // AF_OPD8_VVALID : -{0x6A78,0x048A,0x02}, // AF_OPD9_HDELAY : -{0x6A7A,0x0457,0x02}, // AF_OPD9_VDELAY : -{0x6A7C,0x015F,0x02}, // AF_OPD9_HVALID : -{0x6A7E,0x015F,0x02}, // AF_OPD9_VVALID : -{0x6A80,0x05,0x01}, // AF_OPD1A_WEIGHT : -{0x6A81,0x04,0x01}, // AF_OPD1B_WEIGHT : -{0x6A82,0x03,0x01}, // AF_OPD2A_WEIGHT : +{0x6A70,0x021D,0x02}, // AF_OPD8_HDELAY : +{0x6A72,0x02F5,0x02}, // AF_OPD8_VDELAY : +{0x6A74,0x01AE,0x02}, // AF_OPD8_HVALID : +{0x6A76,0x01AE,0x02}, // AF_OPD8_VVALID : +{0x6A78,0x06A4,0x02}, // AF_OPD9_HDELAY : +{0x6A7A,0x02F5,0x02}, // AF_OPD9_VDELAY : +{0x6A7C,0x01AE,0x02}, // AF_OPD9_HVALID : +{0x6A7E,0x01AE,0x02}, // AF_OPD9_VVALID : +{0x6A80,0x06,0x01}, // AF_OPD1A_WEIGHT : +{0x6A81,0x05,0x01}, // AF_OPD1B_WEIGHT : +{0x6A82,0x02,0x01}, // AF_OPD2A_WEIGHT : {0x6A83,0x02,0x01}, // AF_OPD2B_WEIGHT : {0x6A84,0x08,0x01}, // AF_OPD3A_WEIGHT : {0x6A85,0x07,0x01}, // AF_OPD3B_WEIGHT : -{0x6A86,0x03,0x01}, // AF_OPD4A_WEIGHT : -{0x6A87,0x02,0x01}, // AF_OPD4B_WEIGHT : -{0x6A88,0x00,0x01}, // AF_OPD5A_WEIGHT : -{0x6A89,0x00,0x01}, // AF_OPD5B_WEIGHT : +{0x6A86,0x04,0x01}, // AF_OPD4A_WEIGHT : +{0x6A87,0x03,0x01}, // AF_OPD4B_WEIGHT : +{0x6A88,0x01,0x01}, // AF_OPD5A_WEIGHT : +{0x6A89,0x01,0x01}, // AF_OPD5B_WEIGHT : {0x6646,0x08,0x01}, // AF_OPD_WEIGHT_TH : }; @@ -4277,6 +4264,17 @@ static const isx012_regset_t isx012_Contrast_Plus_2[] = {0x01C7,0xA8,0x01}, //UICONTRAST }; +static const isx012_regset_t isx012_Effect_Sketch[] = +{ +{0x01C5,0x06,0x01}, /* FMODE */ +{0x6C5F,0x04,0x01}, /* SKETCH_APGAIN */ +}; + +static const isx012_regset_t isx012_Effect_Pastel[] = +{ +{0x01C5,0x05,0x01}, /* FMODE */ +}; + static const isx012_regset_t isx012_Effect_Black_White[] = { {0x01C5,0x04,0x01}, //FMODE @@ -4287,6 +4285,11 @@ static const isx012_regset_t ISX012_Effect_Negative[] = {0x01C5,0x02,0x01}, //FMODE }; +static const isx012_regset_t isx012_Effect_Solar[] = +{ +{0x01C5,0x01,0x01}, /* FMODE */ +}; + static const isx012_regset_t isx012_Effect_Normal[] = { {0x01C5,0x00,0x01}, //FMODE @@ -4429,23 +4432,21 @@ static const isx012_regset_t ISX012_Capture_Mode[] = {0x0012,0xFF,0x01}, //INTCLR0 {0x0081,0x02,0x01}, //MODESEL {0x0082,0x01,0x01}, //MONI_REFRESH -{0xFFFF,0x42,0x01}, //$wait,66 }; static const isx012_regset_t ISX012_Lowlux_Night_Capture_Mode[] = { {0x03A0,0xA0,0x01}, //UISATURATION_TYPE3 : -{0x039D,0xF6,0x01}, //UIHUE_TYPE3 : +{0x039D,0xF4,0x01}, //UIHUE_TYPE3 : {0x982A,0xFFD8,0x02}, // CS_CBLLEV_A : {0x9830,0xFFD8,0x02}, // CS_CRLLEV_A : -{0x9805,0x08,0x01}, // CS_SLP_C_A : +{0x9805,0x06,0x01}, // CS_SLP_C_A : {0x008A,0x00,0x01}, //OUTFMT_CAP {0x0084,0x00,0x01}, //SENSMODE_CAP {0x0087,0x03,0x01}, //FPSTYPE_CAP {0x0012,0xFF,0x01}, //INTCLR0 {0x0081,0x02,0x01}, //MODESEL {0x0082,0x01,0x01}, //MONI_REFRESH -{0xFFFF,0x03E8,0x01}, //$wait,1s }; static const isx012_regset_t isx012_Saturation_Default[] = @@ -4478,8 +4479,8 @@ static const isx012_regset_t isx012_Scene_Default[] = {0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x00,0x01}, //SCENE_SELECT }; @@ -4492,8 +4493,8 @@ static const isx012_regset_t isx012_Scene_Landscape[] = {0x03A6,0x2C,0x01}, //UISHARPNESS_NEG_TYPE3 : +1 {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x01,0x01}, //SCENE_SELECT }; @@ -4503,8 +4504,8 @@ static const isx012_regset_t isx012_Scene_Sports[] = {0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x02,0x01}, //SCENE_SELECT }; @@ -4515,8 +4516,8 @@ static const isx012_regset_t isx012_Scene_Party_Indoor[] = {0x039F,0x9E,0x01}, //UISATURATION_TYPE2 : {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x04,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x00,0x01}, //SCENE_SELECT }; @@ -4527,8 +4528,8 @@ static const isx012_regset_t isx012_Scene_Beach_Snow[] = {0x039F,0x9E,0x01}, //UISATURATION_TYPE2 : {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x04,0x01}, //SCENE_SELECT }; @@ -4540,8 +4541,8 @@ static const isx012_regset_t isx012_Scene_Sunset[] = {0x0394,0x00,0x01}, //PICT1_SN6 : {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x05,0x01}, //SCENE_SELECT }; @@ -4553,8 +4554,8 @@ static const isx012_regset_t isx012_Scene_Duskdawn[] = {0x0394,0x00,0x01}, //PICT1_SN6 : {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x05,0x01}, //SCENE_SELECT }; @@ -4566,8 +4567,8 @@ static const isx012_regset_t isx012_Scene_Candle_Light[] = {0x0394,0x00,0x01}, //PICT1_SN6 : {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x05,0x01}, //SCENE_SELECT }; @@ -4580,8 +4581,8 @@ static const isx012_regset_t isx012_Scene_Fall_Color[] = {0x0394,0x04,0x01}, //PICT1_SN6 : {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x05,0x01}, //SCENE_SELECT }; @@ -4591,8 +4592,8 @@ static const isx012_regset_t isx012_Scene_Portrait[] = {0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x50,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x00,0x01}, //SCENE_SELECT }; @@ -4602,8 +4603,8 @@ static const isx012_regset_t isx012_Scene_Nightshot[] = {0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x000C,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x000C,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x07,0x01}, //SCENE_SELECT }; @@ -4613,8 +4614,8 @@ static const isx012_regset_t isx012_Scene_Fireworks[] = {0x02A8,0x00,0x01}, //ISO_TYPE1 : AUTO {0x5E06,0x04,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x000C,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x000C,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x08,0x01}, //SCENE_SELECT }; @@ -4626,8 +4627,8 @@ static const isx012_regset_t isx012_Scene_Text[] = {0x03A6,0x38,0x01}, //UISHARPNESS_NEG_TYPE3 : +2 {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0xA0,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x00,0x01}, //SCENE_SELECT }; @@ -4637,8 +4638,8 @@ static const isx012_regset_t isx012_Scene_Backlight[] = {0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto {0x5E06,0x02,0x01}, //SHTCTRLMAG3 {0x038F,0x00,0x01}, //PICT1_SN1 : -{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR : -{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR : +{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR : +{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR : {0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL {0x0280,0x00,0x01}, //SCENE_SELECT }; @@ -4725,14 +4726,17 @@ static const isx012_regset_t ISX012_Image_Quality_Table[] = static const isx012_regset_t ISX012_Sensor_Off_VCM[] = { +{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F {0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode {0x0081,0x00,0x01}, //MODESEL : Monitoring mode -{0x6600,0x0000,0x02}, -{0x6666,0x0000,0x02}, -{0x6648,0x0020,0x02}, /* AF_MANUAL_POS : MANUA AF search start position */ -{0xFFFF,0x01,0x01}, //$wait, 1 +{0x6600,0x0000,0x02}, // AF_SEARCH_AREA_LOW +{0x6666,0x0000,0x02}, // AF_AREA_LOW_TYPE1 +{0x6648,0x00C8,0x02}, // AF_MANUAL_POS : {0x00B1,0x01,0x01}, //AF_RESTART_F -{0xFFFF,0x96,0x01}, //$wait, 150 +{0xFFFF,0x64,0x01}, // $wait, 100 +{0x6648,0x0019,0x02}, // AF_MANUAL_POS : +{0x00B1,0x01,0x01}, // AF_RESTART_F +{0xFFFF,0x64,0x01}, // $wait, 100 }; static const isx012_regset_t isx012_1280_Preview_E[] = @@ -4750,7 +4754,6 @@ static const isx012_regset_t isx012_800_Preview[] = { {0x0090,0x0320,0x02}, //HSIZE_MONI : 800 {0x0096,0x01E0,0x02}, //VSIZE_MONI : 480 - }; static const isx012_regset_t isx012_720_Preview[] = @@ -4804,6 +4807,11 @@ static const isx012_regset_t isx012_1_5M_WIDE_Capture[] = {0x0282,0x20,0x01}, //AWB_SN1 }; +static const isx012_regset_t isx012_960_720_Capture[] = { +{0x0092,0x03C0,0x02}, /* HSIZE_CAP : 960 */ +{0x0098,0x02D0,0x02}, /* VSIZE_CAP : 720 */ +}; + static const isx012_regset_t isx012_1M_Capture[] = { {0x0282,0x20,0x01}, //AWB_SN1 @@ -5027,6 +5035,12 @@ static const isx012_regset_t isx012_fps_auto[] = {0x018E,0x0012,0x02}, /* VADJ_SENS_1_2 */ }; +static const isx012_regset_t isx012_fps_7fix[] = +{ +{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */ +{0x018E,0x0D59,0x02}, /* VADJ_SENS_1_2 */ +}; + static const isx012_regset_t isx012_fps_15fix[] = { {0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */ @@ -6048,81 +6062,81 @@ static const isx012_regset_t ISX012_Shading_Nocal[] = //SHD2 CW+TL84 33:66 {0xED00,0x9191,0x02},// -{0xEF54,0x21,0x01}, -{0xEF55,0x92,0x01}, -{0xEF56,0xD1,0x01}, -{0xEF57,0x8A,0x01}, -{0xEF58,0x3E,0x01}, -{0xEF59,0xF4,0x01}, -{0xEF5A,0xA1,0x01}, -{0xEF5B,0x10,0x01}, -{0xEF5C,0xB9,0x01}, -{0xEF5D,0x48,0x01}, -{0xEF5E,0x46,0x01}, -{0xEF5F,0x1F,0x01}, -{0xEF60,0x82,0x01}, +{0xEF54,0x28,0x01}, +{0xEF55,0xC2,0x01}, +{0xEF56,0x11,0x01}, +{0xEF57,0x8C,0x01}, +{0xEF58,0x46,0x01}, +{0xEF59,0x34,0x01}, +{0xEF5A,0xA2,0x01}, +{0xEF5B,0x12,0x01}, +{0xEF5C,0xCD,0x01}, +{0xEF5D,0x08,0x01}, +{0xEF5E,0x47,0x01}, +{0xEF5F,0x27,0x01}, +{0xEF60,0xAA,0x01}, {0xEF61,0x10,0x01}, -{0xEF62,0x7E,0x01}, -{0xEF63,0xBC,0x01}, -{0xEF64,0xC3,0x01}, +{0xEF62,0x7F,0x01}, +{0xEF63,0xC2,0x01}, +{0xEF64,0xF3,0x01}, {0xEF65,0x1C,0x01}, -{0xEF66,0xE3,0x01}, -{0xEF67,0x38,0x01}, -{0xEF68,0xC7,0x01}, -{0xEF69,0x3B,0x01}, -{0xEF6A,0xF7,0x01}, -{0xEF6B,0x71,0x01}, +{0xEF66,0xE4,0x01}, +{0xEF67,0x40,0x01}, +{0xEF68,0x27,0x01}, +{0xEF69,0x3C,0x01}, +{0xEF6A,0xFB,0x01}, +{0xEF6B,0xA1,0x01}, {0xEF6C,0x90,0x01}, -{0xEF6D,0x7B,0x01}, -{0xEF6E,0x8E,0x01}, -{0xEF6F,0x53,0x01}, -{0xEF70,0x1A,0x01}, +{0xEF6D,0x7C,0x01}, +{0xEF6E,0x92,0x01}, +{0xEF6F,0x63,0x01}, +{0xEF70,0x9A,0x01}, {0xEF71,0xC5,0x01}, -{0xEF72,0x04,0x01}, -{0xEF73,0x46,0x01}, +{0xEF72,0x0C,0x01}, +{0xEF73,0x66,0x01}, {0xEF74,0x31,0x01}, -{0xEF75,0xA2,0x01}, -{0xEF76,0x39,0x01}, +{0xEF75,0xA4,0x01}, +{0xEF76,0x49,0x01}, {0xEF77,0x0E,0x01}, -{0xEF78,0x7E,0x01}, -{0xEF79,0x9A,0x01}, -{0xEF7A,0xA3,0x01}, -{0xEF7B,0x99,0x01}, -{0xEF7C,0xB5,0x01}, +{0xEF78,0x7F,0x01}, +{0xEF79,0xA0,0x01}, +{0xEF7A,0xB3,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB6,0x01}, {0xEF7D,0x34,0x01}, {0xEF7E,0x85,0x01}, {0xEF7F,0x28,0x01}, {0xEF80,0x4D,0x01}, {0xEF81,0x61,0x01}, -{0xEF82,0x8B,0x01}, -{0xEF83,0x67,0x01}, -{0xEF84,0xB0,0x01}, -{0xEF85,0x53,0x01}, -{0xEF86,0x1B,0x01}, +{0xEF82,0x0B,0x01}, +{0xEF83,0x68,0x01}, +{0xEF84,0xB6,0x01}, +{0xEF85,0x73,0x01}, +{0xEF86,0x9B,0x01}, {0xEF87,0xBB,0x01}, -{0xEF88,0x08,0x01}, +{0xEF88,0x0C,0x01}, {0xEF89,0x45,0x01}, {0xEF8A,0x24,0x01}, {0xEF8B,0x17,0x01}, {0xEF8C,0x11,0x01}, -{0xEF8D,0x09,0x01}, +{0xEF8D,0x49,0x01}, {0xEF8E,0x51,0x01}, -{0xEF8F,0xF2,0x01}, -{0xEF90,0xA2,0x01}, -{0xEF91,0x9B,0x01}, -{0xEF92,0xD3,0x01}, -{0xEF93,0x90,0x01}, +{0xEF8F,0xF4,0x01}, +{0xEF90,0xC2,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD4,0x01}, +{0xEF93,0x94,0x01}, {0xEF94,0xC5,0x01}, {0xEF95,0x25,0x01}, -{0xEF96,0x0A,0x01}, +{0xEF96,0x0B,0x01}, {0xEF97,0x01,0x01}, {0xEF98,0x48,0x01}, {0xEF99,0x43,0x01}, {0xEF9A,0x62,0x01}, -{0xEF9B,0x52,0x01}, -{0xEF9C,0x16,0x01}, +{0xEF9B,0x62,0x01}, +{0xEF9C,0x96,0x01}, {0xEF9D,0xD5,0x01}, -{0xEF9E,0x9C,0x01}, +{0xEF9E,0xA4,0x01}, {0xEF9F,0xC6,0x01}, {0xEFA0,0x2C,0x01}, {0xEFA1,0x2F,0x01}, @@ -6131,71 +6145,71 @@ static const isx012_regset_t ISX012_Shading_Nocal[] = {0xEFA4,0x40,0x01}, {0xEFA5,0x1C,0x01}, {0xEFA6,0x22,0x01}, -{0xEFA7,0x93,0x01}, -{0xEFA8,0xB3,0x01}, -{0xEFA9,0xB8,0x01}, -{0xEFAA,0x46,0x01}, +{0xEFA7,0x13,0x01}, +{0xEFA8,0xB4,0x01}, +{0xEFA9,0xC0,0x01}, +{0xEFAA,0x86,0x01}, {0xEFAB,0x37,0x01}, -{0xEFAC,0x7A,0x01}, -{0xEFAD,0x21,0x01}, -{0xEFAE,0x4A,0x01}, +{0xEFAC,0x7B,0x01}, +{0xEFAD,0x29,0x01}, +{0xEFAE,0x8A,0x01}, {0xEFAF,0x48,0x01}, {0xEFB0,0x30,0x01}, {0xEFB1,0x52,0x01}, {0xEFB2,0x12,0x01}, {0xEFB3,0xA4,0x01}, -{0xEFB4,0xF0,0x01}, -{0xEFB5,0xE5,0x01}, -{0xEFB6,0x37,0x01}, -{0xEFB7,0xD6,0x01}, -{0xEFB8,0xF9,0x01}, -{0xEFB9,0x8C,0x01}, +{0xEFB4,0xF4,0x01}, +{0xEFB5,0x25,0x01}, +{0xEFB6,0x38,0x01}, +{0xEFB7,0xD9,0x01}, +{0xEFB8,0x01,0x01}, +{0xEFB9,0xCD,0x01}, {0xEFBA,0x5B,0x01}, -{0xEFBB,0x9E,0x01}, -{0xEFBC,0x62,0x01}, +{0xEFBB,0xA0,0x01}, +{0xEFBC,0x72,0x01}, {0xEFBD,0x14,0x01}, {0xEFBE,0xA9,0x01}, -{0xEFBF,0xC8,0x01}, -{0xEFC0,0xA5,0x01}, +{0xEFBF,0xCC,0x01}, +{0xEFC0,0xC5,0x01}, {0xEFC1,0x34,0x01}, -{0xEFC2,0xE0,0x01}, -{0xEFC3,0xD1,0x01}, -{0xEFC4,0x8F,0x01}, -{0xEFC5,0x73,0x01}, -{0xEFC6,0x4C,0x01}, -{0xEFC7,0xE3,0x01}, -{0xEFC8,0x18,0x01}, +{0xEFC2,0xE3,0x01}, +{0xEFC3,0xF1,0x01}, +{0xEFC4,0x0F,0x01}, +{0xEFC5,0x74,0x01}, +{0xEFC6,0x50,0x01}, +{0xEFC7,0xF3,0x01}, +{0xEFC8,0x98,0x01}, {0xEFC9,0xC2,0x01}, -{0xEFCA,0x3C,0x01}, -{0xEFCB,0x46,0x01}, +{0xEFCA,0x40,0x01}, +{0xEFCB,0x86,0x01}, {0xEFCC,0x35,0x01}, -{0xEFCD,0xD2,0x01}, -{0xEFCE,0x09,0x01}, -{0xEFCF,0x90,0x01}, -{0xEFD0,0x85,0x01}, -{0xEFD1,0xF6,0x01}, -{0xEFD2,0x03,0x01}, -{0xEFD3,0x1E,0x01}, -{0xEFD4,0xE7,0x01}, -{0xEFD5,0x20,0x01}, -{0xEFD6,0x27,0x01}, +{0xEFCD,0xD4,0x01}, +{0xEFCE,0x29,0x01}, +{0xEFCF,0xD0,0x01}, +{0xEFD0,0x86,0x01}, +{0xEFD1,0xFE,0x01}, +{0xEFD2,0x23,0x01}, +{0xEFD3,0x9E,0x01}, +{0xEFD4,0xE8,0x01}, +{0xEFD5,0x28,0x01}, +{0xEFD6,0x87,0x01}, {0xEFD7,0x3A,0x01}, -{0xEFD8,0xE4,0x01}, -{0xEFD9,0x01,0x01}, -{0xEFDA,0x90,0x01}, -{0xEFDB,0x87,0x01}, -{0xEFDC,0x30,0x01}, -{0xEFDD,0x04,0x01}, -{0xEFDE,0x22,0x01}, -{0xEFDF,0x0B,0x01}, -{0xEFE0,0x2D,0x01}, -{0xEFE1,0x28,0x01}, +{0xEFD8,0xE7,0x01}, +{0xEFD9,0x21,0x01}, +{0xEFDA,0x10,0x01}, +{0xEFDB,0x89,0x01}, +{0xEFDC,0x3E,0x01}, +{0xEFDD,0x64,0x01}, +{0xEFDE,0xA2,0x01}, +{0xEFDF,0x0D,0x01}, +{0xEFE0,0x41,0x01}, +{0xEFE1,0xC8,0x01}, {0xEFE2,0x41,0x01}, -{0xEFE3,0x10,0x01}, -{0xEFE4,0xDA,0x01}, -{0xEFE5,0x90,0x01}, -{0xEFE6,0x88,0x01}, -{0xEFE7,0x3C,0x01}, +{0xEFE3,0x14,0x01}, +{0xEFE4,0x02,0x01}, +{0xEFE5,0x11,0x01}, +{0xEFE6,0x8A,0x01}, +{0xEFE7,0x4C,0x01}, {0xEFE8,0x04,0x01}, {0xEFE9,0x00,0x01}, {0xEFEA,0x00,0x01}, @@ -6204,7 +6218,6 @@ static const isx012_regset_t ISX012_Shading_Nocal[] = {0xEFED,0x00,0x01}, - //SHD3 D65+TL84 C01// {0xED00,0x9191,0x02},// {0xEFEE,0x12,0x01}, @@ -7519,81 +7532,81 @@ static const isx012_regset_t ISX012_Shading_0[] = //SHD2 CW+TL84 33:66 {0xED00,0x9191,0x02},// -{0xEF54,0x21,0x01}, -{0xEF55,0x92,0x01}, -{0xEF56,0xD1,0x01}, -{0xEF57,0x8A,0x01}, -{0xEF58,0x3E,0x01}, -{0xEF59,0xF4,0x01}, -{0xEF5A,0xA1,0x01}, -{0xEF5B,0x10,0x01}, -{0xEF5C,0xB9,0x01}, -{0xEF5D,0x48,0x01}, -{0xEF5E,0x46,0x01}, -{0xEF5F,0x1F,0x01}, -{0xEF60,0x82,0x01}, +{0xEF54,0x28,0x01}, +{0xEF55,0xC2,0x01}, +{0xEF56,0x11,0x01}, +{0xEF57,0x8C,0x01}, +{0xEF58,0x46,0x01}, +{0xEF59,0x34,0x01}, +{0xEF5A,0xA2,0x01}, +{0xEF5B,0x12,0x01}, +{0xEF5C,0xCD,0x01}, +{0xEF5D,0x08,0x01}, +{0xEF5E,0x47,0x01}, +{0xEF5F,0x27,0x01}, +{0xEF60,0xAA,0x01}, {0xEF61,0x10,0x01}, -{0xEF62,0x7E,0x01}, -{0xEF63,0xBC,0x01}, -{0xEF64,0xC3,0x01}, +{0xEF62,0x7F,0x01}, +{0xEF63,0xC2,0x01}, +{0xEF64,0xF3,0x01}, {0xEF65,0x1C,0x01}, -{0xEF66,0xE3,0x01}, -{0xEF67,0x38,0x01}, -{0xEF68,0xC7,0x01}, -{0xEF69,0x3B,0x01}, -{0xEF6A,0xF7,0x01}, -{0xEF6B,0x71,0x01}, +{0xEF66,0xE4,0x01}, +{0xEF67,0x40,0x01}, +{0xEF68,0x27,0x01}, +{0xEF69,0x3C,0x01}, +{0xEF6A,0xFB,0x01}, +{0xEF6B,0xA1,0x01}, {0xEF6C,0x90,0x01}, -{0xEF6D,0x7B,0x01}, -{0xEF6E,0x8E,0x01}, -{0xEF6F,0x53,0x01}, -{0xEF70,0x1A,0x01}, +{0xEF6D,0x7C,0x01}, +{0xEF6E,0x92,0x01}, +{0xEF6F,0x63,0x01}, +{0xEF70,0x9A,0x01}, {0xEF71,0xC5,0x01}, -{0xEF72,0x04,0x01}, -{0xEF73,0x46,0x01}, +{0xEF72,0x0C,0x01}, +{0xEF73,0x66,0x01}, {0xEF74,0x31,0x01}, -{0xEF75,0xA2,0x01}, -{0xEF76,0x39,0x01}, +{0xEF75,0xA4,0x01}, +{0xEF76,0x49,0x01}, {0xEF77,0x0E,0x01}, -{0xEF78,0x7E,0x01}, -{0xEF79,0x9A,0x01}, -{0xEF7A,0xA3,0x01}, -{0xEF7B,0x99,0x01}, -{0xEF7C,0xB5,0x01}, +{0xEF78,0x7F,0x01}, +{0xEF79,0xA0,0x01}, +{0xEF7A,0xB3,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB6,0x01}, {0xEF7D,0x34,0x01}, {0xEF7E,0x85,0x01}, {0xEF7F,0x28,0x01}, {0xEF80,0x4D,0x01}, {0xEF81,0x61,0x01}, -{0xEF82,0x8B,0x01}, -{0xEF83,0x67,0x01}, -{0xEF84,0xB0,0x01}, -{0xEF85,0x53,0x01}, -{0xEF86,0x1B,0x01}, +{0xEF82,0x0B,0x01}, +{0xEF83,0x68,0x01}, +{0xEF84,0xB6,0x01}, +{0xEF85,0x73,0x01}, +{0xEF86,0x9B,0x01}, {0xEF87,0xBB,0x01}, -{0xEF88,0x08,0x01}, +{0xEF88,0x0C,0x01}, {0xEF89,0x45,0x01}, {0xEF8A,0x24,0x01}, {0xEF8B,0x17,0x01}, {0xEF8C,0x11,0x01}, -{0xEF8D,0x09,0x01}, +{0xEF8D,0x49,0x01}, {0xEF8E,0x51,0x01}, -{0xEF8F,0xF2,0x01}, -{0xEF90,0xA2,0x01}, -{0xEF91,0x9B,0x01}, -{0xEF92,0xD3,0x01}, -{0xEF93,0x90,0x01}, +{0xEF8F,0xF4,0x01}, +{0xEF90,0xC2,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD4,0x01}, +{0xEF93,0x94,0x01}, {0xEF94,0xC5,0x01}, {0xEF95,0x25,0x01}, -{0xEF96,0x0A,0x01}, +{0xEF96,0x0B,0x01}, {0xEF97,0x01,0x01}, {0xEF98,0x48,0x01}, {0xEF99,0x43,0x01}, {0xEF9A,0x62,0x01}, -{0xEF9B,0x52,0x01}, -{0xEF9C,0x16,0x01}, +{0xEF9B,0x62,0x01}, +{0xEF9C,0x96,0x01}, {0xEF9D,0xD5,0x01}, -{0xEF9E,0x9C,0x01}, +{0xEF9E,0xA4,0x01}, {0xEF9F,0xC6,0x01}, {0xEFA0,0x2C,0x01}, {0xEFA1,0x2F,0x01}, @@ -7602,71 +7615,71 @@ static const isx012_regset_t ISX012_Shading_0[] = {0xEFA4,0x40,0x01}, {0xEFA5,0x1C,0x01}, {0xEFA6,0x22,0x01}, -{0xEFA7,0x93,0x01}, -{0xEFA8,0xB3,0x01}, -{0xEFA9,0xB8,0x01}, -{0xEFAA,0x46,0x01}, +{0xEFA7,0x13,0x01}, +{0xEFA8,0xB4,0x01}, +{0xEFA9,0xC0,0x01}, +{0xEFAA,0x86,0x01}, {0xEFAB,0x37,0x01}, -{0xEFAC,0x7A,0x01}, -{0xEFAD,0x21,0x01}, -{0xEFAE,0x4A,0x01}, +{0xEFAC,0x7B,0x01}, +{0xEFAD,0x29,0x01}, +{0xEFAE,0x8A,0x01}, {0xEFAF,0x48,0x01}, {0xEFB0,0x30,0x01}, {0xEFB1,0x52,0x01}, {0xEFB2,0x12,0x01}, {0xEFB3,0xA4,0x01}, -{0xEFB4,0xF0,0x01}, -{0xEFB5,0xE5,0x01}, -{0xEFB6,0x37,0x01}, -{0xEFB7,0xD6,0x01}, -{0xEFB8,0xF9,0x01}, -{0xEFB9,0x8C,0x01}, +{0xEFB4,0xF4,0x01}, +{0xEFB5,0x25,0x01}, +{0xEFB6,0x38,0x01}, +{0xEFB7,0xD9,0x01}, +{0xEFB8,0x01,0x01}, +{0xEFB9,0xCD,0x01}, {0xEFBA,0x5B,0x01}, -{0xEFBB,0x9E,0x01}, -{0xEFBC,0x62,0x01}, +{0xEFBB,0xA0,0x01}, +{0xEFBC,0x72,0x01}, {0xEFBD,0x14,0x01}, {0xEFBE,0xA9,0x01}, -{0xEFBF,0xC8,0x01}, -{0xEFC0,0xA5,0x01}, +{0xEFBF,0xCC,0x01}, +{0xEFC0,0xC5,0x01}, {0xEFC1,0x34,0x01}, -{0xEFC2,0xE0,0x01}, -{0xEFC3,0xD1,0x01}, -{0xEFC4,0x8F,0x01}, -{0xEFC5,0x73,0x01}, -{0xEFC6,0x4C,0x01}, -{0xEFC7,0xE3,0x01}, -{0xEFC8,0x18,0x01}, +{0xEFC2,0xE3,0x01}, +{0xEFC3,0xF1,0x01}, +{0xEFC4,0x0F,0x01}, +{0xEFC5,0x74,0x01}, +{0xEFC6,0x50,0x01}, +{0xEFC7,0xF3,0x01}, +{0xEFC8,0x98,0x01}, {0xEFC9,0xC2,0x01}, -{0xEFCA,0x3C,0x01}, -{0xEFCB,0x46,0x01}, +{0xEFCA,0x40,0x01}, +{0xEFCB,0x86,0x01}, {0xEFCC,0x35,0x01}, -{0xEFCD,0xD2,0x01}, -{0xEFCE,0x09,0x01}, -{0xEFCF,0x90,0x01}, -{0xEFD0,0x85,0x01}, -{0xEFD1,0xF6,0x01}, -{0xEFD2,0x03,0x01}, -{0xEFD3,0x1E,0x01}, -{0xEFD4,0xE7,0x01}, -{0xEFD5,0x20,0x01}, -{0xEFD6,0x27,0x01}, +{0xEFCD,0xD4,0x01}, +{0xEFCE,0x29,0x01}, +{0xEFCF,0xD0,0x01}, +{0xEFD0,0x86,0x01}, +{0xEFD1,0xFE,0x01}, +{0xEFD2,0x23,0x01}, +{0xEFD3,0x9E,0x01}, +{0xEFD4,0xE8,0x01}, +{0xEFD5,0x28,0x01}, +{0xEFD6,0x87,0x01}, {0xEFD7,0x3A,0x01}, -{0xEFD8,0xE4,0x01}, -{0xEFD9,0x01,0x01}, -{0xEFDA,0x90,0x01}, -{0xEFDB,0x87,0x01}, -{0xEFDC,0x30,0x01}, -{0xEFDD,0x04,0x01}, -{0xEFDE,0x22,0x01}, -{0xEFDF,0x0B,0x01}, -{0xEFE0,0x2D,0x01}, -{0xEFE1,0x28,0x01}, +{0xEFD8,0xE7,0x01}, +{0xEFD9,0x21,0x01}, +{0xEFDA,0x10,0x01}, +{0xEFDB,0x89,0x01}, +{0xEFDC,0x3E,0x01}, +{0xEFDD,0x64,0x01}, +{0xEFDE,0xA2,0x01}, +{0xEFDF,0x0D,0x01}, +{0xEFE0,0x41,0x01}, +{0xEFE1,0xC8,0x01}, {0xEFE2,0x41,0x01}, -{0xEFE3,0x10,0x01}, -{0xEFE4,0xDA,0x01}, -{0xEFE5,0x90,0x01}, -{0xEFE6,0x88,0x01}, -{0xEFE7,0x3C,0x01}, +{0xEFE3,0x14,0x01}, +{0xEFE4,0x02,0x01}, +{0xEFE5,0x11,0x01}, +{0xEFE6,0x8A,0x01}, +{0xEFE7,0x4C,0x01}, {0xEFE8,0x04,0x01}, {0xEFE9,0x00,0x01}, {0xEFEA,0x00,0x01}, @@ -7675,7 +7688,6 @@ static const isx012_regset_t ISX012_Shading_0[] = {0xEFED,0x00,0x01}, - //SHD3 D65+TL84 C01// {0xED00,0x9191,0x02},// {0xEFEE,0x12,0x01}, @@ -8990,154 +9002,154 @@ static const isx012_regset_t ISX012_Shading_1[] = //SHD2 CW+TL84 33:66 {0xED00,0x9191,0x02},// -{0xEF54,0x21,0x01}, -{0xEF55,0x92,0x01}, -{0xEF56,0xD1,0x01}, -{0xEF57,0x8A,0x01}, -{0xEF58,0x3E,0x01}, -{0xEF59,0xF4,0x01}, +{0xEF54,0x0B,0x01}, +{0xEF55,0xFA,0x01}, +{0xEF56,0x10,0x01}, +{0xEF57,0x87,0x01}, +{0xEF58,0x24,0x01}, +{0xEF59,0x24,0x01}, {0xEF5A,0xA1,0x01}, -{0xEF5B,0x10,0x01}, -{0xEF5C,0xB9,0x01}, -{0xEF5D,0x48,0x01}, -{0xEF5E,0x46,0x01}, -{0xEF5F,0x1F,0x01}, -{0xEF60,0x82,0x01}, -{0xEF61,0x10,0x01}, -{0xEF62,0x7E,0x01}, -{0xEF63,0xBC,0x01}, -{0xEF64,0xC3,0x01}, -{0xEF65,0x1C,0x01}, -{0xEF66,0xE3,0x01}, -{0xEF67,0x38,0x01}, +{0xEF5B,0x09,0x01}, +{0xEF5C,0x7D,0x01}, +{0xEF5D,0x08,0x01}, +{0xEF5E,0x44,0x01}, +{0xEF5F,0x0A,0x01}, +{0xEF60,0x0A,0x01}, +{0xEF61,0x50,0x01}, +{0xEF62,0x7B,0x01}, +{0xEF63,0xAA,0x01}, +{0xEF64,0x53,0x01}, +{0xEF65,0x9C,0x01}, +{0xEF66,0xDF,0x01}, +{0xEF67,0x18,0x01}, {0xEF68,0xC7,0x01}, -{0xEF69,0x3B,0x01}, -{0xEF6A,0xF7,0x01}, -{0xEF6B,0x71,0x01}, -{0xEF6C,0x90,0x01}, -{0xEF6D,0x7B,0x01}, -{0xEF6E,0x8E,0x01}, -{0xEF6F,0x53,0x01}, -{0xEF70,0x1A,0x01}, -{0xEF71,0xC5,0x01}, -{0xEF72,0x04,0x01}, -{0xEF73,0x46,0x01}, -{0xEF74,0x31,0x01}, -{0xEF75,0xA2,0x01}, -{0xEF76,0x39,0x01}, -{0xEF77,0x0E,0x01}, -{0xEF78,0x7E,0x01}, -{0xEF79,0x9A,0x01}, -{0xEF7A,0xA3,0x01}, -{0xEF7B,0x99,0x01}, -{0xEF7C,0xB5,0x01}, -{0xEF7D,0x34,0x01}, -{0xEF7E,0x85,0x01}, +{0xEF69,0x3A,0x01}, +{0xEF6A,0xEC,0x01}, +{0xEF6B,0xF9,0x01}, +{0xEF6C,0x0F,0x01}, +{0xEF6D,0x79,0x01}, +{0xEF6E,0x80,0x01}, +{0xEF6F,0x03,0x01}, +{0xEF70,0x9A,0x01}, +{0xEF71,0xC3,0x01}, +{0xEF72,0xF8,0x01}, +{0xEF73,0xE5,0x01}, +{0xEF74,0x30,0x01}, +{0xEF75,0x9D,0x01}, +{0xEF76,0x01,0x01}, +{0xEF77,0x4E,0x01}, +{0xEF78,0x7B,0x01}, +{0xEF79,0x8C,0x01}, +{0xEF7A,0x53,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB4,0x01}, +{0xEF7D,0x2C,0x01}, +{0xEF7E,0x45,0x01}, {0xEF7F,0x28,0x01}, -{0xEF80,0x4D,0x01}, -{0xEF81,0x61,0x01}, +{0xEF80,0x4B,0x01}, +{0xEF81,0x49,0x01}, {0xEF82,0x8B,0x01}, -{0xEF83,0x67,0x01}, -{0xEF84,0xB0,0x01}, -{0xEF85,0x53,0x01}, -{0xEF86,0x1B,0x01}, -{0xEF87,0xBB,0x01}, -{0xEF88,0x08,0x01}, +{0xEF83,0x66,0x01}, +{0xEF84,0xA0,0x01}, +{0xEF85,0xF3,0x01}, +{0xEF86,0x9A,0x01}, +{0xEF87,0xB9,0x01}, +{0xEF88,0x04,0x01}, {0xEF89,0x45,0x01}, {0xEF8A,0x24,0x01}, -{0xEF8B,0x17,0x01}, -{0xEF8C,0x11,0x01}, -{0xEF8D,0x09,0x01}, -{0xEF8E,0x51,0x01}, -{0xEF8F,0xF2,0x01}, -{0xEF90,0xA2,0x01}, -{0xEF91,0x9B,0x01}, -{0xEF92,0xD3,0x01}, -{0xEF93,0x90,0x01}, -{0xEF94,0xC5,0x01}, +{0xEF8B,0x16,0x01}, +{0xEF8C,0x09,0x01}, +{0xEF8D,0xC9,0x01}, +{0xEF8E,0x50,0x01}, +{0xEF8F,0xEC,0x01}, +{0xEF90,0x42,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD1,0x01}, +{0xEF93,0x88,0x01}, +{0xEF94,0xA5,0x01}, {0xEF95,0x25,0x01}, {0xEF96,0x0A,0x01}, {0xEF97,0x01,0x01}, {0xEF98,0x48,0x01}, {0xEF99,0x43,0x01}, -{0xEF9A,0x62,0x01}, -{0xEF9B,0x52,0x01}, -{0xEF9C,0x16,0x01}, -{0xEF9D,0xD5,0x01}, -{0xEF9E,0x9C,0x01}, -{0xEF9F,0xC6,0x01}, +{0xEF9A,0x60,0x01}, +{0xEF9B,0x32,0x01}, +{0xEF9C,0x96,0x01}, +{0xEF9D,0xD2,0x01}, +{0xEF9E,0x88,0x01}, +{0xEF9F,0x66,0x01}, {0xEFA0,0x2C,0x01}, -{0xEFA1,0x2F,0x01}, +{0xEFA1,0x2E,0x01}, {0xEFA2,0x51,0x01}, {0xEFA3,0x48,0x01}, {0xEFA4,0x40,0x01}, {0xEFA5,0x1C,0x01}, -{0xEFA6,0x22,0x01}, +{0xEFA6,0x12,0x01}, {0xEFA7,0x93,0x01}, -{0xEFA8,0xB3,0x01}, -{0xEFA9,0xB8,0x01}, -{0xEFAA,0x46,0x01}, -{0xEFAB,0x37,0x01}, -{0xEFAC,0x7A,0x01}, -{0xEFAD,0x21,0x01}, +{0xEFA8,0xB2,0x01}, +{0xEFA9,0xA4,0x01}, +{0xEFAA,0x86,0x01}, +{0xEFAB,0x36,0x01}, +{0xEFAC,0x77,0x01}, +{0xEFAD,0x19,0x01}, {0xEFAE,0x4A,0x01}, {0xEFAF,0x48,0x01}, {0xEFB0,0x30,0x01}, {0xEFB1,0x52,0x01}, {0xEFB2,0x12,0x01}, -{0xEFB3,0xA4,0x01}, -{0xEFB4,0xF0,0x01}, -{0xEFB5,0xE5,0x01}, +{0xEFB3,0xA3,0x01}, +{0xEFB4,0xE4,0x01}, +{0xEFB5,0x25,0x01}, {0xEFB6,0x37,0x01}, -{0xEFB7,0xD6,0x01}, -{0xEFB8,0xF9,0x01}, -{0xEFB9,0x8C,0x01}, -{0xEFBA,0x5B,0x01}, -{0xEFBB,0x9E,0x01}, -{0xEFBC,0x62,0x01}, +{0xEFB7,0xCF,0x01}, +{0xEFB8,0xD1,0x01}, +{0xEFB9,0xCC,0x01}, +{0xEFBA,0x5A,0x01}, +{0xEFBB,0x9A,0x01}, +{0xEFBC,0x52,0x01}, {0xEFBD,0x14,0x01}, -{0xEFBE,0xA9,0x01}, -{0xEFBF,0xC8,0x01}, -{0xEFC0,0xA5,0x01}, +{0xEFBE,0xA8,0x01}, +{0xEFBF,0xC0,0x01}, +{0xEFC0,0x05,0x01}, {0xEFC1,0x34,0x01}, -{0xEFC2,0xE0,0x01}, -{0xEFC3,0xD1,0x01}, -{0xEFC4,0x8F,0x01}, -{0xEFC5,0x73,0x01}, -{0xEFC6,0x4C,0x01}, -{0xEFC7,0xE3,0x01}, -{0xEFC8,0x18,0x01}, -{0xEFC9,0xC2,0x01}, -{0xEFCA,0x3C,0x01}, -{0xEFCB,0x46,0x01}, -{0xEFCC,0x35,0x01}, -{0xEFCD,0xD2,0x01}, -{0xEFCE,0x09,0x01}, -{0xEFCF,0x90,0x01}, -{0xEFD0,0x85,0x01}, -{0xEFD1,0xF6,0x01}, -{0xEFD2,0x03,0x01}, -{0xEFD3,0x1E,0x01}, -{0xEFD4,0xE7,0x01}, -{0xEFD5,0x20,0x01}, -{0xEFD6,0x27,0x01}, -{0xEFD7,0x3A,0x01}, -{0xEFD8,0xE4,0x01}, -{0xEFD9,0x01,0x01}, -{0xEFDA,0x90,0x01}, -{0xEFDB,0x87,0x01}, -{0xEFDC,0x30,0x01}, -{0xEFDD,0x04,0x01}, -{0xEFDE,0x22,0x01}, -{0xEFDF,0x0B,0x01}, -{0xEFE0,0x2D,0x01}, -{0xEFE1,0x28,0x01}, -{0xEFE2,0x41,0x01}, -{0xEFE3,0x10,0x01}, -{0xEFE4,0xDA,0x01}, -{0xEFE5,0x90,0x01}, -{0xEFE6,0x88,0x01}, -{0xEFE7,0x3C,0x01}, +{0xEFC2,0xD8,0x01}, +{0xEFC3,0x79,0x01}, +{0xEFC4,0xCF,0x01}, +{0xEFC5,0x71,0x01}, +{0xEFC6,0x42,0x01}, +{0xEFC7,0xA3,0x01}, +{0xEFC8,0x98,0x01}, +{0xEFC9,0xC0,0x01}, +{0xEFCA,0x30,0x01}, +{0xEFCB,0xA6,0x01}, +{0xEFCC,0x34,0x01}, +{0xEFCD,0xCA,0x01}, +{0xEFCE,0xB1,0x01}, +{0xEFCF,0x8F,0x01}, +{0xEFD0,0x81,0x01}, +{0xEFD1,0xE0,0x01}, +{0xEFD2,0x73,0x01}, +{0xEFD3,0x9D,0x01}, +{0xEFD4,0xE3,0x01}, +{0xEFD5,0x04,0x01}, +{0xEFD6,0x47,0x01}, +{0xEFD7,0x39,0x01}, +{0xEFD8,0xDB,0x01}, +{0xEFD9,0xA9,0x01}, +{0xEFDA,0x8F,0x01}, +{0xEFDB,0x83,0x01}, +{0xEFDC,0x06,0x01}, +{0xEFDD,0xE4,0x01}, +{0xEFDE,0xA0,0x01}, +{0xEFDF,0x03,0x01}, +{0xEFE0,0xFD,0x01}, +{0xEFE1,0xA7,0x01}, +{0xEFE2,0x3F,0x01}, +{0xEFE3,0x03,0x01}, +{0xEFE4,0x62,0x01}, +{0xEFE5,0x10,0x01}, +{0xEFE6,0x84,0x01}, +{0xEFE7,0x12,0x01}, {0xEFE8,0x04,0x01}, {0xEFE9,0x00,0x01}, {0xEFEA,0x00,0x01}, @@ -9149,45 +9161,45 @@ static const isx012_regset_t ISX012_Shading_1[] = //SHD3 D65+TL84 C01// {0xED00,0x9191,0x02},// -{0xEFEE,0x12,0x01}, -{0xEFEF,0x42,0x01}, -{0xEFF0,0x51,0x01}, -{0xEFF1,0x89,0x01}, -{0xEFF2,0x38,0x01}, -{0xEFF3,0xD4,0x01}, +{0xEFEE,0x0B,0x01}, +{0xEFEF,0x12,0x01}, +{0xEFF0,0x11,0x01}, +{0xEFF1,0x88,0x01}, +{0xEFF2,0x2E,0x01}, +{0xEFF3,0x94,0x01}, {0xEFF4,0x21,0x01}, -{0xEFF5,0x10,0x01}, -{0xEFF6,0xAD,0x01}, -{0xEFF7,0xA8,0x01}, -{0xEFF8,0x45,0x01}, -{0xEFF9,0x18,0x01}, -{0xEFFA,0x4A,0x01}, +{0xEFF5,0x0E,0x01}, +{0xEFF6,0x99,0x01}, +{0xEFF7,0xE8,0x01}, +{0xEFF8,0x44,0x01}, +{0xEFF9,0x10,0x01}, +{0xEFFA,0x22,0x01}, {0xEFFB,0x50,0x01}, -{0xEFFC,0x7D,0x01}, -{0xEFFD,0xBA,0x01}, -{0xEFFE,0xD3,0x01}, +{0xEFFC,0x7C,0x01}, +{0xEFFD,0xB6,0x01}, +{0xEFFE,0xB3,0x01}, {0xEFFF,0x1C,0x01}, -{0xF000,0xE4,0x01}, -{0xF001,0x40,0x01}, -{0xF002,0x27,0x01}, -{0xF003,0x3C,0x01}, -{0xF004,0xF8,0x01}, -{0xF005,0x69,0x01}, +{0xF000,0xE3,0x01}, +{0xF001,0x38,0x01}, +{0xF002,0xC7,0x01}, +{0xF003,0x3B,0x01}, +{0xF004,0xF4,0x01}, +{0xF005,0x39,0x01}, {0xF006,0x10,0x01}, -{0xF007,0x7B,0x01}, -{0xF008,0x8E,0x01}, -{0xF009,0x63,0x01}, -{0xF00A,0x1A,0x01}, -{0xF00B,0xC6,0x01}, -{0xF00C,0x10,0x01}, -{0xF00D,0xA6,0x01}, +{0xF007,0x7A,0x01}, +{0xF008,0x8A,0x01}, +{0xF009,0x53,0x01}, +{0xF00A,0x9A,0x01}, +{0xF00B,0xC5,0x01}, +{0xF00C,0x0C,0x01}, +{0xF00D,0x86,0x01}, {0xF00E,0x31,0x01}, -{0xF00F,0xA6,0x01}, -{0xF010,0x59,0x01}, -{0xF011,0x8E,0x01}, -{0xF012,0x7E,0x01}, -{0xF013,0x9A,0x01}, -{0xF014,0xB3,0x01}, +{0xF00F,0xA5,0x01}, +{0xF010,0x49,0x01}, +{0xF011,0xCE,0x01}, +{0xF012,0x7D,0x01}, +{0xF013,0x94,0x01}, +{0xF014,0xA3,0x01}, {0xF015,0x19,0x01}, {0xF016,0xB6,0x01}, {0xF017,0x38,0x01}, @@ -9195,22 +9207,22 @@ static const isx012_regset_t ISX012_Shading_1[] = {0xF019,0x28,0x01}, {0xF01A,0x4F,0x01}, {0xF01B,0x79,0x01}, -{0xF01C,0xCB,0x01}, +{0xF01C,0x8B,0x01}, {0xF01D,0x68,0x01}, -{0xF01E,0xBA,0x01}, -{0xF01F,0x53,0x01}, -{0xF020,0x9B,0x01}, +{0xF01E,0xB4,0x01}, +{0xF01F,0x43,0x01}, +{0xF020,0x1B,0x01}, {0xF021,0xBB,0x01}, {0xF022,0x0C,0x01}, -{0xF023,0x65,0x01}, +{0xF023,0x45,0x01}, {0xF024,0x24,0x01}, {0xF025,0x17,0x01}, -{0xF026,0x21,0x01}, +{0xF026,0x19,0x01}, {0xF027,0xC9,0x01}, {0xF028,0x51,0x01}, -{0xF029,0xFC,0x01}, -{0xF02A,0xF2,0x01}, -{0xF02B,0x9B,0x01}, +{0xF029,0xFA,0x01}, +{0xF02A,0xD2,0x01}, +{0xF02B,0x1B,0x01}, {0xF02C,0xD3,0x01}, {0xF02D,0x94,0x01}, {0xF02E,0xC5,0x01}, @@ -9220,11 +9232,11 @@ static const isx012_regset_t ISX012_Shading_1[] = {0xF032,0x48,0x01}, {0xF033,0x43,0x01}, {0xF034,0x66,0x01}, -{0xF035,0x92,0x01}, +{0xF035,0x82,0x01}, {0xF036,0x96,0x01}, -{0xF037,0xD7,0x01}, -{0xF038,0xA0,0x01}, -{0xF039,0xE6,0x01}, +{0xF037,0xD6,0x01}, +{0xF038,0x98,0x01}, +{0xF039,0xC6,0x01}, {0xF03A,0x2C,0x01}, {0xF03B,0x2F,0x01}, {0xF03C,0x51,0x01}, @@ -9232,12 +9244,12 @@ static const isx012_regset_t ISX012_Shading_1[] = {0xF03E,0x40,0x01}, {0xF03F,0x1E,0x01}, {0xF040,0x42,0x01}, -{0xF041,0x93,0x01}, +{0xF041,0x13,0x01}, {0xF042,0xB5,0x01}, -{0xF043,0xCC,0x01}, -{0xF044,0x46,0x01}, +{0xF043,0xC8,0x01}, +{0xF044,0x06,0x01}, {0xF045,0x37,0x01}, -{0xF046,0x7C,0x01}, +{0xF046,0x7B,0x01}, {0xF047,0x29,0x01}, {0xF048,0x8A,0x01}, {0xF049,0x48,0x01}, @@ -9245,58 +9257,58 @@ static const isx012_regset_t ISX012_Shading_1[] = {0xF04B,0x72,0x01}, {0xF04C,0x12,0x01}, {0xF04D,0xA5,0x01}, -{0xF04E,0x00,0x01}, -{0xF04F,0xA6,0x01}, +{0xF04E,0xFC,0x01}, +{0xF04F,0x65,0x01}, {0xF050,0x38,0x01}, -{0xF051,0xD7,0x01}, -{0xF052,0x01,0x01}, -{0xF053,0x0D,0x01}, -{0xF054,0x5C,0x01}, -{0xF055,0xA2,0x01}, +{0xF051,0xD4,0x01}, +{0xF052,0xF9,0x01}, +{0xF053,0xCC,0x01}, +{0xF054,0x5B,0x01}, +{0xF055,0xA0,0x01}, {0xF056,0x82,0x01}, -{0xF057,0x94,0x01}, +{0xF057,0x14,0x01}, {0xF058,0xAA,0x01}, -{0xF059,0xD8,0x01}, -{0xF05A,0x45,0x01}, +{0xF059,0xD4,0x01}, +{0xF05A,0x05,0x01}, {0xF05B,0x35,0x01}, -{0xF05C,0xE5,0x01}, -{0xF05D,0xC9,0x01}, -{0xF05E,0xCF,0x01}, +{0xF05C,0xE2,0x01}, +{0xF05D,0xA9,0x01}, +{0xF05E,0x4F,0x01}, {0xF05F,0x73,0x01}, -{0xF060,0x50,0x01}, -{0xF061,0x03,0x01}, -{0xF062,0x99,0x01}, +{0xF060,0x4E,0x01}, +{0xF061,0xF3,0x01}, +{0xF062,0x18,0x01}, {0xF063,0xC3,0x01}, -{0xF064,0x4C,0x01}, -{0xF065,0xE6,0x01}, +{0xF064,0x48,0x01}, +{0xF065,0xC6,0x01}, {0xF066,0x35,0x01}, -{0xF067,0xD7,0x01}, -{0xF068,0x21,0x01}, -{0xF069,0x10,0x01}, -{0xF06A,0x84,0x01}, -{0xF06B,0xF2,0x01}, -{0xF06C,0x03,0x01}, -{0xF06D,0x9E,0x01}, -{0xF06E,0xE8,0x01}, -{0xF06F,0x2C,0x01}, -{0xF070,0xA7,0x01}, +{0xF067,0xD4,0x01}, +{0xF068,0x01,0x01}, +{0xF069,0xD0,0x01}, +{0xF06A,0x82,0x01}, +{0xF06B,0xEA,0x01}, +{0xF06C,0xD3,0x01}, +{0xF06D,0x1D,0x01}, +{0xF06E,0xE7,0x01}, +{0xF06F,0x24,0x01}, +{0xF070,0x47,0x01}, {0xF071,0x3A,0x01}, -{0xF072,0xE8,0x01}, -{0xF073,0x11,0x01}, -{0xF074,0x90,0x01}, -{0xF075,0x87,0x01}, -{0xF076,0x18,0x01}, -{0xF077,0x94,0x01}, -{0xF078,0x21,0x01}, -{0xF079,0x09,0x01}, -{0xF07A,0x2D,0x01}, -{0xF07B,0x68,0x01}, -{0xF07C,0x41,0x01}, -{0xF07D,0x11,0x01}, -{0xF07E,0xDA,0x01}, -{0xF07F,0x10,0x01}, -{0xF080,0x88,0x01}, -{0xF081,0x2A,0x01}, +{0xF072,0xE5,0x01}, +{0xF073,0xF1,0x01}, +{0xF074,0x0F,0x01}, +{0xF075,0x86,0x01}, +{0xF076,0x0A,0x01}, +{0xF077,0x34,0x01}, +{0xF078,0xA1,0x01}, +{0xF079,0x06,0x01}, +{0xF07A,0x19,0x01}, +{0xF07B,0xE8,0x01}, +{0xF07C,0x40,0x01}, +{0xF07D,0x0D,0x01}, +{0xF07E,0xB2,0x01}, +{0xF07F,0x90,0x01}, +{0xF080,0x86,0x01}, +{0xF081,0x1C,0x01}, {0xF082,0x04,0x01}, {0xF083,0x00,0x01}, {0xF084,0x00,0x01}, @@ -9472,8 +9484,8 @@ static const isx012_regset_t ISX012_Shading_1[] = //PreWB_offset (for SHD2) {0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : //PreWB_offset (for SHD3) -{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB : -{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB : +{0x682C,0x000D,0x02}, // SHD_PRER_OFFSET_RB : +{0x6830,0xFFFE,0x02}, // SHD_PREB_OFFSET_RB : // CXC/SHD EN {0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF @@ -9864,136 +9876,136 @@ static const isx012_regset_t ISX012_Shading_2[] = //SHD1(from CO1) {0xED02,0xE6,0x01}, -{0xED03,0x61,0x01}, +{0xED03,0xD9,0x01}, {0xED04,0x92,0x01}, {0xED05,0x7C,0x01}, -{0xED06,0xBE,0x01}, +{0xED06,0xD8,0x01}, {0xED07,0xB4,0x01}, -{0xED08,0x9E,0x01}, -{0xED09,0x2C,0x01}, +{0xED08,0x1E,0x01}, +{0xED09,0x32,0x01}, {0xED0A,0x75,0x01}, -{0xED0B,0x47,0x01}, -{0xED0C,0x49,0x01}, +{0xED0B,0x67,0x01}, +{0xED0C,0x4A,0x01}, {0xED0D,0xD7,0x01}, -{0xED0E,0x61,0x01}, +{0xED0E,0xA9,0x01}, {0xED0F,0x12,0x01}, {0xED10,0x76,0x01}, -{0xED11,0xA8,0x01}, +{0xED11,0xBC,0x01}, {0xED12,0x34,0x01}, {0xED13,0x1E,0x01}, -{0xED14,0x31,0x01}, +{0xED14,0x37,0x01}, {0xED15,0xA1,0x01}, -{0xED16,0xC7,0x01}, -{0xED17,0x4C,0x01}, +{0xED16,0x87,0x01}, +{0xED17,0x4E,0x01}, {0xED18,0xDE,0x01}, -{0xED19,0xC1,0x01}, -{0xED1A,0xD2,0x01}, +{0xED19,0x41,0x01}, +{0xED1A,0xD3,0x01}, {0xED1B,0x77,0x01}, -{0xED1C,0x76,0x01}, +{0xED1C,0x8C,0x01}, {0xED1D,0x94,0x01}, {0xED1E,0x9C,0x01}, -{0xED1F,0x10,0x01}, +{0xED1F,0x14,0x01}, {0xED20,0xC9,0x01}, -{0xED21,0xC6,0x01}, -{0xED22,0x40,0x01}, +{0xED21,0xA6,0x01}, +{0xED22,0x41,0x01}, {0xED23,0xA2,0x01}, -{0xED24,0x99,0x01}, +{0xED24,0xC1,0x01}, {0xED25,0x8F,0x01}, {0xED26,0x66,0x01}, -{0xED27,0xDC,0x01}, +{0xED27,0xE6,0x01}, {0xED28,0xF3,0x01}, {0xED29,0x19,0x01}, -{0xED2A,0xFC,0x01}, +{0xED2A,0xFF,0x01}, {0xED2B,0xB0,0x01}, -{0xED2C,0xA6,0x01}, -{0xED2D,0x41,0x01}, +{0xED2C,0x66,0x01}, +{0xED2D,0x42,0x01}, {0xED2E,0xC1,0x01}, -{0xED2F,0x49,0x01}, +{0xED2F,0x91,0x01}, {0xED30,0x91,0x01}, {0xED31,0x75,0x01}, -{0xED32,0x8C,0x01}, +{0xED32,0xA2,0x01}, {0xED33,0x74,0x01}, {0xED34,0x1C,0x01}, -{0xED35,0x0B,0x01}, +{0xED35,0x0F,0x01}, {0xED36,0x91,0x01}, -{0xED37,0x86,0x01}, -{0xED38,0x3D,0x01}, +{0xED37,0x26,0x01}, +{0xED38,0x3E,0x01}, {0xED39,0x87,0x01}, -{0xED3A,0x39,0x01}, +{0xED3A,0x51,0x01}, {0xED3B,0x4E,0x01}, {0xED3C,0x5C,0x01}, -{0xED3D,0x50,0x01}, +{0xED3D,0x54,0x01}, {0xED3E,0x83,0x01}, -{0xED3F,0x16,0x01}, -{0xED40,0xCF,0x01}, +{0xED3F,0x96,0x01}, +{0xED40,0xD0,0x01}, {0xED41,0xBC,0x01}, -{0xED42,0x45,0x01}, +{0xED42,0xA5,0x01}, {0xED43,0x35,0x01}, {0xED44,0x83,0x01}, -{0xED45,0x41,0x01}, +{0xED45,0x61,0x01}, {0xED46,0xCE,0x01}, {0xED47,0x67,0x01}, -{0xED48,0xE8,0x01}, +{0xED48,0xF2,0x01}, {0xED49,0x33,0x01}, {0xED4A,0x1C,0x01}, -{0xED4B,0x16,0x01}, +{0xED4B,0x1A,0x01}, {0xED4C,0xC1,0x01}, -{0xED4D,0x86,0x01}, -{0xED4E,0x3E,0x01}, +{0xED4D,0x46,0x01}, +{0xED4E,0x3F,0x01}, {0xED4F,0x83,0x01}, -{0xED50,0xC1,0x01}, +{0xED50,0xD9,0x01}, {0xED51,0x0D,0x01}, {0xED52,0x57,0x01}, -{0xED53,0x02,0x01}, +{0xED53,0x06,0x01}, {0xED54,0x23,0x01}, {0xED55,0x14,0x01}, -{0xED56,0xAE,0x01}, +{0xED56,0xAF,0x01}, {0xED57,0xE4,0x01}, -{0xED58,0x44,0x01}, +{0xED58,0x64,0x01}, {0xED59,0x2A,0x01}, {0xED5A,0x43,0x01}, -{0xED5B,0xF9,0x01}, -{0xED5C,0xCA,0x01}, +{0xED5B,0x01,0x01}, +{0xED5C,0xCB,0x01}, {0xED5D,0x56,0x01}, -{0xED5E,0x0C,0x01}, +{0xED5E,0x10,0x01}, {0xED5F,0x03,0x01}, -{0xED60,0x98,0x01}, -{0xED61,0xE2,0x01}, +{0xED60,0x18,0x01}, +{0xED61,0xE4,0x01}, {0xED62,0xA8,0x01}, -{0xED63,0x26,0x01}, +{0xED63,0xE6,0x01}, {0xED64,0x41,0x01}, {0xED65,0x9E,0x01}, -{0xED66,0xC1,0x01}, +{0xED66,0xE1,0x01}, {0xED67,0xCE,0x01}, {0xED68,0x59,0x01}, -{0xED69,0x1C,0x01}, +{0xED69,0x20,0x01}, {0xED6A,0xB3,0x01}, -{0xED6B,0x93,0x01}, -{0xED6C,0xA7,0x01}, +{0xED6B,0x13,0x01}, +{0xED6C,0xA8,0x01}, {0xED6D,0x74,0x01}, {0xED6E,0x04,0x01}, {0xED6F,0x25,0x01}, {0xED70,0x13,0x01}, -{0xED71,0xD9,0x01}, +{0xED71,0xE1,0x01}, {0xED72,0xC8,0x01}, {0xED73,0x47,0x01}, -{0xED74,0x54,0x01}, +{0xED74,0x56,0x01}, {0xED75,0xD2,0x01}, -{0xED76,0x93,0x01}, -{0xED77,0xAA,0x01}, +{0xED76,0x13,0x01}, +{0xED77,0xAB,0x01}, {0xED78,0x98,0x01}, -{0xED79,0xE5,0x01}, -{0xED7A,0x32,0x01}, +{0xED79,0x25,0x01}, +{0xED7A,0x33,0x01}, {0xED7B,0x9A,0x01}, -{0xED7C,0x29,0x01}, +{0xED7C,0x49,0x01}, {0xED7D,0xCF,0x01}, {0xED7E,0x64,0x01}, -{0xED7F,0x8E,0x01}, +{0xED7F,0x96,0x01}, {0xED80,0x73,0x01}, {0xED81,0x95,0x01}, -{0xED82,0xBB,0x01}, +{0xED82,0xBC,0x01}, {0xED83,0xA4,0x01}, -{0xED84,0xA4,0x01}, +{0xED84,0xC4,0x01}, {0xED85,0x26,0x01}, {0xED86,0x0A,0x01}, {0xED87,0x59,0x01}, @@ -10004,21 +10016,21 @@ static const isx012_regset_t ISX012_Shading_2[] = {0xED8C,0x10,0x01}, {0xED8D,0x88,0x01}, {0xED8E,0xB0,0x01}, -{0xED8F,0x84,0x01}, +{0xED8F,0xA4,0x01}, {0xED90,0x27,0x01}, {0xED91,0x59,0x01}, -{0xED92,0xF1,0x01}, +{0xED92,0xF9,0x01}, {0xED93,0x0B,0x01}, {0xED94,0x64,0x01}, -{0xED95,0xA2,0x01}, +{0xED95,0xA8,0x01}, {0xED96,0x43,0x01}, -{0xED97,0x99,0x01}, -{0xED98,0xE4,0x01}, +{0xED97,0x19,0x01}, +{0xED98,0xE6,0x01}, {0xED99,0x68,0x01}, -{0xED9A,0x25,0x01}, +{0xED9A,0x45,0x01}, {0xED9B,0x2F,0x01}, {0xED9C,0x2B,0x01}, -{0xED9D,0xB1,0x01}, +{0xED9D,0xB9,0x01}, {0xED9E,0xC9,0x01}, {0xED9F,0x42,0x01}, {0xEDA0,0x18,0x01}, @@ -10026,24 +10038,24 @@ static const isx012_regset_t ISX012_Shading_2[] = {0xEDA2,0x90,0x01}, {0xEDA3,0x80,0x01}, {0xEDA4,0x3C,0x01}, -{0xEDA5,0x24,0x01}, +{0xEDA5,0x44,0x01}, {0xEDA6,0x22,0x01}, {0xEDA7,0x2F,0x01}, {0xEDA8,0xF1,0x01}, {0xEDA9,0x09,0x01}, {0xEDAA,0x57,0x01}, -{0xEDAB,0x00,0x01}, +{0xEDAB,0x04,0x01}, {0xEDAC,0x53,0x01}, {0xEDAD,0x99,0x01}, -{0xEDAE,0xEA,0x01}, +{0xEDAE,0xEC,0x01}, {0xEDAF,0x90,0x01}, -{0xEDB0,0xC6,0x01}, -{0xEDB1,0x3B,0x01}, +{0xEDB0,0x66,0x01}, +{0xEDB1,0x3C,0x01}, {0xEDB2,0x6D,0x01}, -{0xEDB3,0x99,0x01}, +{0xEDB3,0xA9,0x01}, {0xEDB4,0x4C,0x01}, {0xEDB5,0x50,0x01}, -{0xEDB6,0xA4,0x01}, +{0xEDB6,0xA6,0x01}, {0xEDB7,0x32,0x01}, {0xEDB8,0x12,0x01}, {0xEDB9,0x94,0x01}, @@ -10054,112 +10066,112 @@ static const isx012_regset_t ISX012_Shading_2[] = {0xEDBE,0x71,0x01}, {0xEDBF,0x49,0x01}, {0xEDC0,0x51,0x01}, -{0xEDC1,0xB2,0x01}, +{0xEDC1,0xB4,0x01}, {0xEDC2,0x02,0x01}, {0xEDC3,0x17,0x01}, -{0xEDC4,0xCD,0x01}, +{0xEDC4,0xCE,0x01}, {0xEDC5,0x98,0x01}, -{0xEDC6,0x86,0x01}, -{0xEDC7,0x3D,0x01}, +{0xEDC6,0x06,0x01}, +{0xEDC7,0x3E,0x01}, {0xEDC8,0xBC,0x01}, -{0xEDC9,0x01,0x01}, +{0xEDC9,0x31,0x01}, {0xEDCA,0x50,0x01}, {0xEDCB,0x63,0x01}, -{0xEDCC,0x80,0x01}, +{0xEDCC,0x86,0x01}, {0xEDCD,0x63,0x01}, {0xEDCE,0x16,0x01}, -{0xEDCF,0xC3,0x01}, +{0xEDCF,0xC4,0x01}, {0xEDD0,0x2C,0x01}, -{0xEDD1,0x25,0x01}, +{0xEDD1,0x45,0x01}, {0xEDD2,0x2C,0x01}, {0xEDD3,0x43,0x01}, -{0xEDD4,0xB1,0x01}, +{0xEDD4,0xB9,0x01}, {0xEDD5,0x4A,0x01}, {0xEDD6,0x53,0x01}, -{0xEDD7,0xCC,0x01}, +{0xEDD7,0xCE,0x01}, {0xEDD8,0x82,0x01}, {0xEDD9,0x96,0x01}, -{0xEDDA,0xC7,0x01}, +{0xEDDA,0xC8,0x01}, {0xEDDB,0x40,0x01}, -{0xEDDC,0xA6,0x01}, -{0xEDDD,0x39,0x01}, +{0xEDDC,0x06,0x01}, +{0xEDDD,0x3A,0x01}, {0xEDDE,0xBE,0x01}, -{0xEDDF,0x91,0x01}, +{0xEDDF,0xC1,0x01}, {0xEDE0,0xD0,0x01}, {0xEDE1,0x75,0x01}, -{0xEDE2,0x54,0x01}, +{0xEDE2,0x64,0x01}, {0xEDE3,0x34,0x01}, -{0xEDE4,0x1B,0x01}, -{0xEDE5,0xFC,0x01}, +{0xEDE4,0x9B,0x01}, +{0xEDE5,0xFE,0x01}, {0xEDE6,0x4C,0x01}, -{0xEDE7,0x46,0x01}, +{0xEDE7,0xA6,0x01}, {0xEDE8,0x39,0x01}, {0xEDE9,0x7D,0x01}, -{0xEDEA,0x71,0x01}, +{0xEDEA,0x89,0x01}, {0xEDEB,0x8D,0x01}, {0xEDEC,0x5D,0x01}, -{0xEDED,0x46,0x01}, +{0xEDED,0x4A,0x01}, {0xEDEE,0xE3,0x01}, -{0xEDEF,0x17,0x01}, -{0xEDF0,0xD9,0x01}, +{0xEDEF,0x97,0x01}, +{0xEDF0,0xDA,0x01}, {0xEDF1,0x50,0x01}, -{0xEDF2,0x86,0x01}, +{0xEDF2,0xE6,0x01}, {0xEDF3,0x3A,0x01}, {0xEDF4,0xB3,0x01}, -{0xEDF5,0x09,0x01}, +{0xEDF5,0x39,0x01}, {0xEDF6,0x50,0x01}, {0xEDF7,0x76,0x01}, -{0xEDF8,0x6A,0x01}, +{0xEDF8,0x7A,0x01}, {0xEDF9,0xF4,0x01}, -{0xEDFA,0x1E,0x01}, -{0xEDFB,0x25,0x01}, +{0xEDFA,0x9E,0x01}, +{0xEDFB,0x2A,0x01}, {0xEDFC,0x61,0x01}, -{0xEDFD,0x67,0x01}, -{0xEDFE,0x45,0x01}, +{0xEDFD,0x87,0x01}, +{0xEDFE,0x46,0x01}, {0xEDFF,0xC0,0x01}, -{0xEE00,0x69,0x01}, +{0xEE00,0x99,0x01}, {0xEE01,0xD0,0x01}, {0xEE02,0x6B,0x01}, -{0xEE03,0xF6,0x01}, -{0xEE04,0x93,0x01}, -{0xEE05,0x9A,0x01}, -{0xEE06,0xFA,0x01}, +{0xEE03,0x02,0x01}, +{0xEE04,0x94,0x01}, +{0xEE05,0x1A,0x01}, +{0xEE06,0xFD,0x01}, {0xEE07,0xB8,0x01}, -{0xEE08,0x26,0x01}, +{0xEE08,0xE6,0x01}, {0xEE09,0x40,0x01}, {0xEE0A,0xC0,0x01}, -{0xEE0B,0xB9,0x01}, +{0xEE0B,0xF1,0x01}, {0xEE0C,0xD0,0x01}, {0xEE0D,0x75,0x01}, -{0xEE0E,0x6E,0x01}, +{0xEE0E,0x80,0x01}, {0xEE0F,0xE4,0x01}, {0xEE10,0x9E,0x01}, -{0xEE11,0x2D,0x01}, +{0xEE11,0x33,0x01}, {0xEE12,0xE1,0x01}, {0xEE13,0xA7,0x01}, -{0xEE14,0x49,0x01}, +{0xEE14,0x4B,0x01}, {0xEE15,0xFD,0x01}, -{0xEE16,0xB9,0x01}, -{0xEE17,0x52,0x01}, +{0xEE16,0x21,0x01}, +{0xEE17,0x53,0x01}, {0xEE18,0x7C,0x01}, -{0xEE19,0x98,0x01}, +{0xEE19,0xAE,0x01}, {0xEE1A,0x64,0x01}, -{0xEE1B,0x1E,0x01}, -{0xEE1C,0x22,0x01}, +{0xEE1B,0x9E,0x01}, +{0xEE1C,0x26,0x01}, {0xEE1D,0x89,0x01}, -{0xEE1E,0xA7,0x01}, -{0xEE1F,0x48,0x01}, +{0xEE1E,0xC7,0x01}, +{0xEE1F,0x49,0x01}, {0xEE20,0xE4,0x01}, -{0xEE21,0x49,0x01}, +{0xEE21,0x99,0x01}, {0xEE22,0x12,0x01}, {0xEE23,0x7D,0x01}, -{0xEE24,0xB4,0x01}, +{0xEE24,0xCA,0x01}, {0xEE25,0xB4,0x01}, -{0xEE26,0x1F,0x01}, -{0xEE27,0x31,0x01}, +{0xEE26,0x9F,0x01}, +{0xEE27,0x37,0x01}, {0xEE28,0xC5,0x01}, {0xEE29,0x47,0x01}, -{0xEE2A,0x4B,0x01}, +{0xEE2A,0x4D,0x01}, {0xEE2B,0xC2,0x01}, {0xEE2C,0x19,0x01}, {0xEE2D,0x0F,0x01}, @@ -10461,154 +10473,154 @@ static const isx012_regset_t ISX012_Shading_2[] = //SHD2 CW+TL84 33:66 {0xED00,0x9191,0x02},// -{0xEF54,0x21,0x01}, -{0xEF55,0x92,0x01}, -{0xEF56,0xD1,0x01}, -{0xEF57,0x8A,0x01}, -{0xEF58,0x3E,0x01}, -{0xEF59,0xF4,0x01}, -{0xEF5A,0xA1,0x01}, -{0xEF5B,0x10,0x01}, -{0xEF5C,0xB9,0x01}, -{0xEF5D,0x48,0x01}, -{0xEF5E,0x46,0x01}, -{0xEF5F,0x1F,0x01}, -{0xEF60,0x82,0x01}, +{0xEF54,0x2F,0x01}, +{0xEF55,0xF2,0x01}, +{0xEF56,0x51,0x01}, +{0xEF57,0x8D,0x01}, +{0xEF58,0x50,0x01}, +{0xEF59,0x74,0x01}, +{0xEF5A,0xA2,0x01}, +{0xEF5B,0x14,0x01}, +{0xEF5C,0xE1,0x01}, +{0xEF5D,0xC8,0x01}, +{0xEF5E,0x47,0x01}, +{0xEF5F,0x2E,0x01}, +{0xEF60,0xD2,0x01}, {0xEF61,0x10,0x01}, -{0xEF62,0x7E,0x01}, -{0xEF63,0xBC,0x01}, -{0xEF64,0xC3,0x01}, -{0xEF65,0x1C,0x01}, -{0xEF66,0xE3,0x01}, -{0xEF67,0x38,0x01}, -{0xEF68,0xC7,0x01}, -{0xEF69,0x3B,0x01}, -{0xEF6A,0xF7,0x01}, -{0xEF6B,0x71,0x01}, -{0xEF6C,0x90,0x01}, -{0xEF6D,0x7B,0x01}, -{0xEF6E,0x8E,0x01}, -{0xEF6F,0x53,0x01}, -{0xEF70,0x1A,0x01}, -{0xEF71,0xC5,0x01}, -{0xEF72,0x04,0x01}, -{0xEF73,0x46,0x01}, +{0xEF62,0x80,0x01}, +{0xEF63,0xC8,0x01}, +{0xEF64,0x13,0x01}, +{0xEF65,0x9D,0x01}, +{0xEF66,0xE5,0x01}, +{0xEF67,0x48,0x01}, +{0xEF68,0x87,0x01}, +{0xEF69,0x3C,0x01}, +{0xEF6A,0xFE,0x01}, +{0xEF6B,0xC9,0x01}, +{0xEF6C,0x50,0x01}, +{0xEF6D,0x7D,0x01}, +{0xEF6E,0x96,0x01}, +{0xEF6F,0x83,0x01}, +{0xEF70,0x9A,0x01}, +{0xEF71,0xC6,0x01}, +{0xEF72,0x10,0x01}, +{0xEF73,0xA6,0x01}, {0xEF74,0x31,0x01}, -{0xEF75,0xA2,0x01}, -{0xEF76,0x39,0x01}, -{0xEF77,0x0E,0x01}, -{0xEF78,0x7E,0x01}, -{0xEF79,0x9A,0x01}, -{0xEF7A,0xA3,0x01}, -{0xEF7B,0x99,0x01}, -{0xEF7C,0xB5,0x01}, -{0xEF7D,0x34,0x01}, -{0xEF7E,0x85,0x01}, +{0xEF75,0xA5,0x01}, +{0xEF76,0x61,0x01}, +{0xEF77,0xCE,0x01}, +{0xEF78,0x7F,0x01}, +{0xEF79,0xA4,0x01}, +{0xEF7A,0xD3,0x01}, +{0xEF7B,0x19,0x01}, +{0xEF7C,0xB6,0x01}, +{0xEF7D,0x38,0x01}, +{0xEF7E,0xA5,0x01}, {0xEF7F,0x28,0x01}, -{0xEF80,0x4D,0x01}, -{0xEF81,0x61,0x01}, -{0xEF82,0x8B,0x01}, -{0xEF83,0x67,0x01}, -{0xEF84,0xB0,0x01}, -{0xEF85,0x53,0x01}, +{0xEF80,0x4E,0x01}, +{0xEF81,0x69,0x01}, +{0xEF82,0x4B,0x01}, +{0xEF83,0x68,0x01}, +{0xEF84,0xBA,0x01}, +{0xEF85,0x93,0x01}, {0xEF86,0x1B,0x01}, -{0xEF87,0xBB,0x01}, -{0xEF88,0x08,0x01}, -{0xEF89,0x45,0x01}, +{0xEF87,0xBC,0x01}, +{0xEF88,0x0C,0x01}, +{0xEF89,0x65,0x01}, {0xEF8A,0x24,0x01}, {0xEF8B,0x17,0x01}, -{0xEF8C,0x11,0x01}, -{0xEF8D,0x09,0x01}, +{0xEF8C,0x19,0x01}, +{0xEF8D,0x49,0x01}, {0xEF8E,0x51,0x01}, -{0xEF8F,0xF2,0x01}, -{0xEF90,0xA2,0x01}, -{0xEF91,0x9B,0x01}, -{0xEF92,0xD3,0x01}, -{0xEF93,0x90,0x01}, +{0xEF8F,0xF6,0x01}, +{0xEF90,0xE2,0x01}, +{0xEF91,0x1B,0x01}, +{0xEF92,0xD5,0x01}, +{0xEF93,0x98,0x01}, {0xEF94,0xC5,0x01}, {0xEF95,0x25,0x01}, -{0xEF96,0x0A,0x01}, +{0xEF96,0x0B,0x01}, {0xEF97,0x01,0x01}, {0xEF98,0x48,0x01}, {0xEF99,0x43,0x01}, -{0xEF9A,0x62,0x01}, -{0xEF9B,0x52,0x01}, -{0xEF9C,0x16,0x01}, -{0xEF9D,0xD5,0x01}, -{0xEF9E,0x9C,0x01}, -{0xEF9F,0xC6,0x01}, +{0xEF9A,0x64,0x01}, +{0xEF9B,0x72,0x01}, +{0xEF9C,0x96,0x01}, +{0xEF9D,0xD6,0x01}, +{0xEF9E,0xA8,0x01}, +{0xEF9F,0xE6,0x01}, {0xEFA0,0x2C,0x01}, -{0xEFA1,0x2F,0x01}, +{0xEFA1,0x30,0x01}, {0xEFA2,0x51,0x01}, {0xEFA3,0x48,0x01}, {0xEFA4,0x40,0x01}, {0xEFA5,0x1C,0x01}, {0xEFA6,0x22,0x01}, {0xEFA7,0x93,0x01}, -{0xEFA8,0xB3,0x01}, -{0xEFA9,0xB8,0x01}, -{0xEFAA,0x46,0x01}, +{0xEFA8,0xB4,0x01}, +{0xEFA9,0xC8,0x01}, +{0xEFAA,0xA6,0x01}, {0xEFAB,0x37,0x01}, -{0xEFAC,0x7A,0x01}, -{0xEFAD,0x21,0x01}, -{0xEFAE,0x4A,0x01}, +{0xEFAC,0x7C,0x01}, +{0xEFAD,0x29,0x01}, +{0xEFAE,0x8A,0x01}, {0xEFAF,0x48,0x01}, {0xEFB0,0x30,0x01}, -{0xEFB1,0x52,0x01}, +{0xEFB1,0x62,0x01}, {0xEFB2,0x12,0x01}, {0xEFB3,0xA4,0x01}, -{0xEFB4,0xF0,0x01}, -{0xEFB5,0xE5,0x01}, -{0xEFB6,0x37,0x01}, -{0xEFB7,0xD6,0x01}, -{0xEFB8,0xF9,0x01}, -{0xEFB9,0x8C,0x01}, -{0xEFBA,0x5B,0x01}, -{0xEFBB,0x9E,0x01}, -{0xEFBC,0x62,0x01}, -{0xEFBD,0x14,0x01}, +{0xEFB4,0xF8,0x01}, +{0xEFB5,0x65,0x01}, +{0xEFB6,0x38,0x01}, +{0xEFB7,0xDB,0x01}, +{0xEFB8,0x11,0x01}, +{0xEFB9,0x0D,0x01}, +{0xEFBA,0x5C,0x01}, +{0xEFBB,0xA0,0x01}, +{0xEFBC,0x72,0x01}, +{0xEFBD,0x94,0x01}, {0xEFBE,0xA9,0x01}, -{0xEFBF,0xC8,0x01}, -{0xEFC0,0xA5,0x01}, -{0xEFC1,0x34,0x01}, -{0xEFC2,0xE0,0x01}, -{0xEFC3,0xD1,0x01}, -{0xEFC4,0x8F,0x01}, -{0xEFC5,0x73,0x01}, -{0xEFC6,0x4C,0x01}, -{0xEFC7,0xE3,0x01}, -{0xEFC8,0x18,0x01}, -{0xEFC9,0xC2,0x01}, -{0xEFCA,0x3C,0x01}, -{0xEFCB,0x46,0x01}, +{0xEFBF,0xD0,0x01}, +{0xEFC0,0x05,0x01}, +{0xEFC1,0x35,0x01}, +{0xEFC2,0xE5,0x01}, +{0xEFC3,0x11,0x01}, +{0xEFC4,0xD0,0x01}, +{0xEFC5,0x74,0x01}, +{0xEFC6,0x52,0x01}, +{0xEFC7,0x03,0x01}, +{0xEFC8,0x19,0x01}, +{0xEFC9,0xC3,0x01}, +{0xEFCA,0x48,0x01}, +{0xEFCB,0xC6,0x01}, {0xEFCC,0x35,0x01}, -{0xEFCD,0xD2,0x01}, -{0xEFCE,0x09,0x01}, -{0xEFCF,0x90,0x01}, -{0xEFD0,0x85,0x01}, -{0xEFD1,0xF6,0x01}, -{0xEFD2,0x03,0x01}, -{0xEFD3,0x1E,0x01}, -{0xEFD4,0xE7,0x01}, -{0xEFD5,0x20,0x01}, -{0xEFD6,0x27,0x01}, +{0xEFCD,0xD7,0x01}, +{0xEFCE,0x41,0x01}, +{0xEFCF,0x10,0x01}, +{0xEFD0,0x88,0x01}, +{0xEFD1,0x06,0x01}, +{0xEFD2,0x54,0x01}, +{0xEFD3,0x9E,0x01}, +{0xEFD4,0xE9,0x01}, +{0xEFD5,0x30,0x01}, +{0xEFD6,0xC7,0x01}, {0xEFD7,0x3A,0x01}, -{0xEFD8,0xE4,0x01}, -{0xEFD9,0x01,0x01}, -{0xEFDA,0x90,0x01}, -{0xEFDB,0x87,0x01}, -{0xEFDC,0x30,0x01}, -{0xEFDD,0x04,0x01}, +{0xEFD8,0xEA,0x01}, +{0xEFD9,0x41,0x01}, +{0xEFDA,0x50,0x01}, +{0xEFDB,0x8A,0x01}, +{0xEFDC,0x4E,0x01}, +{0xEFDD,0xB4,0x01}, {0xEFDE,0x22,0x01}, -{0xEFDF,0x0B,0x01}, -{0xEFE0,0x2D,0x01}, -{0xEFE1,0x28,0x01}, -{0xEFE2,0x41,0x01}, -{0xEFE3,0x10,0x01}, -{0xEFE4,0xDA,0x01}, -{0xEFE5,0x90,0x01}, -{0xEFE6,0x88,0x01}, -{0xEFE7,0x3C,0x01}, +{0xEFDF,0x10,0x01}, +{0xEFE0,0x51,0x01}, +{0xEFE1,0x48,0x01}, +{0xEFE2,0x42,0x01}, +{0xEFE3,0x19,0x01}, +{0xEFE4,0x2A,0x01}, +{0xEFE5,0x91,0x01}, +{0xEFE6,0x8B,0x01}, +{0xEFE7,0x5A,0x01}, {0xEFE8,0x04,0x01}, {0xEFE9,0x00,0x01}, {0xEFEA,0x00,0x01}, @@ -10620,154 +10632,154 @@ static const isx012_regset_t ISX012_Shading_2[] = //SHD3 D65+TL84 C01// {0xED00,0x9191,0x02},// -{0xEFEE,0x12,0x01}, -{0xEFEF,0x42,0x01}, -{0xEFF0,0x51,0x01}, -{0xEFF1,0x89,0x01}, -{0xEFF2,0x38,0x01}, -{0xEFF3,0xD4,0x01}, -{0xEFF4,0x21,0x01}, -{0xEFF5,0x10,0x01}, -{0xEFF6,0xAD,0x01}, -{0xEFF7,0xA8,0x01}, -{0xEFF8,0x45,0x01}, -{0xEFF9,0x18,0x01}, -{0xEFFA,0x4A,0x01}, +{0xEFEE,0x21,0x01}, +{0xEFEF,0xAA,0x01}, +{0xEFF0,0xD1,0x01}, +{0xEFF1,0x8B,0x01}, +{0xEFF2,0x4A,0x01}, +{0xEFF3,0x64,0x01}, +{0xEFF4,0x22,0x01}, +{0xEFF5,0x15,0x01}, +{0xEFF6,0xD9,0x01}, +{0xEFF7,0x28,0x01}, +{0xEFF8,0x47,0x01}, +{0xEFF9,0x26,0x01}, +{0xEFFA,0xA2,0x01}, {0xEFFB,0x50,0x01}, -{0xEFFC,0x7D,0x01}, -{0xEFFD,0xBA,0x01}, -{0xEFFE,0xD3,0x01}, -{0xEFFF,0x1C,0x01}, -{0xF000,0xE4,0x01}, -{0xF001,0x40,0x01}, -{0xF002,0x27,0x01}, +{0xEFFC,0x7F,0x01}, +{0xEFFD,0xC6,0x01}, +{0xEFFE,0x23,0x01}, +{0xEFFF,0x9D,0x01}, +{0xF000,0xE6,0x01}, +{0xF001,0x54,0x01}, +{0xF002,0xE7,0x01}, {0xF003,0x3C,0x01}, -{0xF004,0xF8,0x01}, -{0xF005,0x69,0x01}, -{0xF006,0x10,0x01}, -{0xF007,0x7B,0x01}, -{0xF008,0x8E,0x01}, -{0xF009,0x63,0x01}, -{0xF00A,0x1A,0x01}, -{0xF00B,0xC6,0x01}, -{0xF00C,0x10,0x01}, -{0xF00D,0xA6,0x01}, -{0xF00E,0x31,0x01}, -{0xF00F,0xA6,0x01}, -{0xF010,0x59,0x01}, +{0xF004,0x00,0x01}, +{0xF005,0xBA,0x01}, +{0xF006,0xD0,0x01}, +{0xF007,0x7C,0x01}, +{0xF008,0x98,0x01}, +{0xF009,0xA3,0x01}, +{0xF00A,0x9A,0x01}, +{0xF00B,0xC7,0x01}, +{0xF00C,0x18,0x01}, +{0xF00D,0x06,0x01}, +{0xF00E,0x32,0x01}, +{0xF00F,0xAA,0x01}, +{0xF010,0x81,0x01}, {0xF011,0x8E,0x01}, -{0xF012,0x7E,0x01}, -{0xF013,0x9A,0x01}, -{0xF014,0xB3,0x01}, +{0xF012,0x80,0x01}, +{0xF013,0xA4,0x01}, +{0xF014,0xE3,0x01}, {0xF015,0x19,0x01}, -{0xF016,0xB6,0x01}, -{0xF017,0x38,0x01}, -{0xF018,0xA5,0x01}, +{0xF016,0xB7,0x01}, +{0xF017,0x3C,0x01}, +{0xF018,0xC5,0x01}, {0xF019,0x28,0x01}, -{0xF01A,0x4F,0x01}, -{0xF01B,0x79,0x01}, -{0xF01C,0xCB,0x01}, -{0xF01D,0x68,0x01}, -{0xF01E,0xBA,0x01}, -{0xF01F,0x53,0x01}, +{0xF01A,0x51,0x01}, +{0xF01B,0x89,0x01}, +{0xF01C,0x8B,0x01}, +{0xF01D,0x69,0x01}, +{0xF01E,0xC4,0x01}, +{0xF01F,0x93,0x01}, {0xF020,0x9B,0x01}, -{0xF021,0xBB,0x01}, -{0xF022,0x0C,0x01}, +{0xF021,0xBC,0x01}, +{0xF022,0x10,0x01}, {0xF023,0x65,0x01}, {0xF024,0x24,0x01}, -{0xF025,0x17,0x01}, +{0xF025,0x18,0x01}, {0xF026,0x21,0x01}, -{0xF027,0xC9,0x01}, -{0xF028,0x51,0x01}, -{0xF029,0xFC,0x01}, -{0xF02A,0xF2,0x01}, -{0xF02B,0x9B,0x01}, -{0xF02C,0xD3,0x01}, -{0xF02D,0x94,0x01}, -{0xF02E,0xC5,0x01}, +{0xF027,0x09,0x01}, +{0xF028,0x52,0x01}, +{0xF029,0x00,0x01}, +{0xF02A,0x33,0x01}, +{0xF02B,0x9C,0x01}, +{0xF02C,0xD5,0x01}, +{0xF02D,0x9C,0x01}, +{0xF02E,0xE5,0x01}, {0xF02F,0x25,0x01}, {0xF030,0x0A,0x01}, {0xF031,0x01,0x01}, -{0xF032,0x48,0x01}, +{0xF032,0x88,0x01}, {0xF033,0x43,0x01}, -{0xF034,0x66,0x01}, -{0xF035,0x92,0x01}, -{0xF036,0x96,0x01}, -{0xF037,0xD7,0x01}, -{0xF038,0xA0,0x01}, -{0xF039,0xE6,0x01}, -{0xF03A,0x2C,0x01}, -{0xF03B,0x2F,0x01}, +{0xF034,0x68,0x01}, +{0xF035,0xA2,0x01}, +{0xF036,0x16,0x01}, +{0xF037,0xD9,0x01}, +{0xF038,0xAC,0x01}, +{0xF039,0x06,0x01}, +{0xF03A,0x2D,0x01}, +{0xF03B,0x30,0x01}, {0xF03C,0x51,0x01}, {0xF03D,0x48,0x01}, {0xF03E,0x40,0x01}, {0xF03F,0x1E,0x01}, {0xF040,0x42,0x01}, {0xF041,0x93,0x01}, -{0xF042,0xB5,0x01}, -{0xF043,0xCC,0x01}, -{0xF044,0x46,0x01}, +{0xF042,0xB6,0x01}, +{0xF043,0xDC,0x01}, +{0xF044,0xC6,0x01}, {0xF045,0x37,0x01}, -{0xF046,0x7C,0x01}, -{0xF047,0x29,0x01}, -{0xF048,0x8A,0x01}, +{0xF046,0x7E,0x01}, +{0xF047,0x31,0x01}, +{0xF048,0xCA,0x01}, {0xF049,0x48,0x01}, {0xF04A,0x32,0x01}, {0xF04B,0x72,0x01}, -{0xF04C,0x12,0x01}, +{0xF04C,0x92,0x01}, {0xF04D,0xA5,0x01}, -{0xF04E,0x00,0x01}, -{0xF04F,0xA6,0x01}, -{0xF050,0x38,0x01}, -{0xF051,0xD7,0x01}, -{0xF052,0x01,0x01}, -{0xF053,0x0D,0x01}, +{0xF04E,0x08,0x01}, +{0xF04F,0x26,0x01}, +{0xF050,0x39,0x01}, +{0xF051,0xDC,0x01}, +{0xF052,0x19,0x01}, +{0xF053,0x8D,0x01}, {0xF054,0x5C,0x01}, -{0xF055,0xA2,0x01}, -{0xF056,0x82,0x01}, -{0xF057,0x94,0x01}, -{0xF058,0xAA,0x01}, -{0xF059,0xD8,0x01}, -{0xF05A,0x45,0x01}, +{0xF055,0xA4,0x01}, +{0xF056,0x92,0x01}, +{0xF057,0x14,0x01}, +{0xF058,0xAB,0x01}, +{0xF059,0xE0,0x01}, +{0xF05A,0xA5,0x01}, {0xF05B,0x35,0x01}, -{0xF05C,0xE5,0x01}, -{0xF05D,0xC9,0x01}, -{0xF05E,0xCF,0x01}, -{0xF05F,0x73,0x01}, -{0xF060,0x50,0x01}, -{0xF061,0x03,0x01}, +{0xF05C,0xEA,0x01}, +{0xF05D,0x09,0x01}, +{0xF05E,0x10,0x01}, +{0xF05F,0x75,0x01}, +{0xF060,0x58,0x01}, +{0xF061,0x33,0x01}, {0xF062,0x99,0x01}, -{0xF063,0xC3,0x01}, -{0xF064,0x4C,0x01}, -{0xF065,0xE6,0x01}, -{0xF066,0x35,0x01}, -{0xF067,0xD7,0x01}, -{0xF068,0x21,0x01}, -{0xF069,0x10,0x01}, -{0xF06A,0x84,0x01}, -{0xF06B,0xF2,0x01}, -{0xF06C,0x03,0x01}, -{0xF06D,0x9E,0x01}, -{0xF06E,0xE8,0x01}, -{0xF06F,0x2C,0x01}, -{0xF070,0xA7,0x01}, -{0xF071,0x3A,0x01}, -{0xF072,0xE8,0x01}, -{0xF073,0x11,0x01}, -{0xF074,0x90,0x01}, -{0xF075,0x87,0x01}, -{0xF076,0x18,0x01}, -{0xF077,0x94,0x01}, -{0xF078,0x21,0x01}, -{0xF079,0x09,0x01}, -{0xF07A,0x2D,0x01}, -{0xF07B,0x68,0x01}, -{0xF07C,0x41,0x01}, -{0xF07D,0x11,0x01}, -{0xF07E,0xDA,0x01}, -{0xF07F,0x10,0x01}, -{0xF080,0x88,0x01}, -{0xF081,0x2A,0x01}, +{0xF063,0xC4,0x01}, +{0xF064,0x58,0x01}, +{0xF065,0x66,0x01}, +{0xF066,0x36,0x01}, +{0xF067,0xDB,0x01}, +{0xF068,0x61,0x01}, +{0xF069,0xD0,0x01}, +{0xF06A,0x86,0x01}, +{0xF06B,0x02,0x01}, +{0xF06C,0x64,0x01}, +{0xF06D,0x1E,0x01}, +{0xF06E,0xEB,0x01}, +{0xF06F,0x40,0x01}, +{0xF070,0x47,0x01}, +{0xF071,0x3B,0x01}, +{0xF072,0xEE,0x01}, +{0xF073,0x51,0x01}, +{0xF074,0x10,0x01}, +{0xF075,0x8A,0x01}, +{0xF076,0x36,0x01}, +{0xF077,0x54,0x01}, +{0xF078,0x22,0x01}, +{0xF079,0x0E,0x01}, +{0xF07A,0x51,0x01}, +{0xF07B,0x88,0x01}, +{0xF07C,0x42,0x01}, +{0xF07D,0x1A,0x01}, +{0xF07E,0x2A,0x01}, +{0xF07F,0x11,0x01}, +{0xF080,0x8B,0x01}, +{0xF081,0x48,0x01}, {0xF082,0x04,0x01}, {0xF083,0x00,0x01}, {0xF084,0x00,0x01}, @@ -10943,8 +10955,8 @@ static const isx012_regset_t ISX012_Shading_2[] = //PreWB_offset (for SHD2) {0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 : //PreWB_offset (for SHD3) -{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB : -{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB : +{0x682C,0x000B,0x02}, // SHD_PRER_OFFSET_RB : +{0x6830,0xFFFD,0x02}, // SHD_PREB_OFFSET_RB : // CXC/SHD EN {0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF @@ -11199,6 +11211,26 @@ static const isx012_regset_t ISX012_Flash_AELINE[] = {0x031F,0x02,0x01}, // AELINE_CAP_SN11_12 : }; +static const isx012_regset_t ISX012_ae_manual_mode[] = +{ +{0x0294,0x02,0x01}, /* AE_SN1 */ +{0x0297,0x02,0x01}, /* AE_SN4 */ +{0x029A,0x02,0x01}, /* AE_SN7 */ +{0x029E,0x02,0x01}, /* AE_SN11 */ +{0xFFFF,0x42,0x01}, /* $wait, 66 */ +}; + +static const isx012_regset_t ISX012_flash_fast_ae_awb[] = +{ +{0x5E32,0x0A,0x01}, +{0x5E3D,0x05,0x01}, + +{0x0181,0x01,0x01}, // CAP_HALF_AE_CTRL +{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF +{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF +{0x0081,0x01,0x01}, //MODESEL +}; + static const isx012_regset_t ISX012_Lowlux_Night_Reset[] = { {0x039D,0x00,0x01}, //UIHUE_TYPE3 : diff --git a/drivers/media/video/m5mo.c b/drivers/media/video/m5mo.c index 0750ecb..d411269 100644 --- a/drivers/media/video/m5mo.c +++ b/drivers/media/video/m5mo.c @@ -36,11 +36,6 @@ #define M5MO_DRIVER_NAME "M5MO" -#ifdef CONFIG_MACH_S2PLUS -extern struct class *camera_class; -struct device *m5mo_dev; -#endif - #define M5MO_FW_PATH "/sdcard/RS_M5LS.bin" #define M5MO_FW_DUMP_PATH "/data/RS_M5LS_dump.bin" @@ -117,8 +112,9 @@ static const struct m5mo_frmsizeenum preview_frmsizes[] = { }; static const struct m5mo_frmsizeenum capture_frmsizes[] = { - { M5MO_CAPTURE_VGA, 640, 480, 0x09 }, - { M5MO_CAPTURE_WVGA, 800, 480, 0x0A }, + { M5MO_CAPTURE_VGA, 640, 480, 0x09 }, + { M5MO_CAPTURE_WVGA, 800, 480, 0x0A }, + { M5MO_CAPTURE_SXGA, 1280, 960, 0x14 }, { M5MO_CAPTURE_W2MP, 2048, 1232, 0x2C }, { M5MO_CAPTURE_3MP, 2048, 1536, 0x1B }, { M5MO_CAPTURE_W7MP, 3264, 1968, 0x2D }, @@ -178,9 +174,7 @@ static struct m5mo_control m5mo_ctrls[] = { }, }; -#ifndef CONFIG_MACH_S2PLUS struct class *camera_class; -#endif static inline struct m5mo_state *to_state(struct v4l2_subdev *sd) { @@ -1567,9 +1561,7 @@ static int m5mo_set_af(struct v4l2_subdev *sd, int val) static int m5mo_set_af_mode(struct v4l2_subdev *sd, int val) { struct m5mo_state *state = to_state(sd); -#ifndef CONFIG_MACH_S2PLUS struct regulator *movie = regulator_get(NULL, "led_movie"); -#endif u32 cancel, mode, status = 0; int i, err; @@ -1632,12 +1624,10 @@ retry: CHECK_ERR(err); } -#ifndef CONFIG_MACH_S2PLUS if (val == FOCUS_MODE_MACRO) regulator_set_current_limit(movie, 15000, 17000); else if (state->focus.mode == FOCUS_MODE_MACRO) regulator_set_current_limit(movie, 90000, 110000); -#endif state->focus.mode = val; @@ -1656,7 +1646,7 @@ retry: if ((status & 0x01) != 0x00) { cam_err("failed\n"); - return -ETIMEDOUT; + /*return -ETIMEDOUT;*/ /*This return value cause camera lock-up.*/ } cam_trace("X\n"); @@ -2944,7 +2934,6 @@ static int __devinit m5mo_probe(struct i2c_client *client, #ifdef CAM_DEBUG state->dbg_level = CAM_DEBUG; #endif -#ifndef CONFIG_MACH_S2PLUS if (state->m5mo_dev == NULL) { state->m5mo_dev = device_create(camera_class, NULL, 0, NULL, "rear"); @@ -2964,7 +2953,6 @@ static int __devinit m5mo_probe(struct i2c_client *client, } } } -#endif /* wait queue initialize */ init_waitqueue_head(&state->isp.wait); @@ -3026,30 +3014,9 @@ static struct i2c_driver m5mo_i2c_driver = { static int __init m5mo_mod_init(void) { -#ifdef CONFIG_MACH_S2PLUS - if (!m5mo_dev) { - m5mo_dev = - device_create(camera_class, NULL, 0, NULL, "rear"); - if (IS_ERR(m5mo_dev)) { - cam_err("failed to create device m5mo_dev!\n"); - return 0; - } - if (device_create_file - (m5mo_dev, &dev_attr_rear_camtype) < 0) { - cam_err("failed to create device file, %s\n", - dev_attr_rear_camtype.attr.name); - } - if (device_create_file - (m5mo_dev, &dev_attr_rear_camfw) < 0) { - cam_err("failed to create device file, %s\n", - dev_attr_rear_camfw.attr.name); - } - } -#else camera_class = class_create(THIS_MODULE, "camera"); if (IS_ERR(camera_class)) pr_err("Failed to create class(camera)!\n"); -#endif return i2c_add_driver(&m5mo_i2c_driver); } diff --git a/drivers/media/video/m5mo.h b/drivers/media/video/m5mo.h index 8d41584..6218eba 100644 --- a/drivers/media/video/m5mo.h +++ b/drivers/media/video/m5mo.h @@ -80,6 +80,7 @@ enum m5mo_prev_frmsize { enum m5mo_cap_frmsize { M5MO_CAPTURE_VGA, /* 640 x 480 */ M5MO_CAPTURE_WVGA, /* 800 x 480 */ + M5MO_CAPTURE_SXGA, /*1280 x 960*/ M5MO_CAPTURE_W1MP, /* 1600 x 960 */ M5MO_CAPTURE_2MP, /* UXGA - 1600 x 1200 */ M5MO_CAPTURE_W2MP, /* 2048 x 1232 */ diff --git a/drivers/media/video/m9mo.c b/drivers/media/video/m9mo.c index 8b67610..09c496e 100644 --- a/drivers/media/video/m9mo.c +++ b/drivers/media/video/m9mo.c @@ -37,6 +37,7 @@ extern struct class *camera_class; struct device *m9mo_dev; +static bool leave_power; #if 0 #define M9MO_FW_PATH "/data/RS_M9MO.bin" @@ -44,11 +45,19 @@ struct device *m9mo_dev; #endif #define M9MO_FW_PATH "/sdcard/RS_M9MO.bin" + #define M9MO_FW_REQ_PATH "RS_M9MO.bin" +#define M9MO_EVT31_FW_REQ_PATH "RS_M9MO_EVT3.1.bin" + #define FW_INFO_PATH "/sdcard/FW_INFO.bin" -#define M9MO_FW_DUMP_PATH "/data/RS_M9LS_dump.bin" +#define M9MO_FW_DUMP_PATH "/sdcard/M9MO_dump.bin" + +#if 0 +#define M9MO_FACTORY_CSV_PATH "/data/FACTORY_CSV_RAW.bin" +#endif +#define M9MO_FACTORY_CSV_PATH "/mnt/sdcard/FACTORY_CSV_RAW.bin" #define M9MOTB_FW_PATH "RS_M9LS_TB.bin" /* TECHWIN - SONY */ /* #define M9MOON_FW_PATH "RS_M9LS_ON.bin" */ /* FIBEROPTICS - SONY */ @@ -68,9 +77,12 @@ struct device *m9mo_dev; #if 0 #define M9MO_FW_VER_LEN 22 #define M9MO_FW_VER_FILE_CUR 0x16FF00 +#define M9MO_FW_VER_NUM 0x000018 #else -#define M9MO_FW_VER_LEN 20 +#define M9MO_FW_VER_LEN 20 +#define M9MO_SEN_FW_VER_LEN 30 #define M9MO_FW_VER_FILE_CUR 0x1FF080 +#define M9MO_FW_VER_NUM 0x1FF080 #endif #define M9MO_FLASH_BASE_ADDR 0x00000000 @@ -79,33 +91,65 @@ struct device *m9mo_dev; #define M9MO_FLASH_BASE_ADDR_1 0x001FF000 +u32 M9MO_FLASH_FACTORY_OIS[] = {0x27E031A2, 0x27E031C7}; +u32 M9MO_FLASH_FACTORY_VIB[] = {0x27E031C8, 0x27E031D1}; +u32 M9MO_FLASH_FACTORY_GYRO[] = {0x27E031D2, 0x27E031D7}; +u32 M9MO_FLASH_FACTORY_TELE_RESOL[] = {0x27E03298, 0x27E0329F}; +u32 M9MO_FLASH_FACTORY_WIDE_RESOL[] = {0x27E032A0, 0x27E032A7}; +u32 M9MO_FLASH_FACTORY_AF_FCS[] = {0x27E0323A, 0x27E03275}; +u32 M9MO_FLASH_FACTORY_PUNT[] = {0x27E031D8, 0x27E03239}; + +u32 M9MO_FLASH_FACTORY_BACKLASH[] = {0x27E03276, 0x27E03279}; + +u32 M9MO_FLASH_FACTORY_AF_LED[] = {0x27E032A8, 0x27E032AD}; +u32 M9MO_FLASH_FACTORY_IRIS[] = {0x27E030E8, 0x27E03107}; +u32 M9MO_FLASH_FACTORY_LIVEVIEW[] = {0x27E03108, 0x27E0310F}; +u32 M9MO_FLASH_FACTORY_GAIN_CAPTURE[] = {0x27E03110, 0x27E03117}; +u32 M9MO_FLASH_FACTORY_SH_CLOSE[] = {0x27E0327A, 0x27E03297}; +u32 M9MO_FLASH_FACTORY_FLASH_CHECK[] = {0x27E032AE, 0x27E032B0}; +u32 M9MO_FLASH_FACTORY_WB_ADJ[] = {0x27E03000, 0x27E0304F}; +u32 M9MO_FLASH_FACTORY_FLASH_WB[] = {0x27E032B4, 0x27E032C3}; +u32 M9MO_FLASH_FACTORY_ADJ_FLASH_WB[] = {0x27E032D0, 0x27E032EB}; + +u32 M9MO_FLASH_FACTORY_IR_CHECK[] = {0x27E032C4, 0x27E032CD}; + +u32 M9MO_FLASH_FACTORY_RESULT = 0x27E03128; + #define M9MO_INT_RAM_BASE_ADDR 0x01100000 #define M9MO_I2C_RETRY 5 #define M9MO_I2C_VERIFY 100 -#define M9MO_ISP_TIMEOUT 5000 /* timeout delay for m9mo 3000->5000 */ +/* TODO + Timeout delay is changed to 35 sec to support large shutter speed. + This value must be set according to shutter speed. +*/ +#define M9MO_ISP_TIMEOUT 5000 +#define M9MO_ISP_CAPTURE_TIMEOUT 35000 +#define M9MO_SOUND_TIMEOUT 35000 #define M9MO_ISP_AFB_TIMEOUT 15000 /* FIXME */ #define M9MO_ISP_ESD_TIMEOUT 1000 -#if 1 -#define M9MO_JPEG_MAXSIZE 0x3A0000 -#define M9MO_THUMB_MAXSIZE 0xFC00 -#define M9MO_POST_MAXSIZE 0xBB800 -#else -#define M9MO_JPEG_MAXSIZE 0x43C600 +#define M9MO_JPEG_MAXSIZE 0x17E8000 /* 25M 4K align */ #define M9MO_THUMB_MAXSIZE 0x0 #define M9MO_POST_MAXSIZE 0x0 -#endif #define M9MO_DEF_APEX_DEN 100 -#define m9mo_readb(sd, g, b, v) m9mo_read(sd, 1, g, b, v) -#define m9mo_readw(sd, g, b, v) m9mo_read(sd, 2, g, b, v) -#define m9mo_readl(sd, g, b, v) m9mo_read(sd, 4, g, b, v) +#define m9mo_readb(sd, g, b, v) m9mo_read(__LINE__, sd, 1, g, b, v, true) +#define m9mo_readw(sd, g, b, v) m9mo_read(__LINE__, sd, 2, g, b, v, true) +#define m9mo_readl(sd, g, b, v) m9mo_read(__LINE__, sd, 4, g, b, v, true) + +#define m9mo_writeb(sd, g, b, v) m9mo_write(__LINE__, sd, 1, g, b, v, true) +#define m9mo_writew(sd, g, b, v) m9mo_write(__LINE__, sd, 2, g, b, v, true) +#define m9mo_writel(sd, g, b, v) m9mo_write(__LINE__, sd, 4, g, b, v, true) + +#define m9mo_readb2(sd, g, b, v) m9mo_read(__LINE__, sd, 1, g, b, v, false) +#define m9mo_readw2(sd, g, b, v) m9mo_read(__LINE__, sd, 2, g, b, v, false) +#define m9mo_readl2(sd, g, b, v) m9mo_read(__LINE__, sd, 4, g, b, v, false) -#define m9mo_writeb(sd, g, b, v) m9mo_write(sd, 1, g, b, v) -#define m9mo_writew(sd, g, b, v) m9mo_write(sd, 2, g, b, v) -#define m9mo_writel(sd, g, b, v) m9mo_write(sd, 4, g, b, v) +#define m9mo_writeb2(sd, g, b, v) m9mo_write(__LINE__, sd, 1, g, b, v, false) +#define m9mo_writew2(sd, g, b, v) m9mo_write(__LINE__, sd, 2, g, b, v, false) +#define m9mo_writel2(sd, g, b, v) m9mo_write(__LINE__, sd, 4, g, b, v, false) #define CHECK_ERR(x) if ((x) < 0) { \ cam_err("i2c failed, err %d\n", x); \ @@ -120,51 +164,50 @@ struct device *m9mo_dev; static const struct m9mo_frmsizeenum preview_frmsizes[] = { { M9MO_PREVIEW_QCIF, 176, 144, 0x05 }, /* 176 x 144 */ - { M9MO_PREVIEW_QCIF2, 528, 432, 0x2C }, /* 176 x 144 */ { M9MO_PREVIEW_QVGA, 320, 240, 0x09 }, { M9MO_PREVIEW_VGA, 640, 480, 0x17 }, - { M9MO_PREVIEW_D1, 720, 480, 0x33 }, /* High speed */ - { M9MO_PREVIEW_WVGA, 800, 480, 0x1A }, + { M9MO_PREVIEW_D1, 768, 512, 0x33 }, /* High speed */ + { M9MO_PREVIEW_960_720, 960, 720, 0x34 }, + { M9MO_PREVIEW_1080_720, 1056, 704, 0x35 }, { M9MO_PREVIEW_720P, 1280, 720, 0x21 }, - -#if defined(CONFIG_MACH_Q1_BD) - { M9MO_PREVIEW_880_720, 880, 720, 0x2E }, - { M9MO_PREVIEW_1200_800, 1200, 800, 0x2F }, - { M9MO_PREVIEW_1280_800, 1280, 800, 0x35 }, - { M9MO_PREVIEW_1280_768, 1280, 768, 0x22 }, - { M9MO_PREVIEW_1072_800, 1072, 800, 0x36 }, - { M9MO_PREVIEW_980_800, 980, 800, 0x37 }, -#endif - { M9MO_PREVIEW_1080P, 1920, 1080, 0x28 }, { M9MO_PREVIEW_HDR, 3264, 2448, 0x27 }, { M9MO_PREVIEW_720P_60FPS, 1280, 720, 0x25 }, { M9MO_PREVIEW_VGA_60FPS, 640, 480, 0x2F }, - + { M9MO_PREVIEW_1080P_DUAL, 1920, 1080, 0x2C }, + { M9MO_PREVIEW_720P_DUAL, 1280, 720, 0x2D }, + { M9MO_PREVIEW_VGA_DUAL, 640, 480, 0x2E }, + { M9MO_PREVIEW_QVGA_DUAL, 320, 240, 0x36 }, }; static const struct m9mo_frmsizeenum capture_frmsizes[] = { + { M9MO_CAPTURE_HD, 960, 720, 0x34 }, { M9MO_CAPTURE_1MP, 1024, 768, 0x0F }, { M9MO_CAPTURE_2MPW, 1920, 1080, 0x19 }, { M9MO_CAPTURE_3MP, 1984, 1488, 0x2F }, + { M9MO_CAPTURE_4MP, 2304, 1728, 0x1E }, { M9MO_CAPTURE_5MP, 2592, 1944, 0x20 }, { M9MO_CAPTURE_8MP, 3264, 2448, 0x25 }, { M9MO_CAPTURE_10MP, 3648, 2736, 0x30 }, { M9MO_CAPTURE_12MPW, 4608, 2592, 0x31 }, { M9MO_CAPTURE_14MP, 4608, 3072, 0x32 }, { M9MO_CAPTURE_16MP, 4608, 3456, 0x33 }, - /* for Postview size */ - { M9MO_CAPTURE_POSTWVGA, 800, 480, 0x09 }, +}; + +static const struct m9mo_frmsizeenum postview_frmsizes[] = { + { M9MO_CAPTURE_POSTQVGA, 320, 240, 0x01 }, { M9MO_CAPTURE_POSTVGA, 640, 480, 0x08 }, - { M9MO_CAPTURE_POSTWHD, 1280, 720, 0x0F }, + { M9MO_CAPTURE_POSTWVGA, 800, 480, 0x09 }, { M9MO_CAPTURE_POSTHD, 960, 720, 0x13 }, + { M9MO_CAPTURE_POSTP, 1056, 704, 0x14 }, + { M9MO_CAPTURE_POSTWHD, 1280, 720, 0x0F }, }; static struct m9mo_control m9mo_ctrls[] = { { .id = V4L2_CID_CAMERA_ISO, .minimum = ISO_AUTO, - .maximum = ISO_800, + .maximum = ISO_3200, .step = 1, .value = ISO_AUTO, .default_value = ISO_AUTO, @@ -190,6 +233,13 @@ static struct m9mo_control m9mo_ctrls[] = { .value = SHARPNESS_DEFAULT, .default_value = SHARPNESS_DEFAULT, }, { + .id = V4L2_CID_CAMERA_CONTRAST, + .minimum = CONTRAST_MINUS_2, + .maximum = CONTRAST_MAX - 1, + .step = 1, + .value = CONTRAST_DEFAULT, + .default_value = CONTRAST_DEFAULT, + }, { .id = V4L2_CID_CAMERA_ZOOM, .minimum = ZOOM_LEVEL_0, .maximum = ZOOM_LEVEL_MAX - 1, @@ -208,18 +258,22 @@ static struct m9mo_control m9mo_ctrls[] = { .minimum = ANTI_BANDING_AUTO, .maximum = ANTI_BANDING_OFF, .step = 1, - .value = ANTI_BANDING_50HZ, - .default_value = ANTI_BANDING_50HZ, + .value = ANTI_BANDING_AUTO, + .default_value = ANTI_BANDING_AUTO, }, }; +static u8 sysfs_sensor_fw[7] = {0,}; +static u8 sysfs_phone_fw[7] = {0,}; +static u8 sysfs_sensor_type[25] = {0,}; + static inline struct m9mo_state *to_state(struct v4l2_subdev *sd) { return container_of(sd, struct m9mo_state, sd); } -static int m9mo_read(struct v4l2_subdev *sd, - u8 len, u8 category, u8 byte, int *val) +static int m9mo_read(int _line, struct v4l2_subdev *sd, + u8 len, u8 category, u8 byte, int *val, bool log) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_msg msg; @@ -253,7 +307,8 @@ static int m9mo_read(struct v4l2_subdev *sd, } if (err != 1) { - cam_err("category %#x, byte %#x\n", category, byte); + cam_err("category %#x, byte %#x, err %d\n", + category, byte, err); return err; } @@ -268,7 +323,8 @@ static int m9mo_read(struct v4l2_subdev *sd, } if (err != 1) { - cam_err("category %#x, byte %#x\n", category, byte); + cam_err("RD category %#x, byte %#x, err %d\n", + category, byte, err); return err; } @@ -284,13 +340,16 @@ static int m9mo_read(struct v4l2_subdev *sd, *val = recv_data[1] << 24 | recv_data[2] << 16 | recv_data[3] << 8 | recv_data[4]; - cam_i2c_dbg("category %#02x, byte %#x, value %#x\n", + if (log) + cam_i2c_dbg("[ %4d ] Read %s %#02x, byte %#x, value %#x\n", + _line, (len == 4 ? "L" : (len == 2 ? "W" : "B")), category, byte, *val); + return err; } -static int m9mo_write(struct v4l2_subdev *sd, - u8 len, u8 category, u8 byte, int val) +static int m9mo_write(int _line, struct v4l2_subdev *sd, + u8 len, u8 category, u8 byte, int val, bool log) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_msg msg; @@ -324,7 +383,10 @@ static int m9mo_write(struct v4l2_subdev *sd, data[7] = val & 0xFF; } - cam_i2c_dbg("category %#x, byte %#x, value %#x\n", category, byte, val); + if (log) + cam_i2c_dbg("[ %4d ] Write %s %#x, byte %#x, value %#x\n", + _line, (len == 4 ? "L" : (len == 2 ? "W" : "B")), + category, byte, val); for (i = M9MO_I2C_RETRY; i; i--) { err = i2c_transfer(client->adapter, &msg, 1); @@ -335,7 +397,7 @@ static int m9mo_write(struct v4l2_subdev *sd, return err; } -static int m9mo_mem_read_1(struct v4l2_subdev *sd, u16 len, u32 addr, u8 *val) +static int m9mo_mem_dump(struct v4l2_subdev *sd, u16 len, u32 addr, u8 *val) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_msg msg; @@ -513,6 +575,7 @@ static u32 m9mo_wait_interrupt(struct v4l2_subdev *sd, unsigned int timeout) { struct m9mo_state *state = to_state(sd); + int try_cnt = 30; cam_trace("E\n"); if (wait_event_interruptible_timeout(state->isp.wait, @@ -524,10 +587,20 @@ static u32 m9mo_wait_interrupt(struct v4l2_subdev *sd, state->isp.issued = 0; - m9mo_readw(sd, M9MO_CATEGORY_SYS, - M9MO_SYS_INT_FACTOR, &state->isp.int_factor); - cam_err("state->isp.int_factor = %x\n", state->isp.int_factor); - cam_trace("X\n"); + do { + m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_FACTOR, &state->isp.int_factor); + cam_err(": state->isp.int_factor = %x\n", + state->isp.int_factor); + if (state->isp.int_factor == 0xFFFF) { + try_cnt--; + msleep(20); + } else + try_cnt = 0; + } while (try_cnt); + + cam_trace("X %s\n", + (state->isp.int_factor == 0xFFFF ? "fail(0xFFFF)" : "")); return state->isp.int_factor; } @@ -538,22 +611,20 @@ static int m9mo_wait_framesync(struct v4l2_subdev *sd) s32 read_val = 0; struct m9mo_state *state = to_state(sd); - if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS) { - cam_dbg("Start Continuous capture"); - frame_sync_count = 9; - } else if (state->running_capture_mode == RUNNING_MODE_BRACKET - || state->running_capture_mode == RUNNING_MODE_HDR) { - cam_dbg("Start AutoBracket(AEB) or HDR capture"); + if (state->running_capture_mode == RUNNING_MODE_AE_BRACKET + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT + || state->running_capture_mode == RUNNING_MODE_HDR) { + cam_dbg("Start AE Bracket or HDR capture\n"); frame_sync_count = 3; } else if (state->running_capture_mode == RUNNING_MODE_BLINK) { - cam_dbg("Start FaceDetect EyeBlink capture"); + cam_dbg("Start FaceDetect EyeBlink capture\n"); frame_sync_count = 3; } /* Clear Interrupt factor */ for (i = frame_sync_count; i; i--) { int_factor = m9mo_wait_interrupt(sd, - M9MO_ISP_TIMEOUT); + M9MO_SOUND_TIMEOUT); if (!(int_factor & M9MO_INT_FRAME_SYNC)) { cam_warn("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor); @@ -563,7 +634,7 @@ static int m9mo_wait_framesync(struct v4l2_subdev *sd) M9MO_CATEGORY_SYS, M9MO_SYS_FRAMESYNC_CNT, &read_val); - cam_dbg("Frame interrupt M9MO_INT_FRAME_SYNC cnt[%d]\n", + cam_dbg("Frame interrupt FRAME_SYNC cnt[%d]\n", read_val); } @@ -574,7 +645,8 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode) { int i, err; u32 old_mode, val; - u32 int_factor; + u32 int_factor, int_en; + struct m9mo_state *state = to_state(sd); cam_trace("E\n"); @@ -583,6 +655,15 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode) if (err < 0) return err; + /* don't change mode when cap -> param */ + if (old_mode == M9MO_STILLCAP_MODE && mode == M9MO_PARMSET_MODE) + return 10; + +#if 1 /* Dual Capture */ + if (state->dual_capture_start && mode == M9MO_STILLCAP_MODE) + mode = M9MO_PARMSET_MODE; +#endif + if (old_mode == mode) { cam_dbg("%#x -> %#x\n", old_mode, mode); return old_mode; @@ -623,11 +704,31 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode) if (err < 0) return err; - if (mode == M9MO_STILLCAP_MODE) { + if (mode == M9MO_STILLCAP_MODE + && state->running_capture_mode != RUNNING_MODE_AE_BRACKET + && state->running_capture_mode != RUNNING_MODE_LOWLIGHT) { + m9mo_wait_framesync(sd); + if (state->running_capture_mode == RUNNING_MODE_WB_BRACKET + || state->running_capture_mode == RUNNING_MODE_RAW) { + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_en); + CHECK_ERR(err); + + if (int_en & M9MO_INT_SOUND) { + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, + M9MO_SOUND_TIMEOUT); + if (!(int_factor & M9MO_INT_SOUND)) { + cam_warn("M9MO_INT_SOUND isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + } /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_CAPTURE_TIMEOUT); if (!(int_factor & M9MO_INT_CAPTURE)) { cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", int_factor); @@ -646,18 +747,153 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode) return old_mode; } -static int m9mo_set_capture_mode(struct v4l2_subdev *sd, int val) +static int m9mo_set_mode_part1(struct v4l2_subdev *sd, u32 mode) { - int err, capture_val, shutter_val; + int i, err; + u32 old_mode, val; + u32 int_factor; + u32 int_en; struct m9mo_state *state = to_state(sd); + state->stream_on_part2 = false; cam_trace("E\n"); - state->running_capture_mode = val; + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, &old_mode); - err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_SHUTTER_MODE, &shutter_val); - CHECK_ERR(err); + if (err < 0) + return err; + + /* don't change mode when cap -> param */ + if (old_mode == M9MO_STILLCAP_MODE && mode == M9MO_PARMSET_MODE) + return 10; + +#if 1 /* Dual Capture */ + if (state->dual_capture_start && mode == M9MO_STILLCAP_MODE) + mode = M9MO_PARMSET_MODE; +#endif + + if (old_mode == mode) { + cam_dbg("%#x -> %#x\n", old_mode, mode); + return old_mode; + } + + cam_dbg("%#x -> %#x\n", old_mode, mode); + + switch (old_mode) { + case M9MO_SYSINIT_MODE: + cam_warn("sensor is initializing\n"); + err = -EBUSY; + break; + + case M9MO_PARMSET_MODE: + if (mode == M9MO_STILLCAP_MODE) { + err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_MODE, M9MO_MONITOR_MODE); + if (err < 0) + break; + for (i = M9MO_I2C_VERIFY; i; i--) { + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_MODE, &val); + if (val == M9MO_MONITOR_MODE) + break; + msleep(20); + } + } + case M9MO_MONITOR_MODE: + case M9MO_STILLCAP_MODE: + err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, mode); + break; + + default: + cam_warn("current mode is unknown, %d\n", old_mode); + err = 0;/* -EINVAL; */ + } + + if (err < 0) + return err; + + if (mode == M9MO_STILLCAP_MODE + && state->running_capture_mode != RUNNING_MODE_AE_BRACKET + && state->running_capture_mode != RUNNING_MODE_LOWLIGHT) { + + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_en); + CHECK_ERR(err); + + if (int_en & M9MO_INT_SOUND) { + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, + M9MO_SOUND_TIMEOUT); + if (!(int_factor & M9MO_INT_SOUND)) { + cam_warn("M9MO_INT_SOUND isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + } + + state->stream_on_part2 = true; + + cam_trace("X\n"); + return old_mode; +} + +static int m9mo_set_mode_part2(struct v4l2_subdev *sd, u32 mode) +{ + int i, err; + u32 val; + u32 int_factor; + struct m9mo_state *state = to_state(sd); + + if (state->running_capture_mode != RUNNING_MODE_SINGLE) + return 0; + + if (state->stream_on_part2 == false) + return 0; + + cam_trace("E, %d\n", mode); + +#if 1 /* Dual Capture */ + if (state->dual_capture_start && mode == M9MO_STILLCAP_MODE) + mode = M9MO_PARMSET_MODE; +#endif + + if (mode == M9MO_STILLCAP_MODE + && state->running_capture_mode != RUNNING_MODE_AE_BRACKET + && state->running_capture_mode != RUNNING_MODE_LOWLIGHT) { + + /* m9mo_wait_framesync(sd); */ + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_CAPTURE_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + + for (i = M9MO_I2C_VERIFY; i; i--) { + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, &val); + if (val == mode) + break; + msleep(20); + } + + state->stream_on_part2 = false; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_capture_mode(struct v4l2_subdev *sd, int val) +{ + int err, capture_val, framecount, raw_enable; + struct m9mo_state *state = to_state(sd); + + cam_trace("E capture_mode=%d\n", val); + + state->running_capture_mode = val; err = m9mo_readb(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_CAP_MODE, &capture_val); @@ -665,116 +901,133 @@ static int m9mo_set_capture_mode(struct v4l2_subdev *sd, int val) switch (state->running_capture_mode) { case RUNNING_MODE_CONTINUOUS: - if (shutter_val != 0x00) { - err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_SHUTTER_MODE, 0x00); - CHECK_ERR(err); - } + case RUNNING_MODE_BEST: + cam_dbg("m9mo_set_capture_mode() CONTINUOUS fps=%d\n", + state->continueFps); - if (capture_val != M9MO_CAP_MODE_MULTI_CAPTURE) { - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_MODE, - M9MO_CAP_MODE_MULTI_CAPTURE); - CHECK_ERR(err); - } err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_FRM_COUNT, 0x09); + M9MO_CAPCTRL_CAP_MODE, M9MO_CAP_MODE_MULTI_CAPTURE); CHECK_ERR(err); -#if 0 - switch (state->) { - case _CONTI_3: - cam_trace("~~~~~~ Continuous 3 ~~~~~~\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x03); - CHECK_ERR(err); - break; + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_FRM_INTERVAL, + state->continueFps); + CHECK_ERR(err); /* 0:7.5, 1:5, 2:3fps */ - case _CONTI_5: - cam_trace("~~~~~~ Continuous 5 ~~~~~~\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x01); - CHECK_ERR(err); - break; + framecount = 0x0A; + if (state->running_capture_mode == RUNNING_MODE_BEST) + framecount = 0x08; - case _CONTI_10: - cam_trace("~~~~~~ Continuous 10 ~~~~~~\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x00); - CHECK_ERR(err); - break; - } + cam_dbg("m9mo_set_capture_mode() framecount=%d\n", + framecount); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_FRM_COUNT, framecount+1); + CHECK_ERR(err); /* frame count : A */ + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, 0x03, 0x01); + CHECK_ERR(err); /* Enable limited framerate*/ + + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x18, 0x03); + CHECK_ERR(err); /* OIS */ + + /* AF proc */ +#if 0 + err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, 0x99); + CHECK_ERR(err); #endif - break; + err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_MODE, M9MO_STILLCAP_MODE); + CHECK_ERR(err); - case RUNNING_MODE_BRACKET: - cam_trace("~~~~~~ AutoBracket ~~~~~~\n"); - if (shutter_val != 0x00) { - err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_SHUTTER_MODE, 0x00); - CHECK_ERR(err); + cam_dbg("continue image Start ==========================\n"); + + err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(err & M9MO_INT_FRAME_SYNC)) { + cam_err("m9mo_set_capture_mode() FRAME_SYNC error\n"); + return -ETIMEDOUT; } + break; + case RUNNING_MODE_AE_BRACKET: + case RUNNING_MODE_LOWLIGHT: + cam_trace("~~~~~~ AutoBracket AEB ~~~~~~\n"); if (capture_val != M9MO_CAP_MODE_BRACKET_CAPTURE) { err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_CAP_MODE, M9MO_CAP_MODE_BRACKET_CAPTURE); CHECK_ERR(err); } - break; - case RUNNING_MODE_HDR: - cam_trace("~~~~~~ HDRmode capture ~~~~~~\n"); - if (shutter_val != 0x00) { - err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_SHUTTER_MODE, 0x00); + if (state->running_capture_mode == RUNNING_MODE_LOWLIGHT) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0x0); /* EV 0.0 */ + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x02); + CHECK_ERR(err); /* 0:7.5, 1:5, 2:3fps */ + break; + + case RUNNING_MODE_WB_BRACKET: + cam_trace("~~~~~~ AutoBracket WBB ~~~~~~\n"); + if (capture_val != M9MO_CAP_MODE_SINGLE_CAPTURE) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_MODE, + M9MO_CAP_MODE_SINGLE_CAPTURE); CHECK_ERR(err); } + break; + case RUNNING_MODE_HDR: + cam_trace("~~~~~~ HDRmode capture ~~~~~~\n"); if (capture_val != M9MO_CAP_MODE_BRACKET_CAPTURE) { err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_CAP_MODE, M9MO_CAP_MODE_BRACKET_CAPTURE); CHECK_ERR(err); } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x00); + CHECK_ERR(err); /* 0:7.5, 1:5, 2:3fps */ break; case RUNNING_MODE_BLINK: cam_trace("~~~~~~ EyeBlink capture ~~~~~~\n"); - if (shutter_val != 0x00) { - err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_SHUTTER_MODE, 0x00); - CHECK_ERR(err); - } - if (capture_val != M9MO_CAP_MODE_BLINK_CAPTURE) { err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_CAP_MODE, M9MO_CAP_MODE_BLINK_CAPTURE); CHECK_ERR(err); - /* Set frame rate (0x00, 12 fps) */ - /* err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x00); - CHECK_ERR(err); */ - /* Set frame count (0x03, 3 frames) */ - /* err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_FRM_COUNT, 0x03); - CHECK_ERR(err); */ } break; - case RUNNING_MODE_SINGLE: - default: - cam_trace("~~~~~~ Single capture ~~~~~~\n"); - if (shutter_val != 0x01) { - err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_SHUTTER_MODE, 0x01); + case RUNNING_MODE_RAW: + cam_trace("~~~~~~ raw capture ~~~~~~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM, + 0x78, &raw_enable); + CHECK_ERR(err); + + /* if (capture_val != M9MO_CAP_MODE_RAW) always run */ + if (raw_enable != 0x01) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x78, 0x01); CHECK_ERR(err); } + break; + case RUNNING_MODE_BURST: + cam_trace("~~~~~~ burst capture mode ~~~~~~\n"); + break; + + case RUNNING_MODE_SINGLE: + default: + cam_trace("~~~~~~ Single capture ~~~~~~\n"); if (capture_val != M9MO_CAP_MODE_SINGLE_CAPTURE) { err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_CAP_MODE, 0x00); + M9MO_CAPCTRL_CAP_MODE, + M9MO_CAP_MODE_SINGLE_CAPTURE); CHECK_ERR(err); } break; @@ -804,2903 +1057,9394 @@ static int m9mo_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) return -EINVAL; } -static int m9mo_get_af_result(struct v4l2_subdev *sd, - struct v4l2_control *ctrl); -static int m9mo_get_scene_mode(struct v4l2_subdev *sd, - struct v4l2_control *ctrl) +static int m9mo_set_lock(struct v4l2_subdev *sd, int val) { - int err; + struct m9mo_state *state = to_state(sd); + int err, status; + int cnt = 100; - err = m9mo_readb(sd, M9MO_CATEGORY_NEW, - M9MO_NEW_DETECT_SCENE, &ctrl->value); + cam_trace("%s\n", val ? "on" : "off"); - return ctrl->value; + if (state->running_capture_mode == RUNNING_MODE_BURST) + return 0; + + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AF_AE_LOCK, val); + CHECK_ERR(err); + + /* check AE stability before AE,AWB lock */ + if (val == 1) { + err = m9mo_readb(sd, M9MO_CATEGORY_AE, + M9MO_AE_STABILITY, &status); + + while (!status && cnt) { + msleep(10); + err = m9mo_readb(sd, M9MO_CATEGORY_AE, + M9MO_AE_STABILITY, &status); + CHECK_ERR(err); + cnt--; + } + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, val); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, val); + CHECK_ERR(err); + + state->focus.lock = val; + + cam_trace("X\n"); + return 0; } -static int m9mo_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int m9mo_set_CAF(struct v4l2_subdev *sd, int val) { + int err, range_status, af_range, zoom_status; struct m9mo_state *state = to_state(sd); - int err = 0; - switch (ctrl->id) { - case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT: - m9mo_get_af_result(sd, ctrl); - break; + if (state->fps == 120) { + cam_info("not supported on 120 fps !!!\n"); + return 0; + } - case V4L2_CID_CAM_JPEG_MEMSIZE: - ctrl->value = M9MO_JPEG_MAXSIZE + - M9MO_THUMB_MAXSIZE + M9MO_POST_MAXSIZE; - break; - - case V4L2_CID_CAM_JPEG_MAIN_SIZE: - ctrl->value = state->jpeg.main_size; - break; - - case V4L2_CID_CAM_JPEG_MAIN_OFFSET: - ctrl->value = state->jpeg.main_offset; - break; - - case V4L2_CID_CAM_JPEG_THUMB_SIZE: - ctrl->value = state->jpeg.thumb_size; - break; + err = m9mo_readb2(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_STATUS, &zoom_status); + CHECK_ERR(err); - case V4L2_CID_CAM_JPEG_THUMB_OFFSET: - ctrl->value = state->jpeg.thumb_offset; - break; + if (zoom_status == 1 && val == 1) { + cam_info("zoom moving !!! val : %d\n", val); + return 0; + } - case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET: - ctrl->value = state->jpeg.postview_offset; - break; + state->caf_state = val; - case V4L2_CID_CAMERA_EXIF_FLASH: - ctrl->value = state->exif.flash; - break; + if (val == 1) { + if (state->focus.status != 0x1000) { + /* Set LOCK OFF */ + if (state->focus.lock && state->focus.status != 0x1000) + m9mo_set_lock(sd, 0); - case V4L2_CID_CAMERA_EXIF_ISO: - ctrl->value = state->exif.iso; - break; + /* Set mode to Continuous */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_MODE, 0x01); + CHECK_ERR(err); - case V4L2_CID_CAMERA_EXIF_TV: - ctrl->value = state->exif.tv; - break; + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_SCAN_RANGE, &range_status); - case V4L2_CID_CAMERA_EXIF_BV: - ctrl->value = state->exif.bv; - break; + /* Set range to macro or auto-macro */ + if (state->mode == MODE_CLOSE_UP) + af_range = 0x01; + else + af_range = 0x02; - case V4L2_CID_CAMERA_EXIF_EBV: - ctrl->value = state->exif.ebv; - break; + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_SCAN_RANGE, af_range); + CHECK_ERR(err); - case V4L2_CID_CAMERA_FD_EYE_BLINK_RESULT: - ctrl->value = state->fd_eyeblink_cap; - break; + /* Set Zone REQ */ + if (range_status != af_range) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_INITIAL, 0x04); + CHECK_ERR(err); + } - case V4L2_CID_CAMERA_SCENE_MODE: - err = m9mo_get_scene_mode(sd, ctrl); - cam_info("Smart scene mode = %d\n", ctrl->value); - break; + /* Start Continuous AF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_START_STOP, 0x01); + CHECK_ERR(err); + } + } else { + /* Stop Continuous AF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_START_STOP, 0x02); + CHECK_ERR(err); - default: - cam_err("no such control id %d\n", - ctrl->id - V4L2_CID_PRIVATE_BASE); - /*err = -ENOIOCTLCMD*/ - err = 0; - break; + /* need delay for AF stable time */ + if (state->focus.mode == FOCUS_MODE_CONTINOUS) + msleep(100); } - if (err < 0 && err != -ENOIOCTLCMD) - cam_err("failed, id %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE); - - return err; + cam_trace("X val : %d %d\n", val, state->focus.mode); + return 0; } -static int m9mo_set_antibanding(struct v4l2_subdev *sd, +static int m9mo_get_af_result(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct v4l2_queryctrl qc = {0,}; struct m9mo_state *state = to_state(sd); - int val = ctrl->value, err; - u32 antibanding[] = {0x00, 0x01, 0x02, 0x03}; + int status, err; + static int get_cnt; - if (state->anti_banding == val) - return 0; + cam_trace("E, cnt: %d, status: 0x%x\n", get_cnt, state->focus.status); - cam_dbg("E, value %d\n", val); + get_cnt++; - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + err = m9mo_readw2(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_RESULT, &status); + CHECK_ERR(err); - if (val < qc.minimum || val > qc.maximum) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value; + if ((status != 0x1000) && (status != 0x0)) { + cam_dbg("~~~ success !!!~~~\n"); + msleep(33); + get_cnt = 0; + } else if (status == 0x0) { + cam_dbg("~~~ fail !!!~~~\n"); + msleep(33); + get_cnt = 0; + } else if (status == 0x1000) { + cam_dbg("~~~ focusing !!!~~~\n"); } - val -= qc.minimum; - - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_FLICKER, antibanding[val]); - CHECK_ERR(err); - - state->anti_banding = val; + if (state->focus.mode == FOCUS_MODE_TOUCH && status != 0x1000) + m9mo_set_lock(sd, 0); - cam_trace("X\n"); - return 0; -} + if (state->focus.lock && !(state->focus.start) && status != 0x1000) + m9mo_set_lock(sd, 0); -static int m9mo_set_af_softlanding(struct v4l2_subdev *sd) -{ - struct m9mo_state *state = to_state(sd); - u32 status = 0; - int i, err = 0; + state->focus.status = status; - cam_trace("E\n"); + if (state->caf_state && !(state->focus.start) && status != 0x1000) + m9mo_set_CAF(sd, 1); - if (unlikely(state->isp.bad_fw)) { - cam_err("\"Unknown\" state, please update F/W"); - return -ENOSYS; - } + ctrl->value = state->focus.status; - err = m9mo_set_mode(sd, M9MO_MONITOR_MODE); - if (err <= 0) { - cam_err("failed to set mode\n"); - return err; - } + cam_dbg("X, value 0x%04x\n", ctrl->value); - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, M9MO_LENS_AF_MODE, 0x07); - CHECK_ERR(err); + return ctrl->value; +} - for (i = M9MO_I2C_VERIFY; i; i--) { - msleep(20); - err = m9mo_readb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_STATUS, &status); - CHECK_ERR(err); +static int m9mo_get_scene_mode(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int err; - if ((status & 0x01) == 0x00) - break; - } + err = m9mo_readb2(sd, M9MO_CATEGORY_NEW, + M9MO_NEW_DETECT_SCENE, &ctrl->value); - if ((status & 0x01) != 0x00) { - cam_err("failed\n"); - return -ETIMEDOUT; - } +#if 0 + cam_trace("mode : %d\n", ctrl->value); +#endif - cam_trace("X\n"); - return err; + return ctrl->value; } -static int m9mo_dump_fw(struct v4l2_subdev *sd) +static int m9mo_get_scene_sub_mode(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) { - struct file *fp; - mm_segment_t old_fs; - u8 *buf/*, val*/; - u32 addr, unit, count, intram_unit = 0x1000; - int i, /*j,*/ err; + int err; - old_fs = get_fs(); - set_fs(KERNEL_DS); + err = m9mo_readb2(sd, M9MO_CATEGORY_NEW, 0x0C, &ctrl->value); - fp = filp_open(M9MO_FW_DUMP_PATH, - O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR); - if (IS_ERR(fp)) { - cam_err("failed to open %s, err %ld\n", - M9MO_FW_DUMP_PATH, PTR_ERR(fp)); - err = -ENOENT; - goto file_out; - } + return ctrl->value; +} - buf = kmalloc(intram_unit, GFP_KERNEL); - if (!buf) { - cam_err("failed to allocate memory\n"); - err = -ENOMEM; - goto out; - } +static int m9mo_get_zoom_level(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + int err; + int zoom_level, zoom_status, zoom_lens_status; - cam_dbg("start, file path %s\n", M9MO_FW_DUMP_PATH); + err = m9mo_readb2(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_LEVEL_INFO, &zoom_level); + CHECK_ERR(err); + err = m9mo_readb2(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_STATUS, &zoom_status); + CHECK_ERR(err); -/* - val = 0x7E; - err = m9mo_mem_write(sd, 0x04, sizeof(val), 0x50000308, &val); - if (err < 0) { - cam_err("failed to write memory\n"); - goto out; - } -*/ + err = m9mo_readb2(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_LENS_STATUS, &zoom_lens_status); + CHECK_ERR(err); + if (state->zoom <= 0xF && (zoom_level & 0xF) < 0xF) + state->zoom = zoom_level & 0xF; + ctrl->value = ((0x1 & zoom_status) << 4) + | ((0x1 & zoom_lens_status) << 5) + | (0xF & zoom_level); - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001200 , buf_port_seting0); - CHECK_ERR(err); - mdelay(10); + return 0; +} - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001000 , buf_port_seting1); - CHECK_ERR(err); - mdelay(10); +static int m9mo_get_zoom_status(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + int err; + int curr_zoom_info; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001100 , buf_port_seting2); - CHECK_ERR(err); - mdelay(10); + err = m9mo_readb2(sd, M9MO_CATEGORY_PRO_MODE, + M9MO_PRO_SMART_READ3, &curr_zoom_info); + CHECK_ERR(err); - err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, - 0x1C, 0x0247036D); + if (state->zoom <= 0xF && (curr_zoom_info & 0xF) < 0xF) + state->zoom = curr_zoom_info & 0xF; + ctrl->value = curr_zoom_info & 0x3F; - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, - 0x57, 01); + return 0; +} + +static int m9mo_get_smart_read1(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int value, err; + err = m9mo_readl2(sd, M9MO_CATEGORY_PRO_MODE, + M9MO_PRO_SMART_READ1, &value); CHECK_ERR(err); + ctrl->value = value; - addr = M9MO_FLASH_READ_BASE_ADDR; - unit = SZ_4K; - count = 512; - for (i = 0; i < count; i++) { + return ctrl->value; +} - err = m9mo_mem_read_1(sd, - unit, addr + (i * unit), buf); - cam_err("dump ~~ %d\n", i); - if (err < 0) { - cam_err("i2c falied, err %d\n", err); - goto out; - } - vfs_write(fp, buf, unit, &fp->f_pos); - } -/* - addr = M9MO_FLASH_BASE_ADDR + SZ_64K * count; - unit = SZ_8K; - count = 4; - for (i = 0; i < count; i++) { - for (j = 0; j < unit; j += intram_unit) { - err = m9mo_mem_read(sd, - intram_unit, addr + (i * unit) + j, buf); - if (err < 0) { - cam_err("i2c falied, err %d\n", err); - goto out; - } - vfs_write(fp, buf, intram_unit, &fp->f_pos); - } - } -*/ - cam_dbg("end\n"); +static int m9mo_get_smart_read2(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int value, err; -out: - kfree(buf); - if (!IS_ERR(fp)) - filp_close(fp, current->files); -file_out: - set_fs(old_fs); + err = m9mo_readl2(sd, M9MO_CATEGORY_PRO_MODE, + M9MO_PRO_SMART_READ2, &value); + CHECK_ERR(err); - return err; + ctrl->value = value; + + return ctrl->value; } -static int m9mo_get_sensor_fw_version(struct v4l2_subdev *sd, - char *buf) +static int m9mo_get_lens_status(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) { -#if 0 - u8 val; - int err; -#endif + int value, err; - cam_err("E\n"); -#if 0 - buf = "SJEL01 Fujitsu M9MOLS"; - return 0; -#endif -#if 0 - /* set pin */ - val = 0x7E; - err = m9mo_mem_write(sd, 0x04, sizeof(val), 0x50000308, &val); + err = m9mo_readb2(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_LENS_STATUS, &value); CHECK_ERR(err); - err = m9mo_mem_read(sd, M9MO_FW_VER_LEN, - M9MO_FLASH_BASE_ADDR + M9MO_FW_VER_FILE_CUR, buf); -#endif + ctrl->value = value; - cam_info("%s\n", buf); - return 0; + return ctrl->value; } -static int m9mo_get_phone_fw_version(struct v4l2_subdev *sd, char *buf) +static int m9mo_get_flash_status(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) { - struct device *dev = sd->v4l2_dev->dev; - /*u8 sensor_ver[M9MO_FW_VER_LEN] = {0, };*/ - const struct firmware *fw; - int err = 0; - - struct file *fp; - mm_segment_t old_fs; - long nread; - int fw_requested = 1; - - cam_info("E\n"); - - old_fs = get_fs(); - set_fs(KERNEL_DS); - - fp = filp_open(M9MO_FW_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - cam_trace("failed to open %s, err %ld\n", M9MO_FW_PATH, - PTR_ERR(fp)); - goto request_fw; - } else { - cam_info("FW File(phone) opened.\n"); - } + int err; + int strobe_charge, strobe_up_down; - fw_requested = 0; + err = m9mo_readb2(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_STROBE_CHARGE, &strobe_charge); + CHECK_ERR(err); - err = vfs_llseek(fp, M9MO_FW_VER_FILE_CUR, SEEK_SET); - if (err < 0) { - cam_warn("failed to fseek, %d\n", err); - goto out; - } + err = m9mo_readb2(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_STROBE_UP_DOWN, &strobe_up_down); + CHECK_ERR(err); - nread = vfs_read(fp, (char __user *)buf, M9MO_FW_VER_LEN, &fp->f_pos); - if (nread != M9MO_FW_VER_LEN) { - cam_err("failed to read firmware file, %ld Bytes\n", nread); - err = -EIO; - goto out; - } + strobe_charge &= 0xFF; + strobe_up_down &= 0xFF; -request_fw: - if (fw_requested) { - set_fs(old_fs); + ctrl->value = strobe_charge | (strobe_up_down << 8); #if 0 - m9mo_get_sensor_fw_version(sd, sensor_ver); - - if (sensor_ver[0] == 'T' && sensor_ver[1] == 'B') { - err = request_firmware(&fw, M9MOTB_FW_PATH, dev); -#if defined(CONFIG_MACH_Q1_BD) - } else if (sensor_ver[0] == 'O' && sensor_ver[1] == 'O') { - err = request_firmware(&fw, M9MOOO_FW_PATH, dev); -#endif -#if defined(CONFIG_MACH_U1_KOR_LGT) - } else if (sensor_ver[0] == 'S' && sensor_ver[1] == 'B') { - err = request_firmware(&fw, M9MOSB_FW_PATH, dev); + cam_trace(": strobe_charge %d up_down %d\n", + strobe_charge, strobe_up_down); #endif - } else { - cam_warn("cannot find the matched F/W file\n"); -#if defined(CONFIG_MACH_Q1_BD) - err = request_firmware(&fw, M9MOOO_FW_PATH, dev); -#elif defined(CONFIG_MACH_U1_KOR_LGT) - err = request_firmware(&fw, M9MOSB_FW_PATH, dev); -#else - err = request_firmware(&fw, M9MOTB_FW_PATH, dev); -#endif - } -#else - cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH); - err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev); -#endif - - if (err != 0) { - cam_err("request_firmware falied\n"); - err = -EINVAL; - goto out; - } - - memcpy(buf, (u8 *)&fw->data[M9MO_FW_VER_FILE_CUR], - M9MO_FW_VER_LEN); - } - -out: - if (!fw_requested) { - filp_close(fp, current->files); - set_fs(old_fs); - } else { - release_firmware(fw); - } - cam_dbg("%s\n", buf); return 0; } -static int m9mo_check_fw(struct v4l2_subdev *sd) +static int m9mo_get_object_tracking(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) { struct m9mo_state *state = to_state(sd); - u8 sensor_ver[M9MO_FW_VER_LEN] = "FAILED Fujitsu M9MO"; - u8 phone_ver[M9MO_FW_VER_LEN] = "FAILED Fujitsu M9MO"; - int af_cal_h = 0, af_cal_l = 0; - int rg_cal_h = 0, rg_cal_l = 0; - int bg_cal_h = 0, bg_cal_l = 0; - int update_count = 0; - u32 int_factor; int err; - - cam_trace("E\n"); - - /* F/W version */ - m9mo_get_phone_fw_version(sd, phone_ver); - #if 0 - if (state->isp.bad_fw) - goto out; + int ot_ready, cnt = 30; #endif - m9mo_get_sensor_fw_version(sd, sensor_ver); - - goto out; - - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, M9MO_FLASH_CAM_START, 0x01); + err = m9mo_readb2(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_STATUS, &state->ot_status); CHECK_ERR(err); - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_MODE)) { - cam_err("firmware was erased?\n"); - return -ETIMEDOUT; - } +#if 0 + if (state->ot_status != OBJECT_TRACKING_STATUS_SUCCESS) + return 0; - err = m9mo_readb(sd, M9MO_CATEGORY_LENS, M9MO_LENS_AF_CAL, &af_cal_l); + err = m9mo_readb2(sd, M9MO_CATEGORY_OT, + M9MO_OT_INFO_READY, &ot_ready); CHECK_ERR(err); + while (ot_ready && cnt) { + msleep(20); + err = m9mo_readb(sd, M9MO_CATEGORY_OT, + M9MO_OT_INFO_READY, &ot_ready); + CHECK_ERR(err); + cnt--; + } - err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_AWB_RG_H, &rg_cal_h); + err = m9mo_readw(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_X_LOCATION, + &state->ot_x_loc); CHECK_ERR(err); - err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_AWB_RG_L, &rg_cal_l); + err = m9mo_readw(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_Y_LOCATION, + &state->ot_y_loc); CHECK_ERR(err); - - err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_AWB_BG_H, &bg_cal_h); + err = m9mo_readw(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_FRAME_WIDTH, + &state->ot_width); CHECK_ERR(err); - err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, - M9MO_ADJST_AWB_BG_L, &bg_cal_l); + err = m9mo_readw(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_FRAME_HEIGHT, + &state->ot_height); CHECK_ERR(err); + cam_dbg("OT pos x: %d, y: %d, w: %d, h: %d\n", + state->ot_x_loc, state->ot_y_loc, + state->ot_width, state->ot_height); -out: - if (!state->fw_version) { - state->fw_version = kzalloc(50, GFP_KERNEL); - if (!state->fw_version) { - cam_err("no memory for F/W version\n"); - return -ENOMEM; - } - } + cam_trace("X status : %d\n", state->ot_status); +#endif + return 0; +} - sprintf(state->fw_version, "%s %s %d %x %x %x %x %x %x", - sensor_ver, phone_ver, update_count, - af_cal_h, af_cal_l, rg_cal_h, rg_cal_l, bg_cal_h, bg_cal_l); +static int m9mo_get_warning_condition(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int value, err; - cam_trace("X\n"); - return 0; + err = m9mo_readw2(sd, M9MO_CATEGORY_PRO_MODE, + 0x03, &value); + CHECK_ERR(err); + + ctrl->value = value; + + return ctrl->value; } -#ifdef FAST_CAPTURE -static int m9mo_set_fast_capture(struct v4l2_subdev *sd) +static int m9mo_get_av(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct m9mo_state *state = to_state(sd); - int err; - cam_info("E\n"); + int value, err; - err = m9mo_set_mode(sd, M9MO_STILLCAP_MODE); - if (err < 0) { - cam_err("Mode change is failed to STILLCAP for fast capture\n"); - return err; - } else { - cam_info("Fast capture is issued. mode change start.\n"); - } - return 0; + err = m9mo_readl2(sd, M9MO_CATEGORY_AE, + M9MO_AE_NOW_AV, &value); + CHECK_ERR(err); + + ctrl->value = value; + state->AV = value; + + return ctrl->value; } -#endif -static int m9mo_set_sensor_mode(struct v4l2_subdev *sd, int val) +static int m9mo_get_tv(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct m9mo_state *state = to_state(sd); - int err; - cam_dbg("E, value %d\n", val); + int value, err; - err = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + err = m9mo_readl2(sd, M9MO_CATEGORY_AE, + M9MO_AE_NOW_TV, &value); CHECK_ERR(err); - state->sensor_mode = val; + ctrl->value = value; + state->TV = value; - cam_trace("X\n"); - return 0; + return ctrl->value; } -static int m9mo_set_flash(struct v4l2_subdev *sd, int val, int force) +static int m9mo_get_sv(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct m9mo_state *state = to_state(sd); - int strobe_en = 0; - int err; - cam_dbg("E, value %d\n", val); + int value, err; - if (!force) - state->flash_mode = val; + err = m9mo_readl2(sd, M9MO_CATEGORY_AE, + M9MO_AE_NOW_SV, &value); + CHECK_ERR(err); - /* movie flash mode should be set when recording is started */ - if (state->sensor_mode == SENSOR_MOVIE && !state->recording) - return 0; + ctrl->value = value; + state->SV = ctrl->value; -retry: - switch (val) { - case FLASH_MODE_OFF: - strobe_en = 0; - break; + return ctrl->value; +} - case FLASH_MODE_AUTO: - strobe_en = 2; - break; +static int m9mo_get_ev(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); - case FLASH_MODE_ON: - strobe_en = 1; - break; + state->EV = state->AV + state->TV; - case FLASH_MODE_RED_EYE: - strobe_en = 1; - break; + return state->EV; +} - case FLASH_MODE_FILL_IN: - strobe_en = 1; - break; +static int m9mo_get_lv(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + int value, err; - case FLASH_MODE_SLOW_SYNC: - strobe_en = 1; - break; + err = m9mo_readb2(sd, M9MO_CATEGORY_AE, + M9MO_AE_NOW_LV, &value); + CHECK_ERR(err); - case FLASH_MODE_RED_EYE_FIX: - strobe_en = 2; - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, - M9MO_FD_RED_EYE, 0x01); - CHECK_ERR(err); - break; + ctrl->value = value; + state->LV = ctrl->value; - default: - cam_warn("invalid value, %d\n", val); - val = FLASH_MODE_OFF; - goto retry; - } + return ctrl->value; +} - if (val != FLASH_MODE_RED_EYE_FIX) { - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, - M9MO_FD_RED_EYE, 0x00); + +static int m9mo_get_WBcustomX(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + int value, value2, err, int_factor, int_en; + int changed_capture_mode = false; + + if (state->running_capture_mode != M9MO_CAP_MODE_SINGLE_CAPTURE) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_MODE, + M9MO_CAP_MODE_SINGLE_CAPTURE); CHECK_ERR(err); + changed_capture_mode = true; } - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_STROBE_EN, strobe_en); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); CHECK_ERR(err); - cam_trace("X\n"); - return 0; -} + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x08); + CHECK_ERR(err); -static int m9mo_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct m9mo_state *state = to_state(sd); - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, err; - u32 iso[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x02); + CHECK_ERR(err); - if (state->scene_mode != SCENE_MODE_NONE) { - /* sensor will set internally */ - return 0; + err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_MODE, M9MO_STILLCAP_MODE); + CHECK_ERR(err); + + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_en); + CHECK_ERR(err); + + if (int_en & M9MO_INT_SOUND) { + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_SOUND_TIMEOUT); + if (!(int_factor & M9MO_INT_SOUND)) { + cam_warn("M9MO_INT_SOUND isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } } - cam_dbg("E, value %d\n", val); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + m9mo_set_mode(sd, M9MO_MONITOR_MODE); - if (val < qc.minimum || val > qc.maximum) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value; + err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(err & M9MO_INT_MODE)) { + cam_err("firmware was erased?\n"); + return -ETIMEDOUT; } - val -= qc.minimum; + err = m9mo_readw(sd, M9MO_CATEGORY_WB, + M9MO_WB_GET_CUSTOM_RG, &value); + CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_ISOSEL, iso[val]); + err = m9mo_readw(sd, M9MO_CATEGORY_WB, + M9MO_WB_GET_CUSTOM_BG, &value2); CHECK_ERR(err); - cam_trace("X\n"); - return 0; -} + /* prevent abnormal value, to be fixed by ISP */ + if (value == 0) + value = 424; + if (value2 == 0) + value2 = 452; -static int m9mo_set_metering(struct v4l2_subdev *sd, int val) -{ - int err; - cam_dbg("E, value %d\n", val); + state->wb_custom_rg = value; + state->wb_custom_bg = value2; -retry: - switch (val) { - case METERING_CENTER: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_MODE, 0x03); - CHECK_ERR(err); - break; - case METERING_SPOT: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_MODE, 0x05); - CHECK_ERR(err); - break; - case METERING_MATRIX: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_MODE, 0x01); - CHECK_ERR(err); - break; - default: - cam_warn("invalid value, %d\n", val); - val = METERING_CENTER; - goto retry; - } - - cam_trace("X\n"); - return 0; -} - -static int m9mo_set_exposure(struct v4l2_subdev *sd, - struct v4l2_control *ctrl) -{ - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, err; - /* - -6, -5, -4, +4, +5, +6 is not implemented in ISP - */ - u32 exposure[] = {0x00, 0x00, 0x00, - 0x00, 0x0A, 0x14, 0x1E, 0x28, - 0x32, 0x3C, 0x3C, 0x3C, 0x3C}; - cam_dbg("E, value %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x02); + CHECK_ERR(err); - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + err = m9mo_writew(sd, M9MO_CATEGORY_WB, + M9MO_WB_SET_CUSTOM_RG, state->wb_custom_rg); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_WB, + M9MO_WB_SET_CUSTOM_BG, state->wb_custom_bg); + CHECK_ERR(err); - if (val < qc.minimum || val > qc.maximum) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value; - } + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x01); + CHECK_ERR(err); - val -= qc.minimum; + if (changed_capture_mode) + m9mo_set_capture_mode(sd, state->running_capture_mode); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_INDEX, exposure[val]); - CHECK_ERR(err); + cam_trace("X value : %d value2 : %d\n", value, value2); - cam_trace("X\n"); - return 0; + return value; } -static int m9mo_set_whitebalance(struct v4l2_subdev *sd, int val) +static int m9mo_get_WBcustomY(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - int err; - cam_dbg("E, value %d\n", val); - -retry: - switch (val) { - case WHITE_BALANCE_AUTO: - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MODE, 0x01); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MANUAL, 0x01); - CHECK_ERR(err); - break; - - case WHITE_BALANCE_SUNNY: - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MODE, 0x02); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MANUAL, 0x04); - CHECK_ERR(err); - break; + struct m9mo_state *state = to_state(sd); - case WHITE_BALANCE_CLOUDY: - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MODE, 0x02); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MANUAL, 0x05); - CHECK_ERR(err); - break; + return state->wb_custom_bg; +} - case WHITE_BALANCE_TUNGSTEN: - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MODE, 0x02); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MANUAL, 0x01); - CHECK_ERR(err); - break; +static int m9mo_get_face_detect_number(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + int value, err; - case WHITE_BALANCE_FLUORESCENT: - case WHITE_BALANCE_FLUORESCENT_H: - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MODE, 0x02); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MANUAL, 0x02); - CHECK_ERR(err); - break; + err = m9mo_readb2(sd, M9MO_CATEGORY_FD, 0x0A, &value); + CHECK_ERR(err); - case WHITE_BALANCE_FLUORESCENT_L: - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MODE, 0x02); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, - M9MO_WB_AWB_MANUAL, 0x03); - CHECK_ERR(err); - break; + state->fd_num = value; - default: - cam_warn("invalid value, %d\n", val); - val = WHITE_BALANCE_AUTO; - goto retry; - } +#if 0 + cam_trace("X %d\n", value); +#endif - cam_trace("X\n"); - return 0; + return value; } -static int m9mo_set_sharpness(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +static int m9mo_get_factory_FW_info(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) { - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, err; - u32 sharpness[] = {0x03, 0x04, 0x05, 0x06, 0x07}; - cam_dbg("E, value %d\n", val); + int err = 0; + u32 read_val1, read_val2; + u32 ver = 0; - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + m9mo_readb(sd, M9MO_CATEGORY_SYS, + 0x02, &read_val1); + CHECK_ERR(err); - if (val < qc.minimum || val > qc.maximum) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value; - } + m9mo_readb(sd, M9MO_CATEGORY_SYS, + 0x03, &read_val2); + CHECK_ERR(err); - val -= qc.minimum; + ver = 0; + ver = (read_val1 << 8) | (read_val2); - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_EDGE_LVL, sharpness[val]); - CHECK_ERR(err); + cam_trace("m9mo_get_factory_FW : 0x%x\n", ver); + ctrl->value = ver; - cam_trace("X\n"); return 0; } -static int m9mo_set_saturation(struct v4l2_subdev *sd, +static int m9mo_get_factory_OIS_info(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, err; - u32 saturation[] = {0x01, 0x02, 0x03, 0x04, 0x05}; - cam_dbg("E, value %d\n", val); - - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); - - if (val < qc.minimum || val > qc.maximum) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value; - } - - val -= qc.minimum; + int err; + u32 ver = 0; - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_CHROMA_LVL, saturation[val]); + err = m9mo_readl(sd, M9MO_CATEGORY_NEW, + 0x1B, &ver); CHECK_ERR(err); - cam_trace("X\n"); + cam_trace("m9mo_get_factory_FW : 0x%x\n", ver); + ctrl->value = ver; + return 0; } -static int m9mo_set_scene_mode(struct v4l2_subdev *sd, int val) +static int m9mo_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct m9mo_state *state = to_state(sd); - struct v4l2_control ctrl; - int evp, sharpness, saturation; - int err; - cam_dbg("E, value %d\n", val); + int err = 0; + u32 val = 0; - sharpness = SHARPNESS_DEFAULT; - saturation = CONTRAST_DEFAULT; + switch (ctrl->id) { + case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT: + m9mo_get_af_result(sd, ctrl); + break; -retry: - switch (val) { - case SCENE_MODE_NONE: - evp = 0x00; + case V4L2_CID_CAM_JPEG_MEMSIZE: + ctrl->value = M9MO_JPEG_MAXSIZE + + M9MO_THUMB_MAXSIZE + M9MO_POST_MAXSIZE; break; - case SCENE_MODE_PORTRAIT: - evp = 0x01; - sharpness = SHARPNESS_MINUS_1; + case V4L2_CID_CAM_JPEG_MAIN_SIZE: + ctrl->value = state->jpeg.main_size; break; - case SCENE_MODE_LANDSCAPE: - evp = 0x02; - sharpness = SHARPNESS_PLUS_1; - saturation = SATURATION_PLUS_1; + case V4L2_CID_CAM_JPEG_MAIN_OFFSET: + ctrl->value = state->jpeg.main_offset; break; - case SCENE_MODE_SPORTS: - evp = 0x03; + case V4L2_CID_CAM_JPEG_THUMB_SIZE: + ctrl->value = state->jpeg.thumb_size; break; - case SCENE_MODE_PARTY_INDOOR: - evp = 0x04; - saturation = SATURATION_PLUS_1; + case V4L2_CID_CAM_JPEG_THUMB_OFFSET: + ctrl->value = state->jpeg.thumb_offset; break; - case SCENE_MODE_BEACH_SNOW: - evp = 0x05; - saturation = SATURATION_PLUS_1; + case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET: + ctrl->value = state->jpeg.postview_offset; break; - case SCENE_MODE_SUNSET: - evp = 0x06; + case V4L2_CID_CAMERA_EXIF_FLASH: + ctrl->value = state->exif.flash; break; - case SCENE_MODE_DUSK_DAWN: - evp = 0x07; + case V4L2_CID_CAMERA_EXIF_ISO: + ctrl->value = state->exif.iso; break; - case SCENE_MODE_FALL_COLOR: - evp = 0x08; - saturation = SATURATION_PLUS_2; + case V4L2_CID_CAMERA_EXIF_TV: + ctrl->value = state->exif.tv; break; - case SCENE_MODE_NIGHTSHOT: - evp = 0x09; + case V4L2_CID_CAMERA_EXIF_BV: + ctrl->value = state->exif.bv; break; - case SCENE_MODE_BACK_LIGHT: - evp = 0x0A; + case V4L2_CID_CAMERA_EXIF_AV: + ctrl->value = state->exif.av; break; - case SCENE_MODE_FIREWORKS: - evp = 0x0B; + case V4L2_CID_CAMERA_EXIF_EBV: + ctrl->value = state->exif.ebv; break; - case SCENE_MODE_TEXT: - evp = 0x0C; - sharpness = SHARPNESS_PLUS_2; + case V4L2_CID_CAMERA_EXIF_FL: + ctrl->value = state->exif.focal_length; break; - case SCENE_MODE_CANDLE_LIGHT: - evp = 0x0D; + case V4L2_CID_CAMERA_EXIF_FL_35mm: + ctrl->value = state->exif.focal_35mm_length; break; - default: - cam_warn("invalid value, %d\n", val); - val = SCENE_MODE_NONE; - goto retry; - } + case V4L2_CID_CAMERA_FD_EYE_BLINK_RESULT: + ctrl->value = state->fd_eyeblink_cap; + break; - /* EV-P */ - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_MON, evp); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_CAP, evp); - CHECK_ERR(err); + case V4L2_CID_CAMERA_RED_EYE_FIX_RESULT: + ctrl->value = state->fd_red_eye_status; + break; - /* Chroma Saturation */ - ctrl.id = V4L2_CID_CAMERA_SATURATION; - ctrl.value = saturation; - m9mo_set_saturation(sd, &ctrl); + case V4L2_CID_CAMERA_SCENE_MODE: + err = m9mo_get_scene_mode(sd, ctrl); + break; - /* Sharpness */ - ctrl.id = V4L2_CID_CAMERA_SHARPNESS; - ctrl.value = sharpness; - m9mo_set_sharpness(sd, &ctrl); + case V4L2_CID_CAMERA_SCENE_SUB_MODE: + err = m9mo_get_scene_sub_mode(sd, ctrl); + break; - /* Emotional Color */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_MCC_MODE, val == SCENE_MODE_NONE ? 0x01 : 0x00); - CHECK_ERR(err); - - state->scene_mode = val; - - cam_trace("X\n"); - return 0; -} - - -static int m9mo_set_effect_color(struct v4l2_subdev *sd, int val) -{ - u32 int_factor; - int on, old_mode, cb, cr; - int err; - - err = m9mo_readb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_EFFECT, &on); - CHECK_ERR(err); - if (on) { - old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); - CHECK_ERR(old_mode); + case V4L2_CID_CAMERA_FACTORY_DOWN_RESULT: + ctrl->value = state->factory_down_check; + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_EFFECT, 0); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_AF_INT_RESULT: + ctrl->value = state->factory_result_check; + break; - if (old_mode == M9MO_MONITOR_MODE) { - err = m9mo_set_mode(sd, old_mode); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_END_RESULT: + ctrl->value = state->factory_end_check; + cam_trace("leesm test ----- factory_end_check %d\n", + ctrl->value); + break; - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_MODE)) { - cam_err("M9MO_INT_MODE isn't issued, %#x\n", - int_factor); - return -ETIMEDOUT; - } - CHECK_ERR(err); - } - } + case V4L2_CID_CAMERA_ZOOM: + err = m9mo_get_zoom_status(sd, ctrl); + break; - switch (val) { - case IMAGE_EFFECT_NONE: + case V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL: + err = m9mo_get_zoom_level(sd, ctrl); break; - case IMAGE_EFFECT_SEPIA: - cb = 0xD8; - cr = 0x18; + case V4L2_CID_CAMERA_FLASH_MODE: + err = m9mo_get_flash_status(sd, ctrl); break; - case IMAGE_EFFECT_BNW: - cb = 0x00; - cr = 0x00; + case V4L2_CID_CAMERA_OBJ_TRACKING_STATUS: + err = m9mo_get_object_tracking(sd, ctrl); + ctrl->value = state->ot_status; break; - } - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_COLOR_EFFECT, val == IMAGE_EFFECT_NONE ? 0x00 : 0x01); - CHECK_ERR(err); + case V4L2_CID_CAMERA_AV: + ctrl->value = m9mo_get_av(sd, ctrl); + break; - if (val != IMAGE_EFFECT_NONE) { - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXB, cb); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXR, cr); - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_TV: + ctrl->value = m9mo_get_tv(sd, ctrl); + break; - return 0; -} + case V4L2_CID_CAMERA_SV: + ctrl->value = m9mo_get_sv(sd, ctrl); + break; -static int m9mo_set_effect_gamma(struct v4l2_subdev *sd, s32 val) -{ - u32 int_factor; - int on, effect, old_mode; - int err; + case V4L2_CID_CAMERA_EV: + ctrl->value = m9mo_get_ev(sd, ctrl); + break; - err = m9mo_readb(sd, M9MO_CATEGORY_MON, M9MO_MON_COLOR_EFFECT, &on); - CHECK_ERR(err); - if (on) { - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_COLOR_EFFECT, 0); - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_LV: + ctrl->value = m9mo_get_lv(sd, ctrl); + break; - switch (val) { - case IMAGE_EFFECT_NEGATIVE: - effect = 0x01; + case V4L2_CID_CAMERA_WB_CUSTOM_X: + ctrl->value = m9mo_get_WBcustomX(sd, ctrl); break; - case IMAGE_EFFECT_AQUA: - effect = 0x08; + case V4L2_CID_CAMERA_WB_CUSTOM_Y: + ctrl->value = m9mo_get_WBcustomY(sd, ctrl); break; - } - old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); - CHECK_ERR(old_mode); + case V4L2_CID_CAMERA_GET_MODE: + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_MODE, &val); + if (err < 0) + ctrl->value = -1; + else + ctrl->value = val; + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_EFFECT, effect); - CHECK_ERR(err); + case V4L2_CID_CAMERA_SMART_READ1: + m9mo_get_smart_read1(sd, ctrl); + break; - if (old_mode == M9MO_MONITOR_MODE) { - err = m9mo_set_mode(sd, old_mode); - CHECK_ERR(err); + case V4L2_CID_CAMERA_SMART_READ2: + m9mo_get_smart_read2(sd, ctrl); + break; - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_MODE)) { - cam_err("M9MO_INT_MODE isn't issued, %#x\n", - int_factor); - return -ETIMEDOUT; - } - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_LENS_STATUS: + m9mo_get_lens_status(sd, ctrl); + break; - return err; -} + case V4L2_CID_CAMERA_WARNING_CONDITION: + ctrl->value = m9mo_get_warning_condition(sd, ctrl); + break; -static int m9mo_set_effect(struct v4l2_subdev *sd, int val) -{ - int err; - cam_dbg("E, value %d\n", val); + case V4L2_CID_CAMERA_FACTORY_ISP_FW_CHECK: + err = m9mo_get_factory_FW_info(sd, ctrl); + break; -retry: - switch (val) { - case IMAGE_EFFECT_NONE: - case IMAGE_EFFECT_BNW: - case IMAGE_EFFECT_SEPIA: - err = m9mo_set_effect_color(sd, val); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_OIS_VER_CHECK: + err = m9mo_get_factory_OIS_info(sd, ctrl); break; - case IMAGE_EFFECT_AQUA: - case IMAGE_EFFECT_NEGATIVE: - err = m9mo_set_effect_gamma(sd, val); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACE_DETECT_NUMBER: + ctrl->value = m9mo_get_face_detect_number(sd, ctrl); break; default: - cam_warn("invalid value, %d\n", val); - val = IMAGE_EFFECT_NONE; - goto retry; + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_PRIVATE_BASE); + /*err = -ENOIOCTLCMD*/ + err = 0; + break; } - cam_trace("X\n"); - return 0; -} - -static int m9mo_set_wdr(struct v4l2_subdev *sd, int val) -{ - int contrast, wdr, err; - - cam_dbg("%s\n", val ? "on" : "off"); - - contrast = (val == 1 ? 0x09 : 0x05); - wdr = (val == 1 ? 0x01 : 0x00); - - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_TONE_CTRL, contrast); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_WDR_EN, wdr); - CHECK_ERR(err); + if (err < 0 && err != -ENOIOCTLCMD) + cam_err("failed, id %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE); - cam_trace("X\n"); - return 0; + return err; } -static int m9mo_set_antishake(struct v4l2_subdev *sd, int val) +static int m9mo_set_antibanding(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) { + struct v4l2_queryctrl qc = {0,}; struct m9mo_state *state = to_state(sd); - int ahs, err; + int val = ctrl->value, err; + u32 antibanding[] = {0x00, 0x01, 0x02, 0x03, 0x04}; - if (state->scene_mode != SCENE_MODE_NONE) { - cam_warn("Should not be set with scene mode"); + if (state->anti_banding == val) return 0; - } - cam_dbg("%s\n", val ? "on" : "off"); - - ahs = (val == 1 ? 0x0E : 0x00); - - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_MON, ahs); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_CAP, ahs); - CHECK_ERR(err); + cam_dbg("E, value %d\n", val); - cam_trace("X\n"); - return 0; -} + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); -static int m9mo_set_face_beauty(struct v4l2_subdev *sd, int val) -{ - struct m9mo_state *state = to_state(sd); - int err; + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; + } - cam_dbg("%s\n", val ? "on" : "off"); + val -= qc.minimum; - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_AFB_CAP_EN, val ? 0x01 : 0x00); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_FLICKER, antibanding[val]); CHECK_ERR(err); - state->face_beauty = val; + state->anti_banding = val; cam_trace("X\n"); return 0; } -static int m9mo_set_lock(struct v4l2_subdev *sd, int val) +static int m9mo_set_lens_off(struct v4l2_subdev *sd) { struct m9mo_state *state = to_state(sd); - int err; + u32 int_factor = 0; + int err = 0; + int int_en; - cam_trace("%s\n", val ? "on" : "off"); + cam_trace("E\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, val); + if (unlikely(state->isp.bad_fw)) { + cam_err("\"Unknown\" state, please update F/W"); + return -ENOSYS; + } + + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_en); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, val); + int_en &= ~M9MO_INT_MODE; + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_en); CHECK_ERR(err); - state->focus.lock = val; + err = m9mo_set_mode(sd, M9MO_MONITOR_MODE); + if (err <= 0) { + cam_err("failed to set mode\n"); + return err; + } - cam_trace("X\n"); - return 0; -} -static int m9mo_get_af_result(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct m9mo_state *state = to_state(sd); - int status, err; + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x01, 0x00); - err = m9mo_readb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_STATUS, &status); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - state->focus.status = status; - ctrl->value = status; - /* - Get af result is not supported in ISP now. FIXME - */ - ctrl->value = 0x02; - return ctrl->value; + if (!(int_factor & M9MO_INT_LENS_INIT)) { + cam_err("M9MO_INT_LENS_INIT isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + cam_trace("X\n"); + return err; } -static int m9mo_set_af(struct v4l2_subdev *sd, int val) + +static int m9mo_dump_fw(struct v4l2_subdev *sd) { - struct m9mo_state *state = to_state(sd); - /* int i, status; */ - int err = 0; + struct file *fp; + mm_segment_t old_fs; + u8 *buf/*, val*/; + u32 addr, unit, count, intram_unit = 0x1000; + int i, /*j,*/ err; - cam_info("%s, mode %#x\n", val ? "start" : "stop", state->focus.mode); + old_fs = get_fs(); + set_fs(KERNEL_DS); - state->focus.start = val; + fp = filp_open(M9MO_FW_DUMP_PATH, + O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR); + if (IS_ERR(fp)) { + cam_err("failed to open %s, err %ld\n", + M9MO_FW_DUMP_PATH, PTR_ERR(fp)); + err = -ENOENT; + goto file_out; + } - /* - Single AF is only supported in ISP now. FIXME - */ -#if 0 - if (state->focus.mode != FOCUS_MODE_CONTINOUS) { - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_START, val); - CHECK_ERR(err); + buf = kmalloc(intram_unit, GFP_KERNEL); + if (!buf) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } - if (!(state->focus.touch && - state->focus.mode == FOCUS_MODE_TOUCH)) { - if (val && state->focus.lock) { - m9mo_set_lock(sd, 0); - msleep(100); - } - m9mo_set_lock(sd, val); - } + cam_dbg("start, file path %s\n", M9MO_FW_DUMP_PATH); - } else { - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_START, val ? 0x02 : 0x00); - CHECK_ERR(err); - err = -EBUSY; - for (i = M9MO_I2C_VERIFY; i && err; i--) { - msleep(20); - err = m9mo_readb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_STATUS, &status); - CHECK_ERR(err); - - if ((val && status == 0x05) || (!val && status != 0x05)) - err = 0; - } - } -#endif - if (state->focus.start == 1) { - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - 0x03, 0x00); - CHECK_ERR(err); - msleep(100); +/* + val = 0x7E; + err = m9mo_mem_write(sd, 0x04, sizeof(val), 0x50000308, &val); + if (err < 0) { + cam_err("failed to write memory\n"); + goto out; } +*/ - cam_dbg("X\n"); - return err; -} -static int m9mo_set_af_mode(struct v4l2_subdev *sd, int val) -{ - struct m9mo_state *state = to_state(sd); - u32 cancel, mode, status = 0; - int i, err; + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001200 , buf_port_seting0); + CHECK_ERR(err); + mdelay(10); - cancel = val & FOCUS_MODE_DEFAULT; - val &= 0xFF; + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001000 , buf_port_seting1); + CHECK_ERR(err); + mdelay(10); -retry: - switch (val) { - case FOCUS_MODE_AUTO: - mode = 0x00; - break; + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001100 , buf_port_seting2); + CHECK_ERR(err); + mdelay(10); - case FOCUS_MODE_MACRO: - mode = 0x01; - break; + err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, + 0x1C, 0x0247036D); - case FOCUS_MODE_CONTINOUS: - mode = 0x02; - cancel = 0; - break; + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, + 0x57, 01); - case FOCUS_MODE_FACEDETECT: - mode = 0x03; - break; + CHECK_ERR(err); - case FOCUS_MODE_TOUCH: - mode = 0x04; - cancel = 0; - break; - case FOCUS_MODE_INFINITY: - mode = 0x06; - cancel = 0; - break; + addr = M9MO_FLASH_READ_BASE_ADDR; + unit = SZ_4K; + count = 1024; + for (i = 0; i < count; i++) { - default: - cam_warn("invalid value, %d", val); - val = FOCUS_MODE_AUTO; - goto retry; + err = m9mo_mem_dump(sd, + unit, addr + (i * unit), buf); + cam_err("dump ~~ %d\n", i); + if (err < 0) { + cam_err("i2c falied, err %d\n", err); + goto out; + } + vfs_write(fp, buf, unit, &fp->f_pos); } - - if (cancel) { - m9mo_set_af(sd, 0); - m9mo_set_lock(sd, 0); - } else { - if (state->focus.mode == val) - return 0; +/* + addr = M9MO_FLASH_BASE_ADDR + SZ_64K * count; + unit = SZ_8K; + count = 4; + for (i = 0; i < count; i++) { + for (j = 0; j < unit; j += intram_unit) { + err = m9mo_mem_read(sd, + intram_unit, addr + (i * unit) + j, buf); + if (err < 0) { + cam_err("i2c falied, err %d\n", err); + goto out; + } + vfs_write(fp, buf, intram_unit, &fp->f_pos); + } } +*/ + cam_dbg("end\n"); - cam_dbg("E, value %d\n", val); +out: + kfree(buf); + if (!IS_ERR(fp)) + filp_close(fp, current->files); +file_out: + set_fs(old_fs); - if (val == FOCUS_MODE_FACEDETECT) { - /* enable face detection */ - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x11); - CHECK_ERR(err); - msleep(20); - } else if (state->focus.mode == FOCUS_MODE_FACEDETECT) { - /* disable face detection */ - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x00); - CHECK_ERR(err); - } + return err; +} - state->focus.mode = val; +static int m9mo_get_sensor_fw_version(struct v4l2_subdev *sd) +{ + struct m9mo_state *state = to_state(sd); + int err; + int fw_ver = 0x00; + int awb_ver = 0x00; + int af_ver = 0x00; + int ois_ver = 0x00; + int parm_ver = 0x00; + int user_ver_temp; + char user_ver[20]; + char sensor_ver[7]; + int i = 0; - /* Lens barrel error is occured by this command now. FIXME */ -#if 0 - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, M9MO_LENS_AF_MODE, mode); + cam_err("E\n"); + + /* read F/W version */ + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_VER_FW, &fw_ver); CHECK_ERR(err); -#endif - for (i = M9MO_I2C_VERIFY; i; i--) { - msleep(20); - err = m9mo_readb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_STATUS, &status); + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_VER_AWB, &awb_ver); + CHECK_ERR(err); + + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_VER_PARAM, &parm_ver); + CHECK_ERR(err); + + err = m9mo_readl(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_VERSION, &af_ver); + CHECK_ERR(err); + + err = m9mo_readl(sd, M9MO_CATEGORY_NEW, + M9MO_NEW_OIS_VERSION, &ois_ver); + CHECK_ERR(err); + + + for (i = 0; i < M9MO_FW_VER_LEN; i++) { + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_USER_VER, &user_ver_temp); CHECK_ERR(err); - if (!(status & 0x01)) + if ((char)user_ver_temp == '\0') break; + + user_ver[i] = (char)user_ver_temp; + /*cam_info("user temp version = %c\n", (char)user_ver_temp);*/ + } - if ((status & 0x01) != 0x00) { - cam_err("failed\n"); - return -ETIMEDOUT; + user_ver[i] = '\0'; + + if (user_ver[0] == 'F' && user_ver[1] == 'C') { + for (i = 0; i < M9MO_FW_VER_LEN; i++) { + if (user_ver[i] == 0x20) { + sensor_ver[i] = '\0'; + break; + } + sensor_ver[i] = user_ver[i]; + } + } else { + sprintf(sensor_ver, "%s", "Invalid version"); } - cam_trace("X\n"); + cam_info("f/w version = %x\n", fw_ver); + cam_info("awb version = %x\n", awb_ver); + cam_info("af version = %x\n", af_ver); + cam_info("ois version = %x\n", ois_ver); + cam_info("parm version = %x\n", parm_ver); + cam_info("user version = %s\n", user_ver); + cam_info("sensor version = %s\n", sensor_ver); + + sprintf(state->sensor_ver, "%s", sensor_ver); + sprintf(state->sensor_type, "%d %d %d %x", + awb_ver, af_ver, ois_ver, parm_ver); + memcpy(sysfs_sensor_fw, state->sensor_ver, + sizeof(state->sensor_ver)); + memcpy(sysfs_sensor_type, state->sensor_type, + sizeof(state->sensor_type)); + state->isp_fw_ver = fw_ver; + + cam_info("sensor fw : %s\n", sysfs_sensor_fw); + cam_info("sensor type : %s\n", sysfs_sensor_type); return 0; } -static int m9mo_set_touch_auto_focus(struct v4l2_subdev *sd, int val) +static int m9mo_get_phone_fw_version(struct v4l2_subdev *sd) { struct m9mo_state *state = to_state(sd); + struct device *dev = sd->v4l2_dev->dev; + const struct firmware *fw; int err = 0; - cam_info("%s\n", val ? "start" : "stop"); - - state->focus.touch = val; - - if (val) { - err = m9mo_set_af_mode(sd, FOCUS_MODE_TOUCH); - if (err < 0) { - cam_err("m9mo_set_af_mode failed\n"); - return err; - } - err = m9mo_writew(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_TOUCH_POSX, state->focus.pos_x); - CHECK_ERR(err); - err = m9mo_writew(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_TOUCH_POSY, state->focus.pos_y); - CHECK_ERR(err); - } - cam_trace("X\n"); - return err; -} + struct file *fp; + mm_segment_t old_fs; + long nread; + int fw_requested = 1; + char ver_tmp[20]; + char phone_ver[7]; + int i = 0; -static int m9mo_set_zoom(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct m9mo_state *state = to_state(sd); - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, err, i; - int n_zoom[] = { 75, 150, 225, 300}; - int zoom[] = { 4, 16, 28, 39}; - cam_dbg("E, value %d\n", val); + cam_info("E\n"); - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + old_fs = get_fs(); + set_fs(KERNEL_DS); - if (val < (qc.minimum * 10) || val > (qc.maximum * 10)) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value * 10; + fp = filp_open(M9MO_FW_PATH, O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_trace("failed to open %s, err %ld\n", M9MO_FW_PATH, + PTR_ERR(fp)); + goto request_fw; + } else { + cam_info("FW File(phone) opened.\n"); } - for (i = 0 ; i <= sizeof(n_zoom) ; i++) { - if (n_zoom[i] >= ctrl->value) { - val = i; - break; - } - } + fw_requested = 0; - if (val < 0 || val > 4) { - cam_warn("invalied value, %d\n", val); - val = 0; + err = vfs_llseek(fp, M9MO_FW_VER_NUM, SEEK_SET); + if (err < 0) { + cam_warn("failed to fseek, %d\n", err); + goto out; } - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_ZOOM, zoom[val]); - CHECK_ERR(err); + /*nread = vfs_read(fp, (char __user *)state->phone_ver,*/ + nread = vfs_read(fp, (char __user *)ver_tmp, + M9MO_FW_VER_LEN, &fp->f_pos); + if (nread != M9MO_FW_VER_LEN) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } - state->zoom = val; +request_fw: + if (fw_requested) { + set_fs(old_fs); - cam_trace("X\n"); - return 0; -} +#if 0 + m9mo_get_sensor_fw_version(sd, sensor_ver); -static int m9mo_set_optical_zoom_step(struct v4l2_subdev *sd, - struct v4l2_control *ctrl) -{ - struct m9mo_state *state = to_state(sd); - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, err, i; - int n_zoom[] = { 10, 12, 15, 18, 22, 28, 34, 40, 50, 61, 75, - 94, 114, 139, 179, 210}; + if (sensor_ver[0] == 'T' && sensor_ver[1] == 'B') { + err = request_firmware(&fw, M9MOTB_FW_PATH, dev); +#if defined(CONFIG_MACH_Q1_BD) + } else if (sensor_ver[0] == 'O' && sensor_ver[1] == 'O') { + err = request_firmware(&fw, M9MOOO_FW_PATH, dev); +#endif +#if defined(CONFIG_MACH_U1_KOR_LGT) + } else if (sensor_ver[0] == 'S' && sensor_ver[1] == 'B') { + err = request_firmware(&fw, M9MOSB_FW_PATH, dev); +#endif + } else { + cam_warn("cannot find the matched F/W file\n"); +#if defined(CONFIG_MACH_Q1_BD) + err = request_firmware(&fw, M9MOOO_FW_PATH, dev); +#elif defined(CONFIG_MACH_U1_KOR_LGT) + err = request_firmware(&fw, M9MOSB_FW_PATH, dev); +#else + err = request_firmware(&fw, M9MOTB_FW_PATH, dev); +#endif + } +#else + if (system_rev > 1) { + cam_info("Firmware Path = %s\n", + M9MO_EVT31_FW_REQ_PATH); + err = request_firmware(&fw, + M9MO_EVT31_FW_REQ_PATH, dev); + } else { + cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH); + err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev); + } +#endif - cam_dbg("E, value %d\n", val); + if (err != 0) { + cam_err("request_firmware falied\n"); + err = -EINVAL; + goto out; + } +#if 0 + sprintf(state->phone_ver, "%x%x", + (u32)&fw->data[M9MO_FW_VER_NUM], + (u32)&fw->data[M9MO_FW_VER_NUM + 1]); + cam_info("%s: fw->data[0] = %x, fw->data[1] = %x\n", __func__, + (int)fw->data[M9MO_FW_VER_NUM], + (int)fw->data[M9MO_FW_VER_NUM + 1]); + ver_tmp = (int)fw->data[M9MO_FW_VER_NUM] * 16 * 16; + ver_tmp += (int)fw->data[M9MO_FW_VER_NUM + 1]; + cam_info("ver_tmp = %x\n", ver_tmp); + sprintf(state->phone_ver, "FU%x", ver_tmp); +#endif - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + for (i = 0; i < M9MO_FW_VER_LEN; i++) { + if ((int)fw->data[M9MO_FW_VER_NUM+i] == 0x00) + break; - if (val < (qc.minimum * 10) || val > (qc.maximum * 10)) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value * 10; + ver_tmp[i] = (int)fw->data[M9MO_FW_VER_NUM+i]; + } } +out: + + ver_tmp[M9MO_FW_VER_LEN-1] = '\0'; - for (i = 0 ; i <= sizeof(n_zoom) ; i++) { - if (n_zoom[i] >= ctrl->value) { - val = i; + for (i = 0; i < M9MO_FW_VER_LEN; i++) { + if (ver_tmp[i] == 0x20) { + phone_ver[i] = '\0'; + /*cam_info("phone_ver = %s\n", phone_ver);*/ break; } + phone_ver[i] = ver_tmp[i]; } - if (val < 0 || val > 0x0F) { - cam_warn("invalied value, %d\n", val); - val = 0; + cam_info("ver_tmp = %s\n", ver_tmp); + cam_info("phone_ver = %s\n", phone_ver); + sprintf(state->phone_ver, "%s", phone_ver); + memcpy(sysfs_phone_fw, state->phone_ver, + sizeof(state->phone_ver)); + + if (!fw_requested) { + filp_close(fp, current->files); + set_fs(old_fs); + } else { + release_firmware(fw); } - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_ZOOM_LEVEL, val); - CHECK_ERR(err); + cam_dbg("phone ver : %s\n", sysfs_phone_fw); + return 0; +} - state->optical_zoom = val; - - cam_trace("X\n"); - return 0; -} - -static int m9mo_set_optical_zoom_ctrl(struct v4l2_subdev *sd, int val) +static int m9mo_check_fw(struct v4l2_subdev *sd) { +#if 0 struct m9mo_state *state = to_state(sd); +#endif + int /*af_cal_h = 0,*/ af_cal_l = 0; + int rg_cal_h = 0, rg_cal_l = 0; + int bg_cal_h = 0, bg_cal_l = 0; +#if 0 + int update_count = 0; +#endif + u32 int_factor; int err; - s32 zoom_step; - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_ZOOM_CTRL, val); + cam_trace("E\n"); + + /* F/W version */ + m9mo_get_phone_fw_version(sd); + +#if 0 + if (state->isp.bad_fw) + goto out; +#endif + + m9mo_get_sensor_fw_version(sd); + + goto out; + + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, M9MO_FLASH_CAM_START, 0x01); CHECK_ERR(err); - err = m9mo_readb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_ZOOM_LEVEL, &zoom_step); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_MODE)) { + cam_err("firmware was erased?\n"); + return -ETIMEDOUT; + } + + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, M9MO_LENS_AF_CAL, &af_cal_l); + CHECK_ERR(err); + + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + M9MO_ADJST_AWB_RG_H, &rg_cal_h); + CHECK_ERR(err); + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + M9MO_ADJST_AWB_RG_L, &rg_cal_l); + CHECK_ERR(err); + + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + M9MO_ADJST_AWB_BG_H, &bg_cal_h); + CHECK_ERR(err); + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + M9MO_ADJST_AWB_BG_L, &bg_cal_l); + CHECK_ERR(err); + +out: +#if 0 + if (!state->sensor_type) { + state->sensor_type = kzalloc(50, GFP_KERNEL); + if (!state->sensor_type) { + cam_err("no memory for F/W version\n"); + return -ENOMEM; + } + } +#endif - state->optical_zoom = zoom_step; +#if 0 + sprintf(state->sensor_type, "%s %s %d %x %x %x %x %x %x", + sensor_ver, phone_ver, update_count, + af_cal_h, af_cal_l, rg_cal_h, rg_cal_l, bg_cal_h, bg_cal_l); +#endif + cam_info("phone ver = %s, sensor_ver = %s\n", + sysfs_phone_fw, sysfs_sensor_fw); cam_trace("X\n"); return 0; } -static int m9mo_set_jpeg_quality(struct v4l2_subdev *sd, - struct v4l2_control *ctrl) + +static int m9mo_make_CSV_rawdata(struct v4l2_subdev *sd, + u32 *address, bool bAddResult) { - struct v4l2_queryctrl qc = {0,}; - int val = ctrl->value, ratio, err; - cam_dbg("E, value %d\n", val); + struct file *fp; + mm_segment_t old_fs; + u8 *buf; + u32 addr, unit, intram_unit = 0x1000; + int err; - qc.id = ctrl->id; - m9mo_queryctrl(sd, &qc); + old_fs = get_fs(); + set_fs(KERNEL_DS); - if (val < qc.minimum || val > qc.maximum) { - cam_warn("invalied value, %d\n", val); - val = qc.default_value; + fp = filp_open(M9MO_FACTORY_CSV_PATH, + O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR); + if (IS_ERR(fp)) { + cam_err("failed to open %s, err %ld\n", + M9MO_FACTORY_CSV_PATH, PTR_ERR(fp)); + err = -ENOENT; + goto file_out; } - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_JPEG_RATIO, 0x62); - CHECK_ERR(err); + buf = kmalloc(intram_unit, GFP_KERNEL); + if (!buf) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } -#if 0 /* m9mo */ - if (val <= 65) /* Normal */ - ratio = 0x0A; - else if (val <= 75) /* Fine */ - ratio = 0x05; - else /* Superfine */ -#endif - ratio = 0x00; + cam_dbg("start, file path %s\n", M9MO_FACTORY_CSV_PATH); - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_JPEG_RATIO_OFS, ratio); - CHECK_ERR(err); + addr = address[0]; + unit = address[1]-address[0]+1; - cam_trace("X\n"); - return 0; + cam_trace("m9mo_make_CSV_rawdata() addr[0x%0x] size=%d\n", + addr, unit); + + err = m9mo_mem_read(sd, unit, addr, buf); + if (err < 0) { + cam_err("i2c falied, err %d\n", err); + goto out; + } + +/*"Result27E03128(0:OK, 1:NG)"Bit 0 : IRIS +Bit 1 : Liveview Gain +Bit 2 : ShutterClose +Bit 3 : CaptureGain +Bit 5 : DefectPixel*/ + if (bAddResult) { + m9mo_mem_read(sd, 0x2, + M9MO_FLASH_FACTORY_RESULT, buf+unit); + cam_trace("m9mo_make_CSV_rawdata() size=%d result=%x\n", + unit, *(u16 *)(buf+unit)); + unit += 2; + } + + vfs_write(fp, buf, unit, &fp->f_pos); + msleep(20); + +out: + kfree(buf); + if (!IS_ERR(fp)) + filp_close(fp, current->files); +file_out: + set_fs(old_fs); + + return err; } -static int m9mo_get_exif(struct v4l2_subdev *sd) +static int m9mo_make_CSV_rawdata_direct(struct v4l2_subdev *sd, int nkind) { - struct m9mo_state *state = to_state(sd); - /* standard values */ - u16 iso_std_values[] = { 10, 12, 16, 20, 25, 32, 40, 50, 64, 80, - 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, - 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000}; - /* quantization table */ - u16 iso_qtable[] = { 11, 14, 17, 22, 28, 35, 44, 56, 71, 89, - 112, 141, 178, 224, 282, 356, 449, 565, 712, 890, - 1122, 1414, 1782, 2245, 2828, 3564, 4490, 5657, 7127, 8909}; - int num, den, i, err; + struct file *fp; + mm_segment_t old_fs; + u8 *buf; + int val; + u32 unit, intram_unit = 0x1000; + int i, err, start, end; - /* exposure time */ - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, - M9MO_EXIF_EXPTIME_NUM, &num); - CHECK_ERR(err); - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, - M9MO_EXIF_EXPTIME_DEN, &den); - CHECK_ERR(err); - state->exif.exptime = (u32)num*1000/den; + old_fs = get_fs(); + set_fs(KERNEL_DS); - /* flash */ - err = m9mo_readw(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_FLASH, &num); - CHECK_ERR(err); - state->exif.flash = (u16)num; + fp = filp_open(M9MO_FACTORY_CSV_PATH, + O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR); + if (IS_ERR(fp)) { + cam_err("failed to open %s, err %ld\n", + M9MO_FACTORY_CSV_PATH, PTR_ERR(fp)); + err = -ENOENT; + goto file_out; + } - /* iso */ - err = m9mo_readw(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_ISO, &num); - CHECK_ERR(err); - for (i = 0; i < NELEMS(iso_qtable); i++) { - if (num <= iso_qtable[i]) { - state->exif.iso = iso_std_values[i]; - break; + buf = kmalloc(intram_unit, GFP_KERNEL); + if (!buf) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + if (V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL) { + cam_dbg("start, file path %s\n", M9MO_FACTORY_CSV_PATH); + + start = 0x69; + end = 0x8C; + unit = end-start + 1; + + for (i = start; i <= end; i++) { + err = m9mo_readb(sd, M9MO_CATEGORY_MON, i, &val); + CHECK_ERR(err); + + buf[i-start] = (u8)val; } } + vfs_write(fp, buf, unit, &fp->f_pos); - /* shutter speed */ - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_TV_NUM, &num); - CHECK_ERR(err); - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_TV_DEN, &den); - CHECK_ERR(err); - state->exif.tv = num*M9MO_DEF_APEX_DEN/den; +out: + kfree(buf); - /* brightness */ - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_BV_NUM, &num); - CHECK_ERR(err); - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_BV_DEN, &den); - CHECK_ERR(err); - state->exif.bv = num*M9MO_DEF_APEX_DEN/den; + if (!IS_ERR(fp)) + filp_close(fp, current->files); - /* exposure */ - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_EBV_NUM, &num); - CHECK_ERR(err); - err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_EBV_DEN, &den); - CHECK_ERR(err); - state->exif.ebv = num*M9MO_DEF_APEX_DEN/den; +file_out: + set_fs(old_fs); return err; } -static int m9mo_get_fd_eye_blink_result(struct v4l2_subdev *sd) +#ifdef FAST_CAPTURE +static int m9mo_set_fast_capture(struct v4l2_subdev *sd) { struct m9mo_state *state = to_state(sd); int err; - s32 val_no = 1, val_level = 0; + cam_info("E\n"); - /* EyeBlink error check FRAME No, Level */ - err = m9mo_readb(sd, M9MO_CATEGORY_FD, - M9MO_FD_BLINK_FRAMENO, &val_no); - CHECK_ERR(err); - if (val_no < 1 || val_no > 3) { - val_no = 1; - cam_warn("Read Error FD_BLINK_FRAMENO [0x%x]\n", val_no); + err = m9mo_set_mode(sd, M9MO_STILLCAP_MODE); + if (err < 0) { + cam_err("Mode change is failed to STILLCAP for fast capture\n"); + return err; + } else { + cam_info("Fast capture is issued. mode change start.\n"); } - err = m9mo_readb(sd, M9MO_CATEGORY_FD, - M9MO_FD_BLINK_LEVEL_1+val_no-1, &val_level); + return 0; +} +#endif + +static int m9mo_set_sensor_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err; + int set_shutter_mode; + cam_dbg("E, value %d\n", val); + + /* Do not set CATE_408 0x01,0x02 at mode change */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); CHECK_ERR(err); - if (val_level >= 0x05) - state->fd_eyeblink_cap = 1; + err = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + CHECK_ERR(err); + + if (val == SENSOR_MOVIE) + set_shutter_mode = 0; /* Rolling Shutter */ else - state->fd_eyeblink_cap = 0; - cam_dbg("blink no[%d] level[0x%x]\n", val_no, val_level); + set_shutter_mode = 1; /* Mechanical Shutter */ + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + M9MO_ADJST_SHUTTER_MODE, set_shutter_mode); + CHECK_ERR(err); - return err; + state->sensor_mode = val; + + cam_trace("X\n"); + return 0; } -static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num) +static int m9mo_set_flash_evc_step(struct v4l2_subdev *sd, int val) { - struct m9mo_state *state = to_state(sd); - int err, int_factor; - cam_trace("E\n"); + int err; - if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS) { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_PRV_SEL, frame_num); + cam_trace("E, value %d\n", val); - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; - } - } else if (state->running_capture_mode == RUNNING_MODE_BRACKET) { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_PRV_SEL, frame_num); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_STROBE_EVC, val); + CHECK_ERR(err); - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; - } - } else if (state->running_capture_mode == RUNNING_MODE_HDR) { - cam_warn("HDR have no PostView\n"); - return 0; - } else if (state->running_capture_mode == RUNNING_MODE_BLINK) { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_PRV_SEL, 0xFF); + cam_trace("X\n"); + return 0; +} - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; - } - } else { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_PRV_SEL, 0x01); - } - CHECK_ERR(err); +static int m9mo_set_flash(struct v4l2_subdev *sd, int val, int force) +{ + struct m9mo_state *state = to_state(sd); + int strobe_en = 0; + int err; + cam_dbg("E, value %d\n", val); - /* Set YUV out for Preview */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_YUVOUT_PREVIEW, 0x00); - CHECK_ERR(err); + if (!force) + state->flash_mode = val; - /* Set Preview Image size */ - if (FRM_RATIO(state->capture) == CAM_FRMRATIO_WVGA) { - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x0F); - CHECK_ERR(err); - } else if (FRM_RATIO(state->capture) == CAM_FRMRATIO_VGA) { - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x13); - CHECK_ERR(err); - } + /* movie flash mode should be set when recording is started */ + if (state->sensor_mode == SENSOR_MOVIE && !state->recording) + return 0; - /* Get Preview data */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_TRANSFER, 0x02); - CHECK_ERR(err); +retry: + switch (val) { + case FLASH_MODE_OFF: + strobe_en = 0; + break; - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", - int_factor); - return -ETIMEDOUT; - } + case FLASH_MODE_AUTO: + strobe_en = 0x02; + break; -/* - err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE, - &state->jpeg.main_size); - CHECK_ERR(err); + case FLASH_MODE_ON: + strobe_en = 0x01; + break; - err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE, - &state->jpeg.thumb_size); - CHECK_ERR(err); + case FLASH_MODE_RED_EYE: + strobe_en = 0x12; + break; - state->jpeg.main_offset = 0; - state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; - state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + case FLASH_MODE_FILL_IN: + strobe_en = 0x01; + break; - m9mo_get_exif(sd); -*/ - cam_trace("X\n"); - return err; -} + case FLASH_MODE_SLOW_SYNC: + strobe_en = 0x03; + break; -static int m9mo_start_YUV_capture(struct v4l2_subdev *sd, int frame_num) -{ - struct m9mo_state *state = to_state(sd); - int err, int_factor; - cam_trace("E\n"); + case FLASH_MODE_RED_EYE_FIX: + strobe_en = 0x02; + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_RED_EYE, 0x01); + CHECK_ERR(err); + break; - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_SEL, frame_num); - CHECK_ERR(err); + default: + cam_warn("invalid value, %d\n", val); + val = FLASH_MODE_OFF; + goto retry; + } - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; + if (val != FLASH_MODE_RED_EYE_FIX) { + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_RED_EYE, 0x00); + CHECK_ERR(err); } err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_YUVOUT_MAIN, 0x00); + M9MO_CAPPARM_STROBE_EN, strobe_en); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_MAIN_IMG_SIZE, state->capture->reg_val); - CHECK_ERR(err); - cam_trace("Select image size [ width %d, height : %d ]\n", - state->capture->width, state->capture->height); + cam_trace("X\n"); + return 0; +} - /* Get main YUV data */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_TRANSFER, 0x01); - CHECK_ERR(err); +static int m9mo_set_flash_batt_info(struct v4l2_subdev *sd, int val) +{ + int err; + int set_strobe_batt; - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", - int_factor); - return -ETIMEDOUT; - } + cam_trace("E, value %d\n", val); - err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE, - &state->jpeg.main_size); - CHECK_ERR(err); -/* - err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE, - &state->jpeg.thumb_size); - CHECK_ERR(err); + if (val) + set_strobe_batt = 1; + else + set_strobe_batt = 0; - state->jpeg.main_offset = 0; - state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; - state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_STROBE_BATT_INFO, set_strobe_batt); + CHECK_ERR(err); - m9mo_get_exif(sd); -*/ cam_trace("X\n"); - return err; + return 0; } -static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num) +static int m9mo_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct m9mo_state *state = to_state(sd); - int err, int_factor; - cam_trace("E\n"); - - if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS) { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_SEL, frame_num); - CHECK_ERR(err); + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, err, current_state; + u32 iso[] = {0x00, 0x01, 0x64, 0xC8, 0x190, 0x320, 0x640, 0xC80}; - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; - } - } else if (state->running_capture_mode == RUNNING_MODE_BRACKET) { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_SEL, frame_num); - CHECK_ERR(err); + if (state->scene_mode != SCENE_MODE_NONE) { + /* sensor will set internally */ + return 0; + } - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; - } - } else if (state->running_capture_mode == RUNNING_MODE_BLINK) { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_SEL, 0xFF); - CHECK_ERR(err); + cam_dbg("E, value %d\n", val); - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", - int_factor); - return -ETIMEDOUT; - } + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); - err = m9mo_get_fd_eye_blink_result(sd); - CHECK_ERR(err); - } else { - /* Select image number of frame */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_FRM_SEL, 0x01); - CHECK_ERR(err); + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; } - /* Set main image JPEG fime max size */ - err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_JPEG_SIZE_MAX, 0x00500000); - CHECK_ERR(err); + val -= qc.minimum; - /* Set main image JPEG fime min size */ - err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_JPEG_SIZE_MIN, 0x00100000); - CHECK_ERR(err); + switch (val) { + case 0: + state->iso = 0; + break; - /* Select main image format */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_YUVOUT_MAIN, 0x01); - CHECK_ERR(err); + case 1: + state->iso = 50; + break; -#if 0 - /* Select main image size */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_MAIN_IMG_SIZE, 0x31); - CHECK_ERR(err); -#endif + case 2: + state->iso = 100; + break; - /* Get main JPEG data */ - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, - M9MO_CAPCTRL_TRANSFER, 0x01); + case 3: + state->iso = 200; + break; - /* Clear Interrupt factor */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_CAPTURE)) { - cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", - int_factor); - return -ETIMEDOUT; - } + case 4: + state->iso = 400; + break; - err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE, - &state->jpeg.main_size); - CHECK_ERR(err); + case 5: + state->iso = 800; + break; -/* - err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE, - &state->jpeg.thumb_size); - CHECK_ERR(err); -*/ - state->jpeg.main_offset = 0; - state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; - state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + case 6: + state->iso = 1600; + break; - m9mo_get_exif(sd); + case 7: + state->iso = 3200; + break; - cam_trace("X\n"); - return err; -} + default: + break; + } -/*static int m9mo_set_hdr(struct v4l2_subdev *sd, int val) + err = m9mo_readb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, ¤t_state); + + /* ISO AUTO */ + if (val == 0) { + switch (state->mode) { + case MODE_PROGRAM: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x00); + CHECK_ERR(err); + break; + + case MODE_A: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x01); + CHECK_ERR(err); + break; + + case MODE_S: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x02); + CHECK_ERR(err); + break; + + default: + break; + } + } else { + switch (state->mode) { + case MODE_PROGRAM: + if (current_state != 0x04) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x04); + CHECK_ERR(err); + } + break; + + case MODE_A: + if (current_state != 0x05) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x05); + CHECK_ERR(err); + } + break; + + case MODE_S: + if (current_state != 0x06) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x06); + CHECK_ERR(err); + } + break; + + default: + break; + } + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_ISO_VALUE, iso[val]); + CHECK_ERR(err); + } + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_metering(struct v4l2_subdev *sd, int val) { - cam_trace("E val : %d\n", val); + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case METERING_CENTER: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_MODE, 0x03); + CHECK_ERR(err); + break; + case METERING_SPOT: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_MODE, 0x05); + CHECK_ERR(err); + break; + case METERING_MATRIX: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_MODE, 0x01); + CHECK_ERR(err); + break; + default: + cam_warn("invalid value, %d\n", val); + val = METERING_CENTER; + goto retry; + } + cam_trace("X\n"); return 0; -}*/ +} + +static int m9mo_set_exposure(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, err; + /* + -2.0, -1.7, -1.3, -1.0 -0.7 -0.3 + 0 + +0.3 +0.7 +1.0 +1.3 +1.7 +2.0 + */ + u32 exposure[] = {0x0A, 0x0D, 0x11, 0x14, 0x17, 0x1B, + 0x1E, + 0x21, 0x25, 0x28, 0x2B, 0x2F, 0x32}; + cam_dbg("E, value %d\n", val); + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); -static int m9mo_set_facedetect(struct v4l2_subdev *sd, int val) + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; + } + + val -= qc.minimum; + + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_INDEX, exposure[val]); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_whitebalance(struct v4l2_subdev *sd, int val) { - int err; struct m9mo_state *state = to_state(sd); - cam_trace("E val : %d\n", val); + int err; + cam_dbg("E, value %d\n", val); - state->facedetect_mode = val; +retry: + switch (val) { + case WHITE_BALANCE_AUTO: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x01); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x01); + CHECK_ERR(err); + break; - switch (state->facedetect_mode) { - case FACE_DETECTION_NORMAL: - cam_dbg("~~~~~~ face detect on ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_SIZE, 0x04); + case WHITE_BALANCE_SUNNY: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_MAX, 0x07); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x11); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x04); CHECK_ERR(err); + break; -#if 0 /* AF */ - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_SCAN_RANGE, 0x00); + case WHITE_BALANCE_CLOUDY: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_ADJ_TEMP_VALUE, 0x23); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_ALGORITHM, 0x00); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x05); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, - M9MO_SYS_INT_EN, M9MO_INT_AF); + break; + + case WHITE_BALANCE_TUNGSTEN: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - M9MO_LENS_AF_START, 0x01); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x01); CHECK_ERR(err); -#endif break; - case FACE_DETECTION_SMILE_SHOT: - cam_dbg("~~~~~~ fd smile shot ~~~~~~ val : %d\n", val); + case WHITE_BALANCE_FLUORESCENT: + case WHITE_BALANCE_FLUORESCENT_H: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x02); + CHECK_ERR(err); break; - case FACE_DETECTION_BLINK: - cam_dbg("~~~~~~ fd eye blink ~~~~~~ val : %d\n", val); + case WHITE_BALANCE_FLUORESCENT_L: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x03); + CHECK_ERR(err); break; - case FACE_DETECTION_OFF: - default: - cam_dbg("~~~~~~ face detect off ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x00); + case WHITE_BALANCE_K: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x0A); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_INCANDESCENT: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x01); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_PROHIBITION: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x00); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_HORIZON: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x07); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_LEDLIGHT: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x09); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_CUSTOM: + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x08); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x02); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_WB, + M9MO_WB_SET_CUSTOM_RG, state->wb_custom_rg); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_WB, + M9MO_WB_SET_CUSTOM_BG, state->wb_custom_bg); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x01); CHECK_ERR(err); break; + + default: + cam_warn("invalid value, %d\n", val); + val = WHITE_BALANCE_AUTO; + goto retry; } + cam_trace("X\n"); return 0; } +static int m9mo_set_sharpness(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, err; + u32 sharpness[] = {0x01, 0x02, 0x03, 0x04, 0x05}; + cam_dbg("E, value %d\n", val); + + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); + + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_EDGE_CTRL, sharpness[val]); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_contrast(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, err; + u32 contrast[] = {0x01, 0x02, 0x03, 0x04, 0x05}; + cam_dbg("E, value %d\n", val); + + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); + + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_TONE_CTRL, contrast[val]); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_saturation(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, err; + u32 saturation[] = {0x01, 0x02, 0x03, 0x04, 0x05}; + cam_dbg("E, value %d\n", val); + + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); + + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_CHROMA_LVL, saturation[val]); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_scene_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + struct v4l2_control ctrl; + int evp, sharpness, saturation; + int err; + cam_dbg("E, value %d\n", val); + + sharpness = SHARPNESS_DEFAULT; + saturation = CONTRAST_DEFAULT; + +retry: + switch (val) { + case SCENE_MODE_NONE: + evp = 0x00; + break; + + case SCENE_MODE_PORTRAIT: + evp = 0x01; + sharpness = SHARPNESS_MINUS_1; + break; + + case SCENE_MODE_LANDSCAPE: + evp = 0x02; + sharpness = SHARPNESS_PLUS_1; + saturation = SATURATION_PLUS_1; + break; + + case SCENE_MODE_SPORTS: + evp = 0x03; + break; + + case SCENE_MODE_PARTY_INDOOR: + evp = 0x04; + saturation = SATURATION_PLUS_1; + break; + + case SCENE_MODE_BEACH_SNOW: + evp = 0x05; + saturation = SATURATION_PLUS_1; + break; + + case SCENE_MODE_SUNSET: + evp = 0x06; + break; + + case SCENE_MODE_DUSK_DAWN: + evp = 0x07; + break; + + case SCENE_MODE_FALL_COLOR: + evp = 0x08; + saturation = SATURATION_PLUS_2; + break; + + case SCENE_MODE_NIGHTSHOT: + evp = 0x09; + break; + + case SCENE_MODE_BACK_LIGHT: + evp = 0x0A; + break; + + case SCENE_MODE_FIREWORKS: + evp = 0x0B; + break; + + case SCENE_MODE_TEXT: + evp = 0x0C; + sharpness = SHARPNESS_PLUS_2; + break; + + case SCENE_MODE_CANDLE_LIGHT: + evp = 0x0D; + break; + + default: + cam_warn("invalid value, %d\n", val); + val = SCENE_MODE_NONE; + goto retry; + } + + /* EV-P */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_MON, evp); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_CAP, evp); + CHECK_ERR(err); + + /* Chroma Saturation */ + ctrl.id = V4L2_CID_CAMERA_SATURATION; + ctrl.value = saturation; + m9mo_set_saturation(sd, &ctrl); + + /* Sharpness */ + ctrl.id = V4L2_CID_CAMERA_SHARPNESS; + ctrl.value = sharpness; + m9mo_set_sharpness(sd, &ctrl); + + /* Emotional Color */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_MCC_MODE, val == SCENE_MODE_NONE ? 0x01 : 0x00); + CHECK_ERR(err); + + state->scene_mode = val; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_effect_color(struct v4l2_subdev *sd, int val) +{ + int cb = 0, cr = 0; + int err; + + switch (val) { + case IMAGE_EFFECT_SEPIA: + cb = 0xD8; + cr = 0x18; + break; + + case IMAGE_EFFECT_BNW: + cb = 0x00; + cr = 0x00; + break; + + case IMAGE_EFFECT_ANTIQUE: + cb = 0xD0; + cr = 0x30; + break; + + default: + return 0; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXB, cb); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXR, cr); + CHECK_ERR(err); + + return 0; +} + +static int m9mo_set_effect_point(struct v4l2_subdev *sd, int val) +{ + int point = 0; + int err; + + switch (val) { + case IMAGE_EFFECT_POINT_BLUE: + point = 0; + break; + + case IMAGE_EFFECT_POINT_RED: + point = 1; + break; + + case IMAGE_EFFECT_POINT_YELLOW: + point = 2; + break; + + default: + return 0; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_POINT_COLOR, point); + CHECK_ERR(err); + + return 0; +} + +static int m9mo_set_effect(struct v4l2_subdev *sd, int val) +{ + int set_effect = 0; + int err; + struct m9mo_state *state = to_state(sd); + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case IMAGE_EFFECT_NONE: + set_effect = 0; + break; + + case IMAGE_EFFECT_NEGATIVE: + set_effect = 2; + break; + + case IMAGE_EFFECT_BNW: + case IMAGE_EFFECT_SEPIA: + case IMAGE_EFFECT_ANTIQUE: + err = m9mo_set_effect_color(sd, val); + CHECK_ERR(err); + set_effect = 1; + break; + + case IMAGE_EFFECT_POINT_BLUE: + case IMAGE_EFFECT_POINT_RED: + case IMAGE_EFFECT_POINT_YELLOW: + err = m9mo_set_effect_point(sd, val); + CHECK_ERR(err); + set_effect = 3; + break; + + case IMAGE_EFFECT_VINTAGE_WARM: + set_effect = 4; + break; + + case IMAGE_EFFECT_VINTAGE_COLD: + set_effect = 5; + break; + + case IMAGE_EFFECT_WASHED: + set_effect = 6; + break; + + default: + cam_warn("invalid value, %d\n", val); + val = IMAGE_EFFECT_NONE; + goto retry; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, set_effect); + CHECK_ERR(err); + + state->color_effect = set_effect; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_wdr(struct v4l2_subdev *sd, int val) +{ + int wdr, err; + + cam_dbg("%s\n", val ? "on" : "off"); + + wdr = (val == 1 ? 0x01 : 0x00); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_WDR_EN, wdr); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_antishake(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int ahs, err; + + if (state->scene_mode != SCENE_MODE_NONE) { + cam_warn("Should not be set with scene mode"); + return 0; + } + + cam_dbg("%s\n", val ? "on" : "off"); + + ahs = (val == 1 ? 0x0E : 0x00); + + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_MON, ahs); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_EP_MODE_CAP, ahs); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_face_beauty(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err; + + cam_dbg("%s\n", val ? "on" : "off"); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_AFB_CAP_EN, val ? 0x01 : 0x00); + CHECK_ERR(err); + + state->face_beauty = val; + + cam_trace("X\n"); + return 0; +} + +static unsigned int m9mo_set_cal_rect_pos(struct v4l2_subdev *sd, + unsigned int pos_val) +{ + struct m9mo_state *state = to_state(sd); + unsigned int set_val; + + if (pos_val <= 40) + set_val = 40; + else if (pos_val > (state->preview->width - 40)) + set_val = state->preview->width - 40; + else + set_val = pos_val; + + return set_val; +} + +static int m9mo_set_object_tracking(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + unsigned int set_x, set_y; + + err = m9mo_writeb(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_CTL, 0x10); + CHECK_ERR(err); + + cam_trace("E val : %d\n", val); + + if (val == OT_START) { + set_x = m9mo_set_cal_rect_pos(sd, state->focus.pos_x); + set_y = m9mo_set_cal_rect_pos(sd, state->focus.pos_y); + + cam_dbg("idx[%d] w[%d] h[%d]", state->preview->index, + state->preview->width, state->preview->height); + cam_dbg("pos_x[%d] pos_y[%d] x[%d] y[%d]", + state->focus.pos_x, state->focus.pos_y, + set_x, set_y); + + err = m9mo_writeb(sd, M9MO_CATEGORY_OT, + M9MO_OT_FRAME_WIDTH, 0x02); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_OT, + M9MO_OT_X_START_LOCATION, + set_x - 40); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_OT, + M9MO_OT_Y_START_LOCATION, + set_y - 40); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_OT, + M9MO_OT_X_END_LOCATION, + set_x + 40); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_OT, + M9MO_OT_Y_END_LOCATION, + set_y + 40); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_OT, + M9MO_OT_TRACKING_CTL, 0x11); + CHECK_ERR(err); + } + + return 0; +} + +static int m9mo_set_image_stabilizer_OIS(struct v4l2_subdev *sd, int val) +{ + int err, int_factor, set_ois, int_en; + int wait_int_ois = 0; + + cam_trace("E: mode %d\n", val); + +retry: + switch (val) { + case V4L2_IS_OIS_NONE: + cam_warn("OIS_NONE and OIS End"); + return 0; + + case V4L2_IS_OIS_MOVIE: + set_ois = 0x01; + wait_int_ois = 1; + break; + + case V4L2_IS_OIS_STILL: + set_ois = 0x02; + wait_int_ois = 0; + break; + + case V4L2_IS_OIS_MULTI: + set_ois = 0x03; + wait_int_ois = 0; + break; + + case V4L2_IS_OIS_VSS: + set_ois = 0x04; + wait_int_ois = 1; + break; + + default: + cam_warn("invalid value, %d", val); + val = V4L2_IS_OIS_STILL; + goto retry; + } + + if (wait_int_ois) { + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_en); + CHECK_ERR(err); + + /* enable OIS_SET interrupt */ + int_en |= M9MO_INT_OIS_SET; + + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_en); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x18, set_ois); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_OIS_SET)) { + cam_err("M9MO_INT_OIS_SET isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + CHECK_ERR(err); + + /* enable OIS_SET interrupt */ + int_en &= ~M9MO_INT_OIS_SET; + + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_en); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x18, set_ois); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_af_sensor_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + u32 cancel; + int err; + int af_mode, af_window, af_range; + int range_status, mode_status, window_status; + + cancel = val & FOCUS_MODE_DEFAULT; + val &= 0xFF; + af_range = state->focus_range; + + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case FOCUS_MODE_AUTO: + af_mode = 0x00; + af_window = state->focus_area_mode; + break; + + case FOCUS_MODE_MULTI: + af_mode = 0x00; + af_window = 0x01; + break; + + case FOCUS_MODE_CONTINOUS: + af_mode = 0x01; + af_range = 0x02; + af_window = 0x00; + break; + + case FOCUS_MODE_FACEDETECT: + af_mode = 0x00; + af_window = 0x02; + af_range = 0x02; + break; + + case FOCUS_MODE_TOUCH: + af_mode = 0x00; + af_window = 0x02; + break; + + case FOCUS_MODE_MACRO: + af_mode = 0x00; + af_range = 0x01; + af_window = state->focus_area_mode; + break; + + case FOCUS_MODE_MANUAL: + af_mode = 0x02; + af_window = state->focus_area_mode; + af_range = 0x02; + cancel = 0; + break; + + case FOCUS_MODE_OBJECT_TRACKING: + af_mode = 0x00; + af_window = 0x02; + af_range = 0x02; + break; + + default: + cam_warn("invalid value, %d", val); + val = FOCUS_MODE_AUTO; + goto retry; + } + + if (cancel && state->focus.lock) + m9mo_set_lock(sd, 0); + + state->focus.mode = val; + + /* Set AF Mode */ + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_MODE, &mode_status); + + if (mode_status != af_mode) { + if (state->focus.mode != FOCUS_MODE_TOUCH) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_MODE, af_mode); + CHECK_ERR(err); + } + } + + /* fix range to auto-macro when FD on */ + if (state->facedetect_mode == FACE_DETECTION_NORMAL) + af_range = 0x02; + + /* fix range to macro when CLOSE_UP mode */ + if (state->mode == MODE_CLOSE_UP) + af_range = 0x01; + + /* fix window to center */ + if ((state->focus.mode == 0 || state->focus.mode == 1) + && state->focus_area_mode == 2) + af_window = 0x00; + + /* Set AF Scan Range */ + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_SCAN_RANGE, &range_status); + + if (range_status != af_range) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_SCAN_RANGE, af_range); + CHECK_ERR(err); + } + + /* Set Zone REQ */ + if (range_status != af_range) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_INITIAL, 0x04); + CHECK_ERR(err); + } + + /* Set AF Window Mode */ + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_WINDOW_MODE, &window_status); + + if (window_status != af_window) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_WINDOW_MODE, af_window); + CHECK_ERR(err); + } + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_af(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct m9mo_platform_data *pdata = client->dev.platform_data; + int status, err = 0; + + cam_info("%s, mode %d\n", val ? "start" : "stop", state->focus.mode); + + state->focus.start = val; + + if (val == 1) { + /* AF LED regulator on */ + pdata->af_led_power(1); + + if (state->facedetect_mode == FACE_DETECTION_NORMAL + && state->mode == MODE_SMART_AUTO) { + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_CTL, 0x11); + CHECK_ERR(err); + } + + m9mo_set_af_sensor_mode(sd, state->focus.mode); + + if (state->focus.mode != FOCUS_MODE_CONTINOUS) { + m9mo_set_lock(sd, 1); + + /* Single AF Start */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_START_STOP, 0x00); + CHECK_ERR(err); + } + } else { + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_RESULT, &status); + CHECK_ERR(err); + + if (state->facedetect_mode == FACE_DETECTION_NORMAL + && state->mode == MODE_SMART_AUTO) { + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_CTL, 0x01); + CHECK_ERR(err); + } + + if (state->focus.lock && status != 0x1000) { + if (state->focus.mode != FOCUS_MODE_CONTINOUS) + m9mo_set_lock(sd, 0); + } + /* AF LED regulator off */ + pdata->af_led_power(0); + } + + cam_dbg("X\n"); + return err; +} + +static int m9mo_set_af_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + + state->focus.mode = val; + + cam_trace("X val : %d\n", val); + return 0; +} + +static int m9mo_set_focus_range(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err, range_status; + + /* Set AF Scan Range */ + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_SCAN_RANGE, &range_status); + + if (range_status != val) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_SCAN_RANGE, val); + CHECK_ERR(err); + + /* Set Zone REQ */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_INITIAL, 0x04); + CHECK_ERR(err); + } + + state->focus_range = val; + + cam_trace("X val : %d\n", val); + return 0; +} + +static int m9mo_set_focus_area_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + + state->focus_area_mode = val; + + cam_trace("X val : %d\n", val); + return 0; +} + +static int m9mo_set_touch_auto_focus(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + cam_info("%s\n", val ? "start" : "stop"); + + state->focus.touch = val; + + if (val) { + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_TOUCH_POSX, state->focus.pos_x); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_TOUCH_POSY, state->focus.pos_y); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return err; +} + +static int m9mo_set_AF_LED(struct v4l2_subdev *sd, int val) +{ + int err; + int set_AF_LED_On; + + cam_trace("E, value %d\n", val); + + if (val) + set_AF_LED_On = 1; + else + set_AF_LED_On = 0; + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_LED, set_AF_LED_On); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_zoom(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, err; + int opti_val, digi_val; + int opti_max = 15; + int optical_zoom_val[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15}; + int zoom_val[] = { 0x01, + 0x0E, 0x17, 0x1D, 0x22, 0x26, + 0x29, 0x2C, 0x2E, 0x30, 0x32, + 0x34, 0x35, 0x36, 0x37, 0x38 }; + cam_trace("E, value %d\n", val); + + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); + + if (val < qc.minimum) { + cam_warn("invalied min value, %d\n", val); + val = qc.default_value; + } + + if (val > qc.maximum) { + cam_warn("invalied max value, %d\n", val); + val = qc.maximum; + } + + if (val <= opti_max) { + opti_val = val; + digi_val = 0; + } else { + opti_val = opti_max; + digi_val = val - opti_max; + } + + if (state->recording) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_SPEED, 0x00); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_SPEED, 0x01); + CHECK_ERR(err); + } + + /* AF CANCEL */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_START_STOP, 0x05); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_ZOOM_LEVEL, optical_zoom_val[opti_val]); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_ZOOM, zoom_val[digi_val]); + CHECK_ERR(err); + + state->zoom = val; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_zoom_ctrl(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + + int err; + int zoom_ctrl, zoom_speed; + int read_ctrl, read_speed; + + cam_trace("E, value %d\n", val); + + switch (val) { + case V4L2_OPTICAL_ZOOM_TELE_START: + zoom_ctrl = 0; + zoom_speed = 1; + break; + + case V4L2_OPTICAL_ZOOM_WIDE_START: + zoom_ctrl = 1; + zoom_speed = 1; + break; + + case V4L2_OPTICAL_ZOOM_SLOW_TELE_START: + zoom_ctrl = 0; + zoom_speed = 0; + break; + + case V4L2_OPTICAL_ZOOM_SLOW_WIDE_START: + zoom_ctrl = 1; + zoom_speed = 0; + break; + + case V4L2_OPTICAL_ZOOM_STOP: + zoom_ctrl = 2; + zoom_speed = 0x0F; + break; + + default: + cam_warn("invalid value, %d", val); + return 0; + } + + if (state->recording) + zoom_speed = 0; + + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_SPEED, &read_speed); + CHECK_ERR(err); + + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_ZOOM_CTRL, &read_ctrl); + CHECK_ERR(err); + + if (read_speed != zoom_speed && val != V4L2_OPTICAL_ZOOM_STOP) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_ZOOM_SPEED, zoom_speed); + CHECK_ERR(err); + } + + if (read_ctrl != zoom_ctrl) { + if (val != V4L2_OPTICAL_ZOOM_STOP) { + /* AF CANCEL */ + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_START_STOP, 0x05); + CHECK_ERR(err); + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + M9MO_LENS_AF_ZOOM_CTRL, zoom_ctrl); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_smart_zoom(struct v4l2_subdev *sd, int val) +{ + int err; + int smart_zoom; + struct m9mo_state *state = to_state(sd); + + cam_trace("E, value %d\n", val); + + if (val) + smart_zoom = 0x5C; + else + smart_zoom = 0; + + /* Off:0x00, On: 0x01 ~ 0x5C */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_HR_ZOOM, smart_zoom); + CHECK_ERR(err); + + state->smart_zoom_mode = val; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_jpeg_quality(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct v4l2_queryctrl qc = {0,}; + int val = ctrl->value, ratio, err; + cam_dbg("E, value %d\n", val); + + qc.id = ctrl->id; + m9mo_queryctrl(sd, &qc); + + if (val < qc.minimum || val > qc.maximum) { + cam_warn("invalied value, %d\n", val); + val = qc.default_value; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_JPEG_RATIO, 0x62); + CHECK_ERR(err); + + /* m9mo */ + if (val <= 65) /* Normal */ + ratio = 0x14; + else if (val <= 75) /* Fine */ + ratio = 0x09; + else /* Superfine */ + ratio = 0x02; + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_JPEG_RATIO_OFS, ratio); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_get_exif(struct v4l2_subdev *sd) +{ + struct m9mo_state *state = to_state(sd); +#if 0 /* legacy */ + /* standard values */ + u16 iso_std_values[] = { 10, 12, 16, 20, 25, 32, 40, 50, 64, 80, + 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, + 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000}; + /* quantization table */ + u16 iso_qtable[] = { 11, 14, 17, 22, 28, 35, 44, 56, 71, 89, + 112, 141, 178, 224, 282, 356, 449, 565, 712, 890, + 1122, 1414, 1782, 2245, 2828, 3564, 4490, 5657, 7127, 8909}; +#endif + /* standard values : M9MO */ + u16 iso_std_values[] = { + 64, 80, 100, 125, 160, + 200, 250, 320, 400, 500, + 640, 800, 1000, 1250, 1600, + 2000, 2500, 3200, 4000, 5000, + 6400 + }; + /* quantization table */ + u16 iso_qtable[] = { + 72, 89, 112, 141, 179, + 224, 283, 358, 447, 566, + 716, 894, 1118, 1414, 1789, + 2236, 2828, 3578, 4472, 5657, + 7155 + }; + + s16 ss_std_values[] = { + -400, -358, -300, -258, -200, + -158, -100, -58, 0, 51, + 100, 158, 200, 258, 300, + 332, 391, 432, 491, 549, + 591, 649, 697, 749, 797, + 845, 897, 955, 997, 1055, + }; + + s16 ss_qtable[] = { + -375, -325, -275, -225, -175, + -125, -75, -25, 25, 75, + 125, 175, 225, 275, 325, + 375, 425, 475, 525, 575, + 625, 675, 725, 775, 825, + 875, 925, 975, 1025, 1075, + }; + + int num, den, i, err; + + cam_trace("E\n"); + + /* exposure time */ + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, + M9MO_EXIF_EXPTIME_NUM, &num); + CHECK_ERR(err); + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, + M9MO_EXIF_EXPTIME_DEN, &den); + CHECK_ERR(err); + if (den) + state->exif.exptime = (u32)num*1000/den; + else + state->exif.exptime = 0; + + /* flash */ + err = m9mo_readw(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_FLASH, &num); + CHECK_ERR(err); + state->exif.flash = (u16)num; + + /* iso */ + err = m9mo_readw(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_ISO, &num); + CHECK_ERR(err); + for (i = 0; i < NELEMS(iso_qtable); i++) { + if (num <= iso_qtable[i]) { + state->exif.iso = iso_std_values[i]; + break; + } + } + if (i == NELEMS(iso_qtable)) + state->exif.iso = 8000; + + cam_info("%s: real iso = %d, qtable_iso = %d, stored iso = %d\n", + __func__, num, iso_qtable[i], state->exif.iso); + + /* shutter speed */ + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_TV_NUM, &num); + CHECK_ERR(err); + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_TV_DEN, &den); + CHECK_ERR(err); +#if 0 + if (den) + state->exif.tv = num*M9MO_DEF_APEX_DEN/den; + else + state->exif.tv = 0; +#endif + + if (den) { + for (i = 0; i < NELEMS(ss_qtable); i++) { + if (num*M9MO_DEF_APEX_DEN/den <= ss_qtable[i]) { + state->exif.tv = ss_std_values[i]; + break; + } + } + if (i == NELEMS(ss_qtable)) + state->exif.tv = 1097; + cam_info("%s: real TV = %d, stored TV = %d\n", __func__, + num*M9MO_DEF_APEX_DEN/den, state->exif.tv); + } else + state->exif.tv = 0; + + /* brightness */ + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_BV_NUM, &num); + CHECK_ERR(err); + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_BV_DEN, &den); + CHECK_ERR(err); + if (den) + state->exif.bv = num*M9MO_DEF_APEX_DEN/den; + else + state->exif.bv = 0; + + /* exposure bias value */ + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_EBV_NUM, &num); + CHECK_ERR(err); + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_EBV_DEN, &den); + CHECK_ERR(err); + if (den) + state->exif.ebv = num*M9MO_DEF_APEX_DEN/den; + else + state->exif.ebv = 0; + + /* Aperture */ + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_AV_NUM, &num); + CHECK_ERR(err); + err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_AV_DEN, &den); + CHECK_ERR(err); + if (den) + state->exif.av = num*M9MO_DEF_APEX_DEN/den; + else + state->exif.av = 0; + cam_info("%s: AV num = %d, AV den = %d\n", __func__, num, den); + + /* Focal length */ + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, M9MO_EXIF_FL, &num); + CHECK_ERR(err); + state->exif.focal_length = num * M9MO_DEF_APEX_DEN; + cam_info("%s: FL = %d\n", __func__, num); + + /* Focal length 35m */ + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, M9MO_EXIF_FL_35, &num); + CHECK_ERR(err); + state->exif.focal_35mm_length = num * M9MO_DEF_APEX_DEN; + cam_info("%s: FL_35 = %d\n", __func__, num); + + cam_trace("X\n"); + + return err; +} + +static int m9mo_get_fd_eye_blink_result(struct v4l2_subdev *sd) +{ + struct m9mo_state *state = to_state(sd); + int err; + s32 val_no = 1, val_level = 0; + + /* EyeBlink error check FRAME No, Level */ + err = m9mo_readb(sd, M9MO_CATEGORY_FD, + M9MO_FD_BLINK_FRAMENO, &val_no); + CHECK_ERR(err); + if (val_no < 1 || val_no > 3) { + val_no = 1; + cam_warn("Read Error FD_BLINK_FRAMENO [0x%x]\n", val_no); + } + err = m9mo_readb(sd, M9MO_CATEGORY_FD, + M9MO_FD_BLINK_LEVEL_1+val_no-1, &val_level); + CHECK_ERR(err); + + if (val_level >= 0x05) + state->fd_eyeblink_cap = 1; + else + state->fd_eyeblink_cap = 0; + cam_dbg("blink no[%d] level[0x%x]\n", val_no, val_level); + + return err; +} + +static int m9mo_get_red_eye_fix_result(struct v4l2_subdev *sd) +{ + struct m9mo_state *state = to_state(sd); + int err; + s32 red_eye_status; + + if (state->flash_mode != FLASH_MODE_RED_EYE_FIX) + return 0; + + err = m9mo_readb(sd, M9MO_CATEGORY_FD, + M9MO_FD_RED_DET_STATUS, &red_eye_status); + CHECK_ERR(err); + + state->fd_red_eye_status = red_eye_status; + + cam_dbg("red eye status [0x%x]\n", red_eye_status); + + return err; +} + +static int m9mo_start_dual_postview(struct v4l2_subdev *sd, int frame_num) +{ +#if 0 + struct m9mo_state *state = to_state(sd); +#endif + int err, int_factor; + cam_trace("E : %d frame\n", frame_num); + + /* Select image number of frame Preview image */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_SEL_FRAME_VIDEO_SNAP, frame_num); + CHECK_ERR(err); + + /* Select main image format */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_PREVIEW, 0x00); + CHECK_ERR(err); + +#if 0 + /* Select preview image size */ +#if 0 + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x08); + CHECK_ERR(err); +#else + if (FRM_RATIO(state->preview) == CAM_FRMRATIO_VGA) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x08); + CHECK_ERR(err); + } else if (FRM_RATIO(state->preview) == CAM_FRMRATIO_HD) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x0F); + CHECK_ERR(err); + } +#endif +#endif + + /* Get Video Snap Shot data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_VIDEO_SNAP_IMG_TRANSFER_START, 0x02); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_FRAME_SYNC)) { + cam_err("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor); + return -ETIMEDOUT; + } + + cam_trace("X\n"); + return err; +} + +static int m9mo_start_dual_capture(struct v4l2_subdev *sd, int frame_num) +{ + struct m9mo_state *state = to_state(sd); + int err, int_factor; + cam_trace("E : %d frame\n", frame_num); + + /* Select image number of frame For Video Snap Shot image */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_SEL_FRAME_VIDEO_SNAP, frame_num); + CHECK_ERR(err); + + /* Select main image format */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x01); + CHECK_ERR(err); + + /* Select main image size - 4M */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_MAIN_IMG_SIZE, 0x1E); + CHECK_ERR(err); + + /* Get Video Snap Shot data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_VIDEO_SNAP_IMG_TRANSFER_START, 0x01); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_FRAME_SYNC)) { + cam_err("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor); + return -ETIMEDOUT; + } + + /* Get main image JPEG size */ + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_IMG_SIZE, &state->jpeg.main_size); + CHECK_ERR(err); + cam_trace("~~~~~~ main_size : 0x%x ~~~~~~\n", state->jpeg.main_size); +#if 1 + state->jpeg.main_offset = 0; + state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; + state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + + /* Read Exif information */ + m9mo_get_exif(sd); +#endif + + if (frame_num == state->dual_capture_frame) + state->dual_capture_start = 0; + + cam_trace("X\n"); + return err; +} + +static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num) +{ + struct m9mo_state *state = to_state(sd); + int err, int_factor; + cam_trace("E : %d frame\n", frame_num); + + if (state->dual_capture_start) + return m9mo_start_dual_postview(sd, frame_num); + + if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS + || state->running_capture_mode == RUNNING_MODE_BEST) { + + cam_dbg("m9mo_start_postview_capture (%d)\n", frame_num); + + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_PRV_SEL, frame_num); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } else if (state->running_capture_mode == RUNNING_MODE_AE_BRACKET + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT) { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_PRV_SEL, frame_num); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } else if (state->running_capture_mode == RUNNING_MODE_WB_BRACKET) { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_PRV_SEL, frame_num); + } else if (state->running_capture_mode == RUNNING_MODE_HDR) { + cam_warn("HDR have no PostView\n"); + return 0; + } else if (state->running_capture_mode == RUNNING_MODE_BLINK) { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_PRV_SEL, 0xFF); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } else if (state->running_capture_mode == RUNNING_MODE_BURST) { + int i; + + /* Get Preview data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_TRANSFER, 0x02); + CHECK_ERR(err); + + for (i = 0; i < 3; i++) { /*wait M9MO_INT_FRAME_SYNC*/ + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (int_factor & (M9MO_INT_CAPTURE|M9MO_INT_SOUND)) { + cam_trace("----skip interrupt=%x", int_factor); + continue; + } + + if (!(int_factor & M9MO_INT_FRAME_SYNC)) { + cam_warn("M9MO_INT_FRAME_SYNC isn't issued on transfer, %#x\n", + int_factor); + return -ETIMEDOUT; + } + break; + } + } else { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_PRV_SEL, 0x01); + } + CHECK_ERR(err); + + if (state->running_capture_mode != RUNNING_MODE_BURST) { + /* Set YUV out for Preview */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_PREVIEW, 0x00); + CHECK_ERR(err); + +#if 0 + /* Set Preview(Postview) Image size */ + if (FRM_RATIO(state->capture) == CAM_FRMRATIO_HD) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x0F); + CHECK_ERR(err); + } else if (FRM_RATIO(state->capture) == CAM_FRMRATIO_D1) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x14); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x13); + CHECK_ERR(err); + } +#endif + + /* Get Preview data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_TRANSFER, 0x02); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + +/* + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE, + &state->jpeg.main_size); + CHECK_ERR(err); + + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE, + &state->jpeg.thumb_size); + CHECK_ERR(err); + + state->jpeg.main_offset = 0; + state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; + state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + + m9mo_get_exif(sd); +*/ + cam_trace("X\n"); + return err; +} + +static int m9mo_start_YUV_capture(struct v4l2_subdev *sd, int frame_num) +{ + struct m9mo_state *state = to_state(sd); + int err, int_factor; + cam_trace("E : %d frame\n", frame_num); + + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, frame_num); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x00); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_MAIN_IMG_SIZE, state->capture->reg_val); + CHECK_ERR(err); + if (state->smart_zoom_mode) + m9mo_set_smart_zoom(sd, state->smart_zoom_mode); + cam_trace("Select image size [ w=%d, h=%d ]\n", + state->capture->width, state->capture->height); + + /* Get main YUV data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_TRANSFER, 0x01); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE, + &state->jpeg.main_size); + CHECK_ERR(err); +/* + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE, + &state->jpeg.thumb_size); + CHECK_ERR(err); + + state->jpeg.main_offset = 0; + state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; + state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + + m9mo_get_exif(sd); +*/ + cam_trace("X\n"); + return err; +} + +static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num) +{ + struct m9mo_state *state = to_state(sd); + int err, int_factor; + cam_trace("E : %d frame\n", frame_num); + + if (state->dual_capture_start) + return m9mo_start_dual_capture(sd, frame_num); + + if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS + || state->running_capture_mode == RUNNING_MODE_BEST) { + + cam_dbg("m9mo_start_capture() num=%d\n", frame_num); + + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, frame_num); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } else if (state->running_capture_mode == RUNNING_MODE_AE_BRACKET + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT) { + + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, frame_num); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } else if (state->running_capture_mode == RUNNING_MODE_WB_BRACKET) { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, frame_num); + CHECK_ERR(err); + } else if (state->running_capture_mode == RUNNING_MODE_BLINK) { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, 0xFF); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + err = m9mo_get_fd_eye_blink_result(sd); + CHECK_ERR(err); + } else if (state->running_capture_mode == RUNNING_MODE_RAW) { + /* Select Main Image Format */ + if (frame_num == 0) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x05); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x01); + } + CHECK_ERR(err); + + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, 0x01); + CHECK_ERR(err); + + if (frame_num == 1) { + /* Set Size */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_MAIN_IMG_SIZE, 0x33); + CHECK_ERR(err); + } + } else if (state->running_capture_mode == RUNNING_MODE_BURST) { + err = 0; + + } else { + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_SEL, 0x01); + CHECK_ERR(err); + } + + m9mo_get_red_eye_fix_result(sd); + +#if 0 + /* Set main image JPEG fime max size */ + err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_JPEG_SIZE_MAX, 0x01000000); + CHECK_ERR(err); + + /* Set main image JPEG fime min size */ + err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_JPEG_SIZE_MIN, 0x00100000); + CHECK_ERR(err); +#endif + if (state->running_capture_mode == RUNNING_MODE_LOWLIGHT) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x0); + CHECK_ERR(err); + } else { + if (state->running_capture_mode != RUNNING_MODE_RAW + && state->running_capture_mode != RUNNING_MODE_BURST) { + /* Select main image format */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x01); + CHECK_ERR(err); + } + } + + /* Get main JPEG data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_TRANSFER, 0x01); + + if (state->running_capture_mode == RUNNING_MODE_BURST) { + int i; + for (i = 0; i < 3; i++) { /*wait M9MO_INT_CAPTURE*/ + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (int_factor & (M9MO_INT_FRAME_SYNC|M9MO_INT_SOUND)) { + cam_trace("----skip interrupt=%x", int_factor); + continue; + } + + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", + int_factor); + return -ETIMEDOUT; + } + break; + } + } else { + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE, + &state->jpeg.main_size); + CHECK_ERR(err); + cam_dbg(" ==> jpeg size=%d\n", state->jpeg.main_size); + + state->jpeg.main_offset = 0; + state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE; + state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE; + + if (state->running_capture_mode != RUNNING_MODE_RAW) { + if (state->running_capture_mode != RUNNING_MODE_LOWLIGHT) + m9mo_get_exif(sd); + } else { + if (frame_num == 1) { + m9mo_get_exif(sd); + + m9mo_set_mode(sd, M9MO_MONITOR_MODE); + err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(err & M9MO_INT_MODE)) { + cam_err("m9mo_start_capture() MONITOR_MODE error\n"); + return -ETIMEDOUT; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x78, 0x00); + CHECK_ERR(err); + } + } + + cam_trace("X\n"); + return err; +} + +/*static int m9mo_set_hdr(struct v4l2_subdev *sd, int val) +{ + cam_trace("E val : %d\n", val); + cam_trace("X\n"); + return 0; +}*/ + +static int m9mo_start_capture_thumb(struct v4l2_subdev *sd, int frame_num) +{ + struct m9mo_state *state = to_state(sd); + int err, int_factor; + cam_trace("E : %d frame\n", frame_num); + + cam_dbg("m9mo_start_capture_thumb() num=%d\n", frame_num); + + /* Select image number of frame */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_FRM_THUMB_SEL, frame_num); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_THUMB, 0x01); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_THUMB_IMG_SIZE, 0x04); /* 320 x 240 */ + CHECK_ERR(err); + + /* Get main thumb data */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_TRANSFER, 0x03); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE, + &state->jpeg.thumb_size); + CHECK_ERR(err); + + return err; +} + +static int m9mo_set_facedetect(struct v4l2_subdev *sd, int val) +{ + int err; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + state->facedetect_mode = val; + + switch (state->facedetect_mode) { + case FACE_DETECTION_NORMAL: + cam_dbg("~~~~~~ face detect on ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_SIZE, 0x04); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_MAX, 0x07); + CHECK_ERR(err); + if (state->mode == MODE_SMART_AUTO) { + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_CTL, 0x01); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_CTL, 0x11); + } + CHECK_ERR(err); + break; + + case FACE_DETECTION_SMILE_SHOT: + cam_dbg("~~~~~~ fd smile shot ~~~~~~ val : %d\n", val); + break; + + case FACE_DETECTION_BLINK: + cam_dbg("~~~~~~ fd eye blink ~~~~~~ val : %d\n", val); + break; + + case FACE_DETECTION_OFF: + default: + cam_dbg("~~~~~~ face detect off ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x00); + CHECK_ERR(err); + break; + } + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_bracket_aeb(struct v4l2_subdev *sd, int val) +{ + int err; + cam_trace("E val : %d\n", val); + + switch (val) { + case BRACKET_AEB_VALUE1: + cam_dbg("~~~~~~ AEB value1 ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0x1E); /* EV 0.3 */ + CHECK_ERR(err); + break; + + case BRACKET_AEB_VALUE2: + cam_dbg("~~~~~~ AEB value2 ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0x3C); /* EV 0.6 */ + CHECK_ERR(err); + break; + + case BRACKET_AEB_VALUE3: + cam_dbg("~~~~~~ AEB value3 ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0x64); /* EV 1.0 */ + CHECK_ERR(err); + break; + + case BRACKET_AEB_VALUE4: + cam_dbg("~~~~~~ AEB value4 ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0x82); /* EV 1.3 */ + CHECK_ERR(err); + break; + + case BRACKET_AEB_VALUE5: + cam_dbg("~~~~~~ AEB value5 ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0xA0); /* EV 1.6 */ + CHECK_ERR(err); + break; + + case BRACKET_AEB_VALUE6: + cam_dbg("~~~~~~ AEB value6 ~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0xC8); /* EV 2.0 */ + CHECK_ERR(err); + break; + + default: + cam_err("~~~~ TBD ~~~~ val : %d", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_AUTO_BRACKET_EV, 0x64); /* Ev 1.0 */ + CHECK_ERR(err); + break; + } + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_bracket_wbb(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err; + cam_trace("E val : %d\n", val); + + switch (val) { + case BRACKET_WBB_VALUE1: + cam_trace("~~~~~~ WBB value1 AB 3~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x01); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_AB, 0x30); + CHECK_ERR(err); + break; + + case BRACKET_WBB_VALUE2: + cam_trace("~~~~~~ WBB value2 AB 2~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x01); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_AB, 0x20); + CHECK_ERR(err); + break; + + case BRACKET_WBB_VALUE3: + cam_trace("~~~~~~ WBB value3 AB 1~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x01); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_AB, 0x0F); + CHECK_ERR(err); + break; + + case BRACKET_WBB_VALUE4: + cam_trace("~~~~~~ WBB value4 GM 3~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_GM, 0x30); + CHECK_ERR(err); + break; + + case BRACKET_WBB_VALUE5: + cam_trace("~~~~~~ WBB value5 GM 2~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_GM, 0x20); + CHECK_ERR(err); + break; + + case BRACKET_WBB_VALUE6: + cam_trace("~~~~~~ WBB value6 GM 1~~~~~~ val : %d\n", val); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_GM, 0x0F); + CHECK_ERR(err); + break; + + case BRACKET_WBB_OFF: + cam_trace("~~~~~~ WBB Off ~~~~~~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_WBB_MODE, 0x00); + CHECK_ERR(err); + break; + + default: + val = 0xFF; + cam_err("~~~~ TBD ~~~~ val : %d", val); + break; + } + + if (val != 0xFF) + state->bracket_wbb_val = val; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_bracket(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + cam_trace("E val : %d\n", val); + + switch (val) { + case BRACKET_MODE_OFF: + case BRACKET_MODE_AEB: + cam_dbg("~~~~~~ bracket aeb on ~~~~~~ val : %d\n", val); + m9mo_set_bracket_wbb(sd, BRACKET_WBB_OFF); + break; + + case BRACKET_MODE_WBB: + cam_dbg("~~~~~~ bracket wbb on ~~~~~~ val : %d\n", val); + if (state->bracket_wbb_val == BRACKET_WBB_OFF) + state->bracket_wbb_val = BRACKET_WBB_VALUE3; + m9mo_set_bracket_wbb(sd, state->bracket_wbb_val); + break; + + default: + cam_err("~~~~ TBD ~~~~ val : %d", val); + break; + } + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_cam_sys_mode(struct v4l2_subdev *sd, int val) +{ + int old_mode; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_SYSMODE_CAPTURE: + cam_trace("~ FACTORY_SYSMODE_CAPTURE ~\n"); + old_mode = m9mo_set_mode(sd, M9MO_STILLCAP_MODE); + break; + + case FACTORY_SYSMODE_MONITOR: + break; + + case FACTORY_SYSMODE_PARAM: + cam_trace("~ FACTORY_SYSMODE_PARAM ~\n"); + old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + break; + + default: + cam_trace("~ FACTORY_SYSMODE_DEFAULT ~\n"); + break; + } + cam_trace("X\n"); + return 0; + +} + +static int m9mo_set_fps(struct v4l2_subdev *sd, int val) +{ + int err; + + struct m9mo_state *state = to_state(sd); + cam_trace("E val : %d\n", val); + + if (val == state->fps) { + cam_info("same fps. skip\n"); + return 0; + } + if (val <= 0 || val > 120) { + cam_err("invalid frame rate %d\n", val); + val = 0; /* set to auto(default) */ + } + + cam_info("set AE EP to %d\n", val); + + switch (val) { + case 120: + cam_trace("~~~~~~ 120 fps ~~~~~~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x1C); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x1C); + CHECK_ERR(err); + break; + + case 60: + cam_trace("~~~~~~ 60 fps ~~~~~~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x1A); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x1A); + CHECK_ERR(err); + break; + + case 30: + cam_trace("~~~~~~ 30 fps ~~~~~~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x19); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x19); + CHECK_ERR(err); + break; + + default: + cam_trace("~~~~~~ default : auto fps ~~~~~~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x00); + CHECK_ERR(err); + break; + } + + state->fps = val; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_time_info(struct v4l2_subdev *sd, int val) +{ + int err; +#if 0 + int read_hour, read_min; +#endif + + cam_trace("E val : %x\n", val); + + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + M9MO_NEW_TIME_INFO, val); + CHECK_ERR(err); + +#if 0 /* for check time */ + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + M9MO_NEW_TIME_INFO, &read_hour); + CHECK_ERR(err); + + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + M9MO_NEW_TIME_INFO+1, &read_min); + CHECK_ERR(err); + + cam_dbg("time %02d:%02d\n", read_hour, read_min); +#endif + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_lens_off_timer(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %x\n", val); + + if (val > 0xFF) { + cam_warn("Can not set over 0xFF, but set 0x%x", val); + val = 0xFF; + } + + err = m9mo_writeb2(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_LENS_TIMER, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_widget_mode_level(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err; + + /* valid values are 0, 2, 4 */ + state->widget_mode_level = val * 2 - 2; + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + if (state->mode == MODE_SILHOUETTE) { + /* GAMMA_TBL_RGB_CAP */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x42, 0x0D + state->widget_mode_level); + CHECK_ERR(err); + + /* change to PARAM mode */ + err = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + CHECK_ERR(err); + + /* GAMMA_TBL_RGB_MON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x31, 0x0D + state->widget_mode_level); + CHECK_ERR(err); + + /* change to MON mode */ + m9mo_set_mode(sd, M9MO_MONITOR_MODE); + err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(err & M9MO_INT_MODE)) { + cam_err("M9MO_INT_MODE isn't issued!!!\n"); + return -ETIMEDOUT; + } + } else if (state->mode == MODE_BLUE_SKY) { + /* COLOR EFFECT SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, 0x11 + state->widget_mode_level); + CHECK_ERR(err); + } else if (state->mode == MODE_NATURAL_GREEN) { + /* COLOR EFFECT SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, 0x21 + state->widget_mode_level); + CHECK_ERR(err); + } + + cam_dbg("X %d %d\n", val, state->mode); + return 0; +} + +static int m9mo_set_LDC(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_dbg("%s\n", val ? "on" : "off"); + + if (val == 1) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x1B, 0x01); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x1B, 0x00); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_LSC(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_dbg("%s\n", val ? "on" : "off"); + + if (val == 1) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x07, 0x01); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x07, 0x00); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_aperture_preview(struct v4l2_subdev *sd, int val) +{ + int err, temp, i; + unsigned char convert = 0x00; + + cam_trace("E val : %d\n", val); + + if (val < 28) + val = 28; + + temp = val / 10; + + for (i = 0; i < temp; i++) + convert += 0x10; + + temp = val % 10; + convert += temp; + + cam_trace("check val : %d\n", convert); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, 0x3D, convert); + + CHECK_ERR(err); + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_aperture_capture(struct v4l2_subdev *sd, int val) +{ + int err, temp, i; + unsigned char convert = 0x00; + + cam_trace("E val : %d\n", val); + + if (val < 28) + val = 28; + + temp = val / 10; + + for (i = 0; i < temp; i++) + convert += 0x10; + + temp = val % 10; + convert += temp; + + cam_trace("check val : %d\n", convert); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + 0x36, convert); + CHECK_ERR(err); + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_OIS(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_OIS_RETURN_TO_CENTER: + cam_trace("~ FACTORY_OIS_RETURN_TO_CENTER ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x15, 0x30); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x16, 0x11); + CHECK_ERR(err); + break; + + case FACTORY_OIS_RUN: + cam_trace("~ FACTORY_OIS_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x11, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_OIS_START: + cam_trace("~ FACTORY_OIS_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x20, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_OIS_STOP: + cam_trace("~ FACTORY_OIS_STOP ~\n"); + break; + + case FACTORY_OIS_MODE_ON: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x11, 0x02); + CHECK_ERR(err); + cam_trace("~ FACTORY_OIS_MODE_ON ~\n"); + break; + + case FACTORY_OIS_MODE_OFF: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x10, 0x00); + cam_trace("~ FACTORY_OIS_MODE_OFF ~\n"); + break; + case FACTORY_OIS_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x19, 0x01); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_OIS, false); + CHECK_ERR(err); + cam_trace("~FACTORY_OIS_LOG ~\n"); + break; + + case FACTORY_OIS_ON: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x11, 0x02); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_OIS ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_OIS_shift(struct v4l2_subdev *sd, int val) +{ + int err; + cam_trace("E val : 0x%x\n", val); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + 0x15, val); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + 0x14, 0); + CHECK_ERR(err); + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_punt(struct v4l2_subdev *sd, int val) +{ + int err; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_PUNT_RANGE_START: + cam_trace("~ FACTORY_PUNT_RANGE_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_PUNT_RANGE_STOP: + cam_trace("~ FACTORY_PUNT_RANGE_STOP ~\n"); + break; + + case FACTORY_PUNT_SHORT_SCAN_DATA: + cam_trace("~ FACTORY_PUNT_SHORT_SCAN_DATA ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_PUNT_SHORT_SCAN_START: + cam_trace("~ FACTORY_PUNT_SHORT_SCAN_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_PUNT_SHORT_SCAN_STOP: + cam_trace("~ FACTORY_PUNT_SHORT_SCAN_STOP ~\n"); + break; + + case FACTORY_PUNT_LONG_SCAN_DATA: + cam_trace("~ FACTORY_PUNT_LONG_SCAN_DATA ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_PUNT_LONG_SCAN_START: + cam_trace("~ FACTORY_PUNT_LONG_SCAN_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x02); + CHECK_ERR(err); + break; + + case FACTORY_PUNT_LONG_SCAN_STOP: + cam_trace("~FACTORY_PUNT_LONG_SCAN_STOP ~\n"); + break; + + case FACTORY_PUNT_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x04); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_PUNT, false); + CHECK_ERR(err); + cam_trace("~FACTORY_PUNT_LOG ~\n"); + break; + + case FACTORY_PUNT_SET_RANGE_DATA: + cam_trace("~FACTORY_PUNT_SET_RANGE_DATA ~\n"); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x17, (unsigned short)(state->f_punt_data.min)); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x19, (unsigned short)(state->f_punt_data.max)); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, (unsigned char)(state->f_punt_data.num)); + CHECK_ERR(err); + + cam_trace("~ FACTORY_PUNT_RANGE_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_PUNT_EEP_WRITE: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x05); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_punt ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_zoom(struct v4l2_subdev *sd, int val) +{ + int err; + int end_check = 0; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_ZOOM_MOVE_STEP: + cam_trace("~ FACTORY_ZOOM_MOVE_STEP ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0F, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_RANGE_CHECK_START: + cam_trace("~ FACTORY_ZOOM_RANGE_CHECK_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0F, 0x05); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_RANGE_CHECK_STOP: + cam_trace("~ FACTORY_ZOOM_RANGE_CHECK_STOP ~\n"); + break; + + case FACTORY_ZOOM_SLOPE_CHECK_START: + cam_trace("~ FACTORY_ZOOM_SLOPE_CHECK_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x03); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_SLOPE_CHECK_STOP: + cam_trace("~ FACTORY_ZOOM_SLOPE_CHECK_STOP ~\n"); + break; + + case FACTORY_ZOOM_SET_RANGE_CHECK_DATA: + cam_trace("~ FACTORY_ZOOM_SET_RANGE_CHECK_DATA ~\n"); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x18, (unsigned short)(state->f_zoom_data.range_min)); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, (unsigned short)(state->f_zoom_data.range_max)); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_SET_SLOPE_CHECK_DATA: + cam_trace("~ FACTORY_ZOOM_SET_SLOPE_CHECK_DATA ~\n"); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x18, (unsigned short)(state->f_zoom_data.slope_min)); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, (unsigned short)(state->f_zoom_data.slope_max)); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_STEP_TELE: + cam_trace("~ FACTORY_ZOOM_STEP_TELE ~\n"); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, 0x0F); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_STEP_WIDE: + cam_trace("~ FACTORY_ZOOM_STEP_WIDE ~\n"); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_ZOOM_MOVE_END_CHECK: + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x26, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("~ FACTORY_ZOOM_MOVE_CHECK ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_zoom ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_zoom_step(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); +#if 1 + if (val >= 0 && val < 16) { + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1A, val); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x00); + CHECK_ERR(err); + } + cam_trace("~ FACTORY_ZOOM_MOVE_STEP ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0F, 0x00); + CHECK_ERR(err); +#else + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x06, val); + CHECK_ERR(err); + msleep(500); +#endif + return 0; +} + +static int m9mo_set_factory_fail_stop(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_FAIL_STOP_ON: + cam_trace("~ FACTORY_FAIL_STOP_ON ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_FAIL_STOP_OFF: + cam_trace("~ FACTORY_FAIL_STOP_OFF ~\n"); + break; + + case FACTORY_FAIL_STOP_RUN: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x0C); + CHECK_ERR(err); + + cam_trace("~ FACTORY_FAIL_STOP_RUN ~\n"); + break; + + case FACTORY_FAIL_STOP_STOP: + cam_trace("~ FACTORY_FAIL_STOP_STOP ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_fail_stop ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_nodefocus(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_NODEFOCUSYES_ON: + cam_trace("~ FACTORY_NODEFOCUSYES_ON ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_NODEFOCUSYES_OFF: + cam_trace("~ FACTORY_NODEFOCUSYES_OFF ~\n"); + break; + + case FACTORY_NODEFOCUSYES_RUN: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x09); + CHECK_ERR(err); + + cam_trace("~ FACTORY_NODEFOCUSYES_RUN ~\n"); + break; + + case FACTORY_NODEFOCUSYES_STOP: + cam_trace("~ FACTORY_NODEFOCUSYES_STOP ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_defocus ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_interpolation(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_INTERPOLATION_USE: + cam_trace("~ FACTORY_INTERPOLATION_USE ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x0A); + CHECK_ERR(err); + break; + + case FACTORY_INTERPOLATION_RELEASE: + cam_trace("~ FACTORY_INTERPOLATION_RELEASE ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_interpolation ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_common(struct v4l2_subdev *sd, int val) +{ + int err, down_check = 1, end_check = 0; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_FIRMWARE_DOWNLOAD: + cam_trace("~ FACTORY_FIRMWARE_DOWNLOAD ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x11, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_DOWNLOAD_CHECK: + cam_trace("~ FACTORY_DOWNLOAD_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + 0x11, &down_check); + CHECK_ERR(err); + state->factory_down_check = down_check; + break; + + case FACTORY_END_CHECK: + cam_trace("~ FACTORY_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_COMMON_SET_FOCUS_ZONE_MACRO: + cam_trace("~ FACTORY_COMMON_SET_FOCUS_ZONE_MACRO ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x07, 0x02); + CHECK_ERR(err); + break; + + case FACTORY_FPS30_ON: + cam_trace("~ FACTORY_FPS30_ON ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x3F, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_FPS30_OFF: + cam_trace("~ FACTORY_FPS30_OFF ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x3F, 0x00); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_common ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_vib(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("m9mo_set_factory_vib E val : %d\n", val); + + switch (val) { + case FACTORY_VIB_START: + cam_trace("~ FACTORY_VIB_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x20, 0x02); + CHECK_ERR(err); + break; + + case FACTORY_VIB_STOP: + cam_trace("~ FACTORY_VIB_STOP ~\n"); + break; + + case FACTORY_VIB_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x19, 0x02); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_VIB, false); + CHECK_ERR(err); + cam_trace("~FACTORY_VIB_LOG ~\n"); + break; + + default: + cam_err("~m9mo_set_factory_vib~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_gyro(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_GYRO_START: + cam_trace("~ FACTORY_GYRO_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x20, 0x03); + CHECK_ERR(err); + break; + + case FACTORY_GYRO_STOP: + cam_trace("~ FACTORY_GYRO_STOP ~\n"); + break; + + case FACTORY_GYRO_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x19, 0x03); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_GYRO, false); + CHECK_ERR(err); + cam_trace("~FACTORY_PUNT_LOG ~\n"); + break; + default: + cam_err("~ m9mo_set_factory_gyro ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_backlash(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_BACKLASH_INPUT: + cam_trace("~ FACTORY_BACKLASH_INPUT ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0A, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_BACKLASH_MAX_THR: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0A, 0x00); + CHECK_ERR(err); + cam_trace("~ FACTORY_BACKLASH_MAX_THR ~\n"); + break; + + case FACTORY_BACKLASH_WIDE_RUN: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0A, 0x03); + CHECK_ERR(err); + cam_trace("~ FACTORY_BACKLASH_WIDE_RUN ~\n"); + break; + + case FACTORY_BACKLASH_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0A, 0x05); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_BACKLASH, false); + CHECK_ERR(err); + cam_trace("~FACTORY_BACKLASH_LOG ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_backlash ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_backlash_count(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_af(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + int result_check = 0; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_AF_LOCK_ON_SET: + cam_trace("~ FACTORY_AF_LOCK_ON_SET ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_AF_LOCK_OFF_SET: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x00); + CHECK_ERR(err); + cam_trace("~ FACTORY_AF_LOCK_OFF_SET ~\n"); + break; + + case FACTORY_AF_MOVE: + cam_trace("~ FACTORY_AF_MOVE ~\n"); + break; + + case FACTORY_AF_STEP_LOG: + if (state->factory_test_num == 106) { + cam_trace("~ FACTORY_AF_STEP_LOG WIDE ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x1A); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_WIDE_RESOL, false); + CHECK_ERR(err); + } else if (state->factory_test_num == 107) { + cam_trace("~ FACTORY_AF_STEP_LOG TELE ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x19); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_TELE_RESOL, false); + CHECK_ERR(err); + } else { + cam_trace("~ FACTORY NUMBER ERROR ~\n"); + } + break; + + case FACTORY_AF_LOCK_START: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x01); + CHECK_ERR(err); + cam_trace("~ FACTORY_AF_LOCK_START ~\n"); + break; + + case FACTORY_AF_LOCK_STOP: + cam_trace("~ FACTORY_AF_LOCK_STOP ~\n"); + break; + + case FACTORY_AF_FOCUS_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x0B); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_AF_FCS, false); + CHECK_ERR(err); + + cam_trace("~ FACTORY_AF_FOCUS_LOG ~\n"); + break; + + case FACTORY_AF_INT_SET: + cam_trace("~ FACTORY_AF_INT_SET ~\n"); + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x23, &result_check); + CHECK_ERR(err); + state->factory_result_check = result_check; + break; + + case FACTORY_AF_STEP_SAVE: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x0A); + CHECK_ERR(err); + cam_trace("~ FACTORY_AF_SETP_SAVE ~\n"); + break; + + case FACTORY_AF_SCAN_LIMIT_START: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x06); + CHECK_ERR(err); + cam_trace("~ FACTORY_AF_SCAN_LIMIT_START ~\n"); + break; + + case FACTORY_AF_SCAN_LIMIT_STOP: + cam_trace("~ FACTORY_AF_SCAN_LIMIT_STOP ~\n"); + break; + + case FACTORY_AF_SCAN_RANGE_START: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x07); + CHECK_ERR(err); + cam_trace("~ FACTORY_AF_SCAN_RANGE_START ~\n"); + break; + + case FACTORY_AF_SCAN_RANGE_STOP: + cam_trace("~ FACTORY_AF_SCAN_RANGE_STOP ~\n"); + break; + + case FACTORY_AF_LED_END_CHECK: + cam_trace("~ FACTORY_AF_LED_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_AF_LED_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x4D, 0x02); + CHECK_ERR(err); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_AF_LED, false); + CHECK_ERR(err); + + cam_trace("~ FACTORY_AF_LED_LOG ~\n"); + break; + + case FACTORY_AF_MOVE_END_CHECK: + cam_trace("~ FACTORY_AF_MOVE_END_CHECK ~\n"); + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x29, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_AF_SCAN_END_CHECK: + cam_trace("~ FACTORY_AF_SCAN_END_CHECK ~\n"); + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x20, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + default: + cam_err("~ m9mo_set_factory_af ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_af_step(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_af_position(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0B, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_defocus(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_DEFOCUS_RUN: + cam_trace("~ FACTORY_DEFOCUS_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x18); + CHECK_ERR(err); + break; + + case FACTORY_DEFOCUS_STOP: + cam_trace("~ FACTORY_DEFOCUS_STOP ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_defocus ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_defocus_wide(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1A, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_defocus_tele(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_resol_cap(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_CAP_COMP_ON: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x01); + CHECK_ERR(err); + cam_trace("~ FACTORY_CAP_COMP_ON ~\n"); + break; + + case FACTORY_CAP_COMP_OFF: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x00); + CHECK_ERR(err); + cam_trace("~ FACTORY_CAP_COMP_OFF ~\n"); + break; + + case FACTORY_CAP_COMP_START: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x04); + CHECK_ERR(err); + cam_trace("~ FACTORY_CAP_COMP_START ~\n"); + break; + + case FACTORY_CAP_COMP_STOP: + cam_trace("~ FACTORY_CAP_COMP_STOP ~\n"); + break; + + case FACTORY_CAP_BARREL_ON: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x01); + CHECK_ERR(err); + cam_trace("~ FACTORY_CAP_BARREL_ON ~\n"); + break; + + case FACTORY_CAP_BARREL_OFF: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, 0x00); + CHECK_ERR(err); + cam_trace("~ FACTORY_CAP_BARREL_OFF ~\n"); + break; + + case FACTORY_CAP_BARREL_START: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x05); + CHECK_ERR(err); + cam_trace("~ FACTORY_CAP_BARREL_START ~\n"); + break; + + case FACTORY_CAP_BARREL_STOP: + cam_trace("~ FACTORY_CAP_BARREL_STOP ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_resol_cap ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_af_zone(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_AFZONE_NORMAL: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x07, 0x00); + CHECK_ERR(err); + cam_trace("~ FACTORY_AFZONE_NORMAL ~\n"); + break; + + case FACTORY_AFZONE_MACRO: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x07, 0x01); + CHECK_ERR(err); + cam_trace("~ FACTORY_AFZONE_MACRO ~\n"); + break; + + case FACTORY_AFZONE_AUTO: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x07, 0x02); + CHECK_ERR(err); + cam_trace("~ FACTORY_AFZONE_AUTO ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_resol_cap ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_af_lens(struct v4l2_subdev *sd, int val) +{ + int err; + u32 int_factor; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_AFLENS_OPEN: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x00, 0x00); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + + if (!(int_factor & M9MO_INT_LENS_INIT)) { + cam_err("M9MO_INT_LENS_INIT isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + + cam_trace("~ FACTORY_AFLENS_OPEN ~\n"); + break; + + case FACTORY_AFLENS_CLOSE: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x01, 0x00); + CHECK_ERR(err); + cam_trace("~ FACTORY_AFLENS_CLOSE ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_af_lens ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_adj_iris(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + int int_factor; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_ADJ_IRIS_RUN: + cam_trace("~ FACTORY_ADJ_IRIS_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x53, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_ADJ_IRIS_STOP: + cam_trace("~ FACTORY_ADJ_IRIS_STOP ~\n"); + break; + + case FACTORY_ADJ_IRIS_END_CHECK: + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("FACTORY_ADJ_IRIS_END_CHECK=%d\n", + end_check); + + if (end_check == 2) { + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + break; + + case FACTORY_ADJ_IRIS_LOG: + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_IRIS, true); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_sh_close(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + int int_factor; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_SH_CLOSE_RUN: + cam_trace("~ FACTORY_SH_CLOSE_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x53, 0x05); + CHECK_ERR(err); + break; + + case FACTORY_SH_CLOSE_STOP: + cam_trace("~ FACTORY_SH_CLOSE_STOP ~\n"); + break; + + case FACTORY_SH_CLOSE_END_CHECK: + cam_trace("~ FACTORY_SH_CLOSE_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + if (end_check == 2) { + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor)) { + cam_warn("M9MO_INT_MODE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + break; + + case FACTORY_SH_CLOSE_LOG: + cam_trace("~ FACTORY_SH_CLOSE_LOG ~\n"); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_SH_CLOSE, true); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor)) { + cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + + break; + + default: + cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_adj_gain_liveview(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + int int_factor; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_ADJ_GAIN_LIVEVIEW_RUN: + cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x53, 0x03); + CHECK_ERR(err); + break; + + case FACTORY_ADJ_GAIN_LIVEVIEW_STOP: + cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_STOP ~\n"); + break; + + case FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK: + cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = 0; + + if (end_check == 2) { + state->factory_end_check = 4; + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + break; + + case FACTORY_ADJ_GAIN_LIVEVIEW_LOG: + cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK ~\n"); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_LIVEVIEW, true); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_flicker(struct v4l2_subdev *sd, int val) +{ + int err; + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_FLICKER_AUTO: + cam_trace("~ FACTORY_FLICKER_AUTO ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_FLICKER, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_FLICKER_50HZ: + cam_trace("~ FACTORY_FLICKER_50HZ ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_FLICKER, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_FLICKER_60HZ: + cam_trace("~ FACTORY_FLICKER_60HZ ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_FLICKER, 0x02); + break; + + case FACTORY_FLICKER_50_60: + cam_trace("~ FACTORY_FLICKER_50_60 ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_FLICKER, 0x03); + break; + + case FACTORY_FLICKER_OFF: + cam_trace("~ FACTORY_FLICKER_OFF ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_FLICKER, 0x04); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_capture_gain(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + int int_factor; + struct m9mo_state *state = to_state(sd); + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_CAPTURE_GAIN_RUN: + cam_trace("~ FACTORY_CAPTURE_GAIN_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x53, 0x07); + CHECK_ERR(err); + break; + + case FACTORY_CAPTURE_GAIN_STOP: + cam_trace("~ FACTORY_CAPTURE_GAIN_STOP ~\n"); + break; + + case FACTORY_CAPTURE_GAIN_END_CHECK: + cam_trace("~ FACTORY_CAPTURE_GAIN_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + + state->factory_end_check = 0; + if (end_check == 2) { + state->factory_end_check = 8; + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + + break; + + case FACTORY_CAPTURE_GAIN_LOG: + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_GAIN_CAPTURE, true); + CHECK_ERR(err); + cam_trace("~FACTORY_CAPTURE_GAIN_LOG ~\n"); + break; + + default: + cam_err("~ m9mo_set_factory_capture_gain ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_image_stabilizer_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err; +#if 0 /* Not use Mode Chagne */ + int old_mode, int_factor; +#endif + int cnt = 30; + s32 ois_stability = 1; + cam_trace("E: mode %d\n", val); + +#if 0 /* Not use Mode Chagne */ + old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + CHECK_ERR(old_mode); +#endif + +retry: + switch (val) { + case V4L2_IMAGE_STABILIZER_OFF: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x11, 0x04); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x1A, 0x01); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x11, 0x01); + CHECK_ERR(err); + + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + 0x1A, &ois_stability); + CHECK_ERR(err); + while (ois_stability && cnt) { + msleep(20); + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + 0x1A, &ois_stability); + CHECK_ERR(err); + cnt--; + } + break; + + case V4L2_IMAGE_STABILIZER_OIS: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x1A, 0x01); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x11, 0x02); + CHECK_ERR(err); + + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + 0x1A, &ois_stability); + CHECK_ERR(err); + while (ois_stability && cnt) { + msleep(20); + err = m9mo_readb(sd, M9MO_CATEGORY_NEW, + 0x1A, &ois_stability); + CHECK_ERR(err); + cnt--; + } + break; + + case V4L2_IMAGE_STABILIZER_DUALIS: + /*break;*/ + + default: + val = V4L2_IMAGE_STABILIZER_OFF; + goto retry; + break; + } + +#if 0 /* Not use Mode Chagne */ + if (old_mode == M9MO_MONITOR_MODE) { + err = m9mo_set_mode(sd, old_mode); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_MODE)) { + cam_err("M9MO_INT_MODE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + CHECK_ERR(err); + } +#endif + + state->image_stabilizer_mode = val; + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_capture_ctrl(struct v4l2_subdev *sd, int val) +{ + int err = 0; + int int_factor; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_STILL_CAP_NORMAL: + cam_trace("~ FACTORY_STILL_CAP_NORMAL ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_MODE, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_STILL_CAP_DUALCAP: + cam_trace("~ FACTORY_STILL_CAP_DUALCAP ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_MODE, 0x05); + CHECK_ERR(err); + break; + + case FACTORY_DUAL_CAP_ON: + cam_trace("~ FACTORY_DUAL_CAP_ON ~\n"); +#if 0 + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_factor); + CHECK_ERR(err); + int_factor &= ~M9MO_INT_FRAME_SYNC; + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_factor); + CHECK_ERR(err); +#endif + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_START_DUALCAP, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_DUAL_CAP_OFF: + cam_trace("~ FACTORY_DUAL_CAP_OFF ~\n"); +#if 1 + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor/* & M9MO_INT_SCENARIO_FIN*/)) { + cam_warn( + "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } +#endif + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_START_DUALCAP, 0x02); + CHECK_ERR(err); +#if 1 + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor/* & M9MO_INT_SCENARIO_FIN*/)) { + cam_warn( + "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } +#endif + + break; + + default: + cam_err("~ m9mo_set_factory_capture_ctrl ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_flash(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_FLASH_STROBE_CHECK_ON: + cam_trace("~ FACTORY_FLASH_STROBE_CHECK_ON ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x70, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_FLASH_STROBE_CHECK_OFF: + cam_trace("~ FACTORY_FLASH_STROBE_CHECK_OFF ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x70, 0x00); + CHECK_ERR(err); + break; + + case FACTORY_FLASH_CHARGE: + cam_trace("~ FACTORY_FLASH_CHARGE ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x2A, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_FLASH_LOG: + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_FLASH_CHECK, false); + cam_trace("~ FACTORY_FLASH_LOG ~\n"); + break; + + case FACTORY_FLASH_CHARGE_END_CHECK: + cam_trace("~ FACTORY_FLASH_CHARGE_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_FLASH_STROBE_CHARGE_END_CHECK: + cam_trace("~ FLASH_STROBE_CHARGE_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM, + 0x27, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_ADJ_FLASH_WB_END_CHECK: + cam_trace("~ ADJ_FLASH_WB_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + 0x14, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_FLASH_WB_LOG: + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x31, 0x01); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_FLASH_WB, false); + cam_trace("~ FACTORY_FLASH_WB_LOG ~\n"); + break; + + case FACTORY_ADJ_FLASH_WB_LOG: + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_ADJ_FLASH_WB, false); + cam_trace("~ FACTORY_ADJ_FLASH_WB_LOG ~\n"); + break; + + default: + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_wb(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_WB_INDOOR_RUN: + cam_trace("~ FACTORY_WB_INDOOR_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x14, 0x01); + CHECK_ERR(err); + break; + + case FACTORY_WB_OUTDOOR_RUN: + cam_trace("~ FACTORY_WB_OUTDOOR_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x14, 0x21); + CHECK_ERR(err); + break; + + case FACTORY_WB_INDOOR_END_CHECK: + case FACTORY_WB_OUTDOOR_END_CHECK: + cam_trace("~ FACTORY_WB_END_CHECK ~\n"); + err = m9mo_readw(sd, M9MO_CATEGORY_ADJST, + 0x14, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + break; + + case FACTORY_WB_LOG: + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_WB_ADJ, false); + cam_trace("~ FACTORY_WB_LOG ~\n"); + break; + + default: + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_defectpixel(struct v4l2_subdev *sd, int val) +{ + int err; + int int_factor; + int end_check = 0; +#if 0 + int i; +#endif + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_DEFECTPIXEL_SCENARIO_6: + cam_trace("~ FACTORY_DEFECTPIXEL_SCENARIO_6 ~\n"); + + /*Interrupt Enable*/ + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_factor); + CHECK_ERR(err); + int_factor |= M9MO_INT_SCENARIO_FIN; + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_factor); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x40, 0x00); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + 0x5C, 0x06); + CHECK_ERR(err); + break; + + case FACTORY_DEFECTPIXEL_RUN: + cam_trace("~ FACTORY_DEFECTPIXEL_RUN ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x40, 0x00); + CHECK_ERR(err); + /*Interrrupt Disable*/ +#if 0 + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_factor); + CHECK_ERR(err); + int_factor &= ~M9MO_INT_STNW_DETECT; + int_factor &= ~M9MO_INT_SCENARIO_FIN; + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_factor); + CHECK_ERR(err); +#endif + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + 0x5C, 0x07); + CHECK_ERR(err); +#if 0 + for (i = 0; i < 5; i++) { + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_STNW_DETECT)) { + cam_warn( + "M9MO_INT_STNW_DETECT isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_SCENARIO_FIN)) { + cam_warn( + "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } +#endif + break; + + case FACTORY_DEFECTPIXEL_END_CHECK: + cam_trace("~ FACTORY_DEFECTPIXEL_END_CHECK ~\n"); + err = m9mo_readb(sd, M9MO_CATEGORY_LENS, + 0x40, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; +#if 0 + if (0) { /*end_check != 0) {*/ + msleep(100); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_SCENARIO_FIN)) { + cam_warn( + "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + } +#endif + m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_FACTOR, &state->isp.int_factor); + cam_err("m9mo_wait_interrupt : state->isp.int_factor = %x\n", + state->isp.int_factor); + cam_trace("X\n"); + break; + + case FACTORY_DEFECTPIXEL_CID_WRITE: + cam_trace("~ FACTORY_DEFECTPIXEL_CID_WRITE ~\n"); + m9mo_writeb(sd, M9MO_CATEGORY_SYS, + 0x29, 0x01); + cam_trace("X\n"); + break; + + case FACTORY_DEFECTPIXEL_CID_1: + cam_trace("~ FACTORY_DEFECTPIXEL_CID_1 ~\n"); + m9mo_readw(sd, M9MO_CATEGORY_SYS, + 0x2A, &end_check); + cam_err("CID_1 : %x\n", end_check); + state->factory_end_check = end_check; + cam_trace("X\n"); + break; + + case FACTORY_DEFECTPIXEL_CID_2: + cam_trace("~ FACTORY_DEFECTPIXEL_CID_2 ~\n"); + m9mo_readw(sd, M9MO_CATEGORY_SYS, + 0x2C, &end_check); + cam_err("CID_2 : %x\n", end_check); + state->factory_end_check = end_check; + cam_trace("X\n"); + break; + + case FACTORY_DEFECTPIXEL_CID_3: + cam_trace("~ FACTORY_DEFECTPIXEL_CID_3 ~\n"); + m9mo_readw(sd, M9MO_CATEGORY_SYS, + 0x2E, &end_check); + cam_err("CID_3 : %x\n", end_check); + state->factory_end_check = end_check; + cam_trace("X\n"); + break; + + case FACTORY_DEFECTPIXEL_LOG: + cam_trace("~ FACTORY_DEFECTPIXEL_LOG ~\n"); + +#if 0 + msleep(300); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_SCENARIO_FIN)) { + cam_warn( + "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } +#endif + m9mo_make_CSV_rawdata_direct(sd, + V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL); + + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, + M9MO_INT_MODE | M9MO_INT_CAPTURE | + M9MO_INT_FRAME_SYNC | M9MO_INT_ATSCENE_UPDATE | + M9MO_INT_LENS_INIT/* | M9MO_INT_SOUND*/); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + cam_trace("~ Event clear ~\n"); + break; + + case FACTORY_DEFECTPIXEL_DOT_WRITE_CHECK: + case FACTORY_DEFECTPIXEL_FLASH_MERGE: + err = m9mo_readb(sd, M9MO_CATEGORY_ADJST, + 0x90, &end_check); + CHECK_ERR(err); + cam_trace("DOT DATA END CHECK : %d\n", end_check); + state->factory_end_check = end_check; + break; + + default: + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_tilt(struct v4l2_subdev *sd, int val) +{ + int err, end_check = 0; + struct m9mo_state *state = to_state(sd); + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_TILT_ONE_SCRIPT_RUN: + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0C, 0x06); + CHECK_ERR(err); + cam_trace("FACTORY_TILT_ONE_SCRIPT_RUN\n"); + break; + + case FACTORY_TILT_ONE_SCRIPT_DISP1: + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x34, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP1 %d\n", end_check); + break; + + case FACTORY_TILT_ONE_SCRIPT_DISP2: + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x36, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP2 %d\n", end_check); + break; + + case FACTORY_TILT_ONE_SCRIPT_DISP3: + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x38, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP3 %d\n", end_check); + break; + + case FACTORY_TILT_ONE_SCRIPT_DISP4: + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x3A, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP4 %d\n", end_check); + break; + + case FACTORY_TILT_ONE_SCRIPT_DISP5: + err = m9mo_readw(sd, M9MO_CATEGORY_LENS, + 0x3C, &end_check); + CHECK_ERR(err); + state->factory_end_check = end_check; + cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP5 %d\n", end_check); + break; + + default: + cam_err("~ m9mo_set_factory_common ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_factory_IR_Check(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_trace("E val : %d\n", val); + + switch (val) { + case FACTORY_IR_CHECK_LOG: + cam_trace("~ FACTORY_IR_CHECK_LOG ~\n"); + msleep(40); + err = m9mo_make_CSV_rawdata(sd, + M9MO_FLASH_FACTORY_IR_CHECK, false); + CHECK_ERR(err); + break; + + default: + cam_err("~ m9mo_set_factory_common ~ val : %d", val); + break; + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_send_factory_command_value(struct v4l2_subdev *sd) +{ + int err; + int category = 0, byte = 0, value = 0, size = 0; + struct m9mo_state *state = to_state(sd); + + category = state->factory_category; + byte = state->factory_byte; + value = state->factory_value; + size = state->factory_value_size; + + cam_trace("category : 0x%x, byte : 0x%x, value : 0x%x\n", + category, byte, value); + + if ((size == 4) || (value > 0xFFFF)) { + cam_trace("write long"); + err = m9mo_writel(sd, category, byte, value); + CHECK_ERR(err); + return err; + } + + if ((size == 2) || (value > 0xFF)) { + cam_trace("write word"); + err = m9mo_writew(sd, category, byte, value); + CHECK_ERR(err); + return err; + } + + cam_trace("write byte"); + err = m9mo_writeb(sd, category, byte, value); + CHECK_ERR(err); + return err; +} + +static int m9mo_set_aeawblock(struct v4l2_subdev *sd, int val) +{ + int err; + + cam_err("%d\n", val); + switch (val) { + case AE_UNLOCK_AWB_UNLOCK: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 0); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 0); + CHECK_ERR(err); + break; + + case AE_LOCK_AWB_UNLOCK: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 1); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 0); + CHECK_ERR(err); + break; + + case AE_UNLOCK_AWB_LOCK: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 0); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 1); + CHECK_ERR(err); + break; + + case AE_LOCK_AWB_LOCK: + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 1); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 1); + CHECK_ERR(err); + break; + } + cam_err("X\n"); + return 0; +} + +static int m9mo_set_GBAM(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + + if (state->wb_g_value == 0 && state->wb_b_value == 0 + && state->wb_a_value == 0 && state->wb_m_value == 0) + val = 0; + + cam_trace("E, val = %d\n", val); + + if (val) { + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_GBAM_MODE, 0x01); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_G_VALUE, state->wb_g_value); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_B_VALUE, state->wb_b_value); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_A_VALUE, state->wb_a_value); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_M_VALUE, state->wb_m_value); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_GBAM_MODE, 0x00); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_K(struct v4l2_subdev *sd, int val) +{ + int err = 0; + + cam_trace("E %02X\n", val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_K_VALUE, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_dual_capture_mode(struct v4l2_subdev *sd, int val) +{ + int err = 0; + int old_mode; + struct m9mo_state *state = to_state(sd); + + cam_trace("E, val = %d\n", val); + + if (val == state->vss_mode) { + cam_err("same vss_mode: %d\n", state->vss_mode); + return err; + } + + old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + CHECK_ERR(old_mode); + + switch (val) { + case 0: + /* Normal Video Snap Shot */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_VSS_MODE, 0x00); + CHECK_ERR(err); + break; + + case 1: + /* 4M Video Snap Shot */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_VSS_MODE, 0x01); + CHECK_ERR(err); + break; + default: + val = 0; + break; + } + + state->vss_mode = val; + + cam_trace("X\n"); + return err; +} + +static int m9mo_start_set_dual_capture(struct v4l2_subdev *sd, int frame_num) +{ + struct m9mo_state *state = to_state(sd); + int err, int_factor; + + cam_trace("E, vss mode: %d, frm[%d]\n", state->vss_mode, frame_num); + + if (!state->vss_mode) + return 0; + + /* Start video snap shot */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_START_VIDEO_SNAP_SHOT, 0x01); + CHECK_ERR(err); + + /* Clear Interrupt factor */ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_FRAME_SYNC)) { + cam_err("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor); + return -ETIMEDOUT; + } + + state->dual_capture_start = 1; + state->dual_capture_frame = frame_num; + + cam_trace("X\n"); + return err; +} + +static int m9mo_continue_proc(struct v4l2_subdev *sd, int val) +{ + int err = 1, int_factor; + + cam_trace("E\n"); + + switch (val) { + case V4L2_INT_STATE_FRAME_SYNC: + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_FRAME_SYNC)) { + cam_dbg("m9mo_continue_proc() INT_FRAME_SYNC error%#x\n", + int_factor); + return -ETIMEDOUT; + } + break; + + case V4L2_INT_STATE_CAPTURE_SYNC: + /* continue : cancel CAPTURE or postview end CAPTURE*/ + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_CAPTURE_TIMEOUT); + if (!(int_factor & M9MO_INT_CAPTURE)) { + cam_dbg("m9mo_continue_proc() INT_STATE_CAPTURE_SYNC error%#x\n", + int_factor); + return -ETIMEDOUT; + } + break; + + case V4L2_INT_STATE_CONTINUE_CANCEL: + /* continue cancel */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_START_DUALCAP, 0x02); + CHECK_ERR(err); + cam_dbg("-------------V4L2_INT_STATE_CONTINUE_CANCEL-------------\n"); + /* CAPTURE wait interrupt -> V4L2_INT_STATE_CAPTURE_SYNC */ + break; + + case V4L2_INT_STATE_CONTINUE_END: + m9mo_set_mode(sd, M9MO_MONITOR_MODE); + + err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(err & M9MO_INT_MODE)) { + cam_err("m9mo_continue_proc() INT_STATE_CONTINUE_END error\n"); + return -ETIMEDOUT; + } + break; + + case V4L2_INT_STATE_START_CAPTURE: + m9mo_set_mode(sd, M9MO_STILLCAP_MODE); + break; + } + + cam_dbg("m9mo_continue_proc : 0x%x err=%d\n", + val, err); + + cam_trace("X\n"); + return err; +} + +static int m9mo_burst_set_postview_size(struct v4l2_subdev *sd, int val) +{ + int err = 1, i, num_entries; + struct m9mo_state *state = to_state(sd); + const struct m9mo_frmsizeenum **frmsize; + + int width = val >> 16; + int height = val & 0xFFFF; + + cam_trace("E\n"); + cam_trace("size = (%d x %d)\n", width, height); + + frmsize = &state->postview; + + num_entries = ARRAY_SIZE(postview_frmsizes); + *frmsize = &postview_frmsizes[num_entries-1]; + + for (i = 0; i < num_entries; i++) { + if (width == postview_frmsizes[i].width && + height == postview_frmsizes[i].height) { + *frmsize = &postview_frmsizes[i]; + break; + } + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_PREVIEW_IMG_SIZE, + state->postview->reg_val); + + cam_trace("X\n"); + + return err; +} + +static int m9mo_burst_set_snapshot_size(struct v4l2_subdev *sd, int val) +{ + int err = 1, i, num_entries; + struct m9mo_state *state = to_state(sd); + const struct m9mo_frmsizeenum **frmsize; + + int width = val >> 16; + int height = val & 0xFFFF; + + cam_trace("E\n"); + cam_trace("size = (%d x %d)\n", width, height); + + frmsize = &state->capture; + + num_entries = ARRAY_SIZE(capture_frmsizes); + *frmsize = &capture_frmsizes[num_entries-1]; + + for (i = 0; i < num_entries; i++) { + if (width == capture_frmsizes[i].width && + height == capture_frmsizes[i].height) { + *frmsize = &capture_frmsizes[i]; + break; + } + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_MAIN_IMG_SIZE, + state->capture->reg_val); + + cam_trace("X\n"); + + return err; +} + +static int m9mo_burst_proc(struct v4l2_subdev *sd, int val) +{ + int err = 1, int_factor; + struct m9mo_state *state = to_state(sd); + + cam_trace("E\n"); + + switch (val) { + case V4L2_INT_STATE_BURST_START: + cam_trace("Burstshot Capture START ~~~~~~\n"); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x0F, 0x0); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x10, 0x50); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x11, 0x0); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_YUVOUT_MAIN, 0x01); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x12, 0x0); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_CAP_MODE, 0x0D); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_START_DUALCAP, M9MO_CAP_MODE_MULTI_CAPTURE); + CHECK_ERR(err); +#if 0 + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_SOUND)) { + cam_dbg("m9mo_continue_proc() INT_FRAME_SYNC error%#x\n", + int_factor); + return -ETIMEDOUT; + } +#endif + break; + + case V4L2_INT_STATE_BURST_SYNC: + cam_trace("Burstshot Page SYNC~~~\n"); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_SOUND)) { + cam_dbg("m9mo_continue_proc() INT_FRAME_SYNC error%#x\n", + int_factor); + return -ETIMEDOUT; + } + break; + + case V4L2_INT_STATE_BURST_STOP: + /* continue cancel */ + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, + M9MO_CAPCTRL_START_DUALCAP, 0x02); + CHECK_ERR(err); + + /* CAPTURE wait interrupt -> V4L2_INT_STATE_CAPTURE_SYNC */ + err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(err & M9MO_INT_MODE)) { + cam_err("m9mo_burst_proc() INT_STATE_CONTINUE_END error\n"); + return -ETIMEDOUT; + } + + state->running_capture_mode = RUNNING_MODE_SINGLE; + + cam_trace("Burstshot Capture STOP ~~~~~~\n"); + break; + } + + cam_trace("X\n"); + return err; +} + +static int m9mo_set_gamma(struct v4l2_subdev *sd) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + int gamma_rgb_mon, mon_gamma, cap_gamma, gamma_rgb_cap; + + cam_trace("E, mode %d\n", state->mode); + + /* Set Monitor/Video flag */ + if (state->mode == MODE_VIDEO) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_MOVIE_SELECT, 0x01); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_MOVIE_SELECT, 0x00); + CHECK_ERR(err); + } + + /* Set Gamma value */ + err = m9mo_readb(sd, M9MO_CATEGORY_PARM, 0x0A, &gamma_rgb_mon); + CHECK_ERR(err); + err = m9mo_readb(sd, M9MO_CATEGORY_PARM, 0x31, &mon_gamma); + CHECK_ERR(err); + err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM, 0x41, &cap_gamma); + CHECK_ERR(err); + err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM, 0x42, &gamma_rgb_cap); + CHECK_ERR(err); + + if (mon_gamma < 0xD && gamma_rgb_cap < 0xD) { + state->gamma_rgb_mon = gamma_rgb_mon; + state->gamma_tbl_rgb_mon = mon_gamma; + state->gamma_rgb_cap = cap_gamma; + state->gamma_tbl_rgb_cap = gamma_rgb_cap; + } + + if (state->mode == MODE_SILHOUETTE) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x0A, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x31, 0x0D + state->widget_mode_level); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x41, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x42, 0x0D + state->widget_mode_level); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x0A, state->gamma_rgb_mon); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + 0x31, state->gamma_tbl_rgb_mon); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x41, state->gamma_rgb_cap); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x42, state->gamma_tbl_rgb_cap); + CHECK_ERR(err); + } + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_PASM_mode(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + int color_effect, current_mode; + + cam_dbg("E, value %d\n", val); + + state->mode = val; + + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, ¤t_mode); + + switch (val) { + case MODE_SMART_AUTO: + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Disable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00); + CHECK_ERR(err); + + /* Set Still Mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x01); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* SMART AUTO CAP */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x10); + CHECK_ERR(err); + + if (state->facedetect_mode == FACE_DETECTION_NORMAL) { + err = m9mo_writeb(sd, M9MO_CATEGORY_FD, + M9MO_FD_CTL, 0x01); + CHECK_ERR(err); + } + + break; + + case MODE_PROGRAM: + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Disable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00); + CHECK_ERR(err); + + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM OFF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00); + CHECK_ERR(err); + + /* Set Monitor EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x00); + CHECK_ERR(err); + + /* Set Still Capture EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x00); + CHECK_ERR(err); + + /* Still Capture EVP Set Parameter Mode */ + if (state->iso == 0) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x00); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x04); + CHECK_ERR(err); + } + break; + + case MODE_A: + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Disable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00); + CHECK_ERR(err); + + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM OFF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00); + CHECK_ERR(err); + + /* Set Monitor EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x02); + CHECK_ERR(err); + + /* Set Still Capture EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x02); + CHECK_ERR(err); + + /* Still Capture EVP Set Parameter Mode */ + if (state->iso == 0) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x01); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x05); + CHECK_ERR(err); + } + + /* Set Still Capture F-Number Value */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_F_NUMBER, state->f_number); + CHECK_ERR(err); + break; + + case MODE_S: + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Disable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00); + CHECK_ERR(err); + + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM OFF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00); + CHECK_ERR(err); + + /* Set Monitor EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x04); + CHECK_ERR(err); + + /* Set Still Capture EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x04); + CHECK_ERR(err); + + /* Still Capture EVP Set Parameter Mode */ + if (state->iso == 0) { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x02); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x06); + CHECK_ERR(err); + } + + /* Set Capture Shutter Speed Time */ + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_SS_NUMERATOR, state->numerator); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_SS_DENOMINATOR, state->denominator); + CHECK_ERR(err); + break; + + case MODE_M: + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Disable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00); + CHECK_ERR(err); + + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM OFF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00); + CHECK_ERR(err); + + /* Set Monitor EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_MON, 0x00); + CHECK_ERR(err); + + /* Set Still Capture EV program mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EP_MODE_CAP, 0x00); + CHECK_ERR(err); + + /* Still Capture EVP Set Parameter Mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x07); + CHECK_ERR(err); + + /* Set Still Capture F-Number Value */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_F_NUMBER, state->f_number); + CHECK_ERR(err); + + /* Set Capture Shutter Speed Time */ + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_SS_NUMERATOR, state->numerator); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_SS_DENOMINATOR, state->denominator); + CHECK_ERR(err); + + /* Set Still Capture ISO Value */ + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_ISO_VALUE, state->iso); + CHECK_ERR(err); + break; + + case MODE_VIDEO: + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Disable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM OFF */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00); + CHECK_ERR(err); + + /* Still Capture EVP Set Parameter Mode */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_MODE_CAP, 0x00); + CHECK_ERR(err); + break; + + case MODE_HIGH_SPEED: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_LIGHT_TRAIL_SHOT: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x02); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_WATERFALL: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x03); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_SILHOUETTE: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x04); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + /* Set Color effect */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_SUNSET: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x05); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_CLOSE_UP: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x06); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_FIREWORKS: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x07); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_BACKLIGHT: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x0A); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, state->color_effect); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_BLUE_SKY: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x08); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + /* COLOR EFFECT SET */ + err = m9mo_readb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, &color_effect); + CHECK_ERR(err); + + if (color_effect < 0x11) + state->color_effect = color_effect; + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, 0x11 + state->widget_mode_level); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + case MODE_NATURAL_GREEN: + /* Set CATE_408 to None */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + + /* Set HISTOGRAM ON */ + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01); + CHECK_ERR(err); + + /* LIKE A PRO MODE SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x09); + CHECK_ERR(err); + + /* LIKE A PRO STEP SET */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, + 0x02, state->widget_mode_level); + CHECK_ERR(err); + + /* COLOR EFFECT SET */ + err = m9mo_readb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, &color_effect); + CHECK_ERR(err); + + if (color_effect < 0x11) + state->color_effect = color_effect; + + err = m9mo_writeb(sd, M9MO_CATEGORY_MON, + M9MO_MON_COLOR_EFFECT, 0x21 + state->widget_mode_level); + CHECK_ERR(err); + + /* Set LIKE_PRO_EN Enable */ + err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01); + CHECK_ERR(err); + + /* Set CATE_409 to 1(PREVIEW) */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01); + CHECK_ERR(err); + break; + + default: + break; + } + + cam_trace("X\n"); + + return 0; +} + +static int m9mo_set_shutter_speed(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + int numerator = 1, denominator = 30; + cam_dbg("E, value %d\n", val); + + if (state->mode > MODE_VIDEO) { + cam_trace("Don't set when like a pro !!!\n"); + return 0; + } + + switch (val) { + case 1: + numerator = 16; + denominator = 1; + break; + + case 2: + numerator = 12; + denominator = 1; + break; + + case 3: + numerator = 8; + denominator = 1; + break; + + case 4: + numerator = 6; + denominator = 1; + break; + + case 5: + numerator = 4; + denominator = 1; + break; + + case 6: + numerator = 3; + denominator = 1; + break; + + case 7: + numerator = 2; + denominator = 1; + break; + + case 8: + numerator = 15; + denominator = 10; + break; + + case 9: + numerator = 1; + denominator = 1; + break; + + case 10: + numerator = 7; + denominator = 10; + break; + + case 11: + numerator = 5; + denominator = 10; + break; + + case 12: + numerator = 1; + denominator = 3; + break; + + case 13: + numerator = 1; + denominator = 4; + break; + + case 14: + numerator = 1; + denominator = 6; + break; + + case 15: + numerator = 1; + denominator = 8; + break; + + case 16: + numerator = 1; + denominator = 15; + break; + + case 17: + numerator = 1; + denominator = 20; + break; + + case 18: + numerator = 1; + denominator = 30; + break; + + case 19: + numerator = 1; + denominator = 45; + break; + + case 20: + numerator = 1; + denominator = 60; + break; + + case 21: + numerator = 1; + denominator = 90; + break; + + case 22: + numerator = 1; + denominator = 125; + break; + + case 23: + numerator = 1; + denominator = 180; + break; + + case 24: + numerator = 1; + denominator = 250; + break; + + case 25: + numerator = 1; + denominator = 350; + break; + + case 26: + numerator = 1; + denominator = 500; + break; + + case 27: + numerator = 1; + denominator = 750; + break; + + case 28: + numerator = 1; + denominator = 1000; + break; + + case 29: + numerator = 1; + denominator = 1500; + break; + + case 30: + numerator = 1; + denominator = 2000; + break; + + default: + break; + } + + state->numerator = numerator; + state->denominator = denominator; + + /* Set Capture Shutter Speed Time */ + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_SS_NUMERATOR, numerator); + CHECK_ERR(err); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_SS_DENOMINATOR, denominator); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_f_number(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + + cam_dbg("E, value %d\n", val); + + /* Max value : 15.9 */ + if (val > 159) + val = 159; + + val = (val / 10) * 16 + (val % 10); + state->f_number = val; + + /* Set Still Capture F-Number Value */ + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + M9MO_AE_EV_PRG_F_NUMBER, val); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_wb_custom(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + + cam_dbg("E\n"); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MODE, 0x02); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_AWB_MANUAL, 0x08); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x02); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_WB, + M9MO_WB_SET_CUSTOM_RG, state->wb_custom_rg); + CHECK_ERR(err); + + err = m9mo_writew(sd, M9MO_CATEGORY_WB, + M9MO_WB_SET_CUSTOM_BG, state->wb_custom_bg); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_WB, + M9MO_WB_CWB_MODE, 0x01); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_smart_auto_s1_push(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int int_factor, err; + + cam_dbg("E val : %d\n", val); + + if (state->mode == MODE_SMART_AUTO || + state->mode >= MODE_BACKGROUND_BLUR) { + if (val == 1) { + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x02); + CHECK_ERR(err); + } else if (val == 2) { + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x04); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_ATSCENE_UPDATE)) { + cam_err("M9MO_INT_ATSCENE_UPDATE isn't issued, %#x\n", + int_factor); + return -ETIMEDOUT; + } + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x03); + CHECK_ERR(err); + } + } + cam_trace("X\n"); + return 0; +} + +static int m9mo_set_mon_size(struct v4l2_subdev *sd, int val) +{ + struct m9mo_state *state = to_state(sd); + int err, vss_val; + u32 size_val; + + if (state->isp_fw_ver < 0xA02B) { + cam_dbg("%x firmware cannot working quick monitor mode\n", + state->isp_fw_ver); + return 0; + } + + cam_dbg("E\n"); + + if (state->fps == 60) { + if (state->preview_height == 480) + size_val = 0x2F; + else if (state->preview_height == 720) + size_val = 0x25; + vss_val = 0; + } else if (state->sensor_mode == SENSOR_MOVIE + && state->fps == 30) { + if (state->preview_height == 1080) + size_val = 0x2C; + else if (state->preview_height == 720) + size_val = 0x2D; + else if (state->preview_height == 480) + size_val = 0x2E; + else if (state->preview_height == 240) + size_val = 0x36; + vss_val = 1; + } else { + if (state->preview_width == 640) + size_val = 0x17; + else if (state->preview_width == 768) + size_val = 0x33; + else if (state->preview_width == 960) + size_val = 0x34; + else if (state->preview_width == 1056) + size_val = 0x35; + else if (state->preview_width == 1280) + size_val = 0x21; + vss_val = 0; + } + + if (val == 1080) { + size_val = 0x2C; + vss_val = 1; + } + + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_SIZE, size_val); + CHECK_ERR(err); + + m9mo_set_dual_capture_mode(sd, vss_val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, 0x25, 0x01); + CHECK_ERR(err); + + cam_trace("start quick monitor mode !!!\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, 0x7C, 0x01); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_check_dataline(struct v4l2_subdev *sd, int val) +{ + int err = 0; + + cam_dbg("E, value %d\n", val); + + err = m9mo_writeb(sd, M9MO_CATEGORY_TEST, + M9MO_TEST_OUTPUT_YCO_TEST_DATA, val ? 0x01 : 0x00); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int m9mo_check_esd(struct v4l2_subdev *sd) +{ + s32 val = 0; + int err = 0; + + struct m9mo_state *state = to_state(sd); + + if (state->factory_test_num != 0) { + cam_dbg("factory test mode !!! ignore esd check\n"); + return 0; + } + + /* check ISP */ +#if 0 /* TO DO */ + err = m9mo_readb(sd, M9MO_CATEGORY_TEST, M9MO_TEST_ISP_PROCESS, &val); + CHECK_ERR(err); + cam_dbg("progress %#x\n", val); +#else + val = 0x80; +#endif + + if (val != 0x80) { + goto esd_occur; + } else { + m9mo_wait_interrupt(sd, M9MO_ISP_ESD_TIMEOUT); + + err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_ESD_INT, &val); + CHECK_ERR(err); + + if (val & M9MO_INT_ESD) + goto esd_occur; + } + + cam_warn("ESD is not detected\n"); + return 0; + +esd_occur: + cam_warn("ESD shock is detected\n"); + return -EIO; +} + +static int m9mo_g_ext_ctrl(struct v4l2_subdev *sd, + struct v4l2_ext_control *ctrl) +{ + int err = 0, i = 0; + + char *buf = NULL; + + int size = 0, rtn = 0, cmd_size = 0; + u8 category = 0, sub = 0; + u32 addr = 0; + + size = ctrl->size; + + cam_dbg("ISPD m9mo_g_ext_ctrl() id=%d, size=%d\n", + ctrl->id, ctrl->size); + + if (size > 4096) + return -1; + + switch (ctrl->id) { + case V4L2_CID_ISP_DEBUG_READ: + + cmd_size = 2; + if (size < cmd_size+1) /* category:1, sub:1, data:>1 */ + return -2; + + buf = kmalloc(ctrl->size, GFP_KERNEL); + if (copy_from_user(buf, (void __user *)ctrl->string, size)) { + err = -1; + break; + } + + category = buf[0]; + sub = buf[1]; + + memset(buf, 0, size-cmd_size); + for (i = 0; i < size-cmd_size; i++) { + err = m9mo_readb(sd, category, sub+i, &rtn); + buf[i] = rtn; + cam_dbg("ISPD m9mo_readb(sd, %x, %x, %x\n", + category, sub+i, buf[i]); + CHECK_ERR(err); + } + + if (copy_to_user((void __user *)ctrl->string, + buf, size-cmd_size)) + err = -1; + + kfree(buf); + break; + + case V4L2_CID_ISP_DEBUG_READ_MEM: + + cmd_size = 4; + if (size < cmd_size+1) /* cmd size : 4, data : >1 */ + return -2; + + buf = kmalloc(ctrl->size, GFP_KERNEL); + if (copy_from_user(buf, (void __user *)ctrl->string, size)) { + err = -1; + break; + } + + addr = buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3]; + + memset(buf, 0, size-cmd_size); + err = m9mo_mem_read(sd, size-cmd_size, addr, buf); + cam_dbg("ISPD m9mo_mem_read7(sd, %x, %d)\n", + addr, size-cmd_size); + if (err < 0) + cam_err("i2c falied, err %d\n", err); + + if (copy_to_user((void __user *)ctrl->string, + buf, size-cmd_size)) + err = -1; + + kfree(buf); + break; + + default: + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + /*err = -ENOIOCTLCMD*/ + /*err = 0;*/ + break; + } + + /* FIXME + * if (err < 0 && err != -ENOIOCTLCMD) + * cam_err("failed, id %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + */ + + return err; +} + +static int m9mo_g_ext_ctrls(struct v4l2_subdev *sd, + struct v4l2_ext_controls *ctrls) +{ + struct v4l2_ext_control *ctrl = ctrls->controls; + int i, err = 0; + + for (i = 0; i < ctrls->count; i++, ctrl++) { + err = m9mo_g_ext_ctrl(sd, ctrl); + if (err) { + ctrls->error_idx = i; + break; + } + } + return err; +} + +static int m9mo_makeLog(struct v4l2_subdev *sd, char *filename) +{ + int addr = 0, len = 0xff; /* init */ + int err = 0; + int i = 0, no = 0; + char buf[256]; + + struct file *fp; + mm_segment_t old_fs; + char filepath[256]; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + sprintf(filepath, "/sdcard/ISPD/%s%c", filename, 0); + + fp = filp_open(filepath, + O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR); + if (IS_ERR(fp)) { + cam_err("failed to open %s, err %ld\n", + filepath, PTR_ERR(fp)); + return -1; + } + + err = m9mo_writeb(sd, 0x0d, 0x06, 0x0); + CHECK_ERR(err); + + err = m9mo_readl(sd, 0x0d, 0x08, &addr); + CHECK_ERR(err); + + err = m9mo_writeb(sd, 0x0d, 0x0e, 0x2); + CHECK_ERR(err); + + while (no < 10000) { /* max log count : 10000 */ + err = m9mo_writew(sd, 0x0d, 0x0c, no); + CHECK_ERR(err); + + err = m9mo_writeb(sd, 0x0d, 0x0e, 0x3); + CHECK_ERR(err); + + while (len == 0xff) { + err = m9mo_readb(sd, 0x0d, 0x07, &len); + CHECK_ERR(err); + + if (i++ > 3000) /* only delay code */ + break; + } + + if (len == 0 || len == 0xff) { + err = m9mo_writeb(sd, 0x0d, 0x0e, 0x1); + CHECK_ERR(err); + break; + } + + i = 0; + len += 1; + if (len > sizeof(buf)) + len = sizeof(buf); + err = m9mo_mem_read(sd, len, addr, buf); + if (err < 0) + cam_err("ISPD i2c falied, err %d\n", err); + + buf[len-1] = '\n'; + + vfs_write(fp, buf, len, &fp->f_pos); +#if 0 + cam_dbg("ISPD Log : %x[%d], %d, %32s)\n", + addr, no, len, buf); +#endif + len = 0xff; /* init */ + no++; + } + + if (!IS_ERR(fp)) + filp_close(fp, current->files); + + set_fs(old_fs); + + return 0; +} + +static int m9mo_s_ext_ctrl(struct v4l2_subdev *sd, + struct v4l2_ext_control *ctrl) +{ + int err = 0, i = 0; + char *buf = NULL; + + int size = 0, cmd_size = 0; + u8 category = 0, sub = 0; + u32 addr = 0; + + size = ctrl->size; + + if (size > 1024) + return -1; + + switch (ctrl->id) { + case V4L2_CID_ISP_DEBUG_WRITE: + + cmd_size = 2; + if (size < cmd_size+1) + return -2; + + buf = kmalloc(ctrl->size, GFP_KERNEL); + if (copy_from_user(buf, (void __user *)ctrl->string, size)) { + err = -1; + break; + } + + category = buf[0]; + sub = buf[1]; + + cam_dbg("ISP_DBG write() %x%x%x\n", buf[0], buf[1], buf[2]); + + for (i = 0; i < size-cmd_size; i++) { + err = m9mo_writeb(sd, category, sub+i, buf[i+cmd_size]); + cam_dbg("ISPD m9mo_writeb(sd, %x, %x, %x\n", + category, sub+i, buf[i+cmd_size]); + CHECK_ERR(err); + } + + kfree(buf); + break; + + case V4L2_CID_ISP_DEBUG_WRITE_MEM: + + cmd_size = 4; + if (size < cmd_size+1) + return -2; + + buf = kmalloc(ctrl->size, GFP_KERNEL); + if (copy_from_user(buf, + (void __user *)ctrl->string, size)) { + err = -1; + break; + } + + addr = buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3]; + + cam_dbg("ISP_DBG write_mem() 0x%08x, size=%d\n", + addr, size); + + err = m9mo_mem_write(sd, 0x04, + size-cmd_size, addr, buf+cmd_size); + cam_dbg("ISPD m9mo_mem_write(sd, %x, %d)\n", + addr, size-cmd_size); + if (err < 0) + cam_err("i2c falied, err %d\n", err); + + kfree(buf); + break; + + case V4L2_CID_ISP_DEBUG_LOGV: + + if (size > 0) { + buf = kmalloc(ctrl->size+1, GFP_KERNEL); + if (copy_from_user(buf, + (void __user *)ctrl->string, size)) { + err = -1; + break; + } + buf[size] = 0; + + m9mo_makeLog(sd, buf); + + kfree(buf); + } else { + m9mo_makeLog(sd, "default.log"); + } + + break; + + default: + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + break; + } + + return err; +} + + +static int m9mo_s_ext_ctrls(struct v4l2_subdev *sd, + struct v4l2_ext_controls *ctrls) +{ + struct v4l2_ext_control *ctrl = ctrls->controls; + int i, err = 0; + + for (i = 0; i < ctrls->count; i++, ctrl++) { + err = m9mo_s_ext_ctrl(sd, ctrl); + if (err) { + ctrls->error_idx = i; + break; + } + } + return err; +} + +static int m9mo_check_manufacturer_id(struct v4l2_subdev *sd) +{ + int i, err; + u8 id; + u32 addr[] = {0x1000AAAA, 0x10005554, 0x1000AAAA}; + u8 val[3][2] = { + [0] = {0x00, 0xAA}, + [1] = {0x00, 0x55}, + [2] = {0x00, 0x90}, + }; + u8 reset[] = {0x00, 0xF0}; + + /* set manufacturer's ID read-mode */ + for (i = 0; i < 3; i++) { + err = m9mo_mem_write(sd, 0x06, 2, addr[i], val[i]); + CHECK_ERR(err); + } + + /* read manufacturer's ID */ + err = m9mo_mem_read(sd, sizeof(id), 0x10000001, &id); + CHECK_ERR(err); + + /* reset manufacturer's ID read-mode */ + err = m9mo_mem_write(sd, 0x06, sizeof(reset), 0x10000000, reset); + CHECK_ERR(err); + + cam_dbg("%#x\n", id); + + return id; +} + +static int m9mo_program_fw(struct v4l2_subdev *sd, + u8 *buf, u32 addr, u32 unit, u32 count) +{ + u32 val; + int i, err = 0; + int erase = 0x01; + int test_count = 0; + int retries = 0; + + for (i = 0; i < unit*count; i += unit) { + /* Set Flash ROM memory address */ + err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, + M9MO_FLASH_ADDR, addr + i); + CHECK_ERR(err); + + /* Erase FLASH ROM entire memory */ + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, + M9MO_FLASH_ERASE, erase); + CHECK_ERR(err); + /* Response while sector-erase is operating */ + retries = 0; + do { + mdelay(30); + err = m9mo_readb(sd, M9MO_CATEGORY_FLASH, + M9MO_FLASH_ERASE, &val); + CHECK_ERR(err); + } while (val == erase && retries++ < M9MO_I2C_VERIFY); + + if (val != 0) { + cam_err("failed to erase sector\n"); + return -1; + } + + /* Set FLASH ROM programming size */ + err = m9mo_writew(sd, M9MO_CATEGORY_FLASH, + M9MO_FLASH_BYTE, unit); + CHECK_ERR(err); + + err = m9mo_mem_write(sd, 0x04, unit, + M9MO_INT_RAM_BASE_ADDR, buf + i); + CHECK_ERR(err); + cam_err("fw Send = %x count = %d\n", i, test_count++); + + /* Start Programming */ + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, M9MO_FLASH_WR, 0x01); + CHECK_ERR(err); + + /* Confirm programming has been completed */ + retries = 0; + do { + mdelay(30); + err = m9mo_readb(sd, M9MO_CATEGORY_FLASH, + M9MO_FLASH_WR, &val); + CHECK_ERR(err); + } while (val && retries++ < M9MO_I2C_VERIFY); + + if (val != 0) { + cam_err("failed to program~~~~\n"); + return -1; + } + } + cam_err("m9mo_program_fw out ~~~~~~~~~~~\n"); + return 0; +} + +static int m9mo_load_fw_main(struct v4l2_subdev *sd) +{ + struct m9mo_state *state = to_state(sd); + struct device *dev = sd->v4l2_dev->dev; + const struct firmware *fw = NULL; + u8 *buf_m9mo = NULL; + unsigned int count = 0; + /*int offset;*/ + int err = 0; + + struct file *fp; + mm_segment_t old_fs; + long fsize, nread; + int fw_requested = 1; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + fp = filp_open(M9MO_FW_PATH, O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_trace("failed to open %s, err %ld\n", + M9MO_FW_PATH, PTR_ERR(fp)); + goto request_fw; + } + + fw_requested = 0; + fsize = fp->f_path.dentry->d_inode->i_size; + count = fsize / SZ_4K; + + cam_err("start, file path %s, size %ld Bytes, count %d\n", + M9MO_FW_PATH, fsize, count); + + buf_m9mo = vmalloc(fsize); + if (!buf_m9mo) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + nread = vfs_read(fp, (char __user *)buf_m9mo, fsize, &fp->f_pos); + if (nread != fsize) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } + + filp_close(fp, current->files); + +request_fw: + if (fw_requested) { + set_fs(old_fs); + if (system_rev > 1) { + cam_info("Firmware Path = %s\n", + M9MO_EVT31_FW_REQ_PATH); + err = request_firmware(&fw, + M9MO_EVT31_FW_REQ_PATH, dev); + } else { + cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH); + err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev); + } + + + if (err != 0) { + cam_err("request_firmware failed\n"); + err = -EINVAL; + goto out; + } + count = fw->size / SZ_4K; + cam_err("start, size %d Bytes count = %d\n", fw->size, count); + buf_m9mo = (u8 *)fw->data; + } + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001200 , buf_port_seting0); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001000 , buf_port_seting1); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001100 , buf_port_seting2); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, + 0x1C, 0x0247036D); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, + 0x4A, 0x01); + CHECK_ERR(err); + mdelay(10); + + /* program FLASH ROM */ + err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR, SZ_4K, count); + if (err < 0) + goto out; + + +#if 0 + offset = SZ_64K * 31; + if (id == 0x01) { + err = m9mo_program_fw(sd, buf + offset, + M9MO_FLASH_BASE_ADDR + offset, SZ_8K, 4, id); + } else { + err = m9mo_program_fw(sd, buf + offset, + M9MO_FLASH_BASE_ADDR + offset, SZ_4K, 8, id); + } +#endif + cam_err("end\n"); + state->isp.bad_fw = 0; + +out: + if (!fw_requested) { + vfree(buf_m9mo); + + filp_close(fp, current->files); + set_fs(old_fs); + } else { + release_firmware(fw); + } + + return err; +} + +static int m9mo_load_fw_info(struct v4l2_subdev *sd) +{ + const struct firmware *fw = NULL; + u8 *buf_m9mo = NULL; + /*int offset;*/ + int err = 0; + + struct file *fp; + mm_segment_t old_fs; + long fsize, nread; + int fw_requested = 1; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + fp = filp_open(FW_INFO_PATH, O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_trace("failed to open %s, err %ld\n", + M9MO_FW_PATH, PTR_ERR(fp)); + } + fsize = fp->f_path.dentry->d_inode->i_size; + + cam_err("start, file path %s, size %ld Bytes\n", FW_INFO_PATH, fsize); + + buf_m9mo = vmalloc(fsize); + if (!buf_m9mo) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + nread = vfs_read(fp, (char __user *)buf_m9mo, fsize, &fp->f_pos); + if (nread != fsize) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001200 , buf_port_seting0); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001000 , buf_port_seting1); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001100 , buf_port_seting2); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, + 0x1C, 0x0247036D); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, + 0x4A, 0x01); + CHECK_ERR(err); + mdelay(10); + + /* program FLSH ROM */ + err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR_1, SZ_4K, 1); + if (err < 0) + goto out; + + +#if 0 + offset = SZ_64K * 31; + if (id == 0x01) { + err = m9mo_program_fw(sd, buf + offset, + M9MO_FLASH_BASE_ADDR + offset, SZ_8K, 4, id); + } else { + err = m9mo_program_fw(sd, buf + offset, + M9MO_FLASH_BASE_ADDR + offset, SZ_4K, 8, id); + } +#endif + cam_err("end\n"); + +out: + if (!fw_requested) { + vfree(buf_m9mo); + + filp_close(fp, current->files); + set_fs(old_fs); + } else { + release_firmware(fw); + } + + return err; +} + + + +static int m9mo_load_fw(struct v4l2_subdev *sd) +{ + struct device *dev = sd->v4l2_dev->dev; + const struct firmware *fw = NULL; + u8 sensor_ver[M9MO_FW_VER_LEN] = {0, }; + u8 *buf_m9mo = NULL, *buf_fw_info = NULL; + /*int offset;*/ + int err = 0; + + struct file *fp; + mm_segment_t old_fs; + long fsize, nread; + int fw_requested = 1; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + fp = filp_open(M9MO_FW_PATH, O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_err("failed to open %s, err %ld\n", + M9MO_FW_PATH, PTR_ERR(fp)); + goto request_fw; + } + + fw_requested = 0; + fsize = fp->f_path.dentry->d_inode->i_size; + + cam_err("start, file path %s, size %ld Bytes\n", M9MO_FW_PATH, fsize); + + buf_m9mo = vmalloc(fsize); + if (!buf_m9mo) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + nread = vfs_read(fp, (char __user *)buf_m9mo, fsize, &fp->f_pos); + if (nread != fsize) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } + + filp_close(fp, current->files); + + fp = filp_open(FW_INFO_PATH, O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_trace("failed to open %s, err %ld\n", + FW_INFO_PATH, PTR_ERR(fp)); + goto request_fw; + } + + fw_requested = 0; + fsize = fp->f_path.dentry->d_inode->i_size; + + cam_err("start, file path %s, size %ld Bytes\n", FW_INFO_PATH, fsize); + + buf_fw_info = vmalloc(fsize); + if (!buf_fw_info) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + nread = vfs_read(fp, (char __user *)buf_fw_info, fsize, &fp->f_pos); + if (nread != fsize) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } + + +request_fw: + if (fw_requested) { + set_fs(old_fs); + + m9mo_get_sensor_fw_version(sd); + + if (sensor_ver[0] == 'T' && sensor_ver[1] == 'B') { + err = request_firmware(&fw, M9MOTB_FW_PATH, dev); +#if defined(CONFIG_MACH_Q1_BD) + } else if (sensor_ver[0] == 'O' && sensor_ver[1] == 'O') { + err = request_firmware(&fw, M9MOOO_FW_PATH, dev); +#endif +#if defined(CONFIG_MACH_U1_KOR_LGT) + } else if (sensor_ver[0] == 'S' && sensor_ver[1] == 'B') { + err = request_firmware(&fw, M9MOSB_FW_PATH, dev); +#endif + } else { + cam_err("cannot find the matched F/W file\n"); + err = -EINVAL; + } + + if (err != 0) { + cam_err("request_firmware falied\n"); + err = -EINVAL; + goto out; + } + cam_dbg("start, size %d Bytes\n", fw->size); + buf_m9mo = (u8 *)fw->data; + } + + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001200 , buf_port_seting0); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001000 , buf_port_seting1); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_mem_write(sd, 0x04, SZ_64, + 0x90001100 , buf_port_seting2); + CHECK_ERR(err); + mdelay(10); + + err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, + 0x1C, 0x0247036D); + CHECK_ERR(err); + + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, + 0x4A, 0x01); + CHECK_ERR(err); + mdelay(10); + + /* program FLSH ROM */ + err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR, SZ_4K, 504); + if (err < 0) + goto out; + + err = m9mo_program_fw(sd, buf_fw_info, + M9MO_FLASH_BASE_ADDR_1, SZ_4K, 1); + if (err < 0) + goto out; + +#if 0 + offset = SZ_64K * 31; + if (id == 0x01) { + err = m9mo_program_fw(sd, buf + offset, + M9MO_FLASH_BASE_ADDR + offset, SZ_8K, 4, id); + } else { + err = m9mo_program_fw(sd, buf + offset, + M9MO_FLASH_BASE_ADDR + offset, SZ_4K, 8, id); + } +#endif + cam_err("end\n"); + +out: + if (!fw_requested) { + vfree(buf_m9mo); + vfree(buf_fw_info); + + filp_close(fp, current->files); + set_fs(old_fs); + } else { + release_firmware(fw); + } + + return err; +} + + +static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct m9mo_state *state = to_state(sd); + int err = 0; + int int_en = 0; + s16 temp; + + if (ctrl->id != V4L2_CID_CAMERA_LENS_TIMER) { + cam_trace(" id %d, value %d\n", + ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); + } -static int m9mo_set_bracket(struct v4l2_subdev *sd, int val) -{ - cam_trace("E val : %d\n", val); + if (unlikely(state->isp.bad_fw && ctrl->id != V4L2_CID_CAM_UPDATE_FW)) { + cam_err("\"Unknown\" state, please update F/W"); + return 0; + } - switch (val) { - case BRACKET_MODE_OFF: - cam_dbg("~~~~~~ bracket off ~~~~~~ val : %d\n", val); + switch (ctrl->id) { + case V4L2_CID_CAMERA_HOLD_LENS: + leave_power = true; break; - case BRACKET_MODE_AEB: - cam_dbg("~~~~~~ bracket aeb on ~~~~~~ val : %d\n", val); + case V4L2_CID_CAM_UPDATE_FW: + if (ctrl->value == FW_MODE_DUMP) + err = m9mo_dump_fw(sd); + else + err = m9mo_check_fw(sd); break; - case BRACKET_MODE_WBB: - cam_dbg("~~~~~~ bracket wbb on ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_SENSOR_MODE: +#ifdef FAST_CAPTURE + err = m9mo_set_fast_capture(sd); +#else + err = m9mo_set_sensor_mode(sd, ctrl->value); +#endif break; - default: - cam_err("~~~~ TBD ~~~~ val : %d", val); + case V4L2_CID_CAMERA_FLASH_MODE: + err = m9mo_set_flash(sd, ctrl->value, 0); break; - } - cam_trace("X\n"); - return 0; -} - -static int m9mo_set_bracket_aeb(struct v4l2_subdev *sd, int val) -{ - int err; - cam_trace("E val : %d\n", val); - switch (val) { - case BRACKET_AEB_VALUE1: - cam_trace("~~~~~~ AEB value1 ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0x1E); /* EV 0.3 */ + case V4L2_CID_CAMERA_ISO: + err = m9mo_set_iso(sd, ctrl); break; - case BRACKET_AEB_VALUE2: - cam_trace("~~~~~~ AEB value2 ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0x3C); /* EV 0.6 */ + case V4L2_CID_CAMERA_METERING: + if (state->sensor_mode == SENSOR_CAMERA) + err = m9mo_set_metering(sd, ctrl->value); break; - case BRACKET_AEB_VALUE3: - cam_trace("~~~~~~ AEB value3 ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0x64); /* EV 1.0 */ + case V4L2_CID_CAMERA_BRIGHTNESS: + err = m9mo_set_exposure(sd, ctrl); break; - case BRACKET_AEB_VALUE4: - cam_trace("~~~~~~ AEB value4 ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0x82); /* EV 1.3 */ + case V4L2_CID_CAMERA_SHARPNESS: + err = m9mo_set_sharpness(sd, ctrl); break; - case BRACKET_AEB_VALUE5: - cam_trace("~~~~~~ AEB value5 ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0xA0); /* EV 1.6 */ + case V4L2_CID_CAMERA_CONTRAST: + err = m9mo_set_contrast(sd, ctrl); break; - case BRACKET_AEB_VALUE6: - cam_trace("~~~~~~ AEB value6 ~~~~~~ val : %d\n", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0xC8); /* EV 2.0 */ + case V4L2_CID_CAMERA_SATURATION: + err = m9mo_set_saturation(sd, ctrl); break; - default: - cam_err("~~~~ TBD ~~~~ val : %d", val); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_AUTO_BRACKET_EV, 0x64); /* Ev 1.0 */ + case V4L2_CID_CAMERA_WHITE_BALANCE: + err = m9mo_set_whitebalance(sd, ctrl->value); break; - } - cam_trace("X\n"); - return 0; -} -static int m9mo_set_bracket_wbb(struct v4l2_subdev *sd, int val) -{ - cam_trace("E val : %d\n", val); + case V4L2_CID_CAMERA_SCENE_MODE: + err = m9mo_set_scene_mode(sd, ctrl->value); + break; - switch (val) { - case BRACKET_WBB_VALUE1: - cam_trace("~~~~~~ WBB value1 ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_EFFECT: + err = m9mo_set_effect(sd, ctrl->value); break; - case BRACKET_WBB_VALUE2: - cam_trace("~~~~~~ WBB value2 ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_WDR: + err = m9mo_set_wdr(sd, ctrl->value); break; - case BRACKET_WBB_VALUE3: - cam_trace("~~~~~~ WBB value3 ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_ANTI_SHAKE: + err = m9mo_set_antishake(sd, ctrl->value); break; - case BRACKET_WBB_VALUE4: - cam_trace("~~~~~~ WBB value4 ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_BEAUTY_SHOT: + err = m9mo_set_face_beauty(sd, ctrl->value); break; - case BRACKET_WBB_VALUE5: - cam_trace("~~~~~~ WBB value5 ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_FOCUS_MODE: + err = m9mo_set_af_mode(sd, ctrl->value); break; - case BRACKET_WBB_VALUE6: - cam_trace("~~~~~~ WBB value6 ~~~~~~ val : %d\n", val); + case V4L2_CID_CAMERA_SET_AUTO_FOCUS: + err = m9mo_set_af(sd, ctrl->value); break; - default: - cam_err("~~~~ TBD ~~~~ val : %d", val); + case V4L2_CID_CAMERA_OBJECT_POSITION_X: + state->focus.pos_x = ctrl->value; + #if 0 + /* FIXME - It should be fixed on F/W (touch AF offset) */ + if (state->preview != NULL) { + if (state->exif.unique_id[0] == 'T') { + if (state->preview->index == M9MO_PREVIEW_VGA) + state->focus.pos_x -= 40; + else if (state->preview->index == + M9MO_PREVIEW_WVGA) + state->focus.pos_x -= 50; + } + } + #endif break; - } - cam_trace("X\n"); - return 0; -} -static int m9mo_set_fps(struct v4l2_subdev *sd, int val) -{ - int err, old_mode; - u32 int_factor; + case V4L2_CID_CAMERA_OBJECT_POSITION_Y: + state->focus.pos_y = ctrl->value; + #if 0 + /* FIXME - It should be fixed on F/W (touch AF offset) */ + if (state->preview != NULL) { + if (state->preview->index == M9MO_PREVIEW_VGA) { + if (state->exif.unique_id[0] == 'T') + state->focus.pos_y -= 50; + } else if (state->preview->index == M9MO_PREVIEW_WVGA) { + if (state->exif.unique_id[0] == 'T') + state->focus.pos_y -= 2; + else + state->focus.pos_y += 60; + } + } + #endif + break; - struct m9mo_state *state = to_state(sd); - cam_trace("E val : %d\n", val); + case V4L2_CID_CAMERA_TOUCH_AF_START_STOP: + err = m9mo_set_touch_auto_focus(sd, ctrl->value); + break; - if (state->preview == NULL) { - cam_trace("~~~~~~ return ~~~~~~\n"); - return 0; - } + case V4L2_CID_CAMERA_AF_LED: + err = m9mo_set_AF_LED(sd, ctrl->value); + break; - switch (val) { - case 30: - cam_trace("~~~~~~ 30 fps ~~~~~~\n"); + case V4L2_CID_CAMERA_ZOOM: + err = m9mo_set_zoom(sd, ctrl); + break; - old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); - CHECK_ERR(old_mode); + case V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL: + err = m9mo_set_zoom_ctrl(sd, ctrl->value); + break; - if (state->preview->height == 480) { - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, - M9MO_PARM_MON_SIZE, 0x17); - CHECK_ERR(err); - } else if (state->preview->height == 720) { - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, - M9MO_PARM_MON_SIZE, 0x21); - CHECK_ERR(err); - } + case V4L2_CID_CAM_JPEG_QUALITY: + err = m9mo_set_jpeg_quality(sd, ctrl); + break; - if (old_mode == M9MO_MONITOR_MODE) { - err = m9mo_set_mode(sd, old_mode); - CHECK_ERR(err); + case V4L2_CID_CAMERA_CAPTURE: + err = m9mo_start_capture(sd, ctrl->value); + break; - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_MODE)) { - cam_err("M9MO_INT_MODE isn't issued, %#x\n", - int_factor); - return -ETIMEDOUT; - } - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_CAPTURE_THUMB: + err = m9mo_start_capture_thumb(sd, ctrl->value); break; - case 60: - cam_trace("~~~~~~ 60 fps ~~~~~~\n"); + case V4L2_CID_CAMERA_YUV_CAPTURE: + err = m9mo_start_YUV_capture(sd, ctrl->value); + break; - old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE); - CHECK_ERR(old_mode); + case V4L2_CID_CAMERA_POSTVIEW_CAPTURE: + err = m9mo_start_postview_capture(sd, ctrl->value); + break; - if (state->preview->height == 480) { - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, - M9MO_PARM_MON_SIZE, 0x2F); - CHECK_ERR(err); - } else if (state->preview->height == 720) { - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, - M9MO_PARM_MON_SIZE, 0x25); - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_CAPTURE_MODE: + err = m9mo_set_capture_mode(sd, ctrl->value); + break; - if (old_mode == M9MO_MONITOR_MODE) { - err = m9mo_set_mode(sd, old_mode); - CHECK_ERR(err); + /*case V4L2_CID_CAMERA_HDR: + err = m9mo_set_hdr(sd, ctrl->value); + break;*/ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_MODE)) { - cam_err("M9MO_INT_MODE isn't issued, %#x\n", - int_factor); - return -ETIMEDOUT; - } - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_VT_MODE: + state->vt_mode = ctrl->value; break; - case 120: - cam_trace("~~~~~~ 120 fps ~~~~~~\n"); + case V4L2_CID_CAMERA_CHECK_DATALINE: + state->check_dataline = ctrl->value; break; - default: - cam_err("~~~~ 30fps ~~~~\n"); + case V4L2_CID_CAMERA_ANTI_BANDING: + err = m9mo_set_antibanding(sd, ctrl); break; - } - cam_trace("X\n"); - return 0; -} - -static int m9mo_set_LDC(struct v4l2_subdev *sd, int val) -{ - int err; - cam_dbg("%s\n", val ? "on" : "off"); + case V4L2_CID_CAMERA_CHECK_ESD: + err = m9mo_check_esd(sd); + break; - if (val == 1) { - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_TONE_CTRL, 0x01); - CHECK_ERR(err); - } else { - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_WDR_EN, 0x00); - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK: + err = m9mo_set_aeawblock(sd, ctrl->value); + break; - cam_trace("X\n"); - return 0; -} + case V4L2_CID_CAMERA_FACE_DETECTION: + err = m9mo_set_facedetect(sd, ctrl->value); + break; -static int m9mo_set_LSC(struct v4l2_subdev *sd, int val) -{ - int err; + case V4L2_CID_CAMERA_BRACKET: + err = m9mo_set_bracket(sd, ctrl->value); + break; - cam_dbg("%s\n", val ? "on" : "off"); + case V4L2_CID_CAMERA_BRACKET_AEB: + err = m9mo_set_bracket_aeb(sd, ctrl->value); + break; -#if 0 - if (val == 1) { - err = m9mo_writeb(sd, M9MO_CATEGORY_MON, - M9MO_MON_TONE_CTRL, 0x01); - CHECK_ERR(err); - } else { - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_WDR_EN, 0x00); - CHECK_ERR(err); - } -#endif + case V4L2_CID_CAMERA_BRACKET_WBB: + err = m9mo_set_bracket_wbb(sd, ctrl->value); + break; - cam_trace("X\n"); - return 0; -} + case V4L2_CID_CAMERA_IMAGE_STABILIZER: + err = m9mo_set_image_stabilizer_mode(sd, ctrl->value); + break; -static int m9mo_set_aperture(struct v4l2_subdev *sd, int val) -{ - int err; + case V4L2_CID_CAMERA_IS_OIS_MODE: + err = m9mo_set_image_stabilizer_OIS(sd, ctrl->value); + break; - cam_trace("E val : %d\n", val); + case V4L2_CID_CAMERA_FOCUS_AREA_MODE: + err = m9mo_set_focus_area_mode(sd, ctrl->value); + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_EP_MODE_MON, 0x0C); - CHECK_ERR(err); + case V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP: + err = m9mo_set_object_tracking(sd, ctrl->value); + break; - cam_trace("X\n"); - return 0; -} + case V4L2_CID_CAMERA_FRAME_RATE: + err = m9mo_set_fps(sd, ctrl->value); + break; -static int m9mo_set_aeawblock(struct v4l2_subdev *sd, int val) -{ - int err; + case V4L2_CID_CAMERA_SMART_ZOOM: + err = m9mo_set_smart_zoom(sd, ctrl->value); + break; - cam_err("%d\n", val); - switch (val) { - case AE_UNLOCK_AWB_UNLOCK: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 0); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 0); - CHECK_ERR(err); + case V4L2_CID_CAMERA_LDC: + err = m9mo_set_LDC(sd, ctrl->value); break; - case AE_LOCK_AWB_UNLOCK: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 1); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 0); - CHECK_ERR(err); + case V4L2_CID_CAMERA_LSC: + err = m9mo_set_LSC(sd, ctrl->value); break; - case AE_UNLOCK_AWB_LOCK: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 0); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 1); - CHECK_ERR(err); + case V4L2_CID_CAMERA_WIDGET_MODE_LEVEL: + err = m9mo_set_widget_mode_level(sd, ctrl->value); break; - case AE_LOCK_AWB_LOCK: - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, 1); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, 1); - CHECK_ERR(err); + case V4L2_CID_CAMERA_PREVIEW_WIDTH: + state->preview_width = ctrl->value; break; - } - cam_err("X\n"); - return 0; -} -static int m9mo_check_dataline(struct v4l2_subdev *sd, int val) -{ - int err = 0; + case V4L2_CID_CAMERA_PREVIEW_HEIGHT: + state->preview_height = ctrl->value; + break; - cam_dbg("E, value %d\n", val); + case V4L2_CID_CAMERA_PREVIEW_SIZE: + err = m9mo_set_mon_size(sd, ctrl->value); + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_TEST, - M9MO_TEST_OUTPUT_YCO_TEST_DATA, val ? 0x01 : 0x00); - CHECK_ERR(err); + case V4L2_CID_CAM_APERTURE_PREVIEW: + err = m9mo_set_aperture_preview(sd, ctrl->value); + break; - cam_trace("X\n"); - return 0; -} + case V4L2_CID_CAM_APERTURE_CAPTURE: + err = m9mo_set_aperture_capture(sd, ctrl->value); + break; -static int m9mo_check_esd(struct v4l2_subdev *sd) -{ - s32 val = 0; - int err = 0; + case V4L2_CID_CAMERA_FACTORY_OIS: + err = m9mo_set_factory_OIS(sd, ctrl->value); + break; - /* check ISP */ - err = m9mo_readb(sd, M9MO_CATEGORY_TEST, M9MO_TEST_ISP_PROCESS, &val); - CHECK_ERR(err); - cam_dbg("progress %#x\n", val); + case V4L2_CID_CAMERA_FACTORY_OIS_SHIFT: + err = m9mo_set_factory_OIS_shift(sd, ctrl->value); + break; - if (val != 0x80) { - goto esd_occur; - } else { - m9mo_wait_interrupt(sd, M9MO_ISP_ESD_TIMEOUT); + case V4L2_CID_CAMERA_FACTORY_PUNT: + err = m9mo_set_factory_punt(sd, ctrl->value); + break; - err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_ESD_INT, &val); + case V4L2_CID_CAMERA_FACTORY_PUNT_SHORT_SCAN_DATA: + cam_trace("FACTORY_PUNT_SHORT_SCAN_DATA : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, (unsigned char)(ctrl->value)); CHECK_ERR(err); - if (val & M9MO_INT_ESD) - goto esd_occur; - } - - cam_warn("ESD is not detected\n"); - return 0; + cam_trace("~ FACTORY_PUNT_SHORT_SCAN_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x01); + CHECK_ERR(err); + break; -esd_occur: - cam_warn("ESD shock is detected\n"); - return -EIO; -} + case V4L2_CID_CAMERA_FACTORY_PUNT_LONG_SCAN_DATA: + cam_trace("FACTORY_PUNT_LONG_SCAN_DATA : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, (unsigned char)(ctrl->value)); + CHECK_ERR(err); -static int m9mo_g_ext_ctrl(struct v4l2_subdev *sd, - struct v4l2_ext_control *ctrl) -{ - struct m9mo_state *state = to_state(sd); - int err = 0; + cam_trace("~ FACTORY_PUNT_LONG_SCAN_START ~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0E, 0x02); + CHECK_ERR(err); + break; - switch (ctrl->id) { - case V4L2_CID_CAM_SENSOR_FW_VER: - strcpy(ctrl->string, state->exif.unique_id); + case V4L2_CID_CAMERA_FACTORY_ZOOM: + err = m9mo_set_factory_zoom(sd, ctrl->value); break; - default: - cam_err("no such control id %d\n", - ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); - /*err = -ENOIOCTLCMD*/ - /*err = 0;*/ + case V4L2_CID_CAMERA_FACTORY_ZOOM_STEP: + err = m9mo_set_factory_zoom_step(sd, ctrl->value); break; - } - /* FIXME - * if (err < 0 && err != -ENOIOCTLCMD) - * cam_err("failed, id %d\n", - ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); - */ + case V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MIN: + state->f_punt_data.min = ctrl->value; + break; - return err; -} + case V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MAX: + state->f_punt_data.max = ctrl->value; + break; -static int m9mo_g_ext_ctrls(struct v4l2_subdev *sd, - struct v4l2_ext_controls *ctrls) -{ - struct v4l2_ext_control *ctrl = ctrls->controls; - int i, err = 0; + case V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_NUM: + state->f_punt_data.num = ctrl->value; + break; - for (i = 0; i < ctrls->count; i++, ctrl++) { - err = m9mo_g_ext_ctrl(sd, ctrl); - if (err) { - ctrls->error_idx = i; - break; - } - } - return err; -} + case V4L2_CID_CAMERA_FACTORY_FAIL_STOP: + err = m9mo_set_factory_fail_stop(sd, ctrl->value); + break; -static int m9mo_check_manufacturer_id(struct v4l2_subdev *sd) -{ - int i, err; - u8 id; - u32 addr[] = {0x1000AAAA, 0x10005554, 0x1000AAAA}; - u8 val[3][2] = { - [0] = {0x00, 0xAA}, - [1] = {0x00, 0x55}, - [2] = {0x00, 0x90}, - }; - u8 reset[] = {0x00, 0xF0}; + case V4L2_CID_CAMERA_FACTORY_NODEFOCUS: + err = m9mo_set_factory_nodefocus(sd, ctrl->value); + break; - /* set manufacturer's ID read-mode */ - for (i = 0; i < 3; i++) { - err = m9mo_mem_write(sd, 0x06, 2, addr[i], val[i]); - CHECK_ERR(err); - } + case V4L2_CID_CAMERA_FACTORY_INTERPOLATION: + err = m9mo_set_factory_interpolation(sd, ctrl->value); + break; - /* read manufacturer's ID */ - err = m9mo_mem_read(sd, sizeof(id), 0x10000001, &id); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_COMMON: + err = m9mo_set_factory_common(sd, ctrl->value); + break; - /* reset manufacturer's ID read-mode */ - err = m9mo_mem_write(sd, 0x06, sizeof(reset), 0x10000000, reset); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_VIB: + err = m9mo_set_factory_vib(sd, ctrl->value); + break; - cam_dbg("%#x\n", id); + case V4L2_CID_CAMERA_FACTORY_GYRO: + err = m9mo_set_factory_gyro(sd, ctrl->value); + break; - return id; -} + case V4L2_CID_CAMERA_FACTORY_BACKLASH: + err = m9mo_set_factory_backlash(sd, ctrl->value); + break; -static int m9mo_program_fw(struct v4l2_subdev *sd, - u8 *buf, u32 addr, u32 unit, u32 count) -{ - u32 val; - int i, err = 0; - int erase = 0x01; - int test_count = 0; - int retries = 0; + case V4L2_CID_CAMERA_FACTORY_BACKLASH_COUNT: + err = m9mo_set_factory_backlash_count(sd, ctrl->value); + break; - for (i = 0; i < unit*count; i += unit) { - /* Set Flash ROM memory address */ - err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, - M9MO_FLASH_ADDR, addr + i); + case V4L2_CID_CAMERA_FACTORY_BACKLASH_MAXTHRESHOLD: + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, ctrl->value); CHECK_ERR(err); + break; - /* Erase FLASH ROM entire memory */ - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, - M9MO_FLASH_ERASE, erase); - CHECK_ERR(err); - /* Response while sector-erase is operating */ - retries = 0; - do { - mdelay(30); - err = m9mo_readb(sd, M9MO_CATEGORY_FLASH, - M9MO_FLASH_ERASE, &val); - CHECK_ERR(err); - } while (val == erase && retries++ < M9MO_I2C_VERIFY); + case V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MIN: + state->f_zoom_data.range_min = ctrl->value; + break; - if (val != 0) { - cam_err("failed to erase sector\n"); - return -1; - } + case V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MAX: + state->f_zoom_data.range_max = ctrl->value; + break; - /* Set FLASH ROM programming size */ - err = m9mo_writew(sd, M9MO_CATEGORY_FLASH, - M9MO_FLASH_BYTE, unit); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MIN: + state->f_zoom_data.slope_min = ctrl->value; + break; - err = m9mo_mem_write(sd, 0x04, unit, - M9MO_INT_RAM_BASE_ADDR, buf + i); - CHECK_ERR(err); - cam_err("fw Send = %x count = %d\n", i, test_count++); + case V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MAX: + state->f_zoom_data.slope_max = ctrl->value; + break; - /* Start Programming */ - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, M9MO_FLASH_WR, 0x01); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_AF: + err = m9mo_set_factory_af(sd, ctrl->value); + break; - /* Confirm programming has been completed */ - retries = 0; - do { - mdelay(30); - err = m9mo_readb(sd, M9MO_CATEGORY_FLASH, - M9MO_FLASH_WR, &val); - CHECK_ERR(err); - } while (val && retries++ < M9MO_I2C_VERIFY); + case V4L2_CID_CAMERA_FACTORY_AF_STEP_SET: + err = m9mo_set_factory_af_step(sd, ctrl->value); + break; - if (val != 0) { - cam_err("failed to program~~~~\n"); - return -1; - } - } - cam_err("m9mo_program_fw out ~~~~~~~~~~~\n"); - return 0; -} + case V4L2_CID_CAMERA_FACTORY_AF_POSITION: + err = m9mo_set_factory_af_position(sd, ctrl->value); + break; -static int m9mo_load_fw_main(struct v4l2_subdev *sd) -{ - struct m9mo_state *state = to_state(sd); - struct device *dev = sd->v4l2_dev->dev; - const struct firmware *fw = NULL; - u8 *buf_m9mo = NULL; - /*int offset;*/ - int err = 0; + case V4L2_CID_CAMERA_FACTORY_DEFOCUS: + err = m9mo_set_factory_defocus(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FACTORY_DEFOCUS_WIDE: + err = m9mo_set_factory_defocus_wide(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FACTORY_DEFOCUS_TELE: + err = m9mo_set_factory_defocus_tele(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FACTORY_RESOL_CAP: + err = m9mo_set_factory_resol_cap(sd, ctrl->value); + break; + case V4L2_CID_CAMERA_SET_G_VALUE: + state->wb_g_value = ctrl->value; + break; + + case V4L2_CID_CAMERA_SET_B_VALUE: + state->wb_b_value = ctrl->value; + break; + + case V4L2_CID_CAMERA_SET_A_VALUE: + state->wb_a_value = ctrl->value; + break; - struct file *fp; - mm_segment_t old_fs; - long fsize, nread; - int fw_requested = 1; + case V4L2_CID_CAMERA_SET_M_VALUE: + state->wb_m_value = ctrl->value; + break; - old_fs = get_fs(); - set_fs(KERNEL_DS); + case V4L2_CID_CAMERA_SET_GBAM: + err = m9mo_set_GBAM(sd, ctrl->value); + break; - fp = filp_open(M9MO_FW_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - cam_trace("failed to open %s, err %ld\n", - M9MO_FW_PATH, PTR_ERR(fp)); - goto request_fw; - } + case V4L2_CID_CAMERA_SET_K_VALUE: + err = m9mo_set_K(sd, ctrl->value); + break; - fw_requested = 0; - fsize = fp->f_path.dentry->d_inode->i_size; + case V4L2_CID_CAMERA_SET_FLASH_EVC_STEP: + err = m9mo_set_flash_evc_step(sd, ctrl->value); + break; - cam_err("start, file path %s, size %ld Bytes\n", M9MO_FW_PATH, fsize); + case V4L2_CID_CAMERA_FLASH_BATT_INFO: + err = m9mo_set_flash_batt_info(sd, ctrl->value); + break; - buf_m9mo = vmalloc(fsize); - if (!buf_m9mo) { - cam_err("failed to allocate memory\n"); - err = -ENOMEM; - goto out; - } + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MIN: + cam_trace("==========Range X min Data : 0x%x, %d\n", + (short)ctrl->value, (short)ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x21, (short)(ctrl->value)); + CHECK_ERR(err); + break; - nread = vfs_read(fp, (char __user *)buf_m9mo, fsize, &fp->f_pos); - if (nread != fsize) { - cam_err("failed to read firmware file, %ld Bytes\n", nread); - err = -EIO; - goto out; - } + case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MIN: + case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MIN: + cam_trace("==========Range X min Data : 0x%x, %d\n", + (u16)ctrl->value, (u16)ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x21, (short)(ctrl->value)); + CHECK_ERR(err); + break; - filp_close(fp, current->files); + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MAX: + cam_trace("==========Range X max Data : 0x%x, %d\n", + (short)ctrl->value, (short)ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x23, (short)(ctrl->value)); + CHECK_ERR(err); + break; -request_fw: - if (fw_requested) { - set_fs(old_fs); + case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MAX: + case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MAX: + cam_trace("==========Range X max Data : 0x%x, %d\n", + (u16)ctrl->value, (u16)ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x23, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH); - err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev); + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MIN: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x25, (short)(ctrl->value)); + CHECK_ERR(err); + break; - if (err != 0) { - cam_err("request_firmware failed\n"); - err = -EINVAL; - goto out; - } - cam_dbg("start, size %d Bytes\n", fw->size); - buf_m9mo = (u8 *)fw->data; - } + case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MIN: + case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MIN: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x25, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001200 , buf_port_seting0); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MAX: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x27, (short)(ctrl->value)); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001000 , buf_port_seting1); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MAX: + case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MAX: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x27, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001100 , buf_port_seting2); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_GAIN: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x29, (short)(ctrl->value)); + CHECK_ERR(err); + break; - err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, - 0x1C, 0x0247036D); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_X: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x29, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, - 0x4A, 0x01); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_X: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x2B, (short)(ctrl->value)); + CHECK_ERR(err); + break; - /* program FLASH ROM */ - err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR, SZ_4K, 512); - if (err < 0) - goto out; + case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_Y: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x2B, (u16)(ctrl->value)); + CHECK_ERR(err); + break; + case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_Y: + err = m9mo_writew(sd, M9MO_CATEGORY_NEW, + 0x2D, (u16)(ctrl->value)); + CHECK_ERR(err); + break; -#if 0 - offset = SZ_64K * 31; - if (id == 0x01) { - err = m9mo_program_fw(sd, buf + offset, - M9MO_FLASH_BASE_ADDR + offset, SZ_8K, 4, id); - } else { - err = m9mo_program_fw(sd, buf + offset, - M9MO_FLASH_BASE_ADDR + offset, SZ_4K, 8, id); - } -#endif - cam_err("end\n"); - state->isp.bad_fw = 0; + case V4L2_CID_CAMERA_FACTORY_TEST_NUMBER: + cam_trace("==========FACTORY_TEST_NUMBER : 0x%x\n", + ctrl->value); -out: - if (!fw_requested) { - vfree(buf_m9mo); + err = m9mo_readw(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, &int_en); + CHECK_ERR(err); + int_en &= ~M9MO_INT_SOUND; + err = m9mo_writew(sd, M9MO_CATEGORY_SYS, + M9MO_SYS_INT_EN, int_en); + CHECK_ERR(err); - filp_close(fp, current->files); - set_fs(old_fs); - } else { - release_firmware(fw); - } + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x41, ctrl->value); + state->factory_test_num = ctrl->value; + CHECK_ERR(err); + break; - return err; -} + case V4L2_CID_SET_CONTINUE_FPS: + state->continueFps = ctrl->value; + break; -static int m9mo_load_fw_info(struct v4l2_subdev *sd) -{ - const struct firmware *fw = NULL; - u8 *buf_m9mo = NULL; - /*int offset;*/ - int err = 0; + case V4L2_CID_CONTINUESHOT_PROC: + err = m9mo_continue_proc(sd, ctrl->value); + break; - struct file *fp; - mm_segment_t old_fs; - long fsize, nread; - int fw_requested = 1; + case V4L2_CID_BURSTSHOT_PROC: + err = m9mo_burst_proc(sd, ctrl->value); + break; - old_fs = get_fs(); - set_fs(KERNEL_DS); + case V4L2_CID_BURSTSHOT_SET_POSTVIEW_SIZE: + err = m9mo_burst_set_postview_size(sd, ctrl->value); + break; - fp = filp_open(FW_INFO_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - cam_trace("failed to open %s, err %ld\n", - M9MO_FW_PATH, PTR_ERR(fp)); - } - fsize = fp->f_path.dentry->d_inode->i_size; + case V4L2_CID_BURSTSHOT_SET_SNAPSHOT_SIZE: + err = m9mo_burst_set_snapshot_size(sd, ctrl->value); + break; - cam_err("start, file path %s, size %ld Bytes\n", FW_INFO_PATH, fsize); +#if 0 + case V4L2_CID_CAMERA_DUAL_POSTVIEW: + err = m9mo_start_dual_postview(sd, ctrl->value); + break; - buf_m9mo = vmalloc(fsize); - if (!buf_m9mo) { - cam_err("failed to allocate memory\n"); - err = -ENOMEM; - goto out; - } + case V4L2_CID_CAMERA_DUAL_CAPTURE: + err = m9mo_start_dual_capture(sd, ctrl->value); + break; +#endif - nread = vfs_read(fp, (char __user *)buf_m9mo, fsize, &fp->f_pos); - if (nread != fsize) { - cam_err("failed to read firmware file, %ld Bytes\n", nread); - err = -EIO; - goto out; - } + case V4L2_CID_CAMERA_SET_DUAL_CAPTURE: + err = m9mo_start_set_dual_capture(sd, ctrl->value); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001200 , buf_port_seting0); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_DUAL_CAPTURE_MODE: + /*err = m9mo_set_dual_capture_mode(sd, ctrl->value);*/ + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001000 , buf_port_seting1); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MIN: + case V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MIN: + temp = (short)((ctrl->value) & 0x0000FFFF); + cam_trace("==========Range min Data : 0x%x, %d\n", + temp, temp); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x18, temp); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001100 , buf_port_seting2); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MAX: + case V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MAX: + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, - 0x1C, 0x0247036D); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_AF_LENS: + err = m9mo_set_factory_af_lens(sd, ctrl->value); + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, - 0x4A, 0x01); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_AF_ZONE: + err = m9mo_set_factory_af_zone(sd, ctrl->value); + break; - /* program FLSH ROM */ - err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR_1, SZ_4K, 1); - if (err < 0) - goto out; + case V4L2_CID_CAMERA_FACTORY_LV_TARGET: + cam_trace("FACTORY_LV_TARGET : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x52, ctrl->value); + CHECK_ERR(err); + break; + case V4L2_CID_CAMERA_FACTORY_ADJ_IRIS: + err = m9mo_set_factory_adj_iris(sd, ctrl->value); + break; -#if 0 - offset = SZ_64K * 31; - if (id == 0x01) { - err = m9mo_program_fw(sd, buf + offset, - M9MO_FLASH_BASE_ADDR + offset, SZ_8K, 4, id); - } else { - err = m9mo_program_fw(sd, buf + offset, - M9MO_FLASH_BASE_ADDR + offset, SZ_4K, 8, id); - } -#endif - cam_err("end\n"); + case V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MIN: + cam_trace("FACTORY_ADJ_IRIS_RANGE_MIN : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x54, (unsigned char)(ctrl->value)); + CHECK_ERR(err); + break; -out: - if (!fw_requested) { - vfree(buf_m9mo); + case V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MAX: + cam_trace("FACTORY_ADJ_IRIS_RANGE_MAX : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x55, (unsigned char)(ctrl->value)); + CHECK_ERR(err); + break; - filp_close(fp, current->files); - set_fs(old_fs); - } else { - release_firmware(fw); - } + case V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW: + err = m9mo_set_factory_adj_gain_liveview(sd, ctrl->value); + break; - return err; -} + case V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_MARK: + cam_trace("FACTORY_LIVEVIEW_OFFSET_MARK : 0x%x\n", + ctrl->value); + err = m9mo_writel(sd, M9MO_CATEGORY_ADJST, + 0x3A, (u32)ctrl->value); + CHECK_ERR(err); + break; + + case V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_VAL: + cam_trace("FACTORY_LIVEVIEW_OFFSET_VAL : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x3E, (u16)ctrl->value); + CHECK_ERR(err); + break; + case V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN: + cam_trace("FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x56, (u16)(ctrl->value)); + CHECK_ERR(err); + break; + case V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX: + cam_trace("FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x58, (u16)(ctrl->value)); + CHECK_ERR(err); + break; -static int m9mo_load_fw(struct v4l2_subdev *sd) -{ - struct device *dev = sd->v4l2_dev->dev; - const struct firmware *fw = NULL; - u8 sensor_ver[M9MO_FW_VER_LEN] = {0, }; - u8 *buf_m9mo = NULL, *buf_fw_info = NULL; - /*int offset;*/ - int err = 0; + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE: + err = m9mo_set_factory_sh_close(sd, ctrl->value); + break; - struct file *fp; - mm_segment_t old_fs; - long fsize, nread; - int fw_requested = 1; + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_IRIS_NUM: + cam_trace("FACTORY_SH_CLOSE_IRIS_NUM : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x51, ctrl->value); + CHECK_ERR(err); + break; - old_fs = get_fs(); - set_fs(KERNEL_DS); + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SET_IRIS: + cam_trace("FACTORY_SH_CLOSE_SET_IRIS : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x6E, ctrl->value); + CHECK_ERR(err); + break; + + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_RANGE: + cam_trace("FACTORY_SH_CLOSE_RANGE : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x5A, (u16)(ctrl->value)); + CHECK_ERR(err); + break; + + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_ISO: + cam_trace("FACTORY_SH_CLOSE_ISO : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + 0x3B, ctrl->value); + CHECK_ERR(err); + break; + + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_X: + cam_trace("FACTORY_SH_CLOSE_SPEEDTIME_X : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + 0x37, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - fp = filp_open(M9MO_FW_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - cam_err("failed to open %s, err %ld\n", - M9MO_FW_PATH, PTR_ERR(fp)); - goto request_fw; - } + case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_Y: + cam_trace("FACTORY_SH_CLOSE_SPEEDTIME_Y : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_AE, + 0x39, (u16)(ctrl->value)); + CHECK_ERR(err); + break; - fw_requested = 0; - fsize = fp->f_path.dentry->d_inode->i_size; + case V4L2_CID_CAMERA_FACTORY_FLICKER: + err = m9mo_set_factory_flicker(sd, ctrl->value); + break; - cam_err("start, file path %s, size %ld Bytes\n", M9MO_FW_PATH, fsize); + case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN: + err = m9mo_set_factory_capture_gain(sd, ctrl->value); + break; - buf_m9mo = vmalloc(fsize); - if (!buf_m9mo) { - cam_err("failed to allocate memory\n"); - err = -ENOMEM; - goto out; - } + case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_MARK: + cam_trace("FACTORY_CAPTURE_GAIN_OFFSET_MARK : 0x%x\n", + ctrl->value); + err = m9mo_writel(sd, M9MO_CATEGORY_ADJST, + 0x3A, (u32)ctrl->value); + CHECK_ERR(err); + break; - nread = vfs_read(fp, (char __user *)buf_m9mo, fsize, &fp->f_pos); - if (nread != fsize) { - cam_err("failed to read firmware file, %ld Bytes\n", nread); - err = -EIO; - goto out; - } + case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_VAL: + cam_trace("FACTORY_CAPTURE_GAIN_OFFSET_VAL : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x3E, (u16)ctrl->value); + CHECK_ERR(err); + break; - filp_close(fp, current->files); + case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MIN: + cam_trace("FACTORY_CAPTURE_GAIN_RANGE_MIN : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x56, (u16)ctrl->value); + CHECK_ERR(err); + break; - fp = filp_open(FW_INFO_PATH, O_RDONLY, 0); - if (IS_ERR(fp)) { - cam_trace("failed to open %s, err %ld\n", - FW_INFO_PATH, PTR_ERR(fp)); - goto request_fw; - } + case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MAX: + cam_trace("FACTORY_CAPTURE_GAIN_RANGE_MAX : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x58, (u16)ctrl->value); + CHECK_ERR(err); + break; - fw_requested = 0; - fsize = fp->f_path.dentry->d_inode->i_size; + case V4L2_CID_CAMERA_FACTORY_LSC_TABLE: + cam_trace("FACTORY_LSC_TABLE : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x30, ctrl->value); + CHECK_ERR(err); + break; - cam_err("start, file path %s, size %ld Bytes\n", FW_INFO_PATH, fsize); + case V4L2_CID_CAMERA_FACTORY_LSC_REFERENCE: + cam_trace("FACTORY_LSC_REFERENCE : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x31, ctrl->value); + CHECK_ERR(err); + break; - buf_fw_info = vmalloc(fsize); - if (!buf_fw_info) { - cam_err("failed to allocate memory\n"); - err = -ENOMEM; - goto out; - } + case V4L2_CID_CAMERA_FACTORY_CAPTURE_CTRL: + err = m9mo_set_factory_capture_ctrl(sd, ctrl->value); + break; - nread = vfs_read(fp, (char __user *)buf_fw_info, fsize, &fp->f_pos); - if (nread != fsize) { - cam_err("failed to read firmware file, %ld Bytes\n", nread); - err = -EIO; - goto out; - } + case V4L2_CID_CAMERA_FACTORY_AE_TARGET: + cam_trace("V4L2_CID_CAMERA_FACTORY_AE_TARGET : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_AE, + 0x02, (unsigned char)ctrl->value); + CHECK_ERR(err); + break; + case V4L2_CID_CAMERA_FACTORY_FLASH: + err = m9mo_set_factory_flash(sd, ctrl->value); + break; -request_fw: - if (fw_requested) { - set_fs(old_fs); + case V4L2_CID_CAMERA_FACTORY_FLASH_CHR_CHK_TM: + cam_trace("FLASH_CHR_CHK_TM : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_CAPPARM, + 0x3B, (u16)ctrl->value); + CHECK_ERR(err); + break; - m9mo_get_sensor_fw_version(sd, sensor_ver); + case V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_X: + cam_trace("FLASH_RANGE_X : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x71, (u16)ctrl->value); + CHECK_ERR(err); + break; - if (sensor_ver[0] == 'T' && sensor_ver[1] == 'B') { - err = request_firmware(&fw, M9MOTB_FW_PATH, dev); -#if defined(CONFIG_MACH_Q1_BD) - } else if (sensor_ver[0] == 'O' && sensor_ver[1] == 'O') { - err = request_firmware(&fw, M9MOOO_FW_PATH, dev); -#endif -#if defined(CONFIG_MACH_U1_KOR_LGT) - } else if (sensor_ver[0] == 'S' && sensor_ver[1] == 'B') { - err = request_firmware(&fw, M9MOSB_FW_PATH, dev); -#endif - } else { - cam_err("cannot find the matched F/W file\n"); - err = -EINVAL; - } + case V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_Y: + cam_trace("FLASH_RANGE_Y : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x73, (u16)ctrl->value); + CHECK_ERR(err); + break; - if (err != 0) { - cam_err("request_firmware falied\n"); - err = -EINVAL; - goto out; - } - cam_dbg("start, size %d Bytes\n", fw->size); - buf_m9mo = (u8 *)fw->data; - } + case V4L2_CID_CAMERA_FACTORY_WB: + err = m9mo_set_factory_wb(sd, ctrl->value); + break; + case V4L2_CID_CAMERA_FACTORY_WB_IN_RG_VALUE: + cam_trace("WB_IN_RG_VALUE : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x27, (u16)ctrl->value); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001200 , buf_port_seting0); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_WB_IN_BG_VALUE: + cam_trace("WB_IN_BG_VALUE : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x29, (u16)ctrl->value); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001000 , buf_port_seting1); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_WB_OUT_RG_VALUE: + cam_trace("WB_OUT_RG_VALUE : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x2B, (u16)ctrl->value); + CHECK_ERR(err); + break; - err = m9mo_mem_write(sd, 0x04, SZ_64, - 0x90001100 , buf_port_seting2); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_WB_OUT_BG_VALUE: + cam_trace("WB_OUT_RG_VALUE : 0x%x\n", + ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_ADJST, + 0x2D, (u16)ctrl->value); + CHECK_ERR(err); + break; - err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, - 0x1C, 0x0247036D); - CHECK_ERR(err); + case V4L2_CID_CAMERA_FACTORY_WB_RANGE: + cam_trace("WB_RANGE_PERCENT : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x1F, (u8)ctrl->value); + CHECK_ERR(err); + break; - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, - 0x4A, 0x01); - CHECK_ERR(err); - mdelay(10); + case V4L2_CID_CAMERA_FACTORY_WB_RANGE_FLASH_WRITE: + err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST, + 0x26, 0x01); + CHECK_ERR(err); + break; - /* program FLSH ROM */ - err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR, SZ_4K, 504); - if (err < 0) - goto out; + case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_X: + cam_trace("AFLED_RANGE_DATA_START_X : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x43, (unsigned char)ctrl->value); + CHECK_ERR(err); + break; - err = m9mo_program_fw(sd, buf_fw_info, - M9MO_FLASH_BASE_ADDR_1, SZ_4K, 1); - if (err < 0) - goto out; + case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_X: + cam_trace("AFLED_RANGE_DATA_END_X : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x44, (unsigned char)ctrl->value); + CHECK_ERR(err); + break; -#if 0 - offset = SZ_64K * 31; - if (id == 0x01) { - err = m9mo_program_fw(sd, buf + offset, - M9MO_FLASH_BASE_ADDR + offset, SZ_8K, 4, id); - } else { - err = m9mo_program_fw(sd, buf + offset, - M9MO_FLASH_BASE_ADDR + offset, SZ_4K, 8, id); - } -#endif - cam_err("end\n"); + case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_Y: + cam_trace("AFLED_RANGE_DATA_START_Y : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x45, (unsigned char)ctrl->value); + CHECK_ERR(err); + break; -out: - if (!fw_requested) { - vfree(buf_m9mo); - vfree(buf_fw_info); + case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_Y: + cam_trace("AFLED_RANGE_DATA_END_Y : 0x%x\n", + ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x46, (unsigned char)ctrl->value); + CHECK_ERR(err); + break; - filp_close(fp, current->files); - set_fs(old_fs); - } else { - release_firmware(fw); - } + case V4L2_CID_CAMERA_FACTORY_AF_LED_TIME: + cam_trace("AF_LED_TIME : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x4B, ctrl->value); + CHECK_ERR(err); - return err; -} + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x4D, 0x01); + CHECK_ERR(err); + break; + case V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MIN: + cam_trace("AF_DIFF_CHECK_MIN : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x18, (u16)ctrl->value); + CHECK_ERR(err); + break; -static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct m9mo_state *state = to_state(sd); - int err = 0; + case V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MAX: + cam_trace("AF_DIFF_CHECK_MAX : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, (u16)ctrl->value); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0xD, 0x11); + CHECK_ERR(err); + break; - cam_trace(" id %d, value %d\n", - ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL: + err = m9mo_set_factory_defectpixel(sd, ctrl->value); + break; - if (unlikely(state->isp.bad_fw && ctrl->id != V4L2_CID_CAM_UPDATE_FW)) { - cam_err("\"Unknown\" state, please update F/W"); - return -ENOSYS; - } + case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_CAP: + cam_trace("DFPX_NLV_CAP : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_PARM, + 0x70, (u16) ctrl->value); + CHECK_ERR(err); + break; - switch (ctrl->id) { - case V4L2_CID_CAM_UPDATE_FW: - if (ctrl->value == FW_MODE_DUMP) - err = m9mo_dump_fw(sd); - else - err = m9mo_check_fw(sd); + case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1_HD: + cam_trace("DFPX_NLV_DR1_HD : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_PARM, + 0x7A, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_SENSOR_MODE: -#ifdef FAST_CAPTURE - err = m9mo_set_fast_capture(sd); -#else - err = m9mo_set_sensor_mode(sd, ctrl->value); -#endif + case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR0: + cam_trace("DFPX_NLV_DR0 : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_PARM, + 0x76, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_FLASH_MODE: - err = m9mo_set_flash(sd, ctrl->value, 0); + case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1: + cam_trace("DFPX_NLV_D1 : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_PARM, + 0x72, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_ISO: - err = m9mo_set_iso(sd, ctrl); + case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR2: + cam_trace("DFPX_NLV_DR2 : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_PARM, + 0x78, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_METERING: - if (state->sensor_mode == SENSOR_CAMERA) - err = m9mo_set_metering(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR_HS: + cam_trace("DFPX_NLV_DR_HS : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_PARM, + 0x74, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_BRIGHTNESS: - err = m9mo_set_exposure(sd, ctrl); + case V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MIN: + cam_trace("AF_LED_LV_MIN : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x47, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_WHITE_BALANCE: - err = m9mo_set_whitebalance(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MAX: + cam_trace("AF_LED_LV_MIN : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x49, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_SCENE_MODE: - err = m9mo_set_scene_mode(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_CAM_SYS_MODE: + err = m9mo_set_factory_cam_sys_mode(sd, ctrl->value); break; - case V4L2_CID_CAMERA_EFFECT: - err = m9mo_set_effect(sd, ctrl->value); + case V4L2_CID_CAMERA_PASM_MODE: + err = m9mo_set_PASM_mode(sd, ctrl->value); break; - case V4L2_CID_CAMERA_WDR: - err = m9mo_set_wdr(sd, ctrl->value); + case V4L2_CID_CAMERA_SHUTTER_SPEED: + err = m9mo_set_shutter_speed(sd, ctrl->value); break; - case V4L2_CID_CAMERA_ANTI_SHAKE: - err = m9mo_set_antishake(sd, ctrl->value); + case V4L2_CID_CAMERA_F_NUMBER: + err = m9mo_set_f_number(sd, ctrl->value); break; - case V4L2_CID_CAMERA_BEAUTY_SHOT: - err = m9mo_set_face_beauty(sd, ctrl->value); + case V4L2_CID_CAMERA_WB_CUSTOM_X: + state->wb_custom_rg = ctrl->value; break; - case V4L2_CID_CAMERA_FOCUS_MODE: - err = m9mo_set_af_mode(sd, ctrl->value); + case V4L2_CID_CAMERA_WB_CUSTOM_Y: + state->wb_custom_bg = ctrl->value; break; - case V4L2_CID_CAMERA_SET_AUTO_FOCUS: - err = m9mo_set_af(sd, ctrl->value); + case V4L2_CID_CAMERA_WB_CUSTOM_VALUE: + err = m9mo_set_wb_custom(sd, ctrl->value); break; - case V4L2_CID_CAMERA_OBJECT_POSITION_X: - state->focus.pos_x = ctrl->value; - /* FIXME - It should be fixed on F/W (touch AF offset) */ - if (state->preview != NULL) { - if (state->exif.unique_id[0] == 'T') { - if (state->preview->index == M9MO_PREVIEW_VGA) - state->focus.pos_x -= 40; - else if (state->preview->index == - M9MO_PREVIEW_WVGA) - state->focus.pos_x -= 50; - } + case V4L2_CID_CAMERA_SMART_SCENE_DETECT: + if (ctrl->value == 1) { + state->smart_scene_detect_mode = 1; + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x02); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x0A, 0x01); + CHECK_ERR(err); + } else { + state->smart_scene_detect_mode = 0; + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x0A, 0x00); + CHECK_ERR(err); } break; - case V4L2_CID_CAMERA_OBJECT_POSITION_Y: - state->focus.pos_y = ctrl->value; - /* FIXME - It should be fixed on F/W (touch AF offset) */ - if (state->preview != NULL) { - if (state->preview->index == M9MO_PREVIEW_VGA) { - if (state->exif.unique_id[0] == 'T') - state->focus.pos_y -= 50; - } else if (state->preview->index == M9MO_PREVIEW_WVGA) { - if (state->exif.unique_id[0] == 'T') - state->focus.pos_y -= 2; - else - state->focus.pos_y += 60; + case V4L2_CID_CAMERA_SMART_MOVIE_RECORDING: + if (state->smart_scene_detect_mode == 1) { + if (ctrl->value == 1) { + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x0A, 0x02); + CHECK_ERR(err); + } else { + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x0A, 0x01); + CHECK_ERR(err); } } + + /* add recording check for zoom move */ + if (ctrl->value == 1) { + state->recording = 1; + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, 0x27, 0x01); + CHECK_ERR(err); + } else { + state->recording = 0; + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, 0x27, 0x00); + CHECK_ERR(err); + } break; - case V4L2_CID_CAMERA_TOUCH_AF_START_STOP: - err = m9mo_set_touch_auto_focus(sd, ctrl->value); + case V4L2_CID_CAMERA_SMART_AUTO_S1_PUSH: + err = m9mo_set_smart_auto_s1_push(sd, ctrl->value); break; - case V4L2_CID_CAMERA_ZOOM: - err = m9mo_set_zoom(sd, ctrl); + case V4L2_CID_CAMERA_CAF: + err = m9mo_set_CAF(sd, ctrl->value); break; - case V4L2_CID_CAMERA_OPTICAL_ZOOM_STEP: - err = m9mo_set_optical_zoom_step(sd, ctrl); + case V4L2_CID_CAMERA_FOCUS_RANGE: + err = m9mo_set_focus_range(sd, ctrl->value); break; - case V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL: - err = m9mo_set_optical_zoom_ctrl(sd, ctrl->value); + case V4L2_CID_CAMERA_TIME_INFO: + err = m9mo_set_time_info(sd, ctrl->value); break; - case V4L2_CID_CAM_JPEG_QUALITY: - err = m9mo_set_jpeg_quality(sd, ctrl); + case V4L2_CID_CAMERA_LENS_TIMER: + err = m9mo_set_lens_off_timer(sd, ctrl->value); break; - case V4L2_CID_CAMERA_CAPTURE: - err = m9mo_start_capture(sd, ctrl->value); + case V4L2_CID_CAMERA_STREAM_PART2: /* for shutter sound */ + err = m9mo_set_mode_part2(sd, M9MO_STILLCAP_MODE); break; - case V4L2_CID_CAMERA_YUV_CAPTURE: - err = m9mo_start_YUV_capture(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_SEND_SETTING: + state->factory_category = (ctrl->value) / 1000; + state->factory_byte = (ctrl->value) % 1000; break; - case V4L2_CID_CAMERA_POSTVIEW_CAPTURE: - err = m9mo_start_postview_capture(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_SEND_VALUE: + state->factory_value_size = 1; + state->factory_value = ctrl->value; + m9mo_send_factory_command_value(sd); break; - case V4L2_CID_CAMERA_CAPTURE_MODE: - err = m9mo_set_capture_mode(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_SEND_WORD_VALUE: + state->factory_value_size = 2; + state->factory_value = ctrl->value; + m9mo_send_factory_command_value(sd); break; - /*case V4L2_CID_CAMERA_HDR: - err = m9mo_set_hdr(sd, ctrl->value); - break;*/ + case V4L2_CID_CAMERA_FACTORY_SEND_LONG_VALUE: + state->factory_value_size = 4; + state->factory_value = ctrl->value; + m9mo_send_factory_command_value(sd); + break; - case V4L2_CID_CAMERA_VT_MODE: - state->vt_mode = ctrl->value; + case V4L2_CID_CAMERA_FACTORY_TILT: + cam_trace("TILT_ONE_SCRIPT_RUN : 0x%x\n", ctrl->value); + m9mo_set_factory_tilt(sd, ctrl->value); break; - case V4L2_CID_CAMERA_CHECK_DATALINE: - state->check_dataline = ctrl->value; + case V4L2_CID_CAMERA_FACTORY_IR_CHECK: + cam_trace("IR_CHECK : 0x%x\n", ctrl->value); + m9mo_set_factory_IR_Check(sd, ctrl->value); break; - case V4L2_CID_CAMERA_ANTI_BANDING: - err = m9mo_set_antibanding(sd, ctrl); + case V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MIN: + cam_trace("TILT_SCAN_MIN : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x18, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_CHECK_ESD: - err = m9mo_check_esd(sd); + case V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MAX: + cam_trace("TILT_SCAN_MAX : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, (u16)ctrl->value); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0D, 0x06); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK: - err = m9mo_set_aeawblock(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_TILT_FIELD: + cam_trace("TILT_FIELD : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, (u8)ctrl->value); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0C, 0x00); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_FACE_DETECTION: - err = m9mo_set_facedetect(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MIN: + cam_trace("TILT_AF_RANGE_MIN : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x18, (u16)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_BRACKET: - err = m9mo_set_bracket(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MAX: + cam_trace("TILT_AF_RANGE_MAX : 0x%x\n", ctrl->value); + err = m9mo_writew(sd, M9MO_CATEGORY_LENS, + 0x1A, (u16)ctrl->value); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0C, 0x01); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_BRACKET_AEB: - err = m9mo_set_bracket_aeb(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MIN: + cam_trace("TILT_DIFF_MIN : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1A, (u8)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_BRACKET_WBB: - err = m9mo_set_bracket_wbb(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MAX: + cam_trace("TILT_DIFF_MAX : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x1B, (u8)ctrl->value); + CHECK_ERR(err); + err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, + 0x0C, 0x02); + CHECK_ERR(err); break; - case V4L2_CID_CAMERA_FRAME_RATE: - err = m9mo_set_fps(sd, ctrl->value); - state->fps = ctrl->value; + case V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MIN: + cam_trace("IR_B_GAIN_MIN : 0x%x\n", ctrl->value); break; - case V4L2_CID_CAMERA_LDC: - err = m9mo_set_LDC(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MAX: + cam_trace("IR_B_GAIN_MAX : 0x%x\n", ctrl->value); break; - case V4L2_CID_CAMERA_LSC: - err = m9mo_set_LSC(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MIN: + cam_trace("IR_R_GAIN_MIN : 0x%x\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MAX: + cam_trace("IR_R_GAIN_MAX : 0x%x\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_FACTORY_FLASH_MAN_CHARGE: + cam_trace("FLASH_MAN_CHARGE : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x2A, (u8)ctrl->value); + CHECK_ERR(err); break; - case V4L2_CID_CAM_APERTURE: - err = m9mo_set_aperture(sd, ctrl->value); + case V4L2_CID_CAMERA_FACTORY_FLASH_MAN_EN: + cam_trace("FLASH_MAN_EN : 0x%x\n", ctrl->value); + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + 0x3D, (u8)ctrl->value); + CHECK_ERR(err); break; default: @@ -3737,47 +10481,101 @@ static const struct m9mo_frmsizeenum *m9mo_get_frmsize static int m9mo_set_frmsize(struct v4l2_subdev *sd) { struct m9mo_state *state = to_state(sd); - struct v4l2_control ctrl; int err; + int read_mon_size; + u32 size_val; cam_trace("E\n"); if (state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW) { err = m9mo_set_mode(sd, M9MO_PARMSET_MODE); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, - M9MO_PARM_MON_SIZE, state->preview->reg_val); + m9mo_set_gamma(sd); + + err = m9mo_readb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_SIZE, &read_mon_size); CHECK_ERR(err); - if (state->zoom) { - /* Zoom position returns to 1 - when the monitor size is changed. */ - ctrl.id = V4L2_CID_CAMERA_ZOOM; - ctrl.value = state->zoom; - m9mo_set_zoom(sd, &ctrl); + /* don't set frmsize when returning preivew after capture */ + if (err == 10) + cam_trace("~~~~ return when CAP->PAR ~~~~\n"); + else { + if (state->fps == 60) { + if (state->preview->height == 480) + size_val = 0x2F; + else if (state->preview->height == 720) + size_val = 0x25; + + if (read_mon_size != size_val) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_SIZE, size_val); + CHECK_ERR(err); + } + } else if (state->sensor_mode == SENSOR_MOVIE + && state->fps == 30) { + if (state->preview->height == 1080) + size_val = 0x2C; + else if (state->preview->height == 720) + size_val = 0x2D; + else if (state->preview->width == 640 + && state->preview->height == 480) + size_val = 0x2E; + else if (state->preview->width == 320 + && state->preview->height == 240) + size_val = 0x36; + + if (read_mon_size != size_val) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_SIZE, size_val); + CHECK_ERR(err); + } + } else { + if (read_mon_size != state->preview->reg_val) { + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_MON_SIZE, + state->preview->reg_val); + CHECK_ERR(err); + } } +#if 1 /* Dual Capture */ + if (size_val == 0x2C + || size_val == 0x2D + || size_val == 0x2E + || size_val == 0x36) + m9mo_set_dual_capture_mode(sd, 1); + else + m9mo_set_dual_capture_mode(sd, 0); +#endif + } cam_err("preview frame size %dx%d\n", state->preview->width, state->preview->height); } else { - if (state->pixelformat == V4L2_COLORSPACE_JPEG) { - err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, - M9MO_CAPPARM_MAIN_IMG_SIZE, - state->capture->reg_val); - CHECK_ERR(err); + if (state->pixelformat == V4L2_COLORSPACE_JPEG + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT + || state->running_capture_mode == RUNNING_MODE_HDR) { + if (!state->dual_capture_start) { + err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, + M9MO_CAPPARM_MAIN_IMG_SIZE, + state->capture->reg_val); + CHECK_ERR(err); + if (state->smart_zoom_mode) + m9mo_set_smart_zoom(sd, + state->smart_zoom_mode); + } cam_info("capture frame size %dx%d\n", - state->capture->width, state->capture->height); + state->capture->width, + state->capture->height); } else { err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM, M9MO_CAPPARM_PREVIEW_IMG_SIZE, - state->capture->reg_val); + state->postview->reg_val); CHECK_ERR(err); - cam_info("capture frame size %dx%d\n", - state->capture->width, - state->capture->height); + cam_info("postview frame size %dx%d\n", + state->postview->width, + state->postview->height); } } - cam_trace("X\n"); return 0; } @@ -3801,8 +10599,14 @@ static int m9mo_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *ffmt) state->format_mode = ffmt->field; state->pixelformat = ffmt->colorspace; - frmsize = state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW ? - &state->preview : &state->capture; + if (state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW) + frmsize = &state->preview; + else if (state->pixelformat == V4L2_COLORSPACE_JPEG + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT + || state->running_capture_mode == RUNNING_MODE_HDR) + frmsize = &state->capture; + else + frmsize = &state->postview; old_index = *frmsize ? (*frmsize)->index : -1; *frmsize = NULL; @@ -3817,24 +10621,42 @@ static int m9mo_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *ffmt) } } } else { - num_entries = ARRAY_SIZE(capture_frmsizes); - for (i = 0; i < num_entries; i++) { - if (width == capture_frmsizes[i].width && - height == capture_frmsizes[i].height) { - *frmsize = &capture_frmsizes[i]; - break; + if (state->pixelformat == V4L2_COLORSPACE_JPEG + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT + || state->running_capture_mode == RUNNING_MODE_HDR) { + num_entries = ARRAY_SIZE(capture_frmsizes); + for (i = 0; i < num_entries; i++) { + if (width == capture_frmsizes[i].width && + height == capture_frmsizes[i].height) { + *frmsize = &capture_frmsizes[i]; + break; + } + } + } else { + num_entries = ARRAY_SIZE(postview_frmsizes); + for (i = 0; i < num_entries; i++) { + if (width == postview_frmsizes[i].width && + height == postview_frmsizes[i].height) { + *frmsize = &postview_frmsizes[i]; + break; + } } } } if (*frmsize == NULL) { cam_warn("invalid frame size %dx%d\n", width, height); - *frmsize = state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW ? - m9mo_get_frmsize(preview_frmsizes, num_entries, - M9MO_PREVIEW_VGA) : - - m9mo_get_frmsize(capture_frmsizes, num_entries, - M9MO_CAPTURE_3MP); + if (state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW) + *frmsize = m9mo_get_frmsize(preview_frmsizes, + num_entries, M9MO_PREVIEW_720P); + else if (state->pixelformat == V4L2_COLORSPACE_JPEG + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT + || state->running_capture_mode == RUNNING_MODE_HDR) + *frmsize = m9mo_get_frmsize(capture_frmsizes, + num_entries, M9MO_CAPTURE_12MPW); + else + *frmsize = m9mo_get_frmsize(postview_frmsizes, + num_entries, M9MO_CAPTURE_POSTWHD); } cam_err("%dx%d\n", (*frmsize)->width, (*frmsize)->height); @@ -3868,25 +10690,13 @@ static int m9mo_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) } if (fps != state->fps) { - if (fps <= 0 || fps > 30) { + if (fps <= 0 || fps > 120) { cam_err("invalid frame rate %d\n", fps); - fps = 30; + fps = 0; /* set to auto(default) */ } - state->fps = fps; } -#if 0 - err = m9mo_set_mode(sd, M9MO_PARMSET_MODE); - CHECK_ERR(err); -#endif - - cam_dbg("fixed fps %d\n", state->fps); -#if 0 - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, - M9MO_PARM_FLEX_FPS, state->fps != 30 ? state->fps : 0); - CHECK_ERR(err); -#endif - + cam_info("%s: X, fps = %d\n", __func__, fps); return 0; } @@ -3909,7 +10719,9 @@ static int m9mo_enum_framesizes(struct v4l2_subdev *sd, fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; fsize->discrete.width = state->preview->width; fsize->discrete.height = state->preview->height; - } else { + } else if (state->pixelformat == V4L2_COLORSPACE_JPEG + || state->running_capture_mode == RUNNING_MODE_LOWLIGHT + || state->running_capture_mode == RUNNING_MODE_HDR) { if (state->capture == NULL /* FIXME || state->capture->index < 0 */) return -EINVAL; @@ -3917,6 +10729,14 @@ static int m9mo_enum_framesizes(struct v4l2_subdev *sd, fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; fsize->discrete.width = state->capture->width; fsize->discrete.height = state->capture->height; + } else { + if (state->postview == NULL + /* FIXME || state->postview->index < 0 */) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = state->postview->width; + fsize->discrete.height = state->postview->height; } return 0; @@ -3925,7 +10745,8 @@ static int m9mo_enum_framesizes(struct v4l2_subdev *sd, static int m9mo_s_stream_preview(struct v4l2_subdev *sd, int enable) { struct m9mo_state *state = to_state(sd); - u32 old_mode, int_factor, value; + struct v4l2_control ctrl; + u32 old_mode, int_factor; int err; if (enable) { @@ -3935,23 +10756,6 @@ static int m9mo_s_stream_preview(struct v4l2_subdev *sd, int enable) CHECK_ERR(err); } - if (state->preview->width == 720 && - state->preview->height == 480) { - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_EP_MODE_MON, 0x1C); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_EP_MODE_CAP, 0x1C); - CHECK_ERR(err); - } else { - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_EP_MODE_MON, 0x00); - CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_AE, - M9MO_AE_EP_MODE_CAP, 0x00); - CHECK_ERR(err); - } - old_mode = m9mo_set_mode(sd, M9MO_MONITOR_MODE); if (old_mode <= 0) { cam_err("failed to set mode\n"); @@ -3966,31 +10770,18 @@ static int m9mo_s_stream_preview(struct v4l2_subdev *sd, int enable) return -ETIMEDOUT; } } - err = m9mo_writeb(sd, M9MO_CATEGORY_TEST, - 0x34, 0x00); - err = m9mo_writeb(sd, M9MO_CATEGORY_TEST, - 0x35, 0x02); - err = m9mo_writeb(sd, M9MO_CATEGORY_TEST, - 0x33, 0x01); - msleep(20); - err = m9mo_readb(sd, M9MO_CATEGORY_TEST, - 0x36, &value); - cam_err("******** sensor version = %x *********\n", value); - - m9mo_set_lock(sd, 0); - -#if 0 - cam_err("******** LENS ON *********\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - 0x04, 0x0a); -#endif -#if 0 - if (state->check_dataline) { - err = m9mo_check_dataline(sd, state->check_dataline); - CHECK_ERR(err); + if (state->zoom >= 0x0F) { + /* Zoom position returns to 1 + when the monitor size is changed. */ + ctrl.id = V4L2_CID_CAMERA_ZOOM; + ctrl.value = state->zoom; + m9mo_set_zoom(sd, &ctrl); } -#endif + if (state->smart_zoom_mode) + m9mo_set_smart_zoom(sd, state->smart_zoom_mode); + + m9mo_set_lock(sd, 0); } else { } @@ -4001,13 +10792,18 @@ static int m9mo_s_stream_capture(struct v4l2_subdev *sd, int enable) { /*u32 int_factor;*/ int err; + struct m9mo_state *state = to_state(sd); #ifndef FAST_CAPTURE if (enable) { - err = m9mo_set_mode(sd, M9MO_STILLCAP_MODE); - if (err <= 0) { - cam_err("failed to set mode\n"); - return err; + if (state->running_capture_mode == RUNNING_MODE_SINGLE) { + m9mo_set_mode_part1(sd, M9MO_STILLCAP_MODE); + } else { + err = m9mo_set_mode(sd, M9MO_STILLCAP_MODE); + if (err <= 0) { + cam_err("failed to set mode\n"); + return err; + } } /* int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); @@ -4096,6 +10892,12 @@ static int m9mo_s_stream(struct v4l2_subdev *sd, int enable) return -ENOSYS; } + cam_info("state->format_mode=%d\n", state->format_mode); + if (state->running_capture_mode == RUNNING_MODE_BURST) { + cam_trace("X\n"); + return 0; + } + switch (enable) { case STREAM_MODE_CAM_ON: case STREAM_MODE_CAM_OFF: @@ -4121,8 +10923,10 @@ static int m9mo_s_stream(struct v4l2_subdev *sd, int enable) case STREAM_MODE_MOVIE_ON: state->recording = 1; +#if 0 /* Not use S project */ if (state->flash_mode != FLASH_MODE_OFF) err = m9mo_set_flash(sd, state->flash_mode, 1); +#endif if (state->preview->index == M9MO_PREVIEW_720P || state->preview->index == M9MO_PREVIEW_1080P) @@ -4134,7 +10938,9 @@ static int m9mo_s_stream(struct v4l2_subdev *sd, int enable) state->preview->index == M9MO_PREVIEW_1080P) err = m9mo_set_af(sd, 0); +#if 0 /* Not use S project */ m9mo_set_flash(sd, FLASH_MODE_OFF, 1); +#endif state->recording = 0; break; @@ -4169,15 +10975,18 @@ static int m9mo_check_version(struct v4l2_subdev *sd) static int m9mo_init_param(struct v4l2_subdev *sd) { + struct m9mo_state *state = to_state(sd); int err; cam_trace("E\n"); err = m9mo_writew(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, M9MO_INT_MODE | M9MO_INT_CAPTURE | M9MO_INT_FRAME_SYNC - /* | M9MO_INT_SOUND*/); + | M9MO_INT_ATSCENE_UPDATE + | M9MO_INT_SOUND); CHECK_ERR(err); - err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_OUT_SEL, 0x02); + err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, + M9MO_PARM_OUT_SEL, 0x02); CHECK_ERR(err); /* Capture */ @@ -4185,6 +10994,8 @@ static int m9mo_init_param(struct v4l2_subdev *sd) M9MO_CAPPARM_YUVOUT_MAIN, 0x01); CHECK_ERR(err); + m9mo_set_sensor_mode(sd, state->sensor_mode); + #if 0 err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM, M9MO_CAPPARM_THUMB_JPEG_MAX, M9MO_THUMB_MAXSIZE); @@ -4215,6 +11026,9 @@ static int m9mo_ois_init(struct v4l2_subdev *sd) const struct m9mo_platform_data *pdata = client->dev.platform_data; struct m9mo_state *state = to_state(sd); u32 int_factor, int_en, err, ois_result; + int try_cnt = 2; + + cam_dbg("E\n"); err = m9mo_readw(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, &int_en); CHECK_ERR(err); @@ -4227,33 +11041,48 @@ static int m9mo_ois_init(struct v4l2_subdev *sd) err = m9mo_writew(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, int_en); CHECK_ERR(err); - /* SambaZ PLL enable */ - pdata->config_sambaz(1); - - /* OIS on set */ - err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, - 0x10, 0x01); - CHECK_ERR(err); - - /* OIS F/W download, boot */ - err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, - 0x11, 0x00); + do { + /* OIS on set */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x10, 0x01); + CHECK_ERR(err); - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_OIS_INIT)) { - cam_err("OIS interrupt not issued\n"); - state->isp.bad_fw = 1; - return -ENOSYS; - } - cam_info("OIS init complete\n"); + /* OIS F/W download, boot */ + err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, + 0x11, 0x00); - /* Read OIS result */ - m9mo_readb(sd, M9MO_CATEGORY_NEW, 0x17, &ois_result); - cam_info("ois result = %d", ois_result); + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_OIS_INIT)) { + cam_err("OIS interrupt not issued\n"); + if (try_cnt > 1) { + try_cnt--; + pdata->config_sambaz(0); + msleep(20); + if (try_cnt == 1) + pdata->config_sambaz(1); + continue; + } + state->isp.bad_fw = 1; + return -ENOSYS; + } + cam_info("OIS init complete\n"); + + /* Read OIS result */ + m9mo_readb(sd, M9MO_CATEGORY_NEW, 0x17, &ois_result); + cam_info("ois result = %d", ois_result); + if (ois_result != 0x02) { + try_cnt--; + pdata->config_sambaz(0); + msleep(20); + if (try_cnt == 1) + pdata->config_sambaz(1); + } else + try_cnt = 0; + } while (try_cnt); /* Lens boot */ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - 0x00, 0x00); + M9MO_LENS_AF_INITIAL, 0x00); int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); if (!(int_factor & M9MO_INT_LENS_INIT)) { cam_err("M9MO_INT_LENS_INIT isn't issued, %#x\n", @@ -4261,20 +11090,26 @@ static int m9mo_ois_init(struct v4l2_subdev *sd) return -ETIMEDOUT; } + cam_dbg("X\n"); + return err; } static int m9mo_init(struct v4l2_subdev *sd, u32 val) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct m9mo_platform_data *pdata = client->dev.platform_data; struct m9mo_state *state = to_state(sd); u32 int_factor; /*u32 value;*/ int err; - int fw_ver; + + cam_dbg("E : val = %d\n", val); /* Default state values */ state->preview = NULL; state->capture = NULL; + state->postview = NULL; state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; state->sensor_mode = SENSOR_CAMERA; @@ -4288,58 +11123,61 @@ static int m9mo_init(struct v4l2_subdev *sd, u32 val) state->isp.bad_fw = 0; state->isp.issued = 0; - memset(&state->focus, 0, sizeof(state->focus)); + state->zoom = 0; + state->smart_zoom_mode = 0; - /* Test force update FW */ -#if 0 - err = m9mo_load_fw_main(sd); - msleep(1000); -#endif - if (system_rev > 0) { - err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, - 0x0C, 0x27c00020); - } + state->vss_mode = 0; + state->dual_capture_start = 0; + state->dual_capture_frame = 1; + state->focus_area_mode = V4L2_FOCUS_AREA_CENTER; - /* start camera program(parallel FLASH ROM) */ - cam_info("write 0x0f, 0x12~~~\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, - M9MO_FLASH_CAM_START, 0x01); - CHECK_ERR(err); + state->bracket_wbb_val = BRACKET_WBB_VALUE3; /* AB -+1 */ + state->wb_custom_rg = 424; /* 1A8 */ + state->wb_custom_bg = 452; /* 1C4 */ - int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); - if (!(int_factor & M9MO_INT_MODE)) { - cam_err("firmware was erased?\n"); - state->isp.bad_fw = 1; - return -ENOSYS; - } - cam_info("ISP boot complete\n"); + state->color_effect = 0; + state->gamma_rgb_mon = 2; + state->gamma_rgb_cap = 2; + state->gamma_tbl_rgb_cap = 1; + state->gamma_tbl_rgb_mon = 1; -#if 0 - cam_err("read 0x00, 0x1c~~~\n"); + memset(&state->focus, 0, sizeof(state->focus)); - m9mo_readb(sd, M9MO_CATEGORY_SYS, - M9MO_SYS_INT_FACTOR, &state->isp.int_factor); - cam_err("state->isp.int_factor = %x\n", state->isp.int_factor); + if (!leave_power) { + /* SambaZ PLL enable */ + cam_dbg("SambaZ On start ~~~\n"); + pdata->config_sambaz(1); + cam_dbg("SambaZ On finish ~~~\n"); - m9mo_readb(sd, 0x01, - 0x01, &value); - cam_err("value = %x\n", value); -#endif + if (system_rev > 0) { + err = m9mo_writel(sd, M9MO_CATEGORY_FLASH, + 0x0C, 0x27c00020); + } + + /* start camera program(parallel FLASH ROM) */ + cam_info("write 0x0f, 0x12~~~\n"); + err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH, + M9MO_FLASH_CAM_START, 0x01); + CHECK_ERR(err); + + int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT); + if (!(int_factor & M9MO_INT_MODE)) { + cam_err("firmware was erased?\n"); + state->isp.bad_fw = 1; + return -ENOSYS; + } + cam_info("ISP boot complete\n"); + } /* check up F/W version */ -#if 0 - err = m9mo_check_version(sd); - CHECK_ERR(err); -#else - /* read F/W version */ - m9mo_readw(sd, M9MO_CATEGORY_SYS, - M9MO_SYS_VER_FW, &fw_ver); - cam_info("f/w version = %x\n", fw_ver); -#endif + err = m9mo_check_fw(sd); - m9mo_init_param(sd); - m9mo_ois_init(sd); + if (!leave_power) { + m9mo_init_param(sd); + m9mo_ois_init(sd); + } + leave_power = false; cam_info("Lens boot complete - M9MO init complete\n"); return 0; @@ -4352,6 +11190,7 @@ static const struct v4l2_subdev_core_ops m9mo_core_ops = { .g_ctrl = m9mo_g_ctrl, .s_ctrl = m9mo_s_ctrl, .g_ext_ctrls = m9mo_g_ext_ctrls, + .s_ext_ctrls = m9mo_s_ext_ctrls, }; static const struct v4l2_subdev_video_ops m9mo_video_ops = { @@ -4370,26 +11209,13 @@ static const struct v4l2_subdev_ops m9mo_ops = { static ssize_t m9mo_camera_type_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct m9mo_state *state = dev_get_drvdata(dev); - char type[25]; - - if (state->exif.unique_id[1] == 'B') { - strcpy(type, "SONY_IMX105PQ_M9MOLS"); - } else if (state->exif.unique_id[1] == 'C') { - strcpy(type, "SLSI_S5K3H2YX_M9MOLS"); - } else { - cam_warn("cannot find the matched camera type\n"); - strcpy(type, "SONY_IMX105PQ_M9MOLS"); - } - - return sprintf(buf, "%s\n", type); + return sprintf(buf, "%s\n", sysfs_sensor_type); } static ssize_t m9mo_camera_fw_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct m9mo_state *state = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", state->fw_version); + return sprintf(buf, "%s %s\n", sysfs_phone_fw, sysfs_sensor_fw); } static DEVICE_ATTR(rear_camtype, S_IRUGO, m9mo_camera_type_show, NULL); @@ -4447,27 +11273,30 @@ static int __devexit m9mo_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct m9mo_state *state = to_state(sd); - int err; + int err = 0; + /*int err;*/ - cam_err("******** LENS OFF *********\n"); - err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, - 0x04, 0x0b); - CHECK_ERR(err); - msleep(1500); -/* if (m9mo_set_af_softlanding(sd) < 0) - cam_err("failed to set soft landing\n");*/ + if (!leave_power) { + if (m9mo_set_lens_off(sd) < 0) + cam_err("failed to set m9mo_set_lens_off~~~~~\n"); + } - device_remove_file(state->m9mo_dev, &dev_attr_rear_camtype); - device_remove_file(state->m9mo_dev, &dev_attr_rear_camfw); - device_destroy(camera_class, 0); - state->m9mo_dev = NULL; + if (leave_power) { + err = m9mo_set_lens_off_timer(sd, 0); + CHECK_ERR(err); + + err = m9mo_set_mode(sd, M9MO_PARMSET_MODE); + CHECK_ERR(err); + } if (state->isp.irq > 0) free_irq(state->isp.irq, sd); v4l2_device_unregister_subdev(sd); - kfree(state->fw_version); +#if 0 + kfree(state->sensor_type); +#endif kfree(state); return 0; @@ -4514,13 +11343,9 @@ static int __init m9mo_mod_init(void) static void __exit m9mo_mod_exit(void) { i2c_del_driver(&m9mo_i2c_driver); - if (camera_class) - class_destroy(camera_class); } module_init(m9mo_mod_init); module_exit(m9mo_mod_exit); - -MODULE_AUTHOR("Goeun Lee "); MODULE_DESCRIPTION("driver for Fusitju M9MO LS 16MP camera"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/m9mo.h b/drivers/media/video/m9mo.h index 0c3f24c..4da72a2 100644 --- a/drivers/media/video/m9mo.h +++ b/drivers/media/video/m9mo.h @@ -71,12 +71,12 @@ u8 buf_port_seting0[] = { u8 buf_port_seting1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; u8 buf_port_seting2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -96,35 +96,41 @@ enum m9mo_prev_frmsize { M9MO_PREVIEW_VGA, M9MO_PREVIEW_D1, M9MO_PREVIEW_WVGA, + M9MO_PREVIEW_960_720, + M9MO_PREVIEW_1080_720, M9MO_PREVIEW_720P, -#if defined(CONFIG_MACH_Q1_BD) - M9MO_PREVIEW_880_720, - M9MO_PREVIEW_1200_800, - M9MO_PREVIEW_1280_800, - M9MO_PREVIEW_1280_768, - M9MO_PREVIEW_1072_800, - M9MO_PREVIEW_980_800, -#endif M9MO_PREVIEW_1080P, M9MO_PREVIEW_HDR, M9MO_PREVIEW_720P_60FPS, M9MO_PREVIEW_VGA_60FPS, + M9MO_PREVIEW_1080P_DUAL, + M9MO_PREVIEW_720P_DUAL, + M9MO_PREVIEW_VGA_DUAL, + M9MO_PREVIEW_QVGA_DUAL, }; enum m9mo_cap_frmsize { + M9MO_CAPTURE_HD, /* 960 x 720 */ M9MO_CAPTURE_1MP, /* 1024 x 768 */ M9MO_CAPTURE_2MPW, /* 1920 x 1080 */ M9MO_CAPTURE_3MP, /* 1984 x 1488 */ + M9MO_CAPTURE_4MP, /* 2304 x 1728 */ M9MO_CAPTURE_5MP, /* 2592 x 1944 */ M9MO_CAPTURE_8MP, /* 3264 x 2448 */ M9MO_CAPTURE_10MP, /* 3648 x 2736 */ - M9MO_CAPTURE_12MPW, /* 4608 x 2768 */ + M9MO_CAPTURE_12MPW, /* 4608 x 2592 */ M9MO_CAPTURE_14MP, /* 4608 x 3072 */ M9MO_CAPTURE_16MP, /* 4608 x 3456 */ - M9MO_CAPTURE_POSTWVGA, /* 800 x 480 */ + M9MO_CAPTURE_RAW, /* 4088 x 2500 */ +}; + +enum m9mo_post_frmsize { + M9MO_CAPTURE_POSTQVGA, /* 320 x 240 */ M9MO_CAPTURE_POSTVGA, /* 640 x 480 */ - M9MO_CAPTURE_POSTWHD, /* 1280 x 720 */ M9MO_CAPTURE_POSTHD, /* 960 x 720 */ + M9MO_CAPTURE_POSTP, /* 1056 x 704 */ + M9MO_CAPTURE_POSTWVGA, /* 800 x 480 */ + M9MO_CAPTURE_POSTWHD, /* 1280 x 720 */ }; enum cam_frmratio { @@ -184,6 +190,24 @@ struct m9mo_focus { unsigned int pos_y; }; +struct m9mo_factory_punt_data { + unsigned int min; + unsigned int max; + unsigned int num; +}; + +struct m9mo_factory_zoom_data { + unsigned int range_min; + unsigned int range_max; + unsigned int slope_min; + unsigned int slope_max; +}; + +struct m9mo_factory_zoom_slope_data { + unsigned int min; + unsigned int max; +}; + struct m9mo_exif { char unique_id[7]; u32 exptime; /* us */ @@ -192,6 +216,9 @@ struct m9mo_exif { int tv; /* shutter speed */ int bv; /* brightness */ int ebv; /* exposure bias */ + int av; /* Aperture */ + int focal_length; + int focal_35mm_length; }; struct m9mo_state { @@ -205,6 +232,7 @@ struct m9mo_state { const struct m9mo_frmsizeenum *preview; const struct m9mo_frmsizeenum *capture; + const struct m9mo_frmsizeenum *postview; enum v4l2_pix_format_mode format_mode; enum v4l2_sensor_mode sensor_mode; @@ -212,18 +240,36 @@ struct m9mo_state { enum v4l2_scene_mode scene_mode; int vt_mode; int zoom; - int optical_zoom; + int smart_zoom_mode; int m9mo_fw_done; int fw_info_done; unsigned int fps; + + int factory_down_check; + int factory_result_check; + int factory_end_check; + int factory_category; + int factory_byte; + int factory_value; + int factory_value_size; + struct m9mo_focus focus; + struct m9mo_factory_punt_data f_punt_data; + struct m9mo_factory_zoom_data f_zoom_data; + + unsigned int factory_log_addr; + u16 factory_log_size; + int factory_test_num; struct m9mo_jpeg jpeg; struct m9mo_exif exif; - char *fw_version; + int isp_fw_ver; + u8 sensor_ver[10]; + u8 phone_ver[10]; + u8 sensor_type[25]; #ifdef CONFIG_CAM_DEBUG u8 dbg_level; @@ -232,12 +278,68 @@ struct m9mo_state { int facedetect_mode; int running_capture_mode; int fd_eyeblink_cap; + int fd_red_eye_status; + int image_stabilizer_mode; + int ot_status; + int ot_x_loc; + int ot_y_loc; + int ot_width; + int ot_height; + int bracket_wbb_val; unsigned int face_beauty:1; unsigned int recording:1; unsigned int check_dataline:1; int anti_banding; int pixelformat; + + int wb_g_value; + int wb_b_value; + int wb_a_value; + int wb_m_value; + int wb_custom_rg; + int wb_custom_bg; + + int vss_mode; + int dual_capture_start; + int dual_capture_frame; + + int focus_mode; + int focus_range; + int focus_area_mode; + + int f_number; + int iso; + int numerator; + int denominator; + + int AV; + int TV; + int SV; + int EV; + int LV; + + int smart_scene_detect_mode; + + int continueFps; + + int fd_num; + + int caf_state; + + int mode; + + bool stream_on_part2; + + int widget_mode_level; + int gamma_rgb_mon; + int gamma_rgb_cap; + int gamma_tbl_rgb_mon; + int gamma_tbl_rgb_cap; + int color_effect; + + int preview_width; + int preview_height; }; /* Category */ @@ -246,8 +348,10 @@ struct m9mo_state { #define M9MO_CATEGORY_MON 0x02 #define M9MO_CATEGORY_AE 0x03 #define M9MO_CATEGORY_NEW 0x04 +#define M9MO_CATEGORY_PRO_MODE 0x05 #define M9MO_CATEGORY_WB 0x06 #define M9MO_CATEGORY_EXIF 0x07 +#define M9MO_CATEGORY_OT 0x08 #define M9MO_CATEGORY_FD 0x09 #define M9MO_CATEGORY_LENS 0x0A #define M9MO_CATEGORY_CAPPARM 0x0B @@ -269,6 +373,7 @@ struct m9mo_state { #define M9MO_SYS_INT_EN 0x10 #define M9MO_SYS_INT_FACTOR 0x1C #define M9MO_SYS_FRAMESYNC_CNT 0x14 +#define M9MO_SYS_LENS_TIMER 0x28 /* M9MO_CATEGORY_PARAM: 0x01 */ @@ -277,9 +382,14 @@ struct m9mo_state { #define M9MO_PARM_EFFECT 0x0B #define M9MO_PARM_FLEX_FPS 0x67 #define M9MO_PARM_HDMOVIE 0x32 +#define M9MO_PARM_VIDEO_SNAP_IMG_TRANSFER_START 0x3A +#define M9MO_PARM_SEL_FRAME_VIDEO_SNAP 0x3B +#define M9MO_PARM_MON_MOVIE_SELECT 0x3C +#define M9MO_PARM_VSS_MODE 0x6E /* M9MO_CATEGORY_MON: 0x02 */ #define M9MO_MON_ZOOM 0x01 +#define M9MO_MON_HR_ZOOM 0x04 #define M9MO_MON_MON_REVERSE 0x05 #define M9MO_MON_MON_MIRROR 0x06 #define M9MO_MON_SHOT_REVERSE 0x07 @@ -289,7 +399,11 @@ struct m9mo_state { #define M9MO_MON_COLOR_EFFECT 0x0B #define M9MO_MON_CHROMA_LVL 0x0F #define M9MO_MON_EDGE_LVL 0x11 +#define M9MO_MON_EDGE_CTRL 0x20 +#define M9MO_MON_POINT_COLOR 0x22 #define M9MO_MON_TONE_CTRL 0x25 +#define M9MO_MON_START_VIDEO_SNAP_SHOT 0x56 +#define M9MO_MON_VIDEO_SNAP_SHOT_FRAME_COUNT 0x57 /* M9MO_CATEGORY_AE: 0x03 */ #define M9MO_AE_LOCK 0x00 @@ -299,16 +413,52 @@ struct m9mo_state { #define M9MO_AE_INDEX 0x09 #define M9MO_AE_EP_MODE_MON 0x0A #define M9MO_AE_EP_MODE_CAP 0x0B +#define M9MO_AF_AE_LOCK 0x0D #define M9MO_AE_AUTO_BRACKET_EV 0x20 -#define M9MO_AE_ONESHOT_MAX_EXP 0x36 +#define M9MO_AE_STABILITY 0x21 +#define M9MO_AE_EV_PRG_MODE_CAP 0x34 +#define M9MO_AE_EV_PRG_MODE_MON 0x35 +#define M9MO_AE_EV_PRG_F_NUMBER 0x36 +#define M9MO_AE_EV_PRG_SS_NUMERATOR 0x37 +#define M9MO_AE_EV_PRG_SS_DENOMINATOR 0x39 +#define M9MO_AE_EV_PRG_ISO_VALUE 0x3B +#define M9MO_AE_EV_PRG_F_NUMBER_MON 0x3D +#define M9MO_AE_EV_PRG_SS_NUMERATOR_MON 0x3E +#define M9MO_AE_EV_PRG_SS_DENOMINATOR_MON 0x40 +#define M9MO_AE_EV_PRG_ISO_VALUE_MON 0x42 +#define M9MO_AE_NOW_AV 0x54 +#define M9MO_AE_NOW_TV 0x58 +#define M9MO_AE_NOW_SV 0x5C +#define M9MO_AE_NOW_LV 0x52 /* M9MO_CATEGORY_NEW: 0x04 */ +#define M9MO_NEW_TIME_INFO 0x02 #define M9MO_NEW_DETECT_SCENE 0x0B +#define M9MO_NEW_OIS_VERSION 0x1B + +/* M9MO_CATEGORY_PRO_MODE: 0x05 */ +#define M9MO_PRO_SMART_READ1 0x20 +#define M9MO_PRO_SMART_READ2 0x24 +#define M9MO_PRO_SMART_READ3 0x28 /* M9MO_CATEGORY_WB: 0x06 */ #define M9MO_AWB_LOCK 0x00 #define M9MO_WB_AWB_MODE 0x02 #define M9MO_WB_AWB_MANUAL 0x03 +#define M9MO_WB_GBAM_MODE 0x8D +#define M9MO_WB_G_VALUE 0x8E +#define M9MO_WB_B_VALUE 0x8F +#define M9MO_WB_A_VALUE 0x90 +#define M9MO_WB_M_VALUE 0x91 +#define M9MO_WB_K_VALUE 0x92 +#define M9MO_WB_CWB_MODE 0x93 +#define M9MO_WB_SET_CUSTOM_RG 0x94 +#define M9MO_WB_SET_CUSTOM_BG 0x96 +#define M9MO_WB_GET_CUSTOM_RG 0x98 +#define M9MO_WB_GET_CUSTOM_BG 0x9A +#define M9MO_WB_WBB_MODE 0x9C +#define M9MO_WB_WBB_AB 0x9D +#define M9MO_WB_WBB_GM 0x9E /* M9MO_CATEGORY_EXIF: 0x07 */ #define M9MO_EXIF_EXPTIME_NUM 0x00 @@ -321,12 +471,31 @@ struct m9mo_state { #define M9MO_EXIF_EBV_DEN 0x24 #define M9MO_EXIF_ISO 0x28 #define M9MO_EXIF_FLASH 0x2A +#define M9MO_EXIF_AV_NUM 0x10 +#define M9MO_EXIF_AV_DEN 0x14 +#define M9MO_EXIF_FL 0x11 +#define M9MO_EXIF_FL_35 0x13 + +/* M9MO_CATEGORY_OT: 0x08 */ +#define M9MO_OT_TRACKING_CTL 0x00 +#define M9MO_OT_INFO_READY 0x01 +#define M9MO_OT_X_START_LOCATION 0x05 +#define M9MO_OT_Y_START_LOCATION 0x07 +#define M9MO_OT_X_END_LOCATION 0x09 +#define M9MO_OT_Y_END_LOCATION 0x0B +#define M9MO_OT_TRACKING_X_LOCATION 0x10 +#define M9MO_OT_TRACKING_Y_LOCATION 0x12 +#define M9MO_OT_TRACKING_FRAME_WIDTH 0x14 +#define M9MO_OT_TRACKING_FRAME_HEIGHT 0x16 +#define M9MO_OT_TRACKING_STATUS 0x18 +#define M9MO_OT_FRAME_WIDTH 0x30 /* M9MO_CATEGORY_FD: 0x09 */ #define M9MO_FD_CTL 0x00 #define M9MO_FD_SIZE 0x01 #define M9MO_FD_MAX 0x02 #define M9MO_FD_RED_EYE 0x55 +#define M9MO_FD_RED_DET_STATUS 0x56 #define M9MO_FD_BLINK_FRAMENO 0x59 #define M9MO_FD_BLINK_LEVEL_1 0x5A #define M9MO_FD_BLINK_LEVEL_2 0x5B @@ -334,12 +503,14 @@ struct m9mo_state { /* M9MO_CATEGORY_LENS: 0x0A */ #define M9MO_LENS_AF_INITIAL 0x00 -#define M9MO_LENS_AF_MODE 0x01 +#define M9MO_LENS_AF_LENS_CLOSE 0x01 #define M9MO_LENS_AF_ZOOM_CTRL 0x02 #define M9MO_LENS_AF_START_STOP 0x03 -#define M9MO_LENS_AF_STATUS 0x03 #define M9MO_LENS_AF_IRIS_STEP 0x05 #define M9MO_LENS_AF_ZOOM_LEVEL 0x06 +#define M9MO_LENS_AF_SCAN_RANGE 0x07 +#define M9MO_LENS_AF_MODE 0x08 +#define M9MO_LENS_AF_WINDOW_MODE 0x09 #define M9MO_LENS_AF_BACKLASH_ADJ 0x0A #define M9MO_LENS_AF_FOCUS_ADJ 0x0B #define M9MO_LENS_AF_TILT_ADJ 0x0C @@ -348,9 +519,18 @@ struct m9mo_state { #define M9MO_LENS_AF_ZOOM_ADJ 0x0F #define M9MO_LENS_AF_ADJ_TEMP_VALUE 0x0C #define M9MO_LENS_AF_ALGORITHM 0x0D +#define M9MO_LENS_ZOOM_LEVEL_INFO 0x10 +#define M9MO_LENS_AF_LED 0x1C #define M9MO_LENS_AF_CAL 0x1D +#define M9MO_LENS_AF_RESULT 0x20 +#define M9MO_LENS_ZOOM_SET_INFO 0x22 +#define M9MO_LENS_ZOOM_SPEED 0x25 +#define M9MO_LENS_ZOOM_STATUS 0x26 +#define M9MO_LENS_LENS_STATUS 0x28 +#define M9MO_LENS_ZOOM_LENS_STATUS 0x2A #define M9MO_LENS_AF_TOUCH_POSX 0x30 #define M9MO_LENS_AF_TOUCH_POSY 0x32 +#define M9MO_LENS_AF_VERSION 0x60 /* M9MO_CATEGORY_CAPPARM: 0x0B */ #define M9MO_CAPPARM_YUVOUT_MAIN 0x00 @@ -364,9 +544,13 @@ struct m9mo_state { #define M9MO_CAPPARM_JPEG_RATIO 0x17 #define M9MO_CAPPARM_MCC_MODE 0x1D #define M9MO_CAPPARM_STROBE_EN 0x22 +#define M9MO_CAPPARM_STROBE_CHARGE 0x27 +#define M9MO_CAPPARM_STROBE_EVC 0x28 +#define M9MO_CAPPARM_STROBE_UP_DOWN 0x29 #define M9MO_CAPPARM_WDR_EN 0x2C -#define M9MO_CAPPARM_JPEG_RATIO_OFS 0x34 +#define M9MO_CAPPARM_JPEG_RATIO_OFS 0x1B #define M9MO_CAPPARM_THUMB_JPEG_MAX 0x3C +#define M9MO_CAPPARM_STROBE_BATT_INFO 0x3F #define M9MO_CAPPARM_AFB_CAP_EN 0x53 /* M9MO_CATEGORY_CAPCTRL: 0x0C */ @@ -376,6 +560,7 @@ struct m9mo_state { #define M9MO_CAPCTRL_START_DUALCAP 0x05 #define M9MO_CAPCTRL_FRM_SEL 0x06 #define M9MO_CAPCTRL_FRM_PRV_SEL 0x07 +#define M9MO_CAPCTRL_FRM_THUMB_SEL 0x08 #define M9MO_CAPCTRL_TRANSFER 0x09 #define M9MO_CAPCTRL_IMG_SIZE 0x0D #define M9MO_CAPCTRL_THUMB_SIZE 0x11 @@ -388,6 +573,7 @@ struct m9mo_state { #define M9MO_CAP_MODE_ADDPIXEL_CAPTURE (0x08) #define M9MO_CAP_MODE_PANORAMA_CAPTURE (0x0B) #define M9MO_CAP_MODE_BLINK_CAPTURE (0x0C) +#define M9MO_CAP_MODE_RAW (0x0D) /* M9MO_CATEGORY_ADJST: 0x0E */ #define M9MO_ADJST_SHUTTER_MODE 0x33 @@ -426,6 +612,8 @@ struct m9mo_state { #define M9MO_INT_MODE (1 << 8) #define M9MO_INT_ATSCENE (1 << 7) #define M9MO_INT_ATSCENE_UPDATE (1 << 6) +#define M9MO_INT_AF_STATUS (1 << 5) +#define M9MO_INT_OIS_SET (1 << 4) #define M9MO_INT_OIS_INIT (1 << 3) #define M9MO_INT_STNW_DETECT (1 << 2) #define M9MO_INT_SCENARIO_FIN (1 << 1) diff --git a/drivers/media/video/s5c73m3.c b/drivers/media/video/s5c73m3.c index 47c4297..b8d3574 100644 --- a/drivers/media/video/s5c73m3.c +++ b/drivers/media/video/s5c73m3.c @@ -29,6 +29,7 @@ #ifdef S5C73M3_BUSFREQ_OPP #include +#include #endif #ifdef CONFIG_VIDEO_SAMSUNG_V4L2 @@ -37,7 +38,10 @@ #endif #include + +#ifdef CONFIG_LEDS_AAT1290A #include +#endif #include #include "s5c73m3.h" @@ -70,12 +74,16 @@ static const struct s5c73m3_frmsizeenum preview_frmsizes[] = { { S5C73M3_PREVIEW_QVGA, 320, 240, 0x01 }, { S5C73M3_PREVIEW_CIF, 352, 288, 0x0E }, { S5C73M3_PREVIEW_VGA, 640, 480, 0x02 }, - { S5C73M3_PREVIEW_800X600, 800, 600, 0x09 }, { S5C73M3_PREVIEW_880X720, 880, 720, 0x03 }, { S5C73M3_PREVIEW_960X720, 960, 720, 0x04 }, { S5C73M3_PREVIEW_1008X672, 1008, 672, 0x0F }, { S5C73M3_PREVIEW_1184X666, 1184, 666, 0x05 }, { S5C73M3_PREVIEW_720P, 1280, 720, 0x06 }, +#ifdef CONFIG_MACH_T0 + { S5C73M3_PREVIEW_1280X960, 1280, 960, 0x09 }, +#else + { S5C73M3_PREVIEW_800X600, 800, 600, 0x09 }, +#endif { S5C73M3_VDIS_720P, 1536, 864, 0x07 }, { S5C73M3_PREVIEW_1080P, 1920, 1080, 0x0A}, { S5C73M3_VDIS_1080P, 2304, 1296, 0x0C}, @@ -113,6 +121,7 @@ static const struct s5c73m3_effectenum s5c73m3_effects[] = { {IMAGE_EFFECT_POINT_RED_YELLOW, S5C73M3_IMAGE_EFFECT_POINT_RED_YELLOW}, {IMAGE_EFFECT_POINT_COLOR_3, S5C73M3_IMAGE_EFFECT_POINT_COLOR_3}, {IMAGE_EFFECT_POINT_GREEN, S5C73M3_IMAGE_EFFECT_POINT_GREEN}, + {IMAGE_EFFECT_CARTOONIZE, S5C73M3_IMAGE_EFFECT_CARTOONIZE}, }; static struct s5c73m3_control s5c73m3_ctrls[] = { @@ -397,19 +406,19 @@ void s5c73m3_make_CRC_table(u32 *table, u32 id) { u32 i, j, k; - for(i = 0; i < 256; ++i) { + for (i = 0; i < 256; ++i) { k = i; - for(j = 0; j < 8; ++j) { - if(k & 1) + for (j = 0; j < 8; ++j) { + if (k & 1) k = (k >> 1) ^ id; - else + else k >>= 1; } table[i] = k; } } -static int s5c73m3_reset_module(struct v4l2_subdev *sd, bool powerReset) +static int s5c73m3_reset_module(struct v4l2_subdev *sd, bool powerReset) { struct s5c73m3_state *state = to_state(sd); int err = 0; @@ -468,7 +477,7 @@ static int s5c73m3_set_mode(struct v4l2_subdev *sd) cam_trace("E\n"); if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { - if (state->hdr_mode) { + if (state->hdr_mode || state->yuv_snapshot) { err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT, S5C73M3_HDR_OUTPUT); CHECK_ERR(err); @@ -574,13 +583,23 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd) mm_segment_t old_fs; long ret = 0; char fw_path[25] = {0,}; - u8 mem0 =0, mem1 = 0; + u8 mem0 = 0, mem1 = 0; u32 CRC = 0; u32 DataCRC = 0; u32 IntOriginalCRC = 0; u32 crc_index = 0; int retryCnt = 2; +#ifdef CONFIG_MACH_T0 + if (state->sensor_fw[1] == 'D') { + sprintf(fw_path, "/data/cfw/SlimISP_%cK.bin", + state->sensor_fw[0]); + } else { + sprintf(fw_path, "/data/cfw/SlimISP_%c%c.bin", + state->sensor_fw[0], + state->sensor_fw[1]); + } +#else if (state->sensor_fw[0] == 'O') { sprintf(fw_path, "/data/cfw/SlimISP_G%c.bin", state->sensor_fw[1]); @@ -592,6 +611,7 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd) state->sensor_fw[0], state->sensor_fw[1]); } +#endif /* Make CRC Table */ s5c73m3_make_CRC_table((u32 *)&crc_table, 0xEDB88320); @@ -664,7 +684,7 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd) retry: memset(data_memory, 0, sizeof(data_memory)); - mem0 =0, mem1 = 0; + mem0 = 0, mem1 = 0; CRC = 0; DataCRC = 0; IntOriginalCRC = 0; @@ -684,7 +704,7 @@ retry: CHECK_ERR(err); CRC = ~CRC; - for(crc_index = 0;crc_index < (state->sensor_size-4)/2;crc_index++) { + for (crc_index = 0; crc_index < (state->sensor_size-4)/2; crc_index++) { /*low byte*/ mem0 = (unsigned char)(data_memory[crc_index*2] & 0x00ff); /*high byte*/ @@ -823,7 +843,7 @@ static int s5c73m3_get_sensor_fw_version(struct v4l2_subdev *sd) err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183); CHECK_ERR(err); - for (i = 0; i < 6; i++) { + for (i = 0; i < 5; i++) { err = s5c73m3_read(sd, 0x0000, 0x06+i*2, &sensor_type); CHECK_ERR(err); state->sensor_type[i*2] = sensor_type&0x00ff; @@ -950,6 +970,16 @@ static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd) int retVal = 0; int fw_requested = 1; +#ifdef CONFIG_MACH_T0 + if (state->sensor_fw[1] == 'D') { + sprintf(fw_path, "SlimISP_%cK.bin", + state->sensor_fw[0]); + } else { + sprintf(fw_path, "SlimISP_%c%c.bin", + state->sensor_fw[0], + state->sensor_fw[1]); + } +#else if (state->sensor_fw[0] == 'O') { sprintf(fw_path, "SlimISP_G%c.bin", state->sensor_fw[1]); @@ -961,6 +991,8 @@ static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd) state->sensor_fw[0], state->sensor_fw[1]); } +#endif + sprintf(fw_path_in_data, "/data/cfw/%s", fw_path); @@ -1184,7 +1216,14 @@ static int s5c73m3_check_fw_date(struct v4l2_subdev *sd) phone_date, strcmp((char *)&sensor_date, (char *)&phone_date)); +#ifdef CONFIG_MACH_T0 + if (state->sensor_fw[1] == 'D') + return -1; + else + return strcmp((char *)&sensor_date, (char *)&phone_date); +#else return strcmp((char *)&sensor_date, (char *)&phone_date); +#endif } static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download) @@ -1210,9 +1249,9 @@ static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download) /* retVal = 0 : Same Version retVal < 0 : Phone Version is latest Version than sensorFW. retVal > 0 : Sensor Version is latest version than phoenFW. */ - if (retVal <= 0||download) { + if (retVal <= 0 || download) { cam_dbg("Loading From PhoneFW......\n"); - + /* In case that there is no FW in phone and FW needs to be downloaded from F-ROM, ISP power reset is required before loading FW to ISP for F-ROM to work properly.*/ @@ -1276,8 +1315,17 @@ static int s5c73m3_set_flash(struct v4l2_subdev *sd, int val, int recording) { struct s5c73m3_state *state = to_state(sd); int err; + u16 pre_flash = false; cam_dbg("E, value %d\n", val); + s5c73m3_read(sd, 0x0009, S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash); + if (pre_flash) { + err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH + , S5C73M3_STILL_MAIN_FLASH_CANCEL); + CHECK_ERR(err); + state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED; + } + retry: switch (val) { case FLASH_MODE_OFF: @@ -1452,6 +1500,31 @@ static int s5c73m3_set_contrast(struct v4l2_subdev *sd, return 0; } +static int s5c73m3_set_sharpness(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int err; + int sharpness = 0; + int temp_sharpness = 0; + cam_dbg("E, value %d\n", ctrl->value); + + if (ctrl->value < 0 || ctrl->value > 4) { + cam_warn("invalid value, %d\n", ctrl->value); + ctrl->value = 2; + } + temp_sharpness = ctrl->value - 2; + if (temp_sharpness < 0) + sharpness = (temp_sharpness * (-1)) + 2; + else + sharpness = temp_sharpness; + err = s5c73m3_writeb(sd, S5C73M3_SHARPNESS, + sharpness); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + static int s5c73m3_set_whitebalance(struct v4l2_subdev *sd, int val) { struct s5c73m3_state *state = to_state(sd); @@ -1594,6 +1667,12 @@ retry: CHECK_ERR(err); break; + case SCENE_MODE_LOW_LIGHT: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_LOW_LIGHT); + CHECK_ERR(err); + break; + default: cam_warn("invalid value, %d\n", val); val = SCENE_MODE_NONE; @@ -2143,7 +2222,21 @@ static int s5c73m3_set_frame_rate(struct v4l2_subdev *sd, int fps) return 0; } + cam_dbg("E, value %d\n", fps); + switch (fps) { + case 120: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_120FPS); /* 120fps */ + break; + case 90: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_90FPS); /* 90fps */ + break; + case 60: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_60FPS); /* 60fps */ + break; case 30: err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, S5C73M3_FIXED_30FPS); /* 30fps */ @@ -2160,6 +2253,10 @@ static int s5c73m3_set_frame_rate(struct v4l2_subdev *sd, int fps) err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, S5C73M3_FIXED_10FPS); /* 10fps */ break; + case 7: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_7FPS); /* 7fps */ + break; default: err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, S5C73M3_AUTO_MODE_AE_SET); /* auto */ @@ -2292,6 +2389,19 @@ static int s5c73m3_get_lux(struct v4l2_subdev *sd, return err; } +static int s5c73m3_set_low_light_mode(struct v4l2_subdev *sd, int val) +{ + int err; + cam_dbg("E, value %d\n", val); + + err = s5c73m3_writeb(sd, S5C73M3_AE_LOW_LIGHT_MODE, val); + + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct s5c73m3_state *state = to_state(sd); @@ -2356,6 +2466,10 @@ static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) err = s5c73m3_set_contrast(sd, ctrl); break; + case V4L2_CID_CAMERA_SHARPNESS: + err = s5c73m3_set_sharpness(sd, ctrl); + break; + case V4L2_CID_CAMERA_WHITE_BALANCE: err = s5c73m3_set_whitebalance(sd, ctrl->value); break; @@ -2429,6 +2543,16 @@ static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) err = 0; break; + case V4L2_CID_CAMERA_FAST_MODE: + state->fast_mode = ctrl->value; + err = 0; + break; + + case V4L2_CID_CAMERA_YUV_SNAPSHOT: + state->yuv_snapshot = ctrl->value; + err = 0; + break; + case V4L2_CID_CAMERA_HYBRID_CAPTURE: err = s5c73m3_set_hybrid_capture(sd); break; @@ -2450,6 +2574,10 @@ static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) err = s5c73m3_stop_af_lens(sd, ctrl->value); break; + case V4L2_CID_CAMERA_LOW_LIGHT_MODE: + err = s5c73m3_set_low_light_mode(sd, ctrl->value); + break; + default: cam_err("no such control id %d, value %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); @@ -2557,6 +2685,16 @@ static int s5c73m3_load_fw(struct v4l2_subdev *sd) mm_segment_t old_fs; long fsize = 0, nread; +#ifdef CONFIG_MACH_T0 + if (state->sensor_fw[1] == 'D') { + sprintf(fw_path, "SlimISP_%cK.bin", + state->sensor_fw[0]); + } else { + sprintf(fw_path, "SlimISP_%c%c.bin", + state->sensor_fw[0], + state->sensor_fw[1]); + } +#else if (state->sensor_fw[0] == 'O') { sprintf(fw_path, "SlimISP_G%c.bin", state->sensor_fw[1]); @@ -2568,6 +2706,8 @@ static int s5c73m3_load_fw(struct v4l2_subdev *sd) state->sensor_fw[0], state->sensor_fw[1]); } +#endif + sprintf(fw_path_in_data, "/data/cfw/%s", fw_path); @@ -2661,14 +2801,22 @@ static int s5c73m3_set_frmsize(struct v4l2_subdev *sd) int err ; cam_trace("E\n"); - if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { + if (state->fast_mode == FAST_MODE_SUBSAMPLING_HALF) { + cam_dbg("S5C73M3_FAST_MODE_SUBSAMPLING_HALF\n"); + err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE, + S5C73M3_FAST_MODE_SUBSAMPLING_HALF + | state->preview->reg_val | (state->sensor_mode<<8)); + CHECK_ERR(err); + } else if (state->fast_mode == FAST_MODE_SUBSAMPLING_QUARTER) { + cam_dbg("S5C73M3_FAST_MODE_SUBSAMPLING_QUARTER\n"); err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE, - S5C73M3_YUV_MODE | state->preview->reg_val | - (state->sensor_mode<<8)); + S5C73M3_FAST_MODE_SUBSAMPLING_QUARTER + | state->preview->reg_val | (state->sensor_mode<<8)); CHECK_ERR(err); } else { + cam_dbg("S5C73M3_DEFAULT_MODE\n"); err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE, - S5C73M3_INTERLEAVED_MODE + S5C73M3_DEFAULT_MODE | state->capture->reg_val | state->preview->reg_val |(state->sensor_mode<<8)); CHECK_ERR(err); @@ -2825,7 +2973,7 @@ static int s5c73m3_enum_framesizes(struct v4l2_subdev *sd, return -EINVAL; fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - if (state->hdr_mode) { + if (state->hdr_mode || state->yuv_snapshot) { fsize->discrete.width = state->capture->width; fsize->discrete.height = state->capture->height; } else { @@ -3239,24 +3387,29 @@ static int s5c73m3_read_vdd_core(struct v4l2_subdev *sd) CHECK_ERR(err); if (read_val & 0x200) { - state->pdata->set_vdd_core(1150000); strcpy(sysfs_isp_core, "1.15V"); + state->pdata->set_vdd_core(1150000); vdd_core_val = 1150000; } else if (read_val & 0x800) { - state->pdata->set_vdd_core(1100000); strcpy(sysfs_isp_core, "1.10V"); +#ifdef CONFIG_MACH_M3 + state->pdata->set_vdd_core(1150000); + vdd_core_val = 1150000; +#else + state->pdata->set_vdd_core(1100000); vdd_core_val = 1100000; +#endif } else if (read_val & 0x2000) { - state->pdata->set_vdd_core(1100000); strcpy(sysfs_isp_core, "1.05V"); + state->pdata->set_vdd_core(1100000); vdd_core_val = 1100000; } else if (read_val & 0x8000) { - state->pdata->set_vdd_core(1000000); strcpy(sysfs_isp_core, "1.00V"); + state->pdata->set_vdd_core(1000000); vdd_core_val = 1000000; } else { - state->pdata->set_vdd_core(1150000); strcpy(sysfs_isp_core, "1.15V"); + state->pdata->set_vdd_core(1150000); vdd_core_val = 1150000; } @@ -3423,7 +3576,11 @@ static ssize_t s5c73m3_camera_rear_flash(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { +#ifdef CONFIG_LEDS_AAT1290A return aat1290a_power(dev, attr, buf, count); +#else + return count; +#endif } static ssize_t s5c73m3_camera_isp_core_show(struct device *dev, @@ -3471,7 +3628,10 @@ static int __devinit s5c73m3_probe(struct i2c_client *client, #ifdef S5C73M3_BUSFREQ_OPP /* lock bus frequency */ - dev_lock(bus_dev, s5c73m3_dev, 400200); + if (samsung_rev() >= EXYNOS4412_REV_2_0) + dev_lock(bus_dev, s5c73m3_dev, 440220); + else + dev_lock(bus_dev, s5c73m3_dev, 400200); #endif if (s5c73m3_dev) diff --git a/drivers/media/video/s5c73m3.h b/drivers/media/video/s5c73m3.h index aaf4007..ca12b2d 100644 --- a/drivers/media/video/s5c73m3.h +++ b/drivers/media/video/s5c73m3.h @@ -64,43 +64,33 @@ enum s5c73m3_fw_path{ }; enum s5c73m3_prev_frmsize { - S5C73M3_PREVIEW_QCIF, - S5C73M3_PREVIEW_QCIF2, S5C73M3_PREVIEW_QVGA, S5C73M3_PREVIEW_CIF, S5C73M3_PREVIEW_VGA, S5C73M3_PREVIEW_D1, - S5C73M3_PREVIEW_WVGA, S5C73M3_PREVIEW_800X600, S5C73M3_PREVIEW_880X720, - S5C73M3_PREVIEW_960X640, S5C73M3_PREVIEW_960X720, S5C73M3_PREVIEW_1008X672, - S5C73M3_PREVIEW_1056X704, S5C73M3_PREVIEW_1184X666, S5C73M3_PREVIEW_720P, + S5C73M3_PREVIEW_1280X960, S5C73M3_VDIS_720P, S5C73M3_PREVIEW_1080P, S5C73M3_VDIS_1080P, - S5C73M3_PREVIEW_HDR, }; enum s5c73m3_cap_frmsize { S5C73M3_CAPTURE_VGA, /* 640 x 480 */ - S5C73M3_CAPTURE_WVGA, /* 800 x 480 */ S5C73M3_CAPTURE_960x540, /* 960 x 540 */ S5C73M3_CAPTURE_960x720, /* 960 x 720 */ S5C73M3_CAPTURE_1024X768, /* 1024 x 768 */ S5C73M3_CAPTURE_HD, /* 1280 x 720 */ - S5C73M3_CAPTURE_W1MP, /* 1600 x 960 */ S5C73M3_CAPTURE_2MP, /* UXGA - 1600 x 1200 */ S5C73M3_CAPTURE_W2MP, /* 2048 x 1232 */ S5C73M3_CAPTURE_3MP, /* QXGA - 2048 x 1536 */ - S5C73M3_CAPTURE_W4MP, /* WQXGA - 2560 x 1536 */ S5C73M3_CAPTURE_5MP, /* 2560 x 1920 */ S5C73M3_CAPTURE_W6MP, /* 3072 x 1856 */ - S5C73M3_CAPTURE_7MP, /* 3072 x 2304 */ - S5C73M3_CAPTURE_W7MP, /* WQXGA - 2560 x 1536 */ S5C73M3_CAPTURE_3264X2176, /* 3264 x 2176 */ S5C73M3_CAPTURE_8MP, /* 3264 x 2448 */ }; @@ -169,6 +159,8 @@ struct s5c73m3_state { int vt_mode; int hdr_mode; int hybrid_mode; + int fast_mode; + int yuv_snapshot; int zoom; int stream_enable; int ae_lock; @@ -233,6 +225,7 @@ struct s5c73m3_state { #define S5C73M3_IMAGE_EFFECT_POINT_RED_YELLOW 0x000D #define S5C73M3_IMAGE_EFFECT_POINT_COLOR_3 0x000E #define S5C73M3_IMAGE_EFFECT_POINT_GREEN 0x000F +#define S5C73M3_IMAGE_EFFECT_CARTOONIZE 0x001A #define S5C73M3_IMAGE_QUALITY 0x0B0C #define S5C73M3_IMAGE_QUALITY_SUPERFINE 0x0000 @@ -255,9 +248,9 @@ struct s5c73m3_state { #define S5C73M3_CHG_MODE 0x0B10 -#define S5C73M3_YUV_MODE 0x8000 -#define S5C73M3_INTERLEAVED_MODE 0x8000 - +#define S5C73M3_DEFAULT_MODE 0x8000 +#define S5C73M3_FAST_MODE_SUBSAMPLING_HALF 0xA000 +#define S5C73M3_FAST_MODE_SUBSAMPLING_QUARTER 0xC000 #define S5C73M3_AF_CON 0x0E00 #define S5C73M3_AF_CON_STOP 0x0000 @@ -351,9 +344,11 @@ struct s5c73m3_state { #define S5C73M3_FIXED_30FPS 0x0002 #define S5C73M3_FIXED_20FPS 0x0003 #define S5C73M3_FIXED_15FPS 0x0004 +#define S5C73M3_FIXED_60FPS 0x0007 #define S5C73M3_FIXED_120FPS 0x0008 #define S5C73M3_FIXED_7FPS 0x0009 #define S5C73M3_FIXED_10FPS 0x000A +#define S5C73M3_FIXED_90FPS 0x000B #define S5C73M3_ANTI_SHAKE 0x0013 #define S5C73M3_SHARPNESS 0x0C14 @@ -392,10 +387,13 @@ struct s5c73m3_state { #define S5C73M3_SCENE_MODE_FIRE 0x000B #define S5C73M3_SCENE_MODE_TEXT 0x000C #define S5C73M3_SCENE_MODE_CANDLE 0x000D +#define S5C73M3_SCENE_MODE_LOW_LIGHT 0x0020 #define S5C73M3_FIREWORK_CAPTURE 0x0C20 #define S5C73M3_NIGHTSHOT_CAPTURE 0x0C22 +#define S5C73M3_AE_LOW_LIGHT_MODE 0x0C2C + #define S5C73M3_AE_AUTO_BRAKET 0x0B14 #define S5C73M3_AE_AUTO_BRAKET_EV05 0x0080 #define S5C73M3_AE_AUTO_BRAKET_EV10 0x0100 diff --git a/drivers/media/video/s5k5bbgx.c b/drivers/media/video/s5k5bbgx.c new file mode 100644 index 0000000..329ead4 --- /dev/null +++ b/drivers/media/video/s5k5bbgx.c @@ -0,0 +1,1738 @@ +/* + * Driver for S5K5BBGX from Samsung Electronics + * + * 1/6" 2Mp CMOS Image Sensor SoC with an Embedded Image Processor + * + * Copyright (C) 2010, DongSeong Lim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_VIDEO_SAMSUNG_V4L2 +#include +#endif +#include + +#include "s5k5bbgx.h" + + + +#ifdef S5K5BBGX_USLEEP +#include +#endif + +#define S5K5BBGX_BURST_MODE + +#ifdef CONFIG_LOAD_FILE +#include +#include +#include +#include +#include + +struct test { + u8 data; + struct test *nextBuf; +}; +static struct test *testBuf; +static s32 large_file; + +#define TEST_INIT \ +{ \ + .data = 0; \ + .nextBuf = NULL; \ +} +#endif + +#define CHECK_ERR(x) if (unlikely((x) < 0)) { \ + cam_err("i2c failed, err %d\n", x); \ + return x; \ + } +#define NELEMS(array) (sizeof(array) / sizeof(array[0])) + +#ifdef S5K5BBGX_USLEEP +/* + * Use msleep() if the sleep time is over 1000 us. +*/ +static void s5k5bbgx_usleep(u32 usecs) +{ + ktime_t expires; + u64 add_time = (u64)usecs * 1000; + + if (unlikely(!usecs)) + return; + + expires = ktime_add_ns(ktime_get(), add_time); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_hrtimeout(&expires, HRTIMER_MODE_ABS); +} +#endif + +static inline int s5k5bbgx_read(struct i2c_client *client, + u16 subaddr, u16 *data) +{ + u8 buf[2]; + int err = 0; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = buf, + }; + + *(u16 *)buf = cpu_to_be16(subaddr); + + /* printk("\n\n\n%X %X\n\n\n", buf[0], buf[1]);*/ + + err = i2c_transfer(client->adapter, &msg, 1); + if (unlikely(err < 0)) + cam_err("ERR: %d register read fail\n", __LINE__); + + msg.flags = I2C_M_RD; + + err = i2c_transfer(client->adapter, &msg, 1); + if (unlikely(err < 0)) + cam_err("ERR: %d register read fail\n", __LINE__); + + /*printk("\n\n\n%X %X\n\n\n", buf[0], buf[1]);*/ + *data = ((buf[0] << 8) | buf[1]); + + return err; +} + +/* + * s5k6aafx sensor i2c write routine + * --<2Byte Subaddr><2Byte Value>-- + */ +#ifdef CONFIG_LOAD_FILE +static int loadFile(void) +{ + struct file *fp = NULL; + struct test *nextBuf = NULL; + + u8 *nBuf = NULL; + size_t file_size = 0, max_size = 0, testBuf_size = 0; + ssize_t nread = 0; + s32 check = 0, starCheck = 0; + s32 tmp_large_file = 0; + s32 i = 0; + int ret = 0; + loff_t pos; + + mm_segment_t fs = get_fs(); + set_fs(get_ds()); + + BUG_ON(testBuf); + + fp = filp_open("/mnt/sdcard/external_sd/s5k5bbgx_setfile.h", + O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_err("file open error\n"); + return PTR_ERR(fp); + } + + file_size = (size_t) fp->f_path.dentry->d_inode->i_size; + max_size = file_size; + + cam_dbg("file_size = %d\n", file_size); + + nBuf = kmalloc(file_size, GFP_ATOMIC); + if (nBuf == NULL) { + cam_dbg("Fail to 1st get memory\n"); + nBuf = vmalloc(file_size); + if (nBuf == NULL) { + cam_err("ERR: nBuf Out of Memory\n"); + ret = -ENOMEM; + goto error_out; + } + tmp_large_file = 1; + } + + testBuf_size = sizeof(struct test) * file_size; + if (tmp_large_file) { + testBuf = vmalloc(testBuf_size); + large_file = 1; + } else { + testBuf = kmalloc(testBuf_size, GFP_ATOMIC); + if (testBuf == NULL) { + cam_dbg("Fail to get mem(%d bytes)\n", testBuf_size); + testBuf = vmalloc(testBuf_size); + large_file = 1; + } + } + if (testBuf == NULL) { + cam_err("ERR: Out of Memory\n"); + ret = -ENOMEM; + goto error_out; + } + + pos = 0; + memset(nBuf, 0, file_size); + memset(testBuf, 0, file_size * sizeof(struct test)); + + nread = vfs_read(fp, (char __user *)nBuf, file_size, &pos); + if (nread != file_size) { + cam_err("failed to read file ret = %d\n", nread); + ret = -1; + goto error_out; + } + + set_fs(fs); + + i = max_size; + + printk(KERN_INFO "i = %d\n", i); + + while (i) { + testBuf[max_size - i].data = *nBuf; + if (i != 1) { + testBuf[max_size - i].nextBuf = + &testBuf[max_size - i + 1]; + } else { + testBuf[max_size - i].nextBuf = NULL; + break; + } + i--; + nBuf++; + } + + i = max_size; + nextBuf = &testBuf[0]; + +#if 1 + while (i - 1) { + if (!check && !starCheck) { + if (testBuf[max_size - i].data == '/') { + if (testBuf[max_size-i].nextBuf != NULL) { + if (testBuf[max_size-i].nextBuf->data + == '/') { + check = 1;/* when find '//' */ + i--; + } else if ( + testBuf[max_size-i].nextBuf->data == '*') { + starCheck = 1; + /* when find '/ *' */ + i--; + } + } else + break; + } + if (!check && !starCheck) { + /* ignore '\t' */ + if (testBuf[max_size - i].data != '\t') { + nextBuf->nextBuf = &testBuf[max_size-i]; + nextBuf = &testBuf[max_size - i]; + } + } + } else if (check && !starCheck) { + if (testBuf[max_size - i].data == '/') { + if (testBuf[max_size-i].nextBuf != NULL) { + if ( + testBuf[max_size-i].nextBuf->data == '*') { + starCheck = 1; + /* when find '/ *' */ + check = 0; + i--; + } + } else + break; + } + + /* when find '\n' */ + if (testBuf[max_size - i].data == '\n' && check) { + check = 0; + nextBuf->nextBuf = &testBuf[max_size - i]; + nextBuf = &testBuf[max_size - i]; + } + + } else if (!check && starCheck) { + if (testBuf[max_size - i].data == '*') { + if (testBuf[max_size-i].nextBuf != NULL) { + if ( + testBuf[max_size-i].nextBuf->data == '/') { + starCheck = 0; + /* when find '* /' */ + i--; + } + } else + break; + } + } + + i--; + + if (i < 2) { + nextBuf = NULL; + break; + } + + if (testBuf[max_size - i].nextBuf == NULL) { + nextBuf = NULL; + break; + } + } +#endif + +#if 0 /* for print */ + printk(KERN_INFO "i = %d\n", i); + nextBuf = &testBuf[0]; + while (1) { + /* printk("sdfdsf\n"); */ + if (nextBuf->nextBuf == NULL) + break; + printk(KERN_INFO "%c", nextBuf->data); + nextBuf = nextBuf->nextBuf; + } +#endif + +error_out: + +/* if (nBuf)*/ + tmp_large_file ? vfree(nBuf) : kfree(nBuf); + if (fp) + filp_close(fp, current->files); + return ret; +} +#endif + +static inline int s5k5bbgx_write(struct i2c_client *client, + u32 packet) +{ + u8 buf[4]; + int err = 0, retry_count = 5; + + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .buf = buf, + .len = 4, + }; + + if (!client->adapter) { + cam_err("ERR - can't search i2c client adapter\n"); + return -EIO; + } + + while (retry_count--) { + *(u32 *)buf = cpu_to_be32(packet); + err = i2c_transfer(client->adapter, &msg, 1); + if (likely(err == 1)) + break; + mdelay(10); + } + + if (unlikely(err < 0)) { + cam_err("ERR - 0x%08x write failed err=%d\n", + (u32)packet, err); + return err; + } + + return (err != 1) ? -1 : 0; +} + +#ifdef CONFIG_LOAD_FILE +static int s5k5bbgx_write_regs_from_sd(struct v4l2_subdev *sd, u8 s_name[]) +{ + + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct test *tempData = NULL; + + int ret = -EAGAIN; + u32 temp; + u32 delay = 0; + u8 data[11]; + s32 searched = 0; + size_t size = strlen(s_name); + s32 i; + + cam_dbg("E size = %d, string = %s\n", size, s_name); + tempData = &testBuf[0]; + while (!searched) { + searched = 1; + for (i = 0; i < size; i++) { + if (tempData->data != s_name[i]) { + searched = 0; + break; + } + tempData = tempData->nextBuf; + } + tempData = tempData->nextBuf; + } + /* structure is get..*/ + + while (1) { + if (tempData->data == '{') + break; + else + tempData = tempData->nextBuf; + } + + while (1) { + searched = 0; + while (1) { + if (tempData->data == 'x') { + /* get 10 strings.*/ + data[0] = '0'; + for (i = 1; i < 11; i++) { + data[i] = tempData->data; + tempData = tempData->nextBuf; + } + /*cam_dbg("%s\n", data);*/ + temp = kstrtol(data, NULL, 16); + /*patch error: kstrtol is + * substitute for simple_strtol*/ + break; + } else if (tempData->data == '}') { + searched = 1; + break; + } else + tempData = tempData->nextBuf; + + if (tempData->nextBuf == NULL) + return -1; + } + + if (searched) + break; + + if ((temp & S5K5BBGX_DELAY) == S5K5BBGX_DELAY) { + delay = temp & 0xFFFF; + cam_info("line(%d):delay(0x%x, %d)\n", __LINE__, + delay, delay); + msleep(delay); + continue; + } + + ret = s5k5bbgx_write(client, temp); + + /* In error circumstances */ + /* Give second shot */ + if (unlikely(ret)) { + dev_info(&client->dev, + "s5k5bbgx i2c retry one more time\n"); + ret = s5k5bbgx_write(client, temp); + + /* Give it one more shot */ + if (unlikely(ret)) { + dev_info(&client->dev, + "s5k5bbgx i2c retry twice\n"); + ret = s5k5bbgx_write(client, temp); + } + } + } + + return ret; +} +#endif + +/* +* Read a register. +*/ +static int s5k5bbgx_read_reg(struct v4l2_subdev *sd, + u16 page, u16 addr, u16 *val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + u32 page_cmd = (0x002C << 16) | page; + u32 addr_cmd = (0x002E << 16) | addr; + int err = 0; + + cam_dbg("page_cmd=0x%X, addr_cmd=0x%X\n", page_cmd, addr_cmd); + + err = s5k5bbgx_write(client, page_cmd); + CHECK_ERR(err); + err = s5k5bbgx_write(client, addr_cmd); + CHECK_ERR(err); + err = s5k5bbgx_read(client, 0x0F12, val); + CHECK_ERR(err); + + return 0; +} +#ifdef S5K5BBGX_BURST_MODE + static u16 addr, value; + + static int len; + static u8 buf[SZ_2K] = {0,}; +#else + static u8 buf[4] = {0,}; +#endif +/* program multiple registers */ +static int s5k5bbgx_write_regs(struct v4l2_subdev *sd, + const u32 *packet, u32 num) +{ + struct s5k5bbgx_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = -EAGAIN; + u32 temp = 0; + u16 delay = 0; + int retry_count = 5; + + + struct i2c_msg msg = { + msg.addr = client->addr, + msg.flags = 0, + msg.len = 4, + msg.buf = buf, + }; + + while (num--) { + temp = *packet++; + + if ((temp & S5K5BBGX_DELAY) == S5K5BBGX_DELAY) { + delay = temp & 0xFFFF; + cam_dbg("line(%d):delay(0x%x):delay(%d)\n", + __LINE__, delay, delay); + msleep(delay); + continue; + } + +#ifdef S5K5BBGX_BURST_MODE + addr = temp >> 16; + value = temp & 0xFFFF; + + switch (addr) { + case 0x0F12: + if (len == 0) { + buf[len++] = addr >> 8; + buf[len++] = addr & 0xFF; + } + buf[len++] = value >> 8; + buf[len++] = value & 0xFF; + + if ((*packet >> 16) != addr) { + msg.len = len; + goto s5k5bbgx_burst_write; + } + break; + + case 0xFFFF: + break; + + default: + msg.len = 4; + *(u32 *)buf = cpu_to_be32(temp); + goto s5k5bbgx_burst_write; + } + + continue; +#else + *(u32 *)buf = cpu_to_be32(temp); +#endif + +#ifdef S5K5BBGX_BURST_MODE +s5k5bbgx_burst_write: + len = 0; +#endif + retry_count = 5; + + while (retry_count--) { + ret = i2c_transfer(client->adapter, &msg, 1); + if (likely(ret == 1)) + break; + mdelay(10); + } + + if (unlikely(ret < 0)) { + cam_err("ERR - 0x%08x write failed err=%d\n", + (u32)packet, ret); + break; + } + +#ifdef S5K5BBGX_USLEEP + if (unlikely(state->vt_mode)) + if (!(num%200)) + s5k5bbgx_usleep(3); +#endif + } + + if (unlikely(ret < 0)) { + cam_err("fail to write registers!!\n"); + return -EIO; + } + + return 0; +} + +static int s5k5bbgx_get_exif(struct v4l2_subdev *sd) +{ + struct s5k5bbgx_state *state = to_state(sd); + u16 iso_gain_table[] = {10, 18, 23, 28}; + u16 iso_table[] = {0, 50, 100, 200, 400}; + u16 gain = 0, val = 0; + s32 index = 0; + + state->exif.shutter_speed = 0; + state->exif.iso = 0; + + /* Get shutter speed */ + s5k5bbgx_read_reg(sd, REG_PAGE_SHUTTER, REG_ADDR_SHUTTER, &val); + state->exif.shutter_speed = 1000 * 1000 / (val * 1000 / 400); + cam_dbg("val = %d\n", val); + + /* Get ISO */ + val = 0; + s5k5bbgx_read_reg(sd, REG_PAGE_ISO, REG_ADDR_ISO, &val); + cam_dbg("val = %d\n", val); + gain = val * 10 / 256; + for (index = 0; index < NELEMS(iso_gain_table); index++) { + if (gain < iso_gain_table[index]) + break; + } + state->exif.iso = iso_table[index]; + + cam_dbg("gain=%d, Shutter speed=%d, ISO=%d\n", + gain, state->exif.shutter_speed, state->exif.iso); + return 0; +} + +static int s5k5bbgx_check_dataline(struct v4l2_subdev *sd, s32 val) +{ + int err = 0; + + cam_info("DTP %s\n", val ? "ON" : "OFF"); + +#ifdef CONFIG_LOAD_FILE + if (val) + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_pattern_on"); + else + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_pattern_off"); +#else + if (val) { + cam_dbg("load s5k5bbgx_pattern_on\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_pattern_on, + sizeof(s5k5bbgx_pattern_on) / \ + sizeof(s5k5bbgx_pattern_on[0])); + } else { + cam_dbg("load s5k5bbgx_pattern_off\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_pattern_off, + sizeof(s5k5bbgx_pattern_off) / \ + sizeof(s5k5bbgx_pattern_off[0])); + } +#endif + if (unlikely(err)) { + cam_err("fail to DTP setting\n"); + return err; + } + + return 0; +} + +static int s5k5bbgx_debug_sensor_status(struct v4l2_subdev *sd) +{ + u16 val = 0; + int err = -EINVAL; + + /* Read Mon_DBG_Counters_2 */ + /*err = s5k5bbgx_read_reg(sd, 0x7000, 0x0402, &val); + CHECK_ERR(err); + cam_info("counter = %d\n", val); */ + + /* Read REG_TC_GP_EnableCaptureChanged. */ + err = s5k5bbgx_read_reg(sd, 0x7000, 0x01F6, &val); + CHECK_ERR(err); + + switch (val) { + case 0: + cam_info("In normal mode(0)\n"); + break; + case 1: + cam_info("In swiching to capture mode(1).....\n"); + break; + default: + cam_err("In Unknown mode(?)\n"); + break; + } + + return 0; +} + +static int s5k5bbgx_check_sensor_status(struct v4l2_subdev *sd) +{ + /*struct i2c_client *client = v4l2_get_subdevdata(sd);*/ + u16 val_1 = 0, val_2 = 0; + int err = -EINVAL; + + err = s5k5bbgx_read_reg(sd, 0x7000, 0x00BC, &val_1); + CHECK_ERR(err); + err = s5k5bbgx_read_reg(sd, 0xD000, 0x1002, &val_2); + CHECK_ERR(err); + + cam_dbg("read val1=0x%x, val2=0x%x\n", val_1, val_2); + + if ((val_1 != 0xAAAA) || (val_2 != 0)) + goto error_occur; + + cam_dbg("Sensor error is not detected\n"); + return 0; + +error_occur: + cam_err("ERR: Sensor error occurs\n\n"); + return -EIO; +} + +static inline int s5k5bbgx_check_esd(struct v4l2_subdev *sd) +{ + int err = -EINVAL; + + err = s5k5bbgx_check_sensor_status(sd); + if (err < 0) { + cam_err("ERR: ESD Shock detected!\n"); + return err; + } + + return 0; +} + +static int s5k5bbgx_set_preview_start(struct v4l2_subdev *sd) +{ + struct s5k5bbgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("reset preview\n"); + +#ifdef CONFIG_LOAD_FILE + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_preview"); +#else + cam_dbg("load s5k5bbgx_preview\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_preview, + sizeof(s5k5bbgx_preview) / sizeof(s5k5bbgx_preview[0])); +#endif + if (state->check_dataline) + err = s5k5bbgx_check_dataline(sd, 1); + if (unlikely(err)) { + cam_err("fail to make preview\n"); + return err; + } + + return 0; +} + +static int s5k5bbgx_set_preview_stop(struct v4l2_subdev *sd) +{ + int err = 0; + cam_info("do nothing.\n"); + + return err; +} + +static int s5k5bbgx_set_capture_start(struct v4l2_subdev *sd) +{ + int err = -EINVAL; + u16 val = 1, retry = 0; + + /* set initial regster value */ +#ifdef CONFIG_LOAD_FILE + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_capture"); +#else + cam_dbg("load s5k5bbgx_capture\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_capture, + sizeof(s5k5bbgx_capture) / sizeof(s5k5bbgx_capture[0])); +#endif + if (unlikely(err)) { + cam_err("failed to make capture\n"); + return err; + } + s5k5bbgx_get_exif(sd); + cam_info("Capture ConfigSync\n"); + do { + msleep(20); + err = s5k5bbgx_read_reg(sd, REG_PAGE_CAPTURE_STATUS, + REG_ADDR_CAPTURE_STATUS, &val); + CHECK_ERR(err); + cam_dbg("val = %d\n", val); + if (val == 0) + break; + retry++; + } while (retry <= S5K5BBGX_READ_STATUS_RETRIES); + + + return err; +} + +static int s5k5bbgx_set_sensor_mode(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5k5bbgx_state *state = to_state(sd); + + if ((ctrl->value != SENSOR_CAMERA) && + (ctrl->value != SENSOR_MOVIE)) { + cam_err("ERR: Not support.(%d)\n", ctrl->value); + return -EINVAL; + } + + /* We does not support movie mode when in VT. */ + if ((ctrl->value == SENSOR_MOVIE) && state->vt_mode) { + state->sensor_mode = SENSOR_CAMERA; + cam_warn("ERR: Not support movie\n"); + } else + state->sensor_mode = ctrl->value; + + return 0; +} + +static int s5k5bbgx_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + cam_dbg("E\n"); + return 0; +} + +static int s5k5bbgx_enum_framesizes(struct v4l2_subdev *sd, \ + struct v4l2_frmsizeenum *fsize) +{ + struct s5k5bbgx_state *state = to_state(sd); + + cam_dbg("E\n"); + + /* + * Return the actual output settings programmed to the camera + */ + if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) { + fsize->discrete.width = state->capture_frmsizes.width; + fsize->discrete.height = state->capture_frmsizes.height; + } else { + fsize->discrete.width = state->preview_frmsizes.width; + fsize->discrete.height = state->preview_frmsizes.height; + } + + cam_info("width - %d , height - %d\n", + fsize->discrete.width, fsize->discrete.height); + + return 0; +} + +#if (0) /* not used */ +static int s5k5bbgx_enum_fmt(struct v4l2_subdev *sd, + struct v4l2_fmtdesc *fmtdesc) +{ + int err = 0; + + FUNC_ENTR(); + return err; +} + +static int s5k5bbgx_enum_frameintervals(struct v4l2_subdev *sd, + struct v4l2_frmivalenum *fival) +{ + int err = 0; + + FUNC_ENTR(); + return err; +} +#endif + +static int s5k5bbgx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + int err = 0; + + cam_dbg("E\n"); + + return err; +} + +static int s5k5bbgx_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *ffmt) +{ + struct s5k5bbgx_state *state = to_state(sd); + u32 *width = NULL, *height = NULL; + + cam_dbg("E\n"); + /* + * Just copying the requested format as of now. + * We need to check here what are the formats the camera support, and + * set the most appropriate one according to the request from FIMC + */ + #ifdef CONFIG_VIDEO_CONFERENCE_CALL + if (state->vt_mode == 3) { + state->req_fmt.width = fmt->fmt.pix.height; + state->req_fmt.height = fmt->fmt.pix.width; + } +#endif + + state->req_fmt.width = ffmt->width; + state->req_fmt.height = ffmt->height; + state->req_fmt.priv = ffmt->field; + + switch (state->req_fmt.priv) { + case V4L2_PIX_FMT_MODE_PREVIEW: + cam_dbg("V4L2_PIX_FMT_MODE_PREVIEW\n"); + width = &state->preview_frmsizes.width; + height = &state->preview_frmsizes.height; + break; + + case V4L2_PIX_FMT_MODE_CAPTURE: + cam_dbg("V4L2_PIX_FMT_MODE_CAPTURE\n"); + width = &state->capture_frmsizes.width; + height = &state->capture_frmsizes.height; + break; + + default: + cam_err("ERR(EINVAL)\n"); + return -EINVAL; + } + + if ((*width != state->req_fmt.width) || + (*height != state->req_fmt.height)) { + cam_err("ERR: Invalid size. width= %d, height= %d\n", + state->req_fmt.width, state->req_fmt.height); + } + + return 0; +} + +static int s5k5bbgx_set_frame_rate(struct v4l2_subdev *sd, u32 fps) +{ + int err = 0; + + cam_info("frame rate %d\n\n", fps); + +#ifdef CONFIG_LOAD_FILE + switch (fps) { + case 7: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_7fps"); + break; + case 10: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_10fps"); + + break; + case 12: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_12fps"); + + break; + case 15: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_15fps"); + break; + case 30: + cam_err("frame rate is 30\n"); + break; + default: + cam_err("ERR: Invalid framerate\n"); + break; + } +#else + switch (fps) { + case 7: + cam_dbg("load s5k5bbgx_vt_7fps\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_7fps, + sizeof(s5k5bbgx_vt_7fps) / \ + sizeof(s5k5bbgx_vt_7fps[0])); + break; + case 10: + cam_dbg("load s5k5bbgx_vt_10fps\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_10fps, + sizeof(s5k5bbgx_vt_10fps) / \ + sizeof(s5k5bbgx_vt_10fps[0])); + + break; + case 12: + cam_dbg("load s5k5bbgx_vt_12fps\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_12fps, + sizeof(s5k5bbgx_vt_12fps) / \ + sizeof(s5k5bbgx_vt_12fps[0])); + + break; + case 15: + cam_dbg("load s5k5bbgx_vt_15fps\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_15fps, + sizeof(s5k5bbgx_vt_15fps) / \ + sizeof(s5k5bbgx_vt_15fps[0])); + break; + case 30: + cam_warn("frame rate is 30\n"); + break; + default: + cam_err("ERR: Invalid framerate\n"); + break; + } +#endif + + if (unlikely(err < 0)) { + cam_err("i2c_write for set framerate\n"); + return -EIO; + } + + return err; +} + +static int s5k5bbgx_g_parm(struct v4l2_subdev *sd, + struct v4l2_streamparm *parms) +{ + int err = 0; + + cam_dbg("E\n"); + + return err; +} + +static int s5k5bbgx_s_parm(struct v4l2_subdev *sd, + struct v4l2_streamparm *parms) +{ + int err = 0; + u32 fps = 0; + struct s5k5bbgx_state *state = to_state(sd); + + if (!state->vt_mode) + return 0; + + cam_dbg("E\n"); + + fps = parms->parm.capture.timeperframe.denominator / + parms->parm.capture.timeperframe.numerator; + + if (fps != state->set_fps) { + if (fps < 0 && fps > 15) { + cam_err("invalid frame rate %d\n", fps); + fps = 15; + } + state->req_fps = fps; + + if (state->initialized) { + err = s5k5bbgx_set_frame_rate(sd, state->req_fps); + if (err >= 0) + state->set_fps = state->req_fps; + } + + } + + return err; +} + +#if (0) /* not used */ +static int s5k5bbgx_set_60hz_antibanding(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct s5k5bbgx_state *state = to_state(sd); + int err = -EINVAL; + + FUNC_ENTR(); + + u32 s5k5bbgx_antibanding60hz[] = { + 0xFCFCD000, + 0x00287000, + /* Anti-Flicker */ + /* End user init script*/ + 0x002A0400, + 0x0F12005F, /*REG_TC_DBG_AutoAlgEnBits Auto + Anti-Flicker is enabled bit[5] = 1.*/ + 0x002A03DC, + 0x0F120002, /*02 REG_SF_USER_FlickerQuant set + flicker quantization(0: no AFC, 1: 50Hz, 2: 60 Hz)*/ + 0x0F120001, + }; + + err = s5k5bbgx_write_regs(sd, s5k5bbgx_antibanding60hz, + sizeof(s5k5bbgx_antibanding60hz) / sizeof(s5k5bbgx_antibanding60hz[0])); + printk(KERN_INFO "%s: setting 60hz antibanding\n", __func__); + if (unlikely(err)) { + printk(KERN_INFO "%s: failed to set 60hz antibanding\n", + __func__); + return err; + } + + return 0; +} +#endif + +static int s5k5bbgx_control_stream(struct v4l2_subdev *sd, + enum stream_cmd_t cmd) +{ + int err = 0; + + switch (cmd) { + case STREAM_START: + cam_warn("WARN: do nothing\n"); + break; + + case STREAM_STOP: + cam_dbg("stream stop!!!\n"); +#if 0 +#ifdef CONFIG_LOAD_FILE + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_stream_stop"); +#else + err = s5k5bbgx_write_regs(sd, s5k5bbgx_stream_stop, + sizeof(s5k5bbgx_stream_stop) / \ + sizeof(s5k5bbgx_stream_stop[0])); +#endif +#endif + break; + default: + cam_err("ERR: Invalid cmd\n"); + break; + } + + if (unlikely(err)) + cam_err("failed to stream start(stop)\n"); + + return err; +} + +static int s5k5bbgx_init(struct v4l2_subdev *sd, u32 val) +{ + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + struct s5k5bbgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + + /* set initial regster value */ +#ifdef CONFIG_LOAD_FILE + if (state->sensor_mode == SENSOR_CAMERA) { + if (!state->vt_mode) { + cam_dbg("load camera common setting\n"); + err = s5k5bbgx_write_regs_from_sd(sd, + "s5k5bbgx_common"); + } else { + if (state->vt_mode == 1) { + cam_info("load camera VT call setting\n"); + err = s5k5bbgx_write_regs_from_sd(sd, + "s5k5bbgx_vt_common"); + } else { + cam_info("load camera WIFI VT call setting\n"); + err = s5k5bbgx_write_regs_from_sd(sd, + "s5k5bbgx_vt_wifi_common"); + } + } + } else { + cam_info("load recording setting\n"); + err = s5k5bbgx_write_regs_from_sd(sd, + "s5k5bbgx_recording_common"); + } +#else + if (state->sensor_mode == SENSOR_CAMERA) { + if (!state->vt_mode) { + cam_info("load camera common setting\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_common, + sizeof(s5k5bbgx_common) / \ + sizeof(s5k5bbgx_common[0])); + } else { +#ifdef CONFIG_VIDEO_CONFERENCE_CALL + if (state->vt_mode == 1 || state->vt_mode == 3) { +#else + if (state->vt_mode == 1) { +#endif + cam_info("load camera VT call setting\n"); + err = s5k5bbgx_write_regs(sd, + s5k5bbgx_vt_common, + sizeof(s5k5bbgx_vt_common) / \ + sizeof(s5k5bbgx_vt_common[0])); + } else { + cam_info("load camera WIFI VT call setting\n"); + err = s5k5bbgx_write_regs(sd, + s5k5bbgx_vt_wifi_common, + sizeof(s5k5bbgx_vt_wifi_common) / \ + sizeof(s5k5bbgx_vt_wifi_common[0])); + } + } + } else { + cam_info("load recording setting\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_recording_common, + sizeof(s5k5bbgx_recording_common) / \ + sizeof(s5k5bbgx_recording_common[0])); + } +#endif + + if (unlikely(err)) { + cam_err("failed to init\n"); + return err; + } + + /* We stop stream-output from sensor when starting camera. */ + err = s5k5bbgx_control_stream(sd, STREAM_STOP); + if (unlikely(err < 0)) + return err; + msleep(150); + + if (state->vt_mode && (state->req_fps != state->set_fps)) { + err = s5k5bbgx_set_frame_rate(sd, state->req_fps); + if (unlikely(err < 0)) + return err; + else + state->set_fps = state->req_fps; + } + + state->initialized = 1; + + return 0; +} + +#if 0 +static int s5k5bbgx_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) +{ + FUNC_ENTR(); + return 0; +} + +static int s5k5bbgx_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm) +{ + FUNC_ENTR(); + return 0; +} +#endif + +static int s5k5bbgx_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct s5k5bbgx_state *state = to_state(sd); + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + int err = 0; + + cam_info("stream mode = %d\n", enable); + + switch (enable) { + case STREAM_MODE_CAM_OFF: + if (state->sensor_mode == SENSOR_CAMERA) { + if (state->check_dataline) + err = s5k5bbgx_check_dataline(sd, 0); + else + err = s5k5bbgx_control_stream(sd, STREAM_STOP); + } + break; + + case STREAM_MODE_CAM_ON: + /* The position of this code need to be adjusted later */ + if (state->sensor_mode == SENSOR_CAMERA) { + if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) + err = s5k5bbgx_set_capture_start(sd); + else + err = s5k5bbgx_set_preview_start(sd); + } + break; + + case STREAM_MODE_MOVIE_ON: + cam_dbg("do nothing(movie on)!!\n"); + break; + + case STREAM_MODE_MOVIE_OFF: + cam_dbg("do nothing(movie off)!!\n"); + break; + + default: + cam_err("ERR: Invalid stream mode\n"); + break; + } + + if (unlikely(err < 0)) { + cam_err("ERR: faild\n"); + return err; + } + + return 0; +} + +static int s5k5bbgx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct s5k5bbgx_state *state = to_state(sd); + int err = 0; + + cam_dbg("ctrl->id : %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE); + + switch (ctrl->id) { + case V4L2_CID_CAMERA_EXIF_TV: + ctrl->value = state->exif.shutter_speed; + break; + case V4L2_CID_CAMERA_EXIF_ISO: + ctrl->value = state->exif.iso; + break; + default: + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_PRIVATE_BASE); + break; + } + + return err; +} + +static int s5k5bbgx_set_brightness(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5k5bbgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + if (state->check_dataline) + return 0; + +#ifdef CONFIG_LOAD_FILE + switch (ctrl->value) { + case EV_MINUS_4: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m4"); + break; + case EV_MINUS_3: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m3"); + break; + case EV_MINUS_2: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m2"); + break; + case EV_MINUS_1: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m1"); + break; + case EV_DEFAULT: + err = s5k5bbgx_write_regs_from_sd(sd, + "s5k5bbgx_bright_default"); + break; + case EV_PLUS_1: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p1"); + break; + case EV_PLUS_2: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p2"); + break; + case EV_PLUS_3: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p3"); + break; + case EV_PLUS_4: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p4"); + break; + default: + cam_err("ERR: Invalid brightness(%d)\n", ctrl->value); + return err; + break; + } +#else + switch (ctrl->value) { + case EV_MINUS_4: + cam_dbg("load s5k5bbgx_bright_m4\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m4, \ + sizeof(s5k5bbgx_bright_m4) / \ + sizeof(s5k5bbgx_bright_m4[0])); + break; + case EV_MINUS_3: + cam_dbg("load s5k5bbgx_bright_m3\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m3, \ + sizeof(s5k5bbgx_bright_m3) / \ + sizeof(s5k5bbgx_bright_m3[0])); + + break; + case EV_MINUS_2: + cam_dbg("load s5k5bbgx_bright_m2\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m2, \ + sizeof(s5k5bbgx_bright_m2) / \ + sizeof(s5k5bbgx_bright_m2[0])); + break; + case EV_MINUS_1: + cam_dbg("load s5k5bbgx_bright_m1\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m1, \ + sizeof(s5k5bbgx_bright_m1) / \ + sizeof(s5k5bbgx_bright_m1[0])); + break; + case EV_DEFAULT: + cam_dbg("load s5k5bbgx_bright_default\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_default, \ + sizeof(s5k5bbgx_bright_default) / \ + sizeof(s5k5bbgx_bright_default[0])); + break; + case EV_PLUS_1: + cam_dbg("load s5k5bbgx_bright_p1\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p1, \ + sizeof(s5k5bbgx_bright_p1) / \ + sizeof(s5k5bbgx_bright_p1[0])); + break; + case EV_PLUS_2: + cam_dbg("load s5k5bbgx_bright_p2\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p2, \ + sizeof(s5k5bbgx_bright_p2) / \ + sizeof(s5k5bbgx_bright_p2[0])); + break; + case EV_PLUS_3: + cam_dbg("load s5k5bbgx_bright_p3\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p3, \ + sizeof(s5k5bbgx_bright_p3) / \ + sizeof(s5k5bbgx_bright_p3[0])); + break; + case EV_PLUS_4: + cam_dbg("load s5k5bbgx_bright_p4\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p4, \ + sizeof(s5k5bbgx_bright_p4) / \ + sizeof(s5k5bbgx_bright_p4[0])); + break; + default: + cam_err("ERR: invalid brightness(%d)\n", ctrl->value); + return err; + break; + } +#endif + + if (unlikely(err < 0)) { + cam_err("ERR: i2c_write for set brightness\n"); + return -EIO; + } + + return 0; +} + +static int s5k5bbgx_set_blur(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct s5k5bbgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + if (state->check_dataline) + return 0; + +#ifdef CONFIG_LOAD_FILE + switch (ctrl->value) { + case BLUR_LEVEL_0: + err = s5k5bbgx_write_regs_from_sd(sd, + "s5k5bbgx_vt_pretty_default"); + break; + case BLUR_LEVEL_1: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_pretty_1"); + break; + case BLUR_LEVEL_2: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_pretty_2"); + break; + case BLUR_LEVEL_3: + case BLUR_LEVEL_MAX: + err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_pretty_3"); + break; + default: + cam_err("ERR: Invalid blur(%d)\n", ctrl->value); + return err; + break; + } +#else + switch (ctrl->value) { + case BLUR_LEVEL_0: + cam_dbg("load s5k5bbgx_vt_pretty_default\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_default, \ + sizeof(s5k5bbgx_vt_pretty_default) / \ + sizeof(s5k5bbgx_vt_pretty_default[0])); + break; + case BLUR_LEVEL_1: + cam_dbg("load s5k5bbgx_vt_pretty_1\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_1, \ + sizeof(s5k5bbgx_vt_pretty_1) / \ + sizeof(s5k5bbgx_vt_pretty_1[0])); + break; + case BLUR_LEVEL_2: + cam_dbg("load s5k5bbgx_vt_pretty_2\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_2, \ + sizeof(s5k5bbgx_vt_pretty_2) / \ + sizeof(s5k5bbgx_vt_pretty_2[0])); + break; + case BLUR_LEVEL_3: + case BLUR_LEVEL_MAX: + cam_dbg("load s5k5bbgx_vt_pretty_3\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_3, \ + sizeof(s5k5bbgx_vt_pretty_3) / \ + sizeof(s5k5bbgx_vt_pretty_3[0])); + break; + default: + cam_err("ERR: Invalid blur(%d)\n", ctrl->value); + return err; + break; + } +#endif + + if (unlikely(err < 0)) { + cam_err("ERR: i2c_write for set blur\n"); + return -EIO; + } + + return 0; +} + +static int s5k5bbgx_check_dataline_stop(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct s5k5bbgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_warn("Warning: do nothing!!\n"); + return err; + + + /*s5k5bbgx_write(client, 0xFCFCD000); */ + /*s5k5bbgx_write(client, 0x0028D000); */ + /*s5k5bbgx_write(client, 0x002A3100); */ + /*s5k5bbgx_write(client, 0x0F120000); */ + + /*err = s5k5bbgx_write_regs(sd, s5k5bbgx_pattern_off, + * sizeof(s5k5bbgx_pattern_off) / sizeof(s5k5bbgx_pattern_off[0])); */ + printk(KERN_INFO "%s: sensor reset\n", __func__); +#if defined(CONFIG_TARGET_LOCALE_KOR) || \ + defined(CONFIG_TARGET_LOCALE_EUR) || \ + defined(CONFIG_TARGET_LOCALE_HKTW) || \ + defined(CONFIG_TARGET_LOCALE_HKTW_FET) || \ + defined(CONFIG_TARGET_LOCALE_USAGSM) || \ + defined(CONFIG_TARGET_LOCALE_CANBMC_TEMP) + /* dont't know where this code came from - comment out for + * compile error */ + /* s5k5bbgx_power_reset();*/ + #endif + cam_dbg("load camera init setting\n"); + err = s5k5bbgx_write_regs(sd, s5k5bbgx_common, + sizeof(s5k5bbgx_common) / sizeof(s5k5bbgx_common[0])); + + state->check_dataline = 0; + /* mdelay(100); */ + return err; +} + +static int s5k5bbgx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + struct s5k5bbgx_state *state = to_state(sd); + int err = 0; + + cam_info("ctrl->id : %d, value=%d\n", ctrl->id - V4L2_CID_PRIVATE_BASE, + ctrl->value); + + if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE) + && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE) + && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE)) + && (!state->initialized)) { + cam_warn("camera isn't initialized\n"); + return 0; + } + + switch (ctrl->id) { + case V4L2_CID_CAM_PREVIEW_ONOFF: + if (ctrl->value) + err = s5k5bbgx_set_preview_start(sd); + else + err = s5k5bbgx_set_preview_stop(sd); + cam_dbg("V4L2_CID_CAM_PREVIEW_ONOFF [%d]\n", ctrl->value); + break; + + case V4L2_CID_CAM_CAPTURE: + err = s5k5bbgx_set_capture_start(sd); + cam_dbg("V4L2_CID_CAM_CAPTURE\n"); + break; + + case V4L2_CID_CAMERA_BRIGHTNESS: + err = s5k5bbgx_set_brightness(sd, ctrl); + cam_dbg("V4L2_CID_CAMERA_BRIGHTNESS [%d]\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_VGA_BLUR: + /*err = s5k5bbgx_set_blur(sd, ctrl);*/ + cam_dbg("V4L2_CID_CAMERA_VGA_BLUR [%d]\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_VT_MODE: + state->vt_mode = ctrl->value; + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE: + state->check_dataline = ctrl->value; + cam_dbg("check_dataline = %d\n", state->check_dataline); + err = 0; + break; + + case V4L2_CID_CAMERA_SENSOR_MODE: + err = s5k5bbgx_set_sensor_mode(sd, ctrl); + cam_dbg("sensor_mode = %d\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE_STOP: + err = s5k5bbgx_check_dataline_stop(sd); + break; + + case V4L2_CID_CAMERA_CHECK_ESD: + err = s5k5bbgx_check_esd(sd); + break; + + case V4L2_CID_CAMERA_FRAME_RATE: + cam_dbg("do nothing\n"); + break; + + case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS: + s5k5bbgx_debug_sensor_status(sd); + err = s5k5bbgx_check_sensor_status(sd); + break; + + default: + cam_err("ERR(ENOIOCTLCMD)\n"); + /* no errors return.*/ + break; + } + + cam_dbg("X\n"); + return err; +} + +static const struct v4l2_subdev_core_ops s5k5bbgx_core_ops = { + .init = s5k5bbgx_init, /* initializing API */ +#if 0 + .queryctrl = s5k5bbgx_queryctrl, + .querymenu = s5k5bbgx_querymenu, +#endif + .g_ctrl = s5k5bbgx_g_ctrl, + .s_ctrl = s5k5bbgx_s_ctrl, +}; + +static const struct v4l2_subdev_video_ops s5k5bbgx_video_ops = { + /*.s_crystal_freq = s5k5bbgx_s_crystal_freq,*/ + .s_mbus_fmt = s5k5bbgx_s_fmt, + .s_stream = s5k5bbgx_s_stream, + .enum_framesizes = s5k5bbgx_enum_framesizes, + /*.enum_frameintervals = s5k5bbgx_enum_frameintervals,*/ + /*.enum_fmt = s5k5bbgx_enum_fmt,*/ + .g_parm = s5k5bbgx_g_parm, + .s_parm = s5k5bbgx_s_parm, +}; + +static const struct v4l2_subdev_ops s5k5bbgx_ops = { + .core = &s5k5bbgx_core_ops, + .video = &s5k5bbgx_video_ops, +}; + +ssize_t s5k5bbgx_camera_type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char *cam_type; + cam_info("%s\n", __func__); + + cam_type = "SLSI_S5K5BBGX"; + + return sprintf(buf, "%s\n", cam_type); +} + +static DEVICE_ATTR(front_camtype, S_IRUGO, s5k5bbgx_camera_type_show, NULL); + +/* + * s5k5bbgx_probe + * Fetching platform data is being done with s_config subdev call. + * In probe routine, we just register subdev device + */ +static int s5k5bbgx_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct s5k5bbgx_state *state = NULL; + struct v4l2_subdev *sd = NULL; + struct s5k5bbgx_platform_data *pdata = NULL; + cam_dbg("E\n"); + + state = kzalloc(sizeof(struct s5k5bbgx_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + + sd = &state->sd; + strcpy(sd->name, S5K5BBGX_DRIVER_NAME); + state->initialized = 0; + state->req_fps = state->set_fps = 8; + state->sensor_mode = SENSOR_CAMERA; + + pdata = client->dev.platform_data; + + if (!pdata) { + cam_err("no platform data\n"); + return -ENODEV; + } + /* Registering subdev */ + v4l2_i2c_subdev_init(sd, client, &s5k5bbgx_ops); + if (state->s5k5bbgx_dev == NULL) { + state->s5k5bbgx_dev = + device_create(camera_class, NULL, 0, NULL, + "front"); + if (IS_ERR(state->s5k5bbgx_dev)) { + cam_err("failed to create device s5k5bbgx_dev!\n"); + } else { + dev_set_drvdata(state->s5k5bbgx_dev, state); + if (device_create_file + (state->s5k5bbgx_dev, + &dev_attr_front_camtype) < 0) { + cam_err("failed to create device file, %s\n", + dev_attr_front_camtype.attr.name); + } + } + } + + /* + * Assign default format and resolution + * Use configured default information in platform data + * or without them, use default information in driver + */ + if (!(pdata->default_width && pdata->default_height)) { + state->preview_frmsizes.width = DEFAULT_PREVIEW_WIDTH; + state->preview_frmsizes.height = DEFAULT_PREVIEW_HEIGHT; + } else { + state->preview_frmsizes.width = pdata->default_width; + state->preview_frmsizes.height = pdata->default_height; + } + state->capture_frmsizes.width = DEFAULT_CAPTURE_WIDTH; + state->capture_frmsizes.height = DEFAULT_CAPTURE_HEIGHT; + + cam_dbg("preview_width: %d , preview_height: %d, " + "capture_width: %d, capture_height: %d", + state->preview_frmsizes.width, state->preview_frmsizes.height, + state->capture_frmsizes.width, state->capture_frmsizes.height); + + state->req_fmt.width = state->preview_frmsizes.width; + state->req_fmt.height = state->preview_frmsizes.height; + + if (!pdata->pixelformat) + state->req_fmt.pixelformat = DEFAULT_FMT; + else + state->req_fmt.pixelformat = pdata->pixelformat; + cam_dbg("probed!!\n"); + + return 0; +} + +static int s5k5bbgx_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct s5k5bbgx_state *state = to_state(sd); + + cam_dbg("E\n"); + + state->initialized = 0; + + device_remove_file(state->s5k5bbgx_dev, &dev_attr_front_camtype); + device_destroy(camera_class, 0); + state->s5k5bbgx_dev = NULL; + + v4l2_device_unregister_subdev(sd); + kfree(to_state(sd)); + +#ifdef CONFIG_LOAD_FILE +/* if (testBuf) {*/ + large_file ? vfree(testBuf) : kfree(testBuf); + large_file = 0; + testBuf = NULL; +/* }*/ +#endif + + return 0; +} + +static const struct i2c_device_id s5k5bbgx_id[] = { + { S5K5BBGX_DRIVER_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, s5k5bbgx_id); + +static struct i2c_driver s5k5bbgx_i2c_driver = { + .driver = { + .name = S5K5BBGX_DRIVER_NAME, + }, + .probe = s5k5bbgx_probe, + .remove = s5k5bbgx_remove, + .id_table = s5k5bbgx_id, +}; +static int __init s5k5bbgx_mod_init(void) +{ + cam_dbg("E\n"); + return i2c_add_driver(&s5k5bbgx_i2c_driver); +} + +static void __exit s5k5bbgx_mod_exit(void) +{ + cam_dbg("E\n"); + i2c_del_driver(&s5k5bbgx_i2c_driver); +} +module_init(s5k5bbgx_mod_init); +module_exit(s5k5bbgx_mod_exit); +MODULE_DESCRIPTION("S5K5BBGX ISP driver"); +MODULE_AUTHOR("DongSeong Lim"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/s5k5bbgx.h b/drivers/media/video/s5k5bbgx.h new file mode 100644 index 0000000..3549e93 --- /dev/null +++ b/drivers/media/video/s5k5bbgx.h @@ -0,0 +1,117 @@ +/* + * Driver for S5K5BBGX 2M ISP from Samsung + * + * Copyright (C) 2011, + * DongSeong Lim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __S5K5BBGX_H +#define __S5K5BBGX_H + +#include + +#define S5K5BBGX_DRIVER_NAME "S5K5BBGX" + +extern struct class *camera_class; +extern int s5k5bbgx_power_reset(void); + +enum stream_cmd_t { + STREAM_STOP, + STREAM_START, +}; + +struct s5k5bbgx_framesize { + u32 width; + u32 height; +}; + +struct s5k5bbgx_exif { + u32 shutter_speed; + u16 iso; +}; + + +/* + * Driver information + */ +struct s5k5bbgx_state { + struct v4l2_subdev sd; +struct device *s5k5bbgx_dev; + /* + * req_fmt is the requested format from the application. + * set_fmt is the output format of the camera. Finally FIMC + * converts the camera output(set_fmt) to the requested format + * with hardware scaler. + */ + struct v4l2_pix_format req_fmt; + struct s5k5bbgx_framesize preview_frmsizes; + struct s5k5bbgx_framesize capture_frmsizes; + struct s5k5bbgx_exif exif; + + enum v4l2_sensor_mode sensor_mode; + s32 vt_mode; + s32 check_dataline; + u32 req_fps; + u32 set_fps; + u32 initialized; +}; + +static inline struct s5k5bbgx_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct s5k5bbgx_state, sd); +} + +/*#define CONFIG_CAM_DEBUG*/ +#define cam_warn(fmt, ...) \ + do { \ + printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_err(fmt, ...) \ + do { \ + printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_info(fmt, ...) \ + do { \ + printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#ifdef CONFIG_CAM_DEBUG +#define cam_dbg(fmt, ...) \ + do { \ + printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) +#else +#define cam_dbg(fmt, ...) +#endif /* CONFIG_CAM_DEBUG */ + + +/************ driver feature ************/ +#define S5K5BBGX_USLEEP +/* #define CONFIG_LOAD_FILE */ + + +/*********** Sensor specific ************/ +/* #define S5K5BBGX_100MS_DELAY 0xAA55AA5F */ +/* #define S5K5BBGX_10MS_DELAY 0xAA55AA5E */ +#define S5K5BBGX_DELAY 0xFFFF0000 +#define S5K5BBGX_DEF_APEX_DEN 100 + +/* Register address */ +#define REG_PAGE_SHUTTER 0x7000 +#define REG_ADDR_SHUTTER 0x238C +#define REG_PAGE_ISO 0x7000 +#define REG_ADDR_ISO 0x2390 +#define REG_PAGE_CAPTURE_STATUS 0x7000 +#define REG_ADDR_CAPTURE_STATUS 0x0142 +#define S5K5BBGX_READ_STATUS_RETRIES 20 + +#include "s5k5bbgx_setfile.h" + +#endif /* __S5K5BBGX_H */ diff --git a/drivers/media/video/s5k5bbgx_setfile.h b/drivers/media/video/s5k5bbgx_setfile.h new file mode 100644 index 0000000..1efe6af --- /dev/null +++ b/drivers/media/video/s5k5bbgx_setfile.h @@ -0,0 +1,12066 @@ +/* + * Driver for S5K5BBGX 2M ISP from Samsung + * + * Copyright (C) 2011, + * DongSeong Lim + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __S5K5BBGX_SETFILE_H +#define __S5K5BBGX_SETFILE_H + +#include + + +static const u32 s5k5bbgx_common[] = { + + 0xFCFCD000, + 0x00100001, /*S/W Reset*/ + 0x10300000, /*contint_host_int*/ + 0x00140001, /*sw_load_complete - Release CORE (Arm) from reset + state*/ + 0xFFFF000A, + + /*0x0028D000,*/ /*Driving Current*/ + /*0x002A1082,*/ + /*0x0F1203ff,*/ /*cregs_d0_d4_cd10 D4[9:8], D3[7:6], D2[5:4], D1[3:2], + D0[1:0]*/ + /*0x002A1084,*/ + /*0x0F1203ff,*/ /*cregs_d5_d9_cd10 D9[9:8], D8[7:6], D7[5:4], D6[3:2], + D5[1:0]*/ + /*0x002A1088,*/ + /*0x0F120fcf,*/ /*cregs_clks_output_cd10 SDA[11:10], SCL[9:8], + PCLK[7:6], VSYNC[3:2], HSYNC[1:0]*/ + + 0x0028D000, + 0x002AF404, + 0x0F120038, /*aig_adc_sat[7:0] : 850mV*/ + 0x0F120001, /*ms[2:0]; 2h@Normal, 2h@PLA, 1h@CNT.AVG*/ + 0x0F12000C, /*aig_sig_mx[5:0]*/ + 0x0F120006, /*aig_rst_mx[5:0]*/ + 0x0F120008, /*rmp_option[7:0]; [3]SL_Low_PWR_SAVE On*/ + 0x002AF418, + 0x0F120003, /*aig_dbr_clk_sel[1:0]*/ + 0x002AF41C, + 0x0F120140, /*aig_bist_sig_width_e[10:0]*/ + 0x0F120140, /*aig_bist_sig_width_o[10:0]*/ + 0x0F120066, /*aig_bist_sig_width_o[10:0]*/ + 0x0F120005, /*aig_pix_bias[3:0]*/ + 0x002AF426, + 0x0F1200D4, /*aig_clp_lvl[7:0]*/ + 0x002AF42A, + 0x0F120001, /*aig_ref_option[0] SL_Low_PWR_SAVE On*/ + 0x002AF430, + 0x0F120001, /*aig_pd_cp_rosc[0]*/ + 0x0F120001, /*aig_pd_ncp_rosc[0]*/ + 0x002AF43A, + 0x0F120000, /*aig_pd_fblv[0]*/ + 0x002AF440, + 0x0F120044, /*aig_rosc_tune_ncp[7:4] aig_rosc_tune_cp[3:0]*/ + 0x002AF44A, + 0x0F120000, /*aig_fb_lv[1:0]*/ + 0x002AF45C, + 0x0F120000, /*aig_dshut_en[0]*/ + 0x0F120000, /*aig_srx_en[0]*/ + 0x002AF462, + 0x0F120001, /*aig_pdb_atop[0]*/ + 0x002AF46E, + 0x0F121F02, /*aig_cds_test[15:0]*/ + 0x002AF474, + 0x0F12000E, /*aig_stx_gap[4:0]*/ + 0x002AE42E, + 0x0F120004, /*adlc_qec[2:0]*/ + 0x00287000, + 0x002A13E0, + 0x0F120000, /*senHal_bSRX SRX OFF*/ + 0x002A13C8, + 0x0F120001, /*senHal_bSenAAC AAC Enable*/ + 0x002A12D8, + 0x0F120464, /*senHal_ContPtrs_senModesDataArr[78]*/ + 0x0F120468, /*senHal_ContPtrs_senModesDataArr[79]*/ + 0x002A12F6, + 0x0F120000, /*senHal_ContPtrs_senModesDataArr[93]*/ + 0x002A13CC, + 0x0F121FC0, /*senHal_bSen11ADLC [12:0] : Write tuning value to E404 + register*/ + 0x002A13EC, + 0x0F120001, /*senHal_DarklevelTuneMode*/ + 0x002A184C, + 0x0F121EE1, + 0x00287000, + 0x002A040E, + 0x0F120003, /*skl_usConfigStbySettings*/ + 0xFFFF000A, + 0x002A1218, + 0x0F120002, /*senHal_SenBinFactor*/ + 0x0F120002, /*senHal_SamplingType*/ + 0x002A0C9A, + 0x0F120001, /*setot_bUseDigitalHbin*/ + 0x002A1438, + 0x0F12F468, /*senHal_TuneStr_AngTuneData1[0]*/ + 0x0F120000, /*senHal_TuneStr_AngTuneData1[1] not use binninb block + 0x0000, use binnin blcok 0x0000*/ + 0x0F120008, /*senHal_TuneStr_AngTuneData1[2] not use binninb block + 0x000A, use binnin blcok 0x0008*/ + 0x0F120006, /*senHal_TuneStr_AngTuneData1[3] not use binninb block + 0x0005, use binnin blcok 0x0006*/ + 0x0F120000, /*senHal_TuneStr_AngTuneData1[4]*/ + 0xFFFF000A, + 0x002A0416, + 0x0F12F400, /*skl_usStbyBackupReg[0][0]*/ + 0x0F120074, /*skl_usStbyBackupReg[0][1]*/ + 0x0F12E42E, /*skl_usStbyBackupReg[1][0]*/ + 0x0F120030, /*skl_usStbyBackupReg[1][1]*/ + 0x002A378C, + 0x0F120000, /* On/off regiSter bUSeOTP*/ + 0x002A0AD8, + 0x0F120F00, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F128608, + 0x0F12E960, + 0x0F120243, + 0x0F12128B, + 0x0F12F073, + 0x0F120270, + 0x0F12DF47, + 0x0F12F226, + 0x0F121A31, + 0x0F12DFDA, + 0x0F121200, + 0x0F1205A9, + 0x0F120F16, + 0x0F120F5E, + 0x0F12DF10, + 0x0F1225BF, + 0x0F12FCF0, + 0x0F12DE1B, + 0x0F12025B, + 0x0F12FA8B, + 0x0F12163B, + 0x0F12DF44, + 0x0F12FB2D, + 0x0F1230E6, + 0x0F12FE07, + 0x0F12F47C, + 0x0F1209F2, + 0x0F120AED, + 0x0F12FA09, + 0x0F12E70E, + 0x0F120158, + 0x0F121110, + 0x0F12E28C, + 0x0F120DFB, + 0x0F12074B, + 0x0F12FBE5, + 0x0F12961C, + 0x0F12E21A, + 0x0F120ADF, + 0x0F120A67, + 0x0F12F8A6, + 0x0F12FDC3, + 0x0F12D590, + 0x0F12FA69, + 0x0F1208D5, + 0x0F12F635, + 0x0F12057E, + 0x0F12043B, + 0x0F12155C, + 0x0F1200C6, + 0x0F12F042, + 0x0F12176A, + 0x0F12F818, + 0x0F12F1F3, + 0x0F12026F, + 0x0F1208F6, + 0x0F120CCF, + 0x0F12E42D, + 0x0F120A92, + 0x0F1210EC, + 0x0F12005F, + 0x0F12F02C, + 0x0F120672, + 0x0F1209BF, + 0x0F12F4B5, + 0x0F12FC22, + 0x0F12FD50, + 0x0F120C26, + 0x0F12EED3, + 0x0F1207C3, + 0x0F12080F, + 0x0F12F6CF, + 0x0F127A3B, + 0x0F12E9DC, + 0x0F12088E, + 0x0F1201C8, + 0x0F12043C, + 0x0F12F7E2, + 0x0F12E391, + 0x0F12F3C4, + 0x0F121422, + 0x0F12E845, + 0x0F120D16, + 0x0F1206CA, + 0x0F120DEB, + 0x0F121324, + 0x0F12E814, + 0x0F1216B7, + 0x0F1202AC, + 0x0F12DE4D, + 0x0F1201EA, + 0x0F12F0C2, + 0x0F120E06, + 0x0F12EC6D, + 0x0F12FDF0, + 0x0F122B46, + 0x0F120710, + 0x0F12F84C, + 0x0F120E52, + 0x0F120675, + 0x0F12F0D7, + 0x0F12ED40, + 0x0F12F3AD, + 0x0F12179A, + 0x0F12DE9B, + 0x0F1210BA, + 0x0F120825, + 0x0F12FE0A, + 0x0F1288E9, + 0x0F12E9E0, + 0x0F12043D, + 0x0F120A17, + 0x0F12FC21, + 0x0F12FB58, + 0x0F12DCE0, + 0x0F12F24C, + 0x0F121A19, + 0x0F12E011, + 0x0F1211A3, + 0x0F120649, + 0x0F120D04, + 0x0F120E15, + 0x0F12E112, + 0x0F1227BD, + 0x0F12F7AA, + 0x0F12E06A, + 0x0F120A16, + 0x0F12FD23, + 0x0F121226, + 0x0F12DA34, + 0x0F1207A4, + 0x0F122AD3, + 0x0F12FE27, + 0x0F12EE64, + 0x0F120CAD, + 0x0F1211C5, + 0x0F12EC55, + 0x0F12ED98, + 0x0F12F88A, + 0x0F121842, + 0x0F12E1D5, + 0x0F1208FD, + 0x0F120FB6, + 0x0F12F801, + 0x002A0378, + 0x0F120001, /*REG_TC_DBG_RelnitCmd*/ + 0x002A05E8, + 0x0F1200E4, /*TVAR_ash_AwbAshCord_0_ Horizon*/ + 0x0F1200F0, /*TVAR_ash_AwbAshCord_1_ IncandA*/ + 0x0F120100, /*TVAR_ash_AwbAshCord_2_ WW*/ + 0x0F120120, /*TVAR_ash_AwbAshCord_3_ CW*/ + 0x0F120150, /*TVAR_ash_AwbAshCord_4_ D50*/ + 0x0F120180, /*TVAR_ash_AwbAshCord_5_ D65*/ + 0x0F1201A0, /*TVAR_ash_AwbAshCord_6_ D75*/ + 0x002A05FE, + 0x0F123800, /*TVAR_ash_GASAlpha_0__0_ Horizon*/ + 0x0F124000, /*TVAR_ash_GASAlpha_0__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_0__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_0__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_1__0_ IncandA*/ + 0x0F124000, /*TVAR_ash_GASAlpha_1__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_1__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_1__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_2__0_ WW*/ + 0x0F124000, /*TVAR_ash_GASAlpha_2__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_2__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_2__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_3__0_ CW*/ + 0x0F124000, /*TVAR_ash_GASAlpha_3__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_3__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_3__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_4__0_ D50*/ + 0x0F124000, /*TVAR_ash_GASAlpha_4__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_4__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_4__3_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__0_ D65*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__3_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__0_ D75*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__3_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_0_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_1_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_2_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_3_*/ + 0x00287000, + 0x002A2744, + 0x0F12B510, /* 70002744*/ + 0x0F124A1C, /* 70002746*/ + 0x0F1221FB, /* 70002748*/ + 0x0F12481C, /* 7000274A*/ + 0x0F12C004, /* 7000274C*/ + 0x0F126001, /* 7000274E*/ + 0x0F12491B, /* 70002750*/ + 0x0F12481C, /* 70002752*/ + 0x0F12F000, /* 70002754*/ + 0x0F12FA0E, /* 70002756*/ + 0x0F12491B, /* 70002758*/ + 0x0F12481C, /* 7000275A*/ + 0x0F12F000, /* 7000275C*/ + 0x0F12FA0A, /* 7000275E*/ + 0x0F12491B, /* 70002760*/ + 0x0F12481C, /* 70002762*/ + 0x0F12F000, /* 70002764*/ + 0x0F12FA06, /* 70002766*/ + 0x0F12491B, /* 70002768*/ + 0x0F12481C, /* 7000276A*/ + 0x0F12F000, /* 7000276C*/ + 0x0F12FA02, /* 7000276E*/ + 0x0F12491B, /* 70002770*/ + 0x0F12481C, /* 70002772*/ + 0x0F12F000, /* 70002774*/ + 0x0F12F9FE, /* 70002776*/ + 0x0F12491B, /* 70002778*/ + 0x0F12481C, /* 7000277A*/ + 0x0F12F000, /* 7000277C*/ + 0x0F12F9FA, /* 7000277E*/ + 0x0F12491B, /* 70002780*/ + 0x0F12481C, /* 70002782*/ + 0x0F12F000, /* 70002784*/ + 0x0F12F9F6, /* 70002786*/ + 0x0F12481B, /* 70002788*/ + 0x0F122130, /* 7000278A*/ + 0x0F128001, /* 7000278C*/ + 0x0F1221C0, /* 7000278E*/ + 0x0F128041, /* 70002790*/ + 0x0F122104, /* 70002792*/ + 0x0F128081, /* 70002794*/ + 0x0F122100, /* 70002796*/ + 0x0F1280C1, /* 70002798*/ + 0x0F128101, /* 7000279A*/ + 0x0F124917, /* 7000279C*/ + 0x0F122016, /* 7000279E*/ + 0x0F1283C8, /* 700027A0*/ + 0x0F124917, /* 700027A2*/ + 0x0F124817, /* 700027A4*/ + 0x0F12F000, /* 700027A6*/ + 0x0F12F9E5, /* 700027A8*/ + 0x0F124917, /* 700027AA*/ + 0x0F124817, /* 700027AC*/ + 0x0F12F000, /* 700027AE*/ + 0x0F12F9E1, /* 700027B0*/ + 0x0F12BC10, /* 700027B2*/ + 0x0F12BC08, /* 700027B4*/ + 0x0F124718, /* 700027B6*/ + 0x0F120000, /* 700027B8*/ + 0x0F125BB1, /* 700027BA*/ + 0x0F121770, /* 700027BC*/ + 0x0F127000, /* 700027BE*/ + 0x0F122811, /* 700027C0*/ + 0x0F127000, /* 700027C2*/ + 0x0F12C0BB, /* 700027C4*/ + 0x0F120000, /* 700027C6*/ + 0x0F12284F, /* 700027C8*/ + 0x0F127000, /* 700027CA*/ + 0x0F123609, /* 700027CC*/ + 0x0F120000, /* 700027CE*/ + 0x0F122867, /* 700027D0*/ + 0x0F127000, /* 700027D2*/ + 0x0F1277C7, /* 700027D4*/ + 0x0F120000, /* 700027D6*/ + 0x0F1228F3, /* 700027D8*/ + 0x0F127000, /* 700027DA*/ + 0x0F12727D, /* 700027DC*/ + 0x0F120000, /* 700027DE*/ + 0x0F122949, /* 700027E0*/ + 0x0F127000, /* 700027E2*/ + 0x0F129919, /* 700027E4*/ + 0x0F120000, /* 700027E6*/ + 0x0F122987, /* 700027E8*/ + 0x0F127000, /* 700027EA*/ + 0x0F121C63, /* 700027EC*/ + 0x0F120000, /* 700027EE*/ + 0x0F1229E7, /* 700027F0*/ + 0x0F127000, /* 700027F2*/ + 0x0F1204CB, /* 700027F4*/ + 0x0F120000, /* 700027F6*/ + 0x0F122C7C, /* 700027F8*/ + 0x0F127000, /* 700027FA*/ + 0x0F120CA8, /* 700027FC*/ + 0x0F127000, /* 700027FE*/ + 0x0F122B1D, /* 70002800*/ + 0x0F127000, /* 70002802*/ + 0x0F1250AF, /* 70002804*/ + 0x0F120000, /* 70002806*/ + 0x0F122B2D, /* 70002808*/ + 0x0F127000, /* 7000280A*/ + 0x0F125623, /* 7000280C*/ + 0x0F120000, /* 7000280E*/ + 0x0F12B4F0, /* 70002810*/ + 0x0F126801, /* 70002812*/ + 0x0F12468C, /* 70002814*/ + 0x0F126846, /* 70002816*/ + 0x0F122200, /* 70002818*/ + 0x0F1249C7, /* 7000281A*/ + 0x0F122000, /* 7000281C*/ + 0x0F122724, /* 7000281E*/ + 0x0F124357, /* 70002820*/ + 0x0F12183B, /* 70002822*/ + 0x0F124664, /* 70002824*/ + 0x0F125CE5, /* 70002826*/ + 0x0F12005C, /* 70002828*/ + 0x0F125B34, /* 7000282A*/ + 0x0F12072D, /* 7000282C*/ + 0x0F120F2D, /* 7000282E*/ + 0x0F12800D, /* 70002830*/ + 0x0F12804C, /* 70002832*/ + 0x0F12808B, /* 70002834*/ + 0x0F122301, /* 70002836*/ + 0x0F1280CB, /* 70002838*/ + 0x0F122300, /* 7000283A*/ + 0x0F1280CB, /* 7000283C*/ + 0x0F121C40, /* 7000283E*/ + 0x0F122824, /* 70002840*/ + 0x0F12D3EE, /* 70002842*/ + 0x0F121C52, /* 70002844*/ + 0x0F122A04, /* 70002846*/ + 0x0F12D3E8, /* 70002848*/ + 0x0F12BCF0, /* 7000284A*/ + 0x0F124770, /* 7000284C*/ + 0x0F12B510, /* 7000284E*/ + 0x0F12F000, /* 70002850*/ + 0x0F12F998, /* 70002852*/ + 0x0F1248B9, /* 70002854*/ + 0x0F127A81, /* 70002856*/ + 0x0F1248B9, /* 70002858*/ + 0x0F126B00, /* 7000285A*/ + 0x0F12F000, /* 7000285C*/ + 0x0F12F99A, /* 7000285E*/ + 0x0F12BC10, /* 70002860*/ + 0x0F12BC08, /* 70002862*/ + 0x0F124718, /* 70002864*/ + 0x0F12B5F8, /* 70002866*/ + 0x0F126805, /* 70002868*/ + 0x0F126844, /* 7000286A*/ + 0x0F124EB5, /* 7000286C*/ + 0x0F128861, /* 7000286E*/ + 0x0F128AB0, /* 70002870*/ + 0x0F128A72, /* 70002872*/ + 0x0F122301, /* 70002874*/ + 0x0F124368, /* 70002876*/ + 0x0F121889, /* 70002878*/ + 0x0F1217C2, /* 7000287A*/ + 0x0F120E12, /* 7000287C*/ + 0x0F121810, /* 7000287E*/ + 0x0F121202, /* 70002880*/ + 0x0F128820, /* 70002882*/ + 0x0F12029B, /* 70002884*/ + 0x0F1218C0, /* 70002886*/ + 0x0F12F000, /* 70002888*/ + 0x0F12F98C, /* 7000288A*/ + 0x0F129000, /* 7000288C*/ + 0x0F128AF6, /* 7000288E*/ + 0x0F124268, /* 70002890*/ + 0x0F12210A, /* 70002892*/ + 0x0F124370, /* 70002894*/ + 0x0F12F000, /* 70002896*/ + 0x0F12F98D, /* 70002898*/ + 0x0F12436E, /* 7000289A*/ + 0x0F120007, /* 7000289C*/ + 0x0F12210A, /* 7000289E*/ + 0x0F120030, /* 700028A0*/ + 0x0F12F000, /* 700028A2*/ + 0x0F12F987, /* 700028A4*/ + 0x0F129A00, /* 700028A6*/ + 0x0F120039, /* 700028A8*/ + 0x0F12F000, /* 700028AA*/ + 0x0F12F989, /* 700028AC*/ + 0x0F120002, /* 700028AE*/ + 0x0F128820, /* 700028B0*/ + 0x0F121880, /* 700028B2*/ + 0x0F128020, /* 700028B4*/ + 0x0F1248A4, /* 700028B6*/ + 0x0F1288C1, /* 700028B8*/ + 0x0F1248A2, /* 700028BA*/ + 0x0F123820, /* 700028BC*/ + 0x0F128B40, /* 700028BE*/ + 0x0F124240, /* 700028C0*/ + 0x0F124350, /* 700028C2*/ + 0x0F12F000, /* 700028C4*/ + 0x0F12F976, /* 700028C6*/ + 0x0F128861, /* 700028C8*/ + 0x0F121840, /* 700028CA*/ + 0x0F128060, /* 700028CC*/ + 0x0F12BCF8, /* 700028CE*/ + 0x0F12BC08, /* 700028D0*/ + 0x0F124718, /* 700028D2*/ + 0x0F12B570, /* 700028D4*/ + 0x0F124C9B, /* 700028D6*/ + 0x0F123C20, /* 700028D8*/ + 0x0F128B20, /* 700028DA*/ + 0x0F12F000, /* 700028DC*/ + 0x0F12F978, /* 700028DE*/ + 0x0F124D99, /* 700028E0*/ + 0x0F1280E8, /* 700028E2*/ + 0x0F128B60, /* 700028E4*/ + 0x0F12F000, /* 700028E6*/ + 0x0F12F97B, /* 700028E8*/ + 0x0F128128, /* 700028EA*/ + 0x0F12BC70, /* 700028EC*/ + 0x0F12BC08, /* 700028EE*/ + 0x0F124718, /* 700028F0*/ + 0x0F12B508, /* 700028F2*/ + 0x0F124895, /* 700028F4*/ + 0x0F124669, /* 700028F6*/ + 0x0F12F000, /* 700028F8*/ + 0x0F12F97A, /* 700028FA*/ + 0x0F124894, /* 700028FC*/ + 0x0F12214D, /* 700028FE*/ + 0x0F128201, /* 70002900*/ + 0x0F122196, /* 70002902*/ + 0x0F128281, /* 70002904*/ + 0x0F12211D, /* 70002906*/ + 0x0F128301, /* 70002908*/ + 0x0F12F7FF, /* 7000290A*/ + 0x0F12FFE3, /* 7000290C*/ + 0x0F12F000, /* 7000290E*/ + 0x0F12F977, /* 70002910*/ + 0x0F12466B, /* 70002912*/ + 0x0F128818, /* 70002914*/ + 0x0F128859, /* 70002916*/ + 0x0F121A40, /* 70002918*/ + 0x0F12498E, /* 7000291A*/ + 0x0F126348, /* 7000291C*/ + 0x0F12488A, /* 7000291E*/ + 0x0F129900, /* 70002920*/ + 0x0F123876, /* 70002922*/ + 0x0F12F000, /* 70002924*/ + 0x0F12F974, /* 70002926*/ + 0x0F12466B, /* 70002928*/ + 0x0F12488A, /* 7000292A*/ + 0x0F128819, /* 7000292C*/ + 0x0F123080, /* 7000292E*/ + 0x0F1284C1, /* 70002930*/ + 0x0F128859, /* 70002932*/ + 0x0F128501, /* 70002934*/ + 0x0F124987, /* 70002936*/ + 0x0F122000, /* 70002938*/ + 0x0F123920, /* 7000293A*/ + 0x0F127088, /* 7000293C*/ + 0x0F123140, /* 7000293E*/ + 0x0F127388, /* 70002940*/ + 0x0F12B001, /* 70002942*/ + 0x0F12BC08, /* 70002944*/ + 0x0F124718, /* 70002946*/ + 0x0F12B570, /* 70002948*/ + 0x0F120004, /* 7000294A*/ + 0x0F126820, /* 7000294C*/ + 0x0F126865, /* 7000294E*/ + 0x0F12F000, /* 70002950*/ + 0x0F12F966, /* 70002952*/ + 0x0F120402, /* 70002954*/ + 0x0F124880, /* 70002956*/ + 0x0F120C12, /* 70002958*/ + 0x0F128142, /* 7000295A*/ + 0x0F12487F, /* 7000295C*/ + 0x0F128801, /* 7000295E*/ + 0x0F122900, /* 70002960*/ + 0x0F12D008, /* 70002962*/ + 0x0F12497E, /* 70002964*/ + 0x0F12002B, /* 70002966*/ + 0x0F126D8A, /* 70002968*/ + 0x0F122105, /* 7000296A*/ + 0x0F121C80, /* 7000296C*/ + 0x0F12F000, /* 7000296E*/ + 0x0F12F95F, /* 70002970*/ + 0x0F126020, /* 70002972*/ + 0x0F12E005, /* 70002974*/ + 0x0F12487B, /* 70002976*/ + 0x0F12002B, /* 70002978*/ + 0x0F122105, /* 7000297A*/ + 0x0F12F000, /* 7000297C*/ + 0x0F12F958, /* 7000297E*/ + 0x0F126020, /* 70002980*/ + 0x0F126820, /* 70002982*/ + 0x0F12E7B2, /* 70002984*/ + 0x0F12B5F8, /* 70002986*/ + 0x0F124975, /* 70002988*/ + 0x0F122200, /* 7000298A*/ + 0x0F123160, /* 7000298C*/ + 0x0F1283CA, /* 7000298E*/ + 0x0F126800, /* 70002990*/ + 0x0F124669, /* 70002992*/ + 0x0F12F000, /* 70002994*/ + 0x0F12F92C, /* 70002996*/ + 0x0F12466B, /* 70002998*/ + 0x0F128818, /* 7000299A*/ + 0x0F12F000, /* 7000299C*/ + 0x0F12F918, /* 7000299E*/ + 0x0F120005, /* 700029A0*/ + 0x0F12466B, /* 700029A2*/ + 0x0F128858, /* 700029A4*/ + 0x0F12F000, /* 700029A6*/ + 0x0F12F91B, /* 700029A8*/ + 0x0F120004, /* 700029AA*/ + 0x0F122101, /* 700029AC*/ + 0x0F121928, /* 700029AE*/ + 0x0F1202C9, /* 700029B0*/ + 0x0F121A08, /* 700029B2*/ + 0x0F120286, /* 700029B4*/ + 0x0F120029, /* 700029B6*/ + 0x0F120030, /* 700029B8*/ + 0x0F12F000, /* 700029BA*/ + 0x0F12F941, /* 700029BC*/ + 0x0F120005, /* 700029BE*/ + 0x0F122701, /* 700029C0*/ + 0x0F1202BF, /* 700029C2*/ + 0x0F120021, /* 700029C4*/ + 0x0F120030, /* 700029C6*/ + 0x0F12F000, /* 700029C8*/ + 0x0F12F93A, /* 700029CA*/ + 0x0F124964, /* 700029CC*/ + 0x0F124A61, /* 700029CE*/ + 0x0F123140, /* 700029D0*/ + 0x0F1232A0, /* 700029D2*/ + 0x0F12800D, /* 700029D4*/ + 0x0F128395, /* 700029D6*/ + 0x0F12804F, /* 700029D8*/ + 0x0F1283D7, /* 700029DA*/ + 0x0F128088, /* 700029DC*/ + 0x0F120011, /* 700029DE*/ + 0x0F123120, /* 700029E0*/ + 0x0F128008, /* 700029E2*/ + 0x0F12E773, /* 700029E4*/ + 0x0F12B510, /* 700029E6*/ + 0x0F12485C, /* 700029E8*/ + 0x0F128980, /* 700029EA*/ + 0x0F122800, /* 700029EC*/ + 0x0F12D001, /* 700029EE*/ + 0x0F12F000, /* 700029F0*/ + 0x0F12F92C, /* 700029F2*/ + 0x0F12E734, /* 700029F4*/ + 0x0F12B5FE, /* 700029F6*/ + 0x0F122600, /* 700029F8*/ + 0x0F12495B, /* 700029FA*/ + 0x0F122000, /* 700029FC*/ + 0x0F126108, /* 700029FE*/ + 0x0F1260C8, /* 70002A00*/ + 0x0F12485A, /* 70002A02*/ + 0x0F128901, /* 70002A04*/ + 0x0F124852, /* 70002A06*/ + 0x0F123020, /* 70002A08*/ + 0x0F1288C0, /* 70002A0A*/ + 0x0F129000, /* 70002A0C*/ + 0x0F120840, /* 70002A0E*/ + 0x0F129002, /* 70002A10*/ + 0x0F124856, /* 70002A12*/ + 0x0F128800, /* 70002A14*/ + 0x0F129001, /* 70002A16*/ + 0x0F124853, /* 70002A18*/ + 0x0F123040, /* 70002A1A*/ + 0x0F128B05, /* 70002A1C*/ + 0x0F122900, /* 70002A1E*/ + 0x0F12D01F, /* 70002A20*/ + 0x0F124E52, /* 70002A22*/ + 0x0F122700, /* 70002A24*/ + 0x0F1280F7, /* 70002A26*/ + 0x0F122400, /* 70002A28*/ + 0x0F12E016, /* 70002A2A*/ + 0x0F12494E, /* 70002A2C*/ + 0x0F120060, /* 70002A2E*/ + 0x0F1239C0, /* 70002A30*/ + 0x0F121841, /* 70002A32*/ + 0x0F122020, /* 70002A34*/ + 0x0F125E08, /* 70002A36*/ + 0x0F129902, /* 70002A38*/ + 0x0F121840, /* 70002A3A*/ + 0x0F129900, /* 70002A3C*/ + 0x0F12F000, /* 70002A3E*/ + 0x0F12F8FF, /* 70002A40*/ + 0x0F124B4A, /* 70002A42*/ + 0x0F120202, /* 70002A44*/ + 0x0F1200A1, /* 70002A46*/ + 0x0F12330C, /* 70002A48*/ + 0x0F12505A, /* 70002A4A*/ + 0x0F120002, /* 70002A4C*/ + 0x0F124342, /* 70002A4E*/ + 0x0F120210, /* 70002A50*/ + 0x0F121DDA, /* 70002A52*/ + 0x0F1232F9, /* 70002A54*/ + 0x0F125050, /* 70002A56*/ + 0x0F121C64, /* 70002A58*/ + 0x0F1242A5, /* 70002A5A*/ + 0x0F12DCE6, /* 70002A5C*/ + 0x0F128137, /* 70002A5E*/ + 0x0F12E042, /* 70002A60*/ + 0x0F122400, /* 70002A62*/ + 0x0F12E031, /* 70002A64*/ + 0x0F124940, /* 70002A66*/ + 0x0F120060, /* 70002A68*/ + 0x0F1239C0, /* 70002A6A*/ + 0x0F121841, /* 70002A6C*/ + 0x0F122020, /* 70002A6E*/ + 0x0F125E08, /* 70002A70*/ + 0x0F129902, /* 70002A72*/ + 0x0F121840, /* 70002A74*/ + 0x0F129900, /* 70002A76*/ + 0x0F12F000, /* 70002A78*/ + 0x0F12F8E2, /* 70002A7A*/ + 0x0F124A3B, /* 70002A7C*/ + 0x0F1200A1, /* 70002A7E*/ + 0x0F12320C, /* 70002A80*/ + 0x0F125853, /* 70002A82*/ + 0x0F123A0C, /* 70002A84*/ + 0x0F128852, /* 70002A86*/ + 0x0F124353, /* 70002A88*/ + 0x0F123380, /* 70002A8A*/ + 0x0F120A1F, /* 70002A8C*/ + 0x0F1223FF, /* 70002A8E*/ + 0x0F121C5B, /* 70002A90*/ + 0x0F121A9B, /* 70002A92*/ + 0x0F12469C, /* 70002A94*/ + 0x0F124343, /* 70002A96*/ + 0x0F1218FF, /* 70002A98*/ + 0x0F124B34, /* 70002A9A*/ + 0x0F12330C, /* 70002A9C*/ + 0x0F12505F, /* 70002A9E*/ + 0x0F120003, /* 70002AA0*/ + 0x0F124343, /* 70002AA2*/ + 0x0F124660, /* 70002AA4*/ + 0x0F124343, /* 70002AA6*/ + 0x0F124831, /* 70002AA8*/ + 0x0F125840, /* 70002AAA*/ + 0x0F124350, /* 70002AAC*/ + 0x0F123080, /* 70002AAE*/ + 0x0F124A2F, /* 70002AB0*/ + 0x0F120A00, /* 70002AB2*/ + 0x0F121818, /* 70002AB4*/ + 0x0F125050, /* 70002AB6*/ + 0x0F120039, /* 70002AB8*/ + 0x0F124379, /* 70002ABA*/ + 0x0F123180, /* 70002ABC*/ + 0x0F120A09, /* 70002ABE*/ + 0x0F124281, /* 70002AC0*/ + 0x0F12D201, /* 70002AC2*/ + 0x0F121A40, /* 70002AC4*/ + 0x0F121986, /* 70002AC6*/ + 0x0F121C64, /* 70002AC8*/ + 0x0F1242A5, /* 70002ACA*/ + 0x0F12DCCB, /* 70002ACC*/ + 0x0F120868, /* 70002ACE*/ + 0x0F121980, /* 70002AD0*/ + 0x0F120029, /* 70002AD2*/ + 0x0F12F000, /* 70002AD4*/ + 0x0F12F8B4, /* 70002AD6*/ + 0x0F123008, /* 70002AD8*/ + 0x0F120900, /* 70002ADA*/ + 0x0F129A01, /* 70002ADC*/ + 0x0F124923, /* 70002ADE*/ + 0x0F124290, /* 70002AE0*/ + 0x0F12D901, /* 70002AE2*/ + 0x0F128888, /* 70002AE4*/ + 0x0F1280C8, /* 70002AE6*/ + 0x0F124920, /* 70002AE8*/ + 0x0F1288C8, /* 70002AEA*/ + 0x0F122800, /* 70002AEC*/ + 0x0F12D001, /* 70002AEE*/ + 0x0F121E40, /* 70002AF0*/ + 0x0F1280C8, /* 70002AF2*/ + 0x0F129801, /* 70002AF4*/ + 0x0F122800, /* 70002AF6*/ + 0x0F12D00D, /* 70002AF8*/ + 0x0F124A1B, /* 70002AFA*/ + 0x0F123AC0, /* 70002AFC*/ + 0x0F127B90, /* 70002AFE*/ + 0x0F122802, /* 70002B00*/ + 0x0F12D001, /* 70002B02*/ + 0x0F122803, /* 70002B04*/ + 0x0F12D106, /* 70002B06*/ + 0x0F1288C9, /* 70002B08*/ + 0x0F122900, /* 70002B0A*/ + 0x0F12D003, /* 70002B0C*/ + 0x0F122100, /* 70002B0E*/ + 0x0F120040, /* 70002B10*/ + 0x0F121880, /* 70002B12*/ + 0x0F128081, /* 70002B14*/ + 0x0F12BCFE, /* 70002B16*/ + 0x0F12BC08, /* 70002B18*/ + 0x0F124718, /* 70002B1A*/ + 0x0F12B510, /* 70002B1C*/ + 0x0F126800, /* 70002B1E*/ + 0x0F12F000, /* 70002B20*/ + 0x0F12F89C, /* 70002B22*/ + 0x0F124911, /* 70002B24*/ + 0x0F122001, /* 70002B26*/ + 0x0F128108, /* 70002B28*/ + 0x0F12E699, /* 70002B2A*/ + 0x0F12B510, /* 70002B2C*/ + 0x0F12F000, /* 70002B2E*/ + 0x0F12F89D, /* 70002B30*/ + 0x0F12F7FF, /* 70002B32*/ + 0x0F12FF60, /* 70002B34*/ + 0x0F12E693, /* 70002B36*/ + 0x0F124140, /* 70002B38*/ + 0x0F12D000, /* 70002B3A*/ + 0x0F1219DC, /* 70002B3C*/ + 0x0F127000, /* 70002B3E*/ + 0x0F121B60, /* 70002B40*/ + 0x0F127000, /* 70002B42*/ + 0x0F120DD4, /* 70002B44*/ + 0x0F127000, /* 70002B46*/ + 0x0F1222AC, /* 70002B48*/ + 0x0F127000, /* 70002B4A*/ + 0x0F120F88, /* 70002B4C*/ + 0x0F127000, /* 70002B4E*/ + 0x0F121E8C, /* 70002B50*/ + 0x0F127000, /* 70002B52*/ + 0x0F12214C, /* 70002B54*/ + 0x0F127000, /* 70002B56*/ + 0x0F121A10, /* 70002B58*/ + 0x0F127000, /* 70002B5A*/ + 0x0F123780, /* 70002B5C*/ + 0x0F127000, /* 70002B5E*/ + 0x0F122384, /* 70002B60*/ + 0x0F127000, /* 70002B62*/ + 0x0F12065C, /* 70002B64*/ + 0x0F127000, /* 70002B66*/ + 0x0F121C8C, /* 70002B68*/ + 0x0F127000, /* 70002B6A*/ + 0x0F122C7C, /* 70002B6C*/ + 0x0F127000, /* 70002B6E*/ + 0x0F122D88, /* 70002B70*/ + 0x0F127000, /* 70002B72*/ + 0x0F124778, /* 70002B74*/ + 0x0F1246C0, /* 70002B76*/ + 0x0F12C000, /* 70002B78*/ + 0x0F12E59F, /* 70002B7A*/ + 0x0F12FF1C, /* 70002B7C*/ + 0x0F12E12F, /* 70002B7E*/ + 0x0F12CE77, /* 70002B80*/ + 0x0F120000, /* 70002B82*/ + 0x0F124778, /* 70002B84*/ + 0x0F1246C0, /* 70002B86*/ + 0x0F12C000, /* 70002B88*/ + 0x0F12E59F, /* 70002B8A*/ + 0x0F12FF1C, /* 70002B8C*/ + 0x0F12E12F, /* 70002B8E*/ + 0x0F123609, /* 70002B90*/ + 0x0F120000, /* 70002B92*/ + 0x0F124778, /* 70002B94*/ + 0x0F1246C0, /* 70002B96*/ + 0x0F12C000, /* 70002B98*/ + 0x0F12E59F, /* 70002B9A*/ + 0x0F12FF1C, /* 70002B9C*/ + 0x0F12E12F, /* 70002B9E*/ + 0x0F129F91, /* 70002BA0*/ + 0x0F120000, /* 70002BA2*/ + 0x0F124778, /* 70002BA4*/ + 0x0F1246C0, /* 70002BA6*/ + 0x0F12C000, /* 70002BA8*/ + 0x0F12E59F, /* 70002BAA*/ + 0x0F12FF1C, /* 70002BAC*/ + 0x0F12E12F, /* 70002BAE*/ + 0x0F122AE3, /* 70002BB0*/ + 0x0F120000, /* 70002BB2*/ + 0x0F124778, /* 70002BB4*/ + 0x0F1246C0, /* 70002BB6*/ + 0x0F12F004, /* 70002BB8*/ + 0x0F12E51F, /* 70002BBA*/ + 0x0F12D1DC, /* 70002BBC*/ + 0x0F120000, /* 70002BBE*/ + 0x0F124778, /* 70002BC0*/ + 0x0F1246C0, /* 70002BC2*/ + 0x0F12C000, /* 70002BC4*/ + 0x0F12E59F, /* 70002BC6*/ + 0x0F12FF1C, /* 70002BC8*/ + 0x0F12E12F, /* 70002BCA*/ + 0x0F126869, /* 70002BCC*/ + 0x0F120000, /* 70002BCE*/ + 0x0F124778, /* 70002BD0*/ + 0x0F1246C0, /* 70002BD2*/ + 0x0F12C000, /* 70002BD4*/ + 0x0F12E59F, /* 70002BD6*/ + 0x0F12FF1C, /* 70002BD8*/ + 0x0F12E12F, /* 70002BDA*/ + 0x0F1268BD, /* 70002BDC*/ + 0x0F120000, /* 70002BDE*/ + 0x0F124778, /* 70002BE0*/ + 0x0F1246C0, /* 70002BE2*/ + 0x0F12C000, /* 70002BE4*/ + 0x0F12E59F, /* 70002BE6*/ + 0x0F12FF1C, /* 70002BE8*/ + 0x0F12E12F, /* 70002BEA*/ + 0x0F1268DB, /* 70002BEC*/ + 0x0F120000, /* 70002BEE*/ + 0x0F124778, /* 70002BF0*/ + 0x0F1246C0, /* 70002BF2*/ + 0x0F12C000, /* 70002BF4*/ + 0x0F12E59F, /* 70002BF6*/ + 0x0F12FF1C, /* 70002BF8*/ + 0x0F12E12F, /* 70002BFA*/ + 0x0F121BC9, /* 70002BFC*/ + 0x0F120000, /* 70002BFE*/ + 0x0F124778, /* 70002C00*/ + 0x0F1246C0, /* 70002C02*/ + 0x0F12C000, /* 70002C04*/ + 0x0F12E59F, /* 70002C06*/ + 0x0F12FF1C, /* 70002C08*/ + 0x0F12E12F, /* 70002C0A*/ + 0x0F1271B9, /* 70002C0C*/ + 0x0F120000, /* 70002C0E*/ + 0x0F124778, /* 70002C10*/ + 0x0F1246C0, /* 70002C12*/ + 0x0F12C000, /* 70002C14*/ + 0x0F12E59F, /* 70002C16*/ + 0x0F12FF1C, /* 70002C18*/ + 0x0F12E12F, /* 70002C1A*/ + 0x0F127249, /* 70002C1C*/ + 0x0F120000, /* 70002C1E*/ + 0x0F124778, /* 70002C20*/ + 0x0F1246C0, /* 70002C22*/ + 0x0F12C000, /* 70002C24*/ + 0x0F12E59F, /* 70002C26*/ + 0x0F12FF1C, /* 70002C28*/ + 0x0F12E12F, /* 70002C2A*/ + 0x0F1298CD, /* 70002C2C*/ + 0x0F120000, /* 70002C2E*/ + 0x0F124778, /* 70002C30*/ + 0x0F1246C0, /* 70002C32*/ + 0x0F12C000, /* 70002C34*/ + 0x0F12E59F, /* 70002C36*/ + 0x0F12FF1C, /* 70002C38*/ + 0x0F12E12F, /* 70002C3A*/ + 0x0F12987F, /* 70002C3C*/ + 0x0F120000, /* 70002C3E*/ + 0x0F124778, /* 70002C40*/ + 0x0F1246C0, /* 70002C42*/ + 0x0F12F004, /* 70002C44*/ + 0x0F12E51F, /* 70002C46*/ + 0x0F12D378, /* 70002C48*/ + 0x0F120000, /* 70002C4A*/ + 0x0F124778, /* 70002C4C*/ + 0x0F1246C0, /* 70002C4E*/ + 0x0F12C000, /* 70002C50*/ + 0x0F12E59F, /* 70002C52*/ + 0x0F12FF1C, /* 70002C54*/ + 0x0F12E12F, /* 70002C56*/ + 0x0F1204CB, /* 70002C58*/ + 0x0F120000, /* 70002C5A*/ + 0x0F124778, /* 70002C5C*/ + 0x0F1246C0, /* 70002C5E*/ + 0x0F12C000, /* 70002C60*/ + 0x0F12E59F, /* 70002C62*/ + 0x0F12FF1C, /* 70002C64*/ + 0x0F12E12F, /* 70002C66*/ + 0x0F1250AF, /* 70002C68*/ + 0x0F120000, /* 70002C6A*/ + 0x0F124778, /* 70002C6C*/ + 0x0F1246C0, /* 70002C6E*/ + 0x0F12C000, /* 70002C70*/ + 0x0F12E59F, /* 70002C72*/ + 0x0F12FF1C, /* 70002C74*/ + 0x0F12E12F, /* 70002C76*/ + 0x0F125623, /* 70002C78*/ + 0x0F120000, /* 70002C7A*/ + 0x0028D000, + 0x002A1000, + 0x0F120001, + 0x00287000, + 0x002A00F4, + 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs*/ + 0x0F120000, /*REG_TC_IPRM_InClockMSBs 5DC0h=24000d=24Mhz*/ + 0x002A0110, + 0x0F120002, /*REG_TC_IPRM_UseNPviClocks*/ + 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc*/ + 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 222Eh=8750d*4=35000d=35Mhz*/ + 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0 + 445CEh=8750d*4=35000d=35Mhz*/ + 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0 + 445Ch=8750d*4=35000d=35Mhz*/ + 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_1*/ + 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1*/ + 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1*/ + 0x002A0126, + 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated*/ + /*0x002A0144,*/ + /*0x0F120640,*/ /*REG_TC_GP_PrevReqInputWidth 640h=1600d*/ + /*0x0F1204B0,*/ /*REG_TC_GP_PrevReqInputHeight 4b0h=1200d*/ + /*0x0F120000,*/ /*REG_TC_GP_PrevInputWidthOfs*/ + /*0x0F120000,*/ /*REG_TC_GP_PrevInputHeightOfs*/ + /*0x0F120640,*/ /*REG_TC_GP_CapReqInputWidth 640h=1600d*/ + /*0x0F1204B0,*/ /*REG_TC_GP_CapReqInputHeight 4b0h=1200d*/ + /*0x0F120000,*/ /*REG_TC_GP_CapInputWidthOfs*/ + /*0x0F120000,*/ /*REG_TC_GP_CapInputHeightOfs*/ + /*0x002A0164,*/ + /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInPre*/ + /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInCap*/ + /*0x002A0310,*/ + /*0x0F120640,*/ /*REG_TC_PZOOM_ZoomInputWidth 640h=1600d*/ + /*0x0F1204b0,*/ /*REG_TC_PZOOM_ZoomInputHeight 4b0h=1200d*/ + /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputWidthOfs*/ + /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputHeightOfs*/ + 0x002A0170, + 0x0F120280, /*0500 0320 REG_0TC_PCFG_usWidth*/ + 0x0F1201E0, /*03C0 0258 REG_0TC_PCFG_usHeight*/ + 0x0F120005, /*0005 0005 REG_0TC_PCFG_Format 0 RGB565; + 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; 7 Bayer*/ + 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMaxOut4KHzRate*/ + 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMinOut4KHzRate*/ + 0x0F120042, /*0042 0042 REG_0TC_PCFG_PVIMask*/ + 0x0F120010, /*0010 0010 REG_0TC_PCFG_OIFMask*/ + 0x0F120001, /*0000 0001 REG_0TC_PCFG_uClockInd*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_usFrTimeType 0: dynamic + 1:fix not accurate 2: fixed_Accurate*/ + 0x0F120001, /*0000 0001 REG_0TC_PCFG_FrRateQualityType 1b: FR + (bin) 2b: Quality (no-bin)*/ + 0x0F120535, /*0535 0535 REG_0TC_PCFG_uSMaxFrTimeMSecMult10 max + frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F1202bb, /*029A 029A REG_0TC_PCFG_uSMinFrTimeMSecMult10 max + frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_bSmearOutput*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSaturation*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSharpBlur*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_SColorTemp*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_uDeviceGammaIndex 1:Mirror + (X) 2:Mirror(Y) 4:STAT Mirror(X) 8:STAT Mirror(Y)*/ + 0x0F120003, /*0000 0001 REG_0TC_PCFG_uPrevMirror*/ + 0x0F120003, /*0000 0001 REG_0TC_PCFG_uCaptureMirror*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_uRotation*/ + 0x002A0198, + 0x0F120280, /*0280 REG_1TC_PCFG_uSWidth 2 70000198 640*/ + 0x0F1201E0, /*01E0 REG_1TC_PCFG_uSHeight 2 7000019A 480*/ + 0x0F120005, /*0005 REG_1TC_PCFG_Format 2 7000019C 0 RGB565; + 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; 7 Bayer*/ + 0x0F12222E, /*222E REG_1TC_PCFG_uSMaxOut4KHzRate 2 7000019E*/ + 0x0F12222E, /*222E REG_1TC_PCFG_uSMinOut4KHzRate 2 700001A0*/ + 0x0F120042, /*0042 REG_1TC_PCFG_PVIMaSk 2 700001A2*/ + 0x0F120010, /*0010 REG_1TC_PCFG_OIFMaSk 2 700001A4*/ + 0x0F120001, /*0001 REG_1TC_PCFG_uClockInd 2 700001A6*/ + 0x0F120002, /*0000 REG_1TC_PCFG_uSFrTimeType 2 700001A8 + 0: dynamic 1:fix not accurate 2: fixed_Accurate*/ + 0x0F120001, /*0001 REG_1TC_PCFG_FrRateQualityType 2 700001AA*/ + 0x0F12014D, /*01A0 REG_1TC_PCFG_uSMaxFrTimeMSecMult10 + 2 700001AC + max frame time : 30fpS:014D 15fpS:029a + 7.5fpS:0535 3.75fpS:a6a*/ + 0x0F12014D, /*014D REG_1TC_PCFG_uSMinFrTimeMSecMult10 + 2 700001AE + max frame time : 30fpS:014D 15fpS:029a + 7.5fpS:0535 3.75fpS:a6a*/ + 0x0F120000, /*0000 REG_1TC_PCFG_bSmearOutput 2 700001B0*/ + 0x0F120000, /*0000 REG_1TC_PCFG_SSaturation 2 700001B2*/ + 0x0F120000, /*0000 REG_1TC_PCFG_SSharpBlur 2 700001B4*/ + 0x0F120000, /*0000 REG_1TC_PCFG_SColorTemp 2 700001B6*/ + 0x0F120000, /*0000 REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/ + 0x0F120003, /*0000 REG_1TC_PCFG_uPrevMirror 2 700001BA*/ + 0x0F120003, /*0000 REG_1TC_PCFG_uCaptureMirror 2 700001BC*/ + 0x0F120000, /*0000 REG_1TC_PCFG_uRotation 2 700001BE*/ + 0x002A01C0, + 0x0F120280, /*0320 REG_2TC_PCFG_uSWidth*/ + 0x0F1201e0, /*0258 REG_2TC_PCFG_uSHeight*/ + 0x0F120005, /*REG_2TC_PCFG_Format*/ + 0x0F12222E, /*REG_2TC_PCFG_uSMaxOut4KHzRate*/ + 0x0F12222E, /*REG_2TC_PCFG_uSMinOut4KHzRate*/ + 0x0F120042, /*REG_2TC_PCFG_PVIMaSk*/ + 0x0F120010, /*REG_2TC_PCFG_OIFMaSk*/ + 0x0F120001, /*REG_2TC_PCFG_uClockInd*/ + 0x0F120000, /*REG_2TC_PCFG_uSFrTimeType*/ + 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 1b: FR (bin) + 2b: Quality (no-bin)*/ + 0x0F1207D0, /*REG_2TC_PCFG_uSMaxFrTimeMSecMult10max frame time : + 30fpS 014D; 15fpS 029a; a6a - 3.75 fpS; 0535 - + 7.5FPS*/ + 0x0F12029A, /*REG_2TC_PCFG_uSMinFrTimeMSecMult10 2 700001D6*/ + 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/ + 0x0F120000, /*REG_2TC_PCFG_SSaturation 2 700001DA*/ + 0x0F120000, /*REG_2TC_PCFG_SSharpBlur 2 700001DC*/ + 0x0F120000, /*REG_2TC_PCFG_SColorTemp 2 700001DE*/ + 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/ + 0x0F120003, /*REG_2TC_PCFG_uPrevMirror 2 700001E2 + [0] : x [1]: Y [2] Stat X [3] Stat Y*/ + 0x0F120003, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/ + 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/ + 0x002A01E8, + 0x0F120280, /*0320 REG_3TC_PCFG_uSWidth 2 700001E8*/ + 0x0F1201e0, /*0258 REG_3TC_PCFG_uSHeight 2 700001EA*/ + 0x0F120005, /*REG_3TC_PCFG_Format 2 700001EC*/ + 0x0F12222E, /*REG_3TC_PCFG_uSMaxOut4KHzRate 2 700001EE*/ + 0x0F12222E, /*REG_3TC_PCFG_uSMinOut4KHzRate 2 700001F0*/ + 0x0F120042, /*REG_3TC_PCFG_PVIMaSk 2 700001F2*/ + 0x0F120010, /*REG_3TC_PCFG_OIFMaSk 2 700001F4*/ + 0x0F120001, /*REG_3TC_PCFG_uClockInd 2 700001F6*/ + 0x0F120002, /*REG_3TC_PCFG_uSFrTimeType 2 700001F8 + 0: dynamic 1:fix not accurate 2: fixed_Accurate*/ + 0x0F120001, /*REG_3TC_PCFG_FrRateQualityType 2 700001FA*/ + 0x0F120190, /*REG_3TC_PCFG_uSMaxFrTimeMSecMult10 2 700001FC + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*REG_3TC_PCFG_uSMinFrTimeMSecMult10 2 700001FE + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*REG_3TC_PCFG_bSmearOutput 2 70000200*/ + 0x0F120000, /*REG_3TC_PCFG_SSaturation 2 70000202*/ + 0x0F120000, /*REG_3TC_PCFG_SSharpBlur 2 70000204*/ + 0x0F120000, /*REG_3TC_PCFG_SColorTemp 2 70000206*/ + 0x0F120000, /*REG_3TC_PCFG_uDeviceGammaIndex 2 70000208*/ + 0x0F120003, /*REG_3TC_PCFG_uPrevMirror 2 7000020A*/ + 0x0F120003, /*REG_3TC_PCFG_uCaptureMirror 2 7000020C*/ + 0x0F120000, /*REG_3TC_PCFG_uRotation 2 7000020E*/ + 0x002A0238, + 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/ + 0x0F120640, /*REG_0TC_CCFG_uSWidth 2 7000023A*/ + 0x0F1204B0, /*REG_0TC_CCFG_uSHeight 2 7000023C*/ + 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/ + 0x0F12222E, /*REG_0TC_CCFG_uSMaxOut4KHzRate 2 70000240*/ + 0x0F12222E, /*REG_0TC_CCFG_uSMinOut4KHzRate 2 70000242*/ + 0x0F120042, /*REG_0TC_CCFG_PVIMaSk 2 70000244*/ + 0x0F120000, /*REG_0TC_CCFG_OIFMaSk 2 70000246*/ + 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/ + 0x0F120002, /*REG_0TC_CCFG_uSFrTimeType 2 7000024A*/ + 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/ + 0x0F120514, /*0535 REG_0TC_CCFG_uSMaxFrTimeMSecMult10 + 2 7000024E*/ + 0x0F120514, /*0535 REG_0TC_CCFG_uSMinFrTimeMSecMult10 + 2 70000250*/ + 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/ + 0x0F120000, /*REG_0TC_CCFG_SSaturation 2 70000254*/ + 0x0F120000, /*REG_0TC_CCFG_SSharpBlur 2 70000256*/ + 0x0F120000, /*REG_0TC_CCFG_SColorTemp 2 70000258*/ + 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/ + 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/ + 0x0F120640, /*REG_1TC_CCFG_uSWidth 2 7000025E*/ + 0x0F1204B0, /*REG_1TC_CCFG_uSHeight 2 70000260*/ + 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/ + 0x0F12445C, /*222E REG_1TC_CCFG_uSMaxOut4KHzRate 2 70000264*/ + 0x0F12445C, /*222E REG_1TC_CCFG_uSMinOut4KHzRate 2 70000266*/ + 0x0F120042, /*REG_1TC_CCFG_PVIMaSk 2 70000268*/ + 0x0F120010, /*0000 REG_1TC_CCFG_OIFMaSk 2 7000026A*/ + 0x0F120000,/*0001 REG_1TC_CCFG_uClockInd 2 7000026C*/ + 0x0F120000, /*REG_1TC_CCFG_uSFrTimeType 2 7000026E*/ + 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/ + 0x0F121388, /*REG_1TC_CCFG_uSMaxFrTimeMSecMult10 2 70000272*/ + 0x0F121388, /*REG_1TC_CCFG_uSMinFrTimeMSecMult10 2 70000274*/ + 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/ + 0x0F120000, /*REG_1TC_CCFG_SSaturation 2 70000278*/ + 0x0F120000, /*REG_1TC_CCFG_SSharpBlur 2 7000027A*/ + 0x0F120000, /*REG_1TC_CCFG_SColorTemp 2 7000027C*/ + 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/ + 0x002A1218, + 0x0F120002, /*SenHal_SenBinFactor*/ + 0xFFFF0064, + 0x00287000, + 0x002A0CC0, + 0x0F120001, /*AFC_Default BIT[0] 1:60Hz 0:50Hz*/ + 0x002A0374, + 0x0F12067F, /*REG_TC_DBG BIT[5] : Auto Flicker Disable*/ + + /*Int Time limit*/ + 0x00287000, + 0x002A1220, + 0x0F1201B7, /*senHal_ExpMinPixels*/ + + + + 0x002A10C0, + 0x0F120040, /*TVAR_ae_BrAve*/ + 0x002A10C6, + 0x0F12000F, /*ae_StatMode*/ + 0x002A03B2, + 0x0F12010E, /*lt_uLimitHigh*/ + 0x0F1200F5, /*lt_uLimitLow*/ + 0x002A03C4, + 0x0F123415, /*lt_uMaxExp1 3415h=13333d/400d=33.3325ms*/ + 0x002A03C8, + 0x0F12681F, /*lt_uMaxExp2 681Fh=26655d/400d=66.6375ms*/ + 0x002A03CC, + 0x0F128227, /*lt_uMaxExp3 8227h=33319d/400d=83.2975ms*/ + 0x002A03D0, + 0x0F120D40, /*lt_uMaxExp4 30D40h=50000d/400d=500ms*/ + 0x0F120003, + 0x002A03D4, + 0x0F123415, /*lt_uCapMaxExp1 3415h=13333d/400d=33.3325ms*/ + 0x002A03D8, + 0x0F12681F, /*lt_uCapMaxExp2 681Fh=26655d/400d=66.6375ms*/ + 0x002A03DC, + 0x0F128227, /*lt_uCapMaxExp3 8227h=33319d/400d=83.2975ms*/ + 0x002A03E0, + 0x0F120D40, /*lt_uCapMaxExp4 30D40h=50000d/400d=500ms*/ + 0x0F120003, + 0x002A03E4, + 0x0F120230, /*lt_uMaxAnGain1 0230h=0560d/256d=x2.1875*/ + 0x0F120260, /*lt_uMaxAnGain2 0260h=0608d/256d=x2.375*/ + 0x0F120370, /*lt_uMaxAnGain3 0370h=0704d/256d=x3.4375*/ + 0x0F120880, /*lt_uMaxAnGain4 0710h=2176d/256d=x8.5*/ + 0x0F120100, /*lt_uMaxDigGain*/ + 0x0F128000, /*lt_uMaxTotGain*/ + 0x0F120230, /*lt_uCapMaxAnGain1 0230h=0560d/256d=x2.1875*/ + 0x0F120260, /*lt_uCapMaxAnGain2 0260h=0608d/256d=x2.375*/ + 0x0F120380, /*lt_uCapMaxAnGain3 0370h=0704d/256d=x3.4375*/ + 0x0F120880, /*lt_uCapMaxAnGain4 0710h=2176d/256d=x8.5*/ + 0x0F120100, /*lt_uCapMaxDigGain*/ + 0x0F128000, /*lt_uCapMaxTotGain*/ + 0x002A10CE, + 0x0F120000, /*ae_WeightTbl_16[0]*/ + 0x0F120101, /*ae_WeightTbl_16[1]*/ + 0x0F120101, /*ae_WeightTbl_16[2]*/ + 0x0F120000, /*ae_WeightTbl_16[3]*/ + 0x0F120101, /*ae_WeightTbl_16[4]*/ + 0x0F120101, /*ae_WeightTbl_16[5]*/ + 0x0F120101, /*ae_WeightTbl_16[6]*/ + 0x0F120101, /*ae_WeightTbl_16[7]*/ + 0x0F120201, /*ae_WeightTbl_16[8]*/ + 0x0F120303, /*ae_WeightTbl_16[9]*/ + 0x0F120303, /*ae_WeightTbl_16[10]*/ + 0x0F120102, /*ae_WeightTbl_16[11]*/ + 0x0F120201, /*ae_WeightTbl_16[12]*/ + 0x0F120403, /*ae_WeightTbl_16[13]*/ + 0x0F120304, /*ae_WeightTbl_16[14]*/ + 0x0F120102, /*ae_WeightTbl_16[15]*/ + 0x0F120201, /*ae_WeightTbl_16[16]*/ + 0x0F120403, /*ae_WeightTbl_16[17]*/ + 0x0F120304, /*ae_WeightTbl_16[18]*/ + 0x0F120102, /*ae_WeightTbl_16[19]*/ + 0x0F120201, /*ae_WeightTbl_16[20]*/ + 0x0F120403, /*ae_WeightTbl_16[21]*/ + 0x0F120304, /*ae_WeightTbl_16[22]*/ + 0x0F120102, /*ae_WeightTbl_16[23]*/ + 0x0F120201, /*ae_WeightTbl_16[24]*/ + 0x0F120303, /*ae_WeightTbl_16[25]*/ + 0x0F120303, /*ae_WeightTbl_16[26]*/ + 0x0F120102, /*ae_WeightTbl_16[27]*/ + 0x0F120201, /*ae_WeightTbl_16[28]*/ + 0x0F120202, /*ae_WeightTbl_16[29]*/ + 0x0F120202, /*ae_WeightTbl_16[30]*/ + 0x0F120102, /*ae_WeightTbl_16[31]*/ + 0x002A0DCC, /*AWB Init White Locus*/ + 0x0F120138, /*awbb_IntcR*/ + 0x0F12011C, /*awbb_IntcB*/ + 0x0F1202A7, /*awbb_GLocusR*/ + 0x0F120343, /*awbb_GLocusB*/ + 0x002A0DEC, + 0x0F1205F0, /*awbb_GamutWidthThr1*/ + 0x0F1201F4, /*awbb_GamutHeightThr1*/ + 0x0F12006C, /*awbb_GamutWidthThr2*/ + 0x0F120038, /*awbb_GamutHeightThr2*/ + 0x002A0DD8, + 0x0F12000C, /*awbb_MinNumOfFinalPatches*/ + 0x002A0E50, + 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B*/ + 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B*/ + 0x0F120640, /*awbb_SCDetectionMap_SEC_SunnyNB*/ + 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB*/ + 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B*/ + 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone*/ + 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone*/ + 0x002A0DB4, /*LowTemp Zone*/ + 0x0F12036C, /*awbb_CrclLowT_R_c*/ + 0x002A0DB8, + 0x0F12011D, /*awbb_CrclLowT_B_c*/ + 0x002A0DBC, + 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/ + 0x002A22BA, + 0x0F120006, /*Mon_AWB_ByPassMode*/ + 0x002A0DEA, + 0x0F120000, /*awbb_movingscale10*/ + 0x002A0F7A, + 0x0F120000, /*awbb_RGainOff*/ + 0x0F120000, /*awbb_BGainOff*/ + 0x0F120000, /*awbb_GGainOff*/ + 0x0F1200C2, /*awbb_Alpha_Comp_Mode*/ + 0x0F120002, /*awbb_Rpl_InvalidOutDoor*/ + 0x0F120001, /*awbb_UseGrThrCorr*/ + 0x0F1200E4, /*awbb_Use_Filters*/ + + 0x0F12053C, /*awbb_GainsInit[0]*/ + 0x0F120400, /*awbb_GainsInit[1]*/ + 0x0F1207ac, /*7AC, 55C, awbb_GainsInit[2]*/ + + 0x0F12001E, /*awbb_WpFilterMinThr*/ + 0x0F120190, /*awbb_WpFilterMaxThr*/ + 0x0F120064, /*awbb_WpFilterCoef*/ + + 0x0F120004, /*awbb_WpFilterSize*/ + 0x0F120001, /*awbb_otp_disable*/ + 0x0F120002, /*awbb_GridEnable*/ + 0x002A0CE0, + 0x0F1203F8, /*03F8 03B5 awbb_IndoorGrZones_m_BGrid[0]*/ + 0x0F120422, /*0422 03DF awbb_IndoorGrZones_m_BGrid[1]*/ + 0x0F120390, /*03B4 032D awbb_IndoorGrZones_m_BGrid[2]*/ + 0x0F12042A, /*0408 03D5 awbb_IndoorGrZones_m_BGrid[3]*/ + 0x0F120352, /*0370 0303 awbb_IndoorGrZones_m_BGrid[4]*/ + 0x0F12041E, /*03EE 03BB awbb_IndoorGrZones_m_BGrid[5]*/ + 0x0F120318, /*032C 02DB awbb_IndoorGrZones_m_BGrid[6]*/ + 0x0F1203DC, /*03FC, 03D4 0397 awbb_IndoorGrZones_m_BGrid[7]*/ + 0x0F1202E4, /*02E4, 0302 02B1 awbb_IndoorGrZones_m_BGrid[8]*/ + 0x0F12039C, /*03BA, 03BA 036B awbb_IndoorGrZones_m_BGrid[9]*/ + 0x0F1202B8, /*02B8, 02DA 0289 awbb_IndoorGrZones_m_BGrid[10]*/ + 0x0F120368, /*037E, 0374 0349 awbb_IndoorGrZones_m_BGrid[11]*/ + 0x0F120290, /*0290, 02B0 026F awbb_IndoorGrZones_m_BGrid[12]*/ + 0x0F12033E, /*034A, 0328 0329 awbb_IndoorGrZones_m_BGrid[13]*/ + 0x0F120274, /*0274, 0288 0257 awbb_IndoorGrZones_m_BGrid[14]*/ + 0x0F120316, /*031A, 0300 0309 awbb_IndoorGrZones_m_BGrid[15]*/ + 0x0F120252, /*0270 0241 awbb_IndoorGrZones_m_BGrid[16]*/ + 0x0F1202F8, /*02DE 02DD awbb_IndoorGrZones_m_BGrid[17]*/ + 0x0F120232, /*0258 0227 awbb_IndoorGrZones_m_BGrid[18]*/ + 0x0F1202E0, /*02BE 02C3 awbb_IndoorGrZones_m_BGrid[19]*/ + 0x0F12021E, /*0240 0213 awbb_IndoorGrZones_m_BGrid[20]*/ + 0x0F1202C8, /*02A0 02AF awbb_IndoorGrZones_m_BGrid[21]*/ + 0x0F120206, /*0228 0209 awbb_IndoorGrZones_m_BGrid[22]*/ + 0x0F1202B2, /*0296 0295 awbb_IndoorGrZones_m_BGrid[23]*/ + 0x0F1201FA, /*0212 020D awbb_IndoorGrZones_m_BGrid[24]*/ + 0x0F1202A2, /*0284 0285 awbb_IndoorGrZones_m_BGrid[25]*/ + 0x0F1201F4, /*0208 0223 awbb_IndoorGrZones_m_BGrid[26]*/ + 0x0F120294, /*0274 0261 awbb_IndoorGrZones_m_BGrid[27]*/ + 0x0F120200, /*020C 0000 awbb_IndoorGrZones_m_BGrid[28]*/ + 0x0F120288, /*026E 0000 awbb_IndoorGrZones_m_BGrid[29]*/ + 0x0F120214, /*0222 0000 awbb_IndoorGrZones_m_BGrid[30]*/ + 0x0F120250, /*0260 0000 awbb_IndoorGrZones_m_BGrid[31]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[32]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[33]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[34]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[35]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[36]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[37]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[38]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[39]*/ + 0x0F120005, /*awbb_IndoorGrZones_m_GridStep*/ + 0x002A0D34, + 0x0F120010, /*awbb_IndoorGrZones_ZInfo_m_GridSz*/ + 0x002A0D38, + 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/ + 0x002A0D3C, + 0x0F120294, /*0294 02A4 02B0 02B6 02B8 02A2 02B8 + 029F awbb_OutdoorGrZones_m_BGrid[0]*/ + 0x0F1202F2, /*02F2 02F2 02F0 02F2 02F2 02D4 02F2 + 02CE awbb_OutdoorGrZones_m_BGrid[1]*/ + 0x0F120276, /*0276 0276 028A 0276 028E 0282 028E + 0282 awbb_OutdoorGrZones_m_BGrid[2]*/ + 0x0F12030A, /*030A 030A 02FC 030A 030A 02EE 030A + 02DA awbb_OutdoorGrZones_m_BGrid[3]*/ + 0x0F120258, /*0258 0258 026C 0258 026E 027A 027A + 026D awbb_OutdoorGrZones_m_BGrid[4]*/ + 0x0F12030A, /*0302 0302 030A 0302 030A 030A 030A + 02C2 awbb_OutdoorGrZones_m_BGrid[5]*/ + 0x0F120246, /*0246 0246 0258 0246 025E 027A 0274 + 0256 awbb_OutdoorGrZones_m_BGrid[6]*/ + 0x0F1202FA, /*02EA 02EA 0302 02EA 02FE 030A 02FE + 02A6 awbb_OutdoorGrZones_m_BGrid[7]*/ + 0x0F120256, /*0256 0256 0246 0256 0264 0274 0282 + 026E awbb_OutdoorGrZones_m_BGrid[8]*/ + 0x0F1202DC, /*02B8 02B8 02EA 02B8 02D0 02FE 02DC + 028A awbb_OutdoorGrZones_m_BGrid[9]*/ + 0x0F120000, /*0000 0000 0256 0000 0000 0282 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[10]*/ + 0x0F120000, /*0000 0000 02B8 0000 0000 02DC 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[11]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[12]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[13]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[14]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[15]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[16]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[17]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[18]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[19]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[20]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[21]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[22]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[23]*/ + 0x0F120005, /*awbb_OutdoorGrZones_m_GridStep*/ + 0x002A0D70, + 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/ + 0x002A0D74, + 0x0F1201EB, /*awbb_OutdoorGrZones_m_Boffs*/ + 0x002A0D78, + 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/ + 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/ + 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/ + 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/ + 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/ + 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/ + 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/ + 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/ + 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/ + 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/ + 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/ + 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/ + 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/ + 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/ + 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/ + 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/ + 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/ + 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/ + 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/ + 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/ + 0x0F120006, /*awbb_LowBrGrZones_m_GridStep*/ + 0x002A0DAC, + 0x0F12000A, /*awbb_LowBrGrZones_ZInfo_m_GridSz*/ + 0x002A0DB0, + 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/ + 0x002A0F60, + 0x0F1202E2, /*awbb_GridConst_1[0]*/ + 0x0F12034B, /*awbb_GridConst_1[1]*/ + 0x0F120399, /*awbb_GridConst_1[2]*/ + 0x0F12102D, /*awbb_GridConst_2[0]*/ + 0x0F1210DE, /*awbb_GridConst_2[1]*/ + 0x0F12116E, /*awbb_GridConst_2[2]*/ + 0x0F12117B, /*awbb_GridConst_2[3]*/ + 0x0F12120A, /*11FF awbb_GridConst_2[4]*/ + 0x0F121247, /*awbb_GridConst_2[5]*/ + 0x0F1202C4, /*awbb_GridCoeff_R_1*/ + 0x0F1202E4, /*awbb_GridCoeff_B_1*/ + 0x0F1200C3, /*awbb_GridCoeff_R_2*/ + 0x0F1200A6, /*awbb_GridCoeff_B_2*/ + 0x002A0ED0, + + 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[0][0]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][1]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][2]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][3]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][4]*/ + 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[0][5]*/ + 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[1][0]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][1]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][2]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][3]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][4]*/ + 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[1][5]*/ + 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[2][0]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][1]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][2]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][3]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][4]*/ + 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[2][5]*/ + 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[0][0]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][1]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][2]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][3]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][4]*/ + 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[0][5]*/ + 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[1][0]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][1]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][2]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][3]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][4]*/ + 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[1][5]*/ + 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[2][0]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][1]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][2]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][3]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][4]*/ + 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[2][5]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][0]*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][2]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][3]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][4]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][5]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][0]*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][2]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][3]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][4]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][5]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][0]*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][2]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][3]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][4]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][5]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][0]*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][2]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][3]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][4]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][5]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][0]*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][2]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][3]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][4]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][5]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][0]*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][2]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][3]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][4]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][5]*/ + 0x002A05D2, + 0x0F1200E4, /*SARR_AwbCcmCord[0]*/ + 0x0F1200F0, /*SARR_AwbCcmCord[1]*/ + 0x0F120100, /*SARR_AwbCcmCord[2]*/ + 0x0F120120, /*SARR_AwbCcmCord[3]*/ + 0x0F120150, /*SARR_AwbCcmCord[4]*/ + 0x0F120180, /*SARR_AwbCcmCord[5]*/ + 0x002A05C4, + 0x0F123800, /*TVAR_wbt_pBaseCcms*/ + 0x0F127000, + 0x002A05CC, + 0x0F1238D8, /*TVAR_wbt_pOutdoorCcm*/ + 0x0F127000, + 0x002A3800, + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/ + 0x0F1201C4, /*01D3 01D0 TVAR_wbt_pBaseCcms[36]*/ + 0x0F12FFAC, /*FFBB FFA1 TVAR_wbt_pBaseCcms[37]*/ + 0x0F12FFFB, /*FFDD FFFA TVAR_wbt_pBaseCcms[38]*/ + 0x0F12FF6F, /*FF6F FF6F TVAR_wbt_pBaseCcms[39]*/ + 0x0F120140, /*0140 0140 TVAR_wbt_pBaseCcms[40]*/ + 0x0F12FF49, /*FF49 FF49 TVAR_wbt_pBaseCcms[41]*/ + 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[42]*/ + 0x0F12001F, /*001F 001F TVAR_wbt_pBaseCcms[43]*/ + 0x0F1201BD, /*01BD 01BD TVAR_wbt_pBaseCcms[44]*/ + 0x0F12013F, /*013F 013F TVAR_wbt_pBaseCcms[45]*/ + 0x0F1200E1, /*00E1 00E1 TVAR_wbt_pBaseCcms[46]*/ + 0x0F12FF43, /*FF43 FF43 TVAR_wbt_pBaseCcms[47]*/ + 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[48]*/ + 0x0F12FFC0, /*FFC0 FFC0 TVAR_wbt_pBaseCcms[49]*/ + 0x0F1201B7, /*01B7 01B7 TVAR_wbt_pBaseCcms[50]*/ + 0x0F12FF30, /*FF30 FF30 TVAR_wbt_pBaseCcms[51]*/ + 0x0F12015F, /*015F 015F TVAR_wbt_pBaseCcms[52]*/ + 0x0F120106, /*0106 0106 TVAR_wbt_pBaseCcms[53]*/ + 0x0F1201B5, /*01C6, 01D0 TVAR_wbt_pBaseCcms[54]*/ + 0x0F12FFC6, /*FFBE, FFA1 TVAR_wbt_pBaseCcms[55]*/ + 0x0F12FFEF, /*FFE6, FFFA TVAR_wbt_pBaseCcms[56]*/ + 0x0F12FF6F, /*FF6F, FF6F TVAR_wbt_pBaseCcms[57]*/ + 0x0F120140, /*0140, 0140 TVAR_wbt_pBaseCcms[58]*/ + 0x0F12FF49, /*FF49, FF49 TVAR_wbt_pBaseCcms[59]*/ + 0x0F12FFC1, /*FFC1, FFC1 TVAR_wbt_pBaseCcms[60]*/ + 0x0F12001F, /*001F, 001F TVAR_wbt_pBaseCcms[61]*/ + 0x0F1201BD, /*01BD, 01BD TVAR_wbt_pBaseCcms[62]*/ + 0x0F12013F, /*013F, 013F TVAR_wbt_pBaseCcms[63]*/ + 0x0F1200E1, /*00E1, 00E1 TVAR_wbt_pBaseCcms[64]*/ + 0x0F12FF43, /*FF43, FF43 TVAR_wbt_pBaseCcms[65]*/ + 0x0F120191, /*0191, 0191 TVAR_wbt_pBaseCcms[66]*/ + 0x0F12FFC0, /*FFC0, FFC0 TVAR_wbt_pBaseCcms[67]*/ + 0x0F1201B7, /*01B7, 01B7 TVAR_wbt_pBaseCcms[68]*/ + 0x0F12FF30, /*FF30, FF30 TVAR_wbt_pBaseCcms[69]*/ + 0x0F12015F, /*015F, 015F TVAR_wbt_pBaseCcms[70]*/ + 0x0F120106, /*0106, 0106 TVAR_wbt_pBaseCcms[71]*/ + 0x0F1201B7, /*C8 01BF TVAR_wbt_pBaseCcms[72]*/ + 0x0F12FFC4, /*FFBA FFBF TVAR_wbt_pBaseCcms[73]*/ + 0x0F120001, /*FFE8 FFFE TVAR_wbt_pBaseCcms[74]*/ + 0x0F12FF6D, /*FF6D FF6F FF6D TVAR_wbt_pBaseCcms[75]*/ + 0x0F1201B4, /*01B4 0140 01B4 TVAR_wbt_pBaseCcms[76]*/ + 0x0F12FF66, /*FF66 FF49 FF66 TVAR_wbt_pBaseCcms[77]*/ + 0x0F12FFCA, /*FFCA FFC1 FFCA TVAR_wbt_pBaseCcms[78]*/ + 0x0F12FFCE, /*FFCE 001F FFCE TVAR_wbt_pBaseCcms[79]*/ + 0x0F12017B, /*017B 01BD 017B TVAR_wbt_pBaseCcms[80]*/ + 0x0F120136, /*0136 013F 0136 TVAR_wbt_pBaseCcms[81]*/ + 0x0F120132, /*0132 00E1 0132 TVAR_wbt_pBaseCcms[82]*/ + 0x0F12FF85, /*FF85 FF43 FF85 TVAR_wbt_pBaseCcms[83]*/ + 0x0F12018B, /*018B 0191 018B TVAR_wbt_pBaseCcms[84]*/ + 0x0F12FF73, /*FF73 FFC0 FF73 TVAR_wbt_pBaseCcms[85]*/ + 0x0F120191, /*0191 01B7 0191 TVAR_wbt_pBaseCcms[86]*/ + 0x0F12FF3F, /*FF3F FF30 FF3F TVAR_wbt_pBaseCcms[87]*/ + 0x0F12015B, /*015B 015F 015B TVAR_wbt_pBaseCcms[88]*/ + 0x0F1200D0, /*00D0 0106 00D0 TVAR_wbt_pBaseCcms[89]*/ + 0x0F1201CA, /*01CA 01C1 TVAR_wbt_pBaseCcms[90]*/ + 0x0F12FFBE, /*FFBE FFC5 TVAR_wbt_pBaseCcms[91]*/ + 0x0F12FFF1, /*FFF1 FFF5 TVAR_wbt_pBaseCcms[92]*/ + 0x0F12FEFB, /*FF15 FF3B TVAR_wbt_pBaseCcms[93]*/ + 0x0F12021C, /*01F3 0217 TVAR_wbt_pBaseCcms[94]*/ + 0x0F12FF6B, /*FF7B FF32 TVAR_wbt_pBaseCcms[95]*/ + 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[96]*/ + 0x0F12FFC5, /*FFC5 FFC5 TVAR_wbt_pBaseCcms[97]*/ + 0x0F12018A, /*018A 018B TVAR_wbt_pBaseCcms[98]*/ + 0x0F1200FB, /*00FB 0136 TVAR_wbt_pBaseCcms[99]*/ + 0x0F120167, /*0167 0132 TVAR_wbt_pBaseCcms[100]*/ + 0x0F12FF8C, /*FF8C FF85 TVAR_wbt_pBaseCcms[101]*/ + 0x0F12018B, /*018B 018B TVAR_wbt_pBaseCcms[102]*/ + 0x0F12FF73, /*FF73 FF73 TVAR_wbt_pBaseCcms[103]*/ + 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[104]*/ + 0x0F12FF3F, /*FF3F FF3F TVAR_wbt_pBaseCcms[105]*/ + 0x0F12015B, /*015B 015B TVAR_wbt_pBaseCcms[106]*/ + 0x0F1200D0, /*00D0 00D0 TVAR_wbt_pBaseCcms[107]*/ + 0x002A38D8, + 0x0F120221, /*022C 0235 TVAR_wbt_pOutdoorCcm[0]*/ + 0x0F120005, /*FFD8 FFEF TVAR_wbt_pOutdoorCcm[1]*/ + 0x0F120012, /*0034 0014 TVAR_wbt_pOutdoorCcm[2]*/ + 0x0F12FF67, /*FF67 FF67 TVAR_wbt_pOutdoorCcm[3]*/ + 0x0F12027D, /*027D 027D TVAR_wbt_pOutdoorCcm[4]*/ + 0x0F12FFBA, /*FFBA FFBA TVAR_wbt_pOutdoorCcm[5]*/ + 0x0F12000D, /*000D 000D TVAR_wbt_pOutdoorCcm[6]*/ + 0x0F120062, /*0062 0062 TVAR_wbt_pOutdoorCcm[7]*/ + 0x0F1202A7, /*02A7 02A7 TVAR_wbt_pOutdoorCcm[8]*/ + 0x0F1200C7, /*00C7 00C9 TVAR_wbt_pOutdoorCcm[9]*/ + 0x0F12011F, /*011F 0123 TVAR_wbt_pOutdoorCcm[10]*/ + 0x0F12FF3C, /*FF3C FF36 TVAR_wbt_pOutdoorCcm[11]*/ + 0x0F1201AD, /*01AD 01AD TVAR_wbt_pOutdoorCcm[12]*/ + 0x0F12FFC8, /*FFC8 FFC8 TVAR_wbt_pOutdoorCcm[13]*/ + 0x0F120202, /*0202 0202 TVAR_wbt_pOutdoorCcm[14]*/ + 0x0F12FFCF, /*FFCF FFCF TVAR_wbt_pOutdoorCcm[15]*/ + 0x0F120257, /*0257 0257 TVAR_wbt_pOutdoorCcm[16]*/ + 0x0F12022C, /*022C 022C TVAR_wbt_pOutdoorCcm[17]*/ + 0x002A23DC, + 0x0F1201DD, /*Mon_AAIO_PrevFrmData_NormBr*/ + 0x002A0460, + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/ + 0x002A065C, + 0x0F12003F, /*afit_uNoiseIndInDoor_0_*/ + 0x0F120041, /*afit_uNoiseIndInDoor_1_*/ + 0x0F1200CB, /*afit_uNoiseIndInDoor_2_*/ + 0x0F1201E0, /*afit_uNoiseIndInDoor_3_*/ + 0x0F120220, /*afit_uNoiseIndInDoor_4_*/ + 0x002A3780, + 0x0F120000, /*on/off AFIT by NB option*/ + 0x0F120014, /*SARR_uNormBrInDoor*/ + 0x0F1200D2, /*SARR_uNormBrInDoor*/ + 0x0F120384, /*SARR_uNormBrInDoor*/ + 0x0F1207D0, /*SARR_uNormBrInDoor*/ + 0x0F121388, /*SARR_uNormBrInDoor*/ + 0x002A06BC, + 0x0F120000, /*AFIT16_BRIGHTNESS*/ + 0x0F120000, /*AFIT16_CONTRAST*/ + 0x0F120014, /*AFIT16_SATURATION*/ + 0x0F120000, /*AFIT16_SHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F12001E, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F12001E, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201F4, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F120A3B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F12001E, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F121982, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120B80, /*0A80 AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F126444, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F129650, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121464, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121404, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F121403, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120114, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F124446, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F122832, /*5064 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F12141E, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F126407, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120414, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F126E44, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122864, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120014, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120A6E, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F122801, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F12231E, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12961E, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120764, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F12143C, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121401, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F121E28, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120A0C, /*1419 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120200, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123C07, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121E1E, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F123C01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F125A3A, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122858, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120000, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122A03, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F129601, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F122828, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F122401, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F123622, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122832, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121E04, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120F40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120000, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F1200C8, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F120050, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12002D, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],AFIT8_sddd8a_repl_thresh + [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],AFIT8_sddd8a_sat_level + [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],AFIT8_sddd8a_sat_mpl + [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F123C3C, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121E01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12221C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F12281E, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121402, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F12060E, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120C40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120000, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F120032, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F12028A, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120032, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F1201F4, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120002, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201AA, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F12003C, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120050, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F120046, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F120503, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F12080F, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120808, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12022D, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12061E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120606, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A03, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120028, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120002, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128001, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F121219, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12320D, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120A0A, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122304, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A08, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120832, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F122A0A, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F124006, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120604, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125006, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120A28, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F12040A, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120820, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F12280A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120532, /*0A64 AFIT8_Sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F12062A, /*AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120606, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F124646, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121801, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12191C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122818, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121405, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F12050C, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F121440, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F127DFA, /*ConstAfitBaseVals*/ + 0x0F12FFBD, /*ConstAfitBaseVals_1_*/ + 0x0F1226FE, /*ConstAfitBaseVals_2_*/ + 0x0F12F7BC, /*ConstAfitBaseVals_3_*/ + 0x0F127E06, /*ConstAfitBaseVals_4_*/ + 0x0F1200D3, /*ConstAfitBaseVals_5_*/ + 0x002A0156, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig*/ + 0x002A015E, + 0x0F120000, /*REG_TC_GP_ActiveCapConfig*/ + 0x002A015A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange*/ + 0x002A0142, + 0x0F120001, /*REG_TC_GP_NewConfigSync*/ + 0x002A0158, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged*/ + 0x002A0160, + 0x0F120001, /*REG_TC_GP_CapConfigChanged*/ + 0x002A013A, + 0x0F120001, /*REG_TC_GP_EnablePreview*/ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged*/ + 0xFFFF0096, + +}; + +/* Set-data based on SKT VT standard ,when using 3G network +* 8fps +*/ +static const u32 s5k5bbgx_vt_common[] = { + 0xFCFCD000, + 0x00100001, /*sw_reset*/ + /*For divided ARM CLK 1/2*/ + /*WRITE D00000A0 0000*/ + 0x10300000, /*contint_host_int*/ + 0x00140001, /*sw_load_complete-Release CORE (Arm) from reset state*/ + 0x01520084, /*make alive voltage low*/ + 0xFFFF000A, + /* Start of Patch data*/ + 0x00287000, + 0x002A2744, + 0x0F12B510, /* 70002744*/ + 0x0F124A12, /* 70002746*/ + 0x0F12217B, /* 70002748*/ + 0x0F124812, /* 7000274A*/ + 0x0F12C004, /* 7000274C*/ + 0x0F126001, /* 7000274E*/ + 0x0F124911, /* 70002750*/ + 0x0F124812, /* 70002752*/ + 0x0F12F000, /* 70002754*/ + 0x0F12F926, /* 70002756*/ + 0x0F124911, /* 70002758*/ + 0x0F124812, /* 7000275A*/ + 0x0F12F000, /* 7000275C*/ + 0x0F12F922, /* 7000275E*/ + 0x0F124911, /* 70002760*/ + 0x0F124812, /* 70002762*/ + 0x0F12F000, /* 70002764*/ + 0x0F12F91E, /* 70002766*/ + 0x0F124911, /* 70002768*/ + 0x0F124812, /* 7000276A*/ + 0x0F12F000, /* 7000276C*/ + 0x0F12F91A, /* 7000276E*/ + 0x0F124911, /* 70002770*/ + 0x0F124812, /* 70002772*/ + 0x0F12F000, /* 70002774*/ + 0x0F12F916, /* 70002776*/ + 0x0F124911, /* 70002778*/ + 0x0F124812, /* 7000277A*/ + 0x0F12F000, /* 7000277C*/ + 0x0F12F912, /* 7000277E*/ + 0x0F124911, /* 70002780*/ + 0x0F124812, /* 70002782*/ + 0x0F12F000, /* 70002784*/ + 0x0F12F90E, /* 70002786*/ + 0x0F12BC10, /* 70002788*/ + 0x0F12BC08, /* 7000278A*/ + 0x0F124718, /* 7000278C*/ + 0x0F120000, /* 7000278E*/ + 0x0F120000, /* 70002790*/ + 0x0F125BB1, /* 70002792*/ + 0x0F121770, /* 70002794*/ + 0x0F127000, /* 70002796*/ + 0x0F1227D1, /* 70002798*/ + 0x0F127000, /* 7000279A*/ + 0x0F12C0BB, /* 7000279C*/ + 0x0F120000, /* 7000279E*/ + 0x0F12280F, /* 700027A0*/ + 0x0F127000, /* 700027A2*/ + 0x0F123609, /* 700027A4*/ + 0x0F120000, /* 700027A6*/ + 0x0F122827, /* 700027A8*/ + 0x0F127000, /* 700027AA*/ + 0x0F1277C7, /* 700027AC*/ + 0x0F120000, /* 700027AE*/ + 0x0F1228B3, /* 700027B0*/ + 0x0F127000, /* 700027B2*/ + 0x0F12727D, /* 700027B4*/ + 0x0F120000, /* 700027B6*/ + 0x0F1228CD, /* 700027B8*/ + 0x0F127000, /* 700027BA*/ + 0x0F129919, /* 700027BC*/ + 0x0F120000, /* 700027BE*/ + 0x0F12290B, /* 700027C0*/ + 0x0F127000, /* 700027C2*/ + 0x0F121C63, /* 700027C4*/ + 0x0F120000, /* 700027C6*/ + 0x0F12296B, /* 700027C8*/ + 0x0F127000, /* 700027CA*/ + 0x0F1204CB, /* 700027CC*/ + 0x0F120000, /* 700027CE*/ + 0x0F12B4F0, /* 700027D0*/ + 0x0F126801, /* 700027D2*/ + 0x0F12468C, /* 700027D4*/ + 0x0F126846, /* 700027D6*/ + 0x0F122200, /* 700027D8*/ + 0x0F124968, /* 700027DA*/ + 0x0F122000, /* 700027DC*/ + 0x0F122724, /* 700027DE*/ + 0x0F124357, /* 700027E0*/ + 0x0F12183B, /* 700027E2*/ + 0x0F124664, /* 700027E4*/ + 0x0F125CE5, /* 700027E6*/ + 0x0F12005C, /* 700027E8*/ + 0x0F125B34, /* 700027EA*/ + 0x0F12072D, /* 700027EC*/ + 0x0F120F2D, /* 700027EE*/ + 0x0F12800D, /* 700027F0*/ + 0x0F12804C, /* 700027F2*/ + 0x0F12808B, /* 700027F4*/ + 0x0F122301, /* 700027F6*/ + 0x0F1280CB, /* 700027F8*/ + 0x0F122300, /* 700027FA*/ + 0x0F1280CB, /* 700027FC*/ + 0x0F121C40, /* 700027FE*/ + 0x0F122824, /* 70002800*/ + 0x0F12D3EE, /* 70002802*/ + 0x0F121C52, /* 70002804*/ + 0x0F122A04, /* 70002806*/ + 0x0F12D3E8, /* 70002808*/ + 0x0F12BCF0, /* 7000280A*/ + 0x0F124770, /* 7000280C*/ + 0x0F12B510, /* 7000280E*/ + 0x0F12F000, /* 70002810*/ + 0x0F12F8D0, /* 70002812*/ + 0x0F12485A, /* 70002814*/ + 0x0F127A81, /* 70002816*/ + 0x0F12485A, /* 70002818*/ + 0x0F126B00, /* 7000281A*/ + 0x0F12F000, /* 7000281C*/ + 0x0F12F8D2, /* 7000281E*/ + 0x0F12BC10, /* 70002820*/ + 0x0F12BC08, /* 70002822*/ + 0x0F124718, /* 70002824*/ + 0x0F12B5F8, /* 70002826*/ + 0x0F126805, /* 70002828*/ + 0x0F126844, /* 7000282A*/ + 0x0F124E56, /* 7000282C*/ + 0x0F128861, /* 7000282E*/ + 0x0F128AB0, /* 70002830*/ + 0x0F128A72, /* 70002832*/ + 0x0F122301, /* 70002834*/ + 0x0F124368, /* 70002836*/ + 0x0F121889, /* 70002838*/ + 0x0F1217C2, /* 7000283A*/ + 0x0F120E12, /* 7000283C*/ + 0x0F121810, /* 7000283E*/ + 0x0F121202, /* 70002840*/ + 0x0F128820, /* 70002842*/ + 0x0F12029B, /* 70002844*/ + 0x0F1218C0, /* 70002846*/ + 0x0F12F000, /* 70002848*/ + 0x0F12F8C4, /* 7000284A*/ + 0x0F129000, /* 7000284C*/ + 0x0F128AF6, /* 7000284E*/ + 0x0F124268, /* 70002850*/ + 0x0F12210A, /* 70002852*/ + 0x0F124370, /* 70002854*/ + 0x0F12F000, /* 70002856*/ + 0x0F12F8C5, /* 70002858*/ + 0x0F12436E, /* 7000285A*/ + 0x0F120007, /* 7000285C*/ + 0x0F12210A, /* 7000285E*/ + 0x0F120030, /* 70002860*/ + 0x0F12F000, /* 70002862*/ + 0x0F12F8BF, /* 70002864*/ + 0x0F129A00, /* 70002866*/ + 0x0F120039, /* 70002868*/ + 0x0F12F000, /* 7000286A*/ + 0x0F12F8C1, /* 7000286C*/ + 0x0F120002, /* 7000286E*/ + 0x0F128820, /* 70002870*/ + 0x0F121880, /* 70002872*/ + 0x0F128020, /* 70002874*/ + 0x0F124845, /* 70002876*/ + 0x0F1288C1, /* 70002878*/ + 0x0F124843, /* 7000287A*/ + 0x0F123820, /* 7000287C*/ + 0x0F128B40, /* 7000287E*/ + 0x0F124240, /* 70002880*/ + 0x0F124350, /* 70002882*/ + 0x0F12F000, /* 70002884*/ + 0x0F12F8AE, /* 70002886*/ + 0x0F128861, /* 70002888*/ + 0x0F121840, /* 7000288A*/ + 0x0F128060, /* 7000288C*/ + 0x0F12BCF8, /* 7000288E*/ + 0x0F12BC08, /* 70002890*/ + 0x0F124718, /* 70002892*/ + 0x0F12B570, /* 70002894*/ + 0x0F124C3C, /* 70002896*/ + 0x0F123C20, /* 70002898*/ + 0x0F128B20, /* 7000289A*/ + 0x0F12F000, /* 7000289C*/ + 0x0F12F8B0, /* 7000289E*/ + 0x0F124D3A, /* 700028A0*/ + 0x0F1280E8, /* 700028A2*/ + 0x0F128B60, /* 700028A4*/ + 0x0F12F000, /* 700028A6*/ + 0x0F12F8B3, /* 700028A8*/ + 0x0F128128, /* 700028AA*/ + 0x0F12BC70, /* 700028AC*/ + 0x0F12BC08, /* 700028AE*/ + 0x0F124718, /* 700028B0*/ + 0x0F12B510, /* 700028B2*/ + 0x0F124836, /* 700028B4*/ + 0x0F12214D, /* 700028B6*/ + 0x0F128201, /* 700028B8*/ + 0x0F122196, /* 700028BA*/ + 0x0F128281, /* 700028BC*/ + 0x0F12211D, /* 700028BE*/ + 0x0F128301, /* 700028C0*/ + 0x0F12F7FF, /* 700028C2*/ + 0x0F12FFE7, /* 700028C4*/ + 0x0F12F000, /* 700028C6*/ + 0x0F12F8AB, /* 700028C8*/ + 0x0F12E7A9, /* 700028CA*/ + 0x0F12B570, /* 700028CC*/ + 0x0F120004, /* 700028CE*/ + 0x0F126820, /* 700028D0*/ + 0x0F126865, /* 700028D2*/ + 0x0F12F000, /* 700028D4*/ + 0x0F12F8AC, /* 700028D6*/ + 0x0F120402, /* 700028D8*/ + 0x0F12482E, /* 700028DA*/ + 0x0F120C12, /* 700028DC*/ + 0x0F128142, /* 700028DE*/ + 0x0F12482D, /* 700028E0*/ + 0x0F128801, /* 700028E2*/ + 0x0F122900, /* 700028E4*/ + 0x0F12D008, /* 700028E6*/ + 0x0F12492C, /* 700028E8*/ + 0x0F12002B, /* 700028EA*/ + 0x0F126D8A, /* 700028EC*/ + 0x0F122105, /* 700028EE*/ + 0x0F121C80, /* 700028F0*/ + 0x0F12F000, /* 700028F2*/ + 0x0F12F8A5, /* 700028F4*/ + 0x0F126020, /* 700028F6*/ + 0x0F12E005, /* 700028F8*/ + 0x0F124829, /* 700028FA*/ + 0x0F12002B, /* 700028FC*/ + 0x0F122105, /* 700028FE*/ + 0x0F12F000, /* 70002900*/ + 0x0F12F89E, /* 70002902*/ + 0x0F126020, /* 70002904*/ + 0x0F126820, /* 70002906*/ + 0x0F12E7D0, /* 70002908*/ + 0x0F12B5F8, /* 7000290A*/ + 0x0F124923, /* 7000290C*/ + 0x0F122200, /* 7000290E*/ + 0x0F123160, /* 70002910*/ + 0x0F1283CA, /* 70002912*/ + 0x0F126800, /* 70002914*/ + 0x0F124669, /* 70002916*/ + 0x0F12F000, /* 70002918*/ + 0x0F12F89A, /* 7000291A*/ + 0x0F12466B, /* 7000291C*/ + 0x0F128818, /* 7000291E*/ + 0x0F12F000, /* 70002920*/ + 0x0F12F86E, /* 70002922*/ + 0x0F120005, /* 70002924*/ + 0x0F12466B, /* 70002926*/ + 0x0F128858, /* 70002928*/ + 0x0F12F000, /* 7000292A*/ + 0x0F12F871, /* 7000292C*/ + 0x0F120004, /* 7000292E*/ + 0x0F122101, /* 70002930*/ + 0x0F121928, /* 70002932*/ + 0x0F1202C9, /* 70002934*/ + 0x0F121A08, /* 70002936*/ + 0x0F120286, /* 70002938*/ + 0x0F120029, /* 7000293A*/ + 0x0F120030, /* 7000293C*/ + 0x0F12F000, /* 7000293E*/ + 0x0F12F88F, /* 70002940*/ + 0x0F120005, /* 70002942*/ + 0x0F122701, /* 70002944*/ + 0x0F1202BF, /* 70002946*/ + 0x0F120021, /* 70002948*/ + 0x0F120030, /* 7000294A*/ + 0x0F12F000, /* 7000294C*/ + 0x0F12F888, /* 7000294E*/ + 0x0F124912, /* 70002950*/ + 0x0F124A0E, /* 70002952*/ + 0x0F123140, /* 70002954*/ + 0x0F123AC0, /* 70002956*/ + 0x0F12800D, /* 70002958*/ + 0x0F128395, /* 7000295A*/ + 0x0F12804F, /* 7000295C*/ + 0x0F1283D7, /* 7000295E*/ + 0x0F128088, /* 70002960*/ + 0x0F120011, /* 70002962*/ + 0x0F123120, /* 70002964*/ + 0x0F128008, /* 70002966*/ + 0x0F12E791, /* 70002968*/ + 0x0F12B510, /* 7000296A*/ + 0x0F12480A, /* 7000296C*/ + 0x0F128980, /* 7000296E*/ + 0x0F122800, /* 70002970*/ + 0x0F12D001, /* 70002972*/ + 0x0F12F000, /* 70002974*/ + 0x0F12F87A, /* 70002976*/ + 0x0F12E752, /* 70002978*/ + 0x0F120000, /* 7000297A*/ + 0x0F124140, /* 7000297C*/ + 0x0F12D000, /* 7000297E*/ + 0x0F1219DC, /* 70002980*/ + 0x0F127000, /* 70002982*/ + 0x0F121B60, /* 70002984*/ + 0x0F127000, /* 70002986*/ + 0x0F120DD4, /* 70002988*/ + 0x0F127000, /* 7000298A*/ + 0x0F1222AC, /* 7000298C*/ + 0x0F127000, /* 7000298E*/ + 0x0F121E8C, /* 70002990*/ + 0x0F127000, /* 70002992*/ + 0x0F121A10, /* 70002994*/ + 0x0F127000, /* 70002996*/ + 0x0F123780, /* 70002998*/ + 0x0F127000, /* 7000299A*/ + 0x0F122384, /* 7000299C*/ + 0x0F127000, /* 7000299E*/ + 0x0F12065C, /* 700029A0*/ + 0x0F127000, /* 700029A2*/ + 0x0F124778, /* 700029A4*/ + 0x0F1246C0, /* 700029A6*/ + 0x0F12C000, /* 700029A8*/ + 0x0F12E59F, /* 700029AA*/ + 0x0F12FF1C, /* 700029AC*/ + 0x0F12E12F, /* 700029AE*/ + 0x0F12CE77, /* 700029B0*/ + 0x0F120000, /* 700029B2*/ + 0x0F124778, /* 700029B4*/ + 0x0F1246C0, /* 700029B6*/ + 0x0F12C000, /* 700029B8*/ + 0x0F12E59F, /* 700029BA*/ + 0x0F12FF1C, /* 700029BC*/ + 0x0F12E12F, /* 700029BE*/ + 0x0F123609, /* 700029C0*/ + 0x0F120000, /* 700029C2*/ + 0x0F124778, /* 700029C4*/ + 0x0F1246C0, /* 700029C6*/ + 0x0F12C000, /* 700029C8*/ + 0x0F12E59F, /* 700029CA*/ + 0x0F12FF1C, /* 700029CC*/ + 0x0F12E12F, /* 700029CE*/ + 0x0F129F91, /* 700029D0*/ + 0x0F120000, /* 700029D2*/ + 0x0F124778, /* 700029D4*/ + 0x0F1246C0, /* 700029D6*/ + 0x0F12C000, /* 700029D8*/ + 0x0F12E59F, /* 700029DA*/ + 0x0F12FF1C, /* 700029DC*/ + 0x0F12E12F, /* 700029DE*/ + 0x0F122AE3, /* 700029E0*/ + 0x0F120000, /* 700029E2*/ + 0x0F124778, /* 700029E4*/ + 0x0F1246C0, /* 700029E6*/ + 0x0F12F004, /* 700029E8*/ + 0x0F12E51F, /* 700029EA*/ + 0x0F12D1DC, /* 700029EC*/ + 0x0F120000, /* 700029EE*/ + 0x0F124778, /* 700029F0*/ + 0x0F1246C0, /* 700029F2*/ + 0x0F12C000, /* 700029F4*/ + 0x0F12E59F, /* 700029F6*/ + 0x0F12FF1C, /* 700029F8*/ + 0x0F12E12F, /* 700029FA*/ + 0x0F126869, /* 700029FC*/ + 0x0F120000, /* 700029FE*/ + 0x0F124778, /* 70002A00*/ + 0x0F1246C0, /* 70002A02*/ + 0x0F12C000, /* 70002A04*/ + 0x0F12E59F, /* 70002A06*/ + 0x0F12FF1C, /* 70002A08*/ + 0x0F12E12F, /* 70002A0A*/ + 0x0F1268BD, /* 70002A0C*/ + 0x0F120000, /* 70002A0E*/ + 0x0F124778, /* 70002A10*/ + 0x0F1246C0, /* 70002A12*/ + 0x0F12C000, /* 70002A14*/ + 0x0F12E59F, /* 70002A16*/ + 0x0F12FF1C, /* 70002A18*/ + 0x0F12E12F, /* 70002A1A*/ + 0x0F1268DB, /* 70002A1C*/ + 0x0F120000, /* 70002A1E*/ + 0x0F124778, /* 70002A20*/ + 0x0F1246C0, /* 70002A22*/ + 0x0F12C000, /* 70002A24*/ + 0x0F12E59F, /* 70002A26*/ + 0x0F12FF1C, /* 70002A28*/ + 0x0F12E12F, /* 70002A2A*/ + 0x0F1271B9, /* 70002A2C*/ + 0x0F120000, /* 70002A2E*/ + 0x0F124778, /* 70002A30*/ + 0x0F1246C0, /* 70002A32*/ + 0x0F12C000, /* 70002A34*/ + 0x0F12E59F, /* 70002A36*/ + 0x0F12FF1C, /* 70002A38*/ + 0x0F12E12F, /* 70002A3A*/ + 0x0F1298CD, /* 70002A3C*/ + 0x0F120000, /* 70002A3E*/ + 0x0F124778, /* 70002A40*/ + 0x0F1246C0, /* 70002A42*/ + 0x0F12C000, /* 70002A44*/ + 0x0F12E59F, /* 70002A46*/ + 0x0F12FF1C, /* 70002A48*/ + 0x0F12E12F, /* 70002A4A*/ + 0x0F12987F, /* 70002A4C*/ + 0x0F120000, /* 70002A4E*/ + 0x0F124778, /* 70002A50*/ + 0x0F1246C0, /* 70002A52*/ + 0x0F12C000, /* 70002A54*/ + 0x0F12E59F, /* 70002A56*/ + 0x0F12FF1C, /* 70002A58*/ + 0x0F12E12F, /* 70002A5A*/ + 0x0F121BC9, /* 70002A5C*/ + 0x0F120000, /* 70002A5E*/ + 0x0F124778, /* 70002A60*/ + 0x0F1246C0, /* 70002A62*/ + 0x0F12F004, /* 70002A64*/ + 0x0F12E51F, /* 70002A66*/ + 0x0F12D378, /* 70002A68*/ + 0x0F120000, /* 70002A6A*/ + 0x0F124778, /* 70002A6C*/ + 0x0F1246C0, /* 70002A6E*/ + 0x0F12C000, /* 70002A70*/ + 0x0F12E59F, /* 70002A72*/ + 0x0F12FF1C, /* 70002A74*/ + 0x0F12E12F, /* 70002A76*/ + 0x0F1204CB, /* 70002A78*/ + 0x0F120000, /* 70002A7A*/ + /* End of Patch Data(Last : 70002A7Ah)*/ + /* This parameter should be set before HOST command interrupt + * (1000 0001)*/ + 0x002A378C, + 0x0F120000, /* On/off register bUseOTP*/ + 0x002A0DCC, + 0x0F120138, /*awbb_IntcR*/ + 0x0F12011C, /*awbb_IntcB*/ + /*===================================================================*/ + /*Analog & APS Control*/ + /*===================================================================*/ + 0x0028D000, + 0x002AF404, + 0x0F120038, /* aig_adc_sat[7:0] : 850mV, revised by Ana 20100524*/ + 0x0F120001, /* aig_ms[2:0] : revised by Ana 20100202*/ + 0x0F12000C, /* aig_sig_mx[5:0]*/ + 0x0F120006, /* aig_rst_mx[5:0]*/ + 0x0F120008, /* aig_rmp_option[3] SL_Low_PWR_SAVE On : + revised by Ana 20100204*/ + 0x002AF418, + 0x0F120003, /* aig_dbr_clk_sel[1:0] : revised by Ana 20100201*/ + 0x002AF41C, + 0x0F120140, /* aig_bist_sig_width_e[10:0]*/ + 0x0F120140, /* aig_bist_sig_width_o[10:0]*/ + 0x0F120066, /* aig_bist_sig_width_o[10:0]*/ + 0x0F120005, /* aig_pix_bias[3:0]*/ + 0x002AF426, + 0x0F1200D4, /* aig_clp_lvl[7:0]*/ + 0x002AF42A, + 0x0F120001, /* aig_ref_option[0] SL_Low_PWR_SAVE On : + revised by Ana 20100204*/ + 0x002AF430, + 0x0F120001, /* aig_pd_cp_rosc[0] : revised by Ana 20100201*/ + 0x0F120001, /* aig_pd_ncp_rosc[0] : revised by Ana 20100201*/ + 0x002AF43A, + 0x0F120000, /* aig_pd_fblv[0] : revised by Ana 20100203*/ + 0x002AF440, + 0x0F120044, /* aig_rosc_tune_ncp[7:4]*/ + /* aig_rosc_tune_cp[3:0]*/ + 0x002AF44A, + 0x0F120000, /* aig_fb_lv[1:0] : revised by Ana 20100204*/ + 0x002AF45C, + 0x0F120000, /* aig_dshut_en[0] : revised by APS 20100223*/ + 0x0F120000, /* aig_srx_en[0]*/ + 0x002AF462, + 0x0F120001, /* aig_pdb_atop[0]*/ + 0x002AF46E, + 0x0F121F02, /* aig_cds_test[15:0]*/ + 0x002AF474, + 0x0F12000E, /* aig_stx_gap[4:0]*/ + /*====================================================================*/ + 0x002AE42E, + 0x0F120004, /* adlc_qec[2:0] : revised by + Dithered L-ADLC Designer 20100203*/ + 0x00287000, + 0x002A13E0, + 0x0F120000, /*700013E0 SRX OFF*/ + 0x002A13C8, + 0x0F120001, /*700013C8 AAC Enable*/ + 0x002A12D8, + 0x0F120464, /*700012d8*/ + 0x0F120468, /*700012da*/ + 0x002A12F6, + 0x0F120000, /*700012f6*/ + 0x002A13CC, + 0x0F121FC0, /* [12:0] : Write tuning value to E404 register*/ + 0x002A13EC, + 0x0F120001, + 0x002A184C, + 0x0F121EE1, + 0x0028D000, + 0x002A1000, + 0x0F120001, + 0x00287000, + 0x002A040E, + 0x0F120003, /*STBY TnP enable setting STBY TnP enable setting [0] + bit STBY enable,[1] bit STBY ø TnP ? on/off bit*/ + 0xFFFF000A, + /*H-Digital binning & V-PLA*/ + 0x002A1218, + 0x0F120002, /*subsampling number.*/ + 0x0F120002, /*subsampling number.*/ + 0x002A0C9A, + 0x0F120001, /* setot_bUseDigitalHbin 0 : do not use bin block*/ + 0x002A1438, + 0x0F12F468, /* senHal_TuneStr_AngTuneData1[0] : tuning register + setting.*/ + 0x0F120000, /* not use binninb block 0x0000 ,use binnin blcok + 0x0000*/ + 0x0F120008, /* not use binninb block 0x000A ,use binnin blcok + 0x0008*/ + 0x0F120006, /* not use binninb block 0x0005 ,use binnin blcok + 0x0006*/ + 0x0F120000, /* 0x0000 , 0x0000*/ + 0xFFFF000A, + 0x002A0416, + 0x0F12F400, + 0x0F120074, + 0x0F12E42E, + 0x0F120030, + /*clk Settings*/ + 0x00287000, + 0x002A00F4, + 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs 2 700000F4*/ + 0x002A0110, + 0x0F120003, /*REG_TC_IPRM_UseNPviClocks 2 70000110*/ + 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc 2 70000112*/ + /*SYSTEM CLOCK*/ + 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 2 70000114 + 35000Khz/4=HEX()*/ + 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0 2 70000116*/ + 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0 2 70000118*/ + 0x0F121117, /*1770 REG_TC_IPRM_OpClk4KHz_1 2 7000011A + 24000Khz/4*/ + 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1 2 7000011C + 36000khz/4 =2328hex*/ + 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1 2 7000011E*/ + 0x0F120BB8, /*REG_TC_IPRM_OpClk4KHz_2 2 70000120 + 12000Khz*/ + 0x0F1205DC, /*REG_TC_IPRM_MinOutRate4KHz_2 2 70000122*/ + 0x0F121770, /*REG_TC_IPRM_MaxOutRate4KHz_2 2 70000124*/ + 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated 2 70000126*/ + 0xFFFF0064, + 0x002A1218, + 0x0F120002, + /*===================================================================*/ + /*Preview0 1600x1200 system 32M PCLK 70M From APS*/ + /*===================================================================*/ + 0x002A0144, + 0x0F120640, + 0x0F1204B0, + 0x0F120000, + 0x0F120000, + /*Preview0 for 7.5~15fps*/ + 0x002A0170, + 0x0F120280, /*REG_0TC_PCFG_usWidth 2 70000170*/ + 0x0F1201e0, /*REG_0TC_PCFG_usHeight 2 70000172*/ + 0x0F120005, /*REG_0TC_PCFG_Format 2 70000174*/ + 0x0F12222E, /*REG_0TC_PCFG_usMaxOut4KHzRate 2 70000176*/ + 0x0F12222E, /*REG_0TC_PCFG_usMinOut4KHzRate 2 70000178*/ + 0x0F120042, /*REG_0TC_PCFG_PVIMask 2 7000017A*/ + 0x0F120010, /*REG_0TC_PCFG_OIFMask 2 7000017C*/ + 0x0F120001, /*REG_0TC_PCFG_uClockInd 2 7000017E*/ + 0x0F120002, /*REG_0TC_PCFG_usFrTimeType 2 70000180 + 0b : dynamic 01:fix not accurate 02b: fixed_Accurate*/ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType 2 70000182 + 1b: FR (bin) 2b: Quality (no-bin)*/ + 0x0F1204E2, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 2 70000184 + max frame time : 30fps 014D 15fps 029a; a6a - + 3.75 fps; 0535 - 7.5FPS*/ + 0x0F1204E2, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 2 70000186*/ + 0x0F120000, /*REG_0TC_PCFG_bSmearOutput 2 70000188*/ + 0x0F120000, /*REG_0TC_PCFG_sSaturation 2 7000018A*/ + 0x0F120000, /*REG_0TC_PCFG_sSharpBlur 2 7000018C*/ + 0x0F120000, /*REG_0TC_PCFG_sColorTemp 2 7000018E*/ + 0x0F120000, /*REG_0TC_PCFG_uDeviceGammaIndex 2 70000190*/ + 0x0F120003, /*REG_0TC_PCFG_uPrevMirror 2 70000192*/ + 0x0F120003, /*REG_0TC_PCFG_uCaptureMirror 2 70000194*/ + 0x0F120000, /*REG_0TC_PCFG_uRotation 2 70000196*/ + /*Preview1 for fixed 15fps*/ + 0x0F120320, /*REG_1TC_PCFG_usWidth 2 70000198*/ + 0x0F120258, /*REG_1TC_PCFG_usHeight 2 7000019A*/ + 0x0F120005, /*REG_1TC_PCFG_Format 2 7000019C*/ + 0x0F12222E, /*REG_1TC_PCFG_usMaxOut4KHzRate 2 7000019E*/ + 0x0F12222E, /*REG_1TC_PCFG_usMinOut4KHzRate 2 700001A0*/ + 0x0F120042, /*REG_1TC_PCFG_PVIMask 2 700001A2*/ + 0x0F120010, /*REG_1TC_PCFG_OIFMask 2 700001A4*/ + 0x0F120001, /*REG_1TC_PCFG_uClockInd 2 700001A6*/ + 0x0F120000, /*REG_1TC_PCFG_usFrTimeType 2 700001A8*/ + 0x0F120001, /*REG_1TC_PCFG_FrRateQualityType 2 700001AA*/ + 0x0F12029A, /*REG_1TC_PCFG_usMaxFrTimeMsecMult10 2 700001AC*/ + 0x0F12029A, /*REG_1TC_PCFG_usMinFrTimeMsecMult10 2 700001AE*/ + 0x0F120000, /*REG_1TC_PCFG_bSmearOutput 2 700001B0*/ + 0x0F120000, /*REG_1TC_PCFG_sSaturation 2 700001B2*/ + 0x0F120000, /*REG_1TC_PCFG_sSharpBlur 2 700001B4*/ + 0x0F120000, /*REG_1TC_PCFG_sColorTemp 2 700001B6*/ + 0x0F120000, /*REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/ + 0x0F120003, /*REG_1TC_PCFG_uPrevMirror 2 700001BA*/ + 0x0F120003, /*REG_1TC_PCFG_uCaptureMirror 2 700001BC*/ + 0x0F120000, /*REG_1TC_PCFG_uRotation 2 700001BE*/ + /*Preview2 for nightshot*/ + 0x0F120320, /*REG_2TC_PCFG_usWidth 2 700001C0*/ + 0x0F120258, /*REG_2TC_PCFG_usHeight 2 700001C2*/ + 0x0F120005, /*REG_2TC_PCFG_Format 2 700001C4*/ + 0x0F12222E, /*REG_2TC_PCFG_usMaxOut4KHzRate 2 700001C6*/ + 0x0F12222E, /*REG_2TC_PCFG_usMinOut4KHzRate 2 700001C8*/ + 0x0F120042, /*REG_2TC_PCFG_PVIMask 2 700001CA*/ + 0x0F120010, /*REG_2TC_PCFG_OIFMask 2 700001CC*/ + 0x0F120000, /*REG_2TC_PCFG_uClockInd 2 700001CE*/ + 0x0F120000, /*REG_2TC_PCFG_usFrTimeType 2 700001D0*/ + 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 2 700001D2 + 1b: FR (bin) 2b: Quality (no-bin)*/ + 0x0F12014D, /*REG_2TC_PCFG_usMaxFrTimeMsecMult10 2 700001D4 + max frame time : 30fps 014D 15fps 029a; a6a - + 3.75 fps; 0535 - 7.5FPS*/ + 0x0F12014D, /*REG_2TC_PCFG_usMinFrTimeMsecMult10 2 700001D6*/ + 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/ + 0x0F120000, /*REG_2TC_PCFG_sSaturation 2 700001DA*/ + 0x0F120000, /*REG_2TC_PCFG_sSharpBlur 2 700001DC*/ + 0x0F120000, /*REG_2TC_PCFG_sColorTemp 2 700001DE*/ + 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/ + 0x0F120003, /*REG_2TC_PCFG_uPrevMirror 2 700001E2 + [0] : x [1]: Y [2] Stat X [3] Stat Y*/ + 0x0F120003, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/ + 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/ + 0x002A0238, + 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/ + 0x0F120640, /*REG_0TC_CCFG_usWidth 2 7000023A*/ + 0x0F1204B0, /*REG_0TC_CCFG_usHeight 2 7000023C*/ + 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/ + 0x0F12222E, /*REG_0TC_CCFG_usMaxOut4KHzRate 2 70000240*/ + 0x0F12222E, /*REG_0TC_CCFG_usMinOut4KHzRate 2 70000242*/ + 0x0F120042, /*REG_0TC_CCFG_PVIMask 2 70000244*/ + 0x0F120000, /*REG_0TC_CCFG_OIFMask 2 70000246*/ + 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/ + 0x0F120000, /*REG_0TC_CCFG_usFrTimeType 2 7000024A*/ + 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/ + 0x0F1205D0, /*REG_0TC_CCFG_usMaxFrTimeMsecMult10 2 7000024E*/ + 0x0F1204D0, /*REG_0TC_CCFG_usMinFrTimeMsecMult10 2 70000250*/ + 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/ + 0x0F120000, /*REG_0TC_CCFG_sSaturation 2 70000254*/ + 0x0F120000, /*REG_0TC_CCFG_sSharpBlur 2 70000256*/ + 0x0F120000, /*REG_0TC_CCFG_sColorTemp 2 70000258*/ + 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/ + 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/ + 0x0F120640, /*REG_1TC_CCFG_usWidth 2 7000025E*/ + 0x0F1204B0, /*REG_1TC_CCFG_usHeight 2 70000260*/ + 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/ + 0x0F12222E, /*REG_1TC_CCFG_usMaxOut4KHzRate 2 70000264*/ + 0x0F12222E, /*REG_1TC_CCFG_usMinOut4KHzRate 2 70000266*/ + 0x0F120042, /*REG_1TC_CCFG_PVIMask 2 70000268*/ + 0x0F120000, /*REG_1TC_CCFG_OIFMask 2 7000026A*/ + 0x0F120001, /*REG_1TC_CCFG_uClockInd 2 7000026C*/ + 0x0F120000, /*REG_1TC_CCFG_usFrTimeType 2 7000026E*/ + 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/ + 0x0F121388, /*REG_1TC_CCFG_usMaxFrTimeMsecMult10 2 70000272*/ + 0x0F121388, /*REG_1TC_CCFG_usMinFrTimeMsecMult10 2 70000274*/ + 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/ + 0x0F120000, /*REG_1TC_CCFG_sSaturation 2 70000278*/ + 0x0F120000, /*REG_1TC_CCFG_sSharpBlur 2 7000027A*/ + 0x0F120000, /*REG_1TC_CCFG_sColorTemp 2 7000027C*/ + 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/ + 0x002A1218, + 0x0F120002, + /*PREVIEW*/ + 0x002A0156, + 0x0F120000, + 0x002A015E, + 0x0F120000, + 0x002A015A, + 0x0F120001, + 0x002A0142, + 0x0F120001, + 0x002A0158, + 0x0F120001, + 0x002A0160, + 0x0F120001, + 0x002A013A, + 0x0F120001, + 0x0F120001, + 0xFFFF0064, + /*===================================================================*/ + /*AFC*/ + /*===================================================================*/ + /*Auto*/ + 0x00287000, + 0x002A0CC0, + 0x0F120001, /*AFC_Default60Hz 01:60hz 00:50Hz*/ + 0x002A0374, + 0x0F12067F, /*REG_TC_DBG_AutoAlgEnBits*/ + /*===================================================================*/ + /*Shading*/ + /*===================================================================*/ + /* TVAR_ash_pGAS_high*/ + 0x00287000, + 0x002A0AD8, + 0x0F120F00, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + /* TVAR_ash_pGAS_low*/ + 0x0F128608, + 0x0F12E960, + 0x0F120243, + 0x0F12128B, + 0x0F12F073, + 0x0F120270, + 0x0F12DF47, + 0x0F12F226, + 0x0F121A31, + 0x0F12DFDA, + 0x0F121200, + 0x0F1205A9, + 0x0F120F16, + 0x0F120F5E, + 0x0F12DF10, + 0x0F1225BF, + 0x0F12FCF0, + 0x0F12DE1B, + 0x0F12025B, + 0x0F12FA8B, + 0x0F12163B, + 0x0F12DF44, + 0x0F12FB2D, + 0x0F1230E6, + 0x0F12FE07, + 0x0F12F47C, + 0x0F1209F2, + 0x0F120AED, + 0x0F12FA09, + 0x0F12E70E, + 0x0F120158, + 0x0F121110, + 0x0F12E28C, + 0x0F120DFB, + 0x0F12074B, + 0x0F12FBE5, + 0x0F12961C, + 0x0F12E21A, + 0x0F120ADF, + 0x0F120A67, + 0x0F12F8A6, + 0x0F12FDC3, + 0x0F12D590, + 0x0F12FA69, + 0x0F1208D5, + 0x0F12F635, + 0x0F12057E, + 0x0F12043B, + 0x0F12155C, + 0x0F1200C6, + 0x0F12F042, + 0x0F12176A, + 0x0F12F818, + 0x0F12F1F3, + 0x0F12026F, + 0x0F1208F6, + 0x0F120CCF, + 0x0F12E42D, + 0x0F120A92, + 0x0F1210EC, + 0x0F12005F, + 0x0F12F02C, + 0x0F120672, + 0x0F1209BF, + 0x0F12F4B5, + 0x0F12FC22, + 0x0F12FD50, + 0x0F120C26, + 0x0F12EED3, + 0x0F1207C3, + 0x0F12080F, + 0x0F12F6CF, + 0x0F127A3B, + 0x0F12E9DC, + 0x0F12088E, + 0x0F1201C8, + 0x0F12043C, + 0x0F12F7E2, + 0x0F12E391, + 0x0F12F3C4, + 0x0F121422, + 0x0F12E845, + 0x0F120D16, + 0x0F1206CA, + 0x0F120DEB, + 0x0F121324, + 0x0F12E814, + 0x0F1216B7, + 0x0F1202AC, + 0x0F12DE4D, + 0x0F1201EA, + 0x0F12F0C2, + 0x0F120E06, + 0x0F12EC6D, + 0x0F12FDF0, + 0x0F122B46, + 0x0F120710, + 0x0F12F84C, + 0x0F120E52, + 0x0F120675, + 0x0F12F0D7, + 0x0F12ED40, + 0x0F12F3AD, + 0x0F12179A, + 0x0F12DE9B, + 0x0F1210BA, + 0x0F120825, + 0x0F12FE0A, + 0x0F1288E9, + 0x0F12E9E0, + 0x0F12043D, + 0x0F120A17, + 0x0F12FC21, + 0x0F12FB58, + 0x0F12DCE0, + 0x0F12F24C, + 0x0F121A19, + 0x0F12E011, + 0x0F1211A3, + 0x0F120649, + 0x0F120D04, + 0x0F120E15, + 0x0F12E112, + 0x0F1227BD, + 0x0F12F7AA, + 0x0F12E06A, + 0x0F120A16, + 0x0F12FD23, + 0x0F121226, + 0x0F12DA34, + 0x0F1207A4, + 0x0F122AD3, + 0x0F12FE27, + 0x0F12EE64, + 0x0F120CAD, + 0x0F1211C5, + 0x0F12EC55, + 0x0F12ED98, + 0x0F12F88A, + 0x0F121842, + 0x0F12E1D5, + 0x0F1208FD, + 0x0F120FB6, + 0x0F12F801, + 0x002A0378, + 0x0F120001, /*REG_TC_DBG_RelnitCmd*/ + /*===================================================================*/ + /*Shading - Alpha*/ + /*===================================================================*/ + 0x002A05E8, + 0x0F1200E4, /*TVAR_ash_AwbAshCord[0] 2 70000568*/ + 0x0F1200F0, /*TVAR_ash_AwbAshCord[1] 2 7000056A*/ + 0x0F120100, /*TVAR_ash_AwbAshCord[2] 2 7000056C*/ + 0x0F120120, /*TVAR_ash_AwbAshCord[3] 2 7000056E*/ + 0x0F120150, /*TVAR_ash_AwbAshCord[4] 2 70000570*/ + 0x0F120180, /*TVAR_ash_AwbAshCord[5] 2 70000572*/ + 0x0F1201A0, /*TVAR_ash_AwbAshCord[6] 2 70000574*/ + 0x002A05FE, + 0x0F123800, /*TVAR_ash_GASAlpha[0][0] 2 7000057E*/ + 0x0F124000, /*TVAR_ash_GASAlpha[0][1] 2 70000580*/ + 0x0F124000, /*TVAR_ash_GASAlpha[0][2] 2 70000582*/ + 0x0F124000, /*TVAR_ash_GASAlpha[0][3] 2 70000584*/ + 0x0F123800, /*TVAR_ash_GASAlpha[1][0] 2 70000586*/ + 0x0F124000, /*TVAR_ash_GASAlpha[1][1] 2 70000588*/ + 0x0F124000, /*TVAR_ash_GASAlpha[1][2] 2 7000058A*/ + 0x0F124000, /*TVAR_ash_GASAlpha[1][3] 2 7000058C*/ + 0x0F123800, /*TVAR_ash_GASAlpha[2][0] 2 7000058E*/ + 0x0F124000, /*TVAR_ash_GASAlpha[2][1] 2 70000590*/ + 0x0F124000, /*TVAR_ash_GASAlpha[2][2] 2 70000592*/ + 0x0F124000, /*TVAR_ash_GASAlpha[2][3] 2 70000594*/ + 0x0F123800, /*TVAR_ash_GASAlpha[3][0] 2 70000596*/ + 0x0F124000, /*TVAR_ash_GASAlpha[3][1] 2 70000598*/ + 0x0F124000, /*TVAR_ash_GASAlpha[3][2] 2 7000059A*/ + 0x0F124000, /*TVAR_ash_GASAlpha[3][3] 2 7000059C*/ + 0x0F123800, /*TVAR_ash_GASAlpha[4][0] 2 7000059E*/ + 0x0F124000, /*TVAR_ash_GASAlpha[4][1] 2 700005A0*/ + 0x0F124000, /*TVAR_ash_GASAlpha[4][2] 2 700005A2*/ + 0x0F124000, /*TVAR_ash_GASAlpha[4][3] 2 700005A4*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][0] 2 700005A6*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][1] 2 700005A8*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][2] 2 700005AA*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][3] 2 700005AC*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][0] 2 700005AE*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][1] 2 700005B0*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][2] 2 700005B2*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][3] 2 700005B4*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[0] 2 700005B6*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[1] 2 700005B8*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[2] 2 700005BA*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[3] 2 700005BC*/ + /*===================================================================*/ + /*Gamma*/ + /*===================================================================*/ + 0x002A0460, + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/ + + + /*===================================================================*/ + /*AE - shutter*/ + /*===================================================================*/ + /*AE_Target*/ + 0x002A10C0, + 0x0F120045, /*TVAR_ae_BrAve*/ + 0x002A10C6, + 0x0F12000F, /*ae_StatMode 2 70001046*/ + /*AE_state,*/ + 0x002A03B2, + 0x0F12010E, /*#lt_uLimitHigh*/ + 0x0F1200F5, /*#lt_uLimitLow*/ + /*For 60Hz,*/ + 0x002A03C4, + 0x0F123415, /*#lt_uMaxExp1*/ + 0x002A03C8, + 0x0F12681F, /*#lt_uMaxExp2*/ + 0x002A03CC, + 0x0F128227, /*#lt_uMaxExp3*/ + 0x002A03D0, + 0x0F120D40, /*C350 #lt_uMaxExp4*/ + 0x0F120003, /*0000 #lt_uMaxExp4*/ + 0x002A03D4, + 0x0F123415, /*#lt_uCapMaxExp1*/ + 0x002A03D8, + 0x0F12681F, /*#lt_uCapMaxExp2*/ + 0x002A03DC, + 0x0F128227, /*#lt_uCapMaxExp3*/ + 0x002A03E0, + 0x0F120D40, /*C350 #lt_uCapMaxExp4*/ + 0x0F120003, /*0000 #lt_uCapMaxExp4*/ + 0x002A03E4, + 0x0F1201C0, /*0230 #lt_uMaxAnGain1*/ + 0x0F1201D0, /*0260 #lt_uMaxAnGain2*/ + 0x0F1202D0, /*0380 #lt_uMaxAnGain3*/ + 0x0F120700, /*#lt_uMaxAnGain4*/ + 0x0F120100, /*#lt_uMaxDigGain*/ + 0x0F128000, /*#lt_uMaxTotGain Total-gain is limited by + #lt_uMaxTotGain*/ + 0x0F1201C0, /*#lt_uCapMaxAnGain1*/ + 0x0F1201D0, /*#lt_uCapMaxAnGain2*/ + 0x0F1202D0, /*#lt_uCapMaxAnGain3*/ + 0x0F120700, /*#lt_uCapMaxAnGain4*/ + 0x0F120100, /*#lt_uCapMaxDigGain*/ + 0x0F128000, /*#lt_uCapMaxTotGain Total-gain is limited by + #lt_uMaxTotGain*/ + /*===================================================================*/ + /*AE - Weights*/ + /*===================================================================*/ + 0x002A10CE, + 0x0F120000, /*ae_WeightTbl_16[0] 2 7000104E*/ + 0x0F120101, /*ae_WeightTbl_16[1] 2 70001050*/ + 0x0F120101, /*ae_WeightTbl_16[2] 2 70001052*/ + 0x0F120000, /*ae_WeightTbl_16[3] 2 70001054*/ + 0x0F120101, /*ae_WeightTbl_16[4] 2 70001056*/ + 0x0F120101, /*ae_WeightTbl_16[5] 2 70001058*/ + 0x0F120101, /*ae_WeightTbl_16[6] 2 7000105A*/ + 0x0F120101, /*ae_WeightTbl_16[7] 2 7000105C*/ + 0x0F120201, /*ae_WeightTbl_16[8] 2 7000105E*/ + 0x0F120303, /*ae_WeightTbl_16[9] 2 70001060*/ + 0x0F120303, /*ae_WeightTbl_16[10] 2 70001062*/ + 0x0F120102, /*ae_WeightTbl_16[11] 2 70001064*/ + 0x0F120201, /*ae_WeightTbl_16[12] 2 70001066*/ + 0x0F120403, /*ae_WeightTbl_16[13] 2 70001068*/ + 0x0F120304, /*ae_WeightTbl_16[14] 2 7000106A*/ + 0x0F120102, /*ae_WeightTbl_16[15] 2 7000106C*/ + 0x0F120201, /*ae_WeightTbl_16[16] 2 7000106E*/ + 0x0F120403, /*ae_WeightTbl_16[17] 2 70001070*/ + 0x0F120304, /*ae_WeightTbl_16[18] 2 70001072*/ + 0x0F120102, /*ae_WeightTbl_16[19] 2 70001074*/ + 0x0F120201, /*ae_WeightTbl_16[20] 2 70001076*/ + 0x0F120403, /*ae_WeightTbl_16[21] 2 70001078*/ + 0x0F120304, /*ae_WeightTbl_16[22] 2 7000107A*/ + 0x0F120102, /*ae_WeightTbl_16[23] 2 7000107C*/ + 0x0F120201, /*ae_WeightTbl_16[24] 2 7000107E*/ + 0x0F120303, /*ae_WeightTbl_16[25] 2 70001080*/ + 0x0F120303, /*ae_WeightTbl_16[26] 2 70001082*/ + 0x0F120102, /*ae_WeightTbl_16[27] 2 70001084*/ + 0x0F120201, /*ae_WeightTbl_16[28] 2 70001086*/ + 0x0F120202, /*ae_WeightTbl_16[29] 2 70001088*/ + 0x0F120202, /*ae_WeightTbl_16[30] 2 7000108A*/ + 0x0F120102, /*ae_WeightTbl_16[31] 2 7000108C*/ + /*===================================================================*/ + /*AWB-BASIC setting*/ + /*===================================================================*/ + 0x002A0DCC, + 0x0F120138, /*awbb_IntcR*/ + 0x0F12011C, /*awbb_IntcB*/ + 0x0F1202A7, /*awbb_GLocusR*/ + 0x0F120343, /*awbb_GLocusB*/ + 0x002A0DB4, + 0x0F12036C, /*awbb_CrclLowT_R_c*/ + 0x002A0DB8, + 0x0F12011D, /*awbb_CrclLowT_B_c*/ + 0x002A0DBC, + 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/ + 0x002A0DEC, + 0x0F1205F0, /*awbb_GamutWidthThr1*/ + 0x0F1201F4, /*awbb_GamutHeightThr1*/ + 0x0F12006C, /*awbb_GamutWidthThr2*/ + 0x0F120038, /*awbb_GamutHeightThr2*/ + 0x002A0DD8, + 0x0F12000C, /*awbb_MinNumOfFinalPatches*/ + 0x0F12001E, /*awbb_MinNumOfLowBrFinalPatches*/ + 0x0F120046, /*awbb_MinNumOfLowBr0_FinalPatches*/ + 0x002A22BA, + 0x0F120006, /* #Mon_AWB_ByPassMode [0]Outdoor [1]LowBr [2]LowTemp*/ + 0x002A0F7A, + 0x0F120000, /*awbb_RGainOff 2 70000EFA*/ + 0x0F120000, /*awbb_BGainOff 2 70000EFC*/ + 0x0F120000, /*awbb_GGainOff 2 70000EFE*/ + 0x0F1200C2, /*awbb_Alpha_Comp_Mode 2 70000F00*/ + 0x0F120002, /*awbb_Rpl_InvalidOutDoor 2 70000F02*/ + 0x0F120001, /*awbb_UseGrThrCorr 2 70000F04*/ + 0x0F1200E4, /*awbb_Use_Filters 2 70000F06*/ + 0x0F12053C, /*awbb_GainsInit[0] 2 70000F08*/ + 0x0F120400, /*awbb_GainsInit[1] 2 70000F0A*/ + 0x0F12055C, /*awbb_GainsInit[2] 2 70000F0C*/ + 0x0F12001E, /*awbb_WpFilterMinThr 2 70000F0E*/ + 0x0F120190, /*awbb_WpFilterMaxThr 2 70000F10*/ + 0x0F1200A0, /*awbb_WpFilterCoef 2 70000F12*/ + 0x0F120004, /*awbb_WpFilterSize 2 70000F14*/ + 0x0F120001, /*awbb_otp_disable 2 70000F16*/ + /*===================================================================*/ + /*AWB-Zone*/ + /*===================================================================*/ + /* param_start awbb_IndoorGrZones_m_BGrid*/ + 0x002A0CE0, + 0x0F1203F8, /*03B5 awbb_IndoorGrZones_m_BGrid[0]*/ + 0x0F120422, /*03DF awbb_IndoorGrZones_m_BGrid[1]*/ + 0x0F1203B4, /*032D awbb_IndoorGrZones_m_BGrid[2]*/ + 0x0F120408, /*03D5 awbb_IndoorGrZones_m_BGrid[3]*/ + 0x0F120370, /*0303 awbb_IndoorGrZones_m_BGrid[4]*/ + 0x0F1203EE, /*03BB awbb_IndoorGrZones_m_BGrid[5]*/ + 0x0F12032C, /*02DB awbb_IndoorGrZones_m_BGrid[6]*/ + 0x0F1203D4, /*0397 awbb_IndoorGrZones_m_BGrid[7]*/ + 0x0F120302, /*02B1 awbb_IndoorGrZones_m_BGrid[8]*/ + 0x0F1203BA, /*036B awbb_IndoorGrZones_m_BGrid[9]*/ + 0x0F1202DA, /*0289 awbb_IndoorGrZones_m_BGrid[10]*/ + 0x0F120374, /*0349 awbb_IndoorGrZones_m_BGrid[11]*/ + 0x0F1202B0, /*026F awbb_IndoorGrZones_m_BGrid[12]*/ + 0x0F120328, /*0329 awbb_IndoorGrZones_m_BGrid[13]*/ + 0x0F120288, /*0257 awbb_IndoorGrZones_m_BGrid[14]*/ + 0x0F120300, /*0309 awbb_IndoorGrZones_m_BGrid[15]*/ + 0x0F120270, /*0241 awbb_IndoorGrZones_m_BGrid[16]*/ + 0x0F1202DE, /*02DD awbb_IndoorGrZones_m_BGrid[17]*/ + 0x0F120258, /*0227 awbb_IndoorGrZones_m_BGrid[18]*/ + 0x0F1202BE, /*02C3 awbb_IndoorGrZones_m_BGrid[19]*/ + 0x0F120240, /*0213 awbb_IndoorGrZones_m_BGrid[20]*/ + 0x0F1202A0, /*02AF awbb_IndoorGrZones_m_BGrid[21]*/ + 0x0F120228, /*0209 awbb_IndoorGrZones_m_BGrid[22]*/ + 0x0F120296, /*0295 awbb_IndoorGrZones_m_BGrid[23]*/ + 0x0F120212, /*020D awbb_IndoorGrZones_m_BGrid[24]*/ + 0x0F120284, /*0285 awbb_IndoorGrZones_m_BGrid[25]*/ + 0x0F120208, /*0223 awbb_IndoorGrZones_m_BGrid[26]*/ + 0x0F120274, /*0261 awbb_IndoorGrZones_m_BGrid[27]*/ + 0x0F12020C, /*0000 awbb_IndoorGrZones_m_BGrid[28]*/ + 0x0F12026E, /*0000 awbb_IndoorGrZones_m_BGrid[29]*/ + 0x0F120222, /*0000 awbb_IndoorGrZones_m_BGrid[30]*/ + 0x0F120260, /*0000 awbb_IndoorGrZones_m_BGrid[31]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[32]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[33]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[34]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[35]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[36]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[37]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[38]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[39]*/ + /* param_end awbb_IndoorGrZones_m_BGrid*/ + 0x0F120005, /*awbb_IndoorGrZones_m_Grid*/ + 0x002A0D38, + 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/ + /* param_start awbb_OutdoorGrZones_m_BGrid*/ + 0x002A0D3C, + 0x0F1202B8, /*029F awbb_OutdoorGrZones_m_BGrid[0]*/ + 0x0F1202F2, /*02CE awbb_OutdoorGrZones_m_BGrid[1]*/ + 0x0F12028E, /*0282 awbb_OutdoorGrZones_m_BGrid[2]*/ + 0x0F12030A, /*02DA awbb_OutdoorGrZones_m_BGrid[3]*/ + 0x0F12027A, /*026D awbb_OutdoorGrZones_m_BGrid[4]*/ + 0x0F12030A, /*02C2 awbb_OutdoorGrZones_m_BGrid[5]*/ + 0x0F120274, /*0256 awbb_OutdoorGrZones_m_BGrid[6]*/ + 0x0F1202FE, /*02A6 awbb_OutdoorGrZones_m_BGrid[7]*/ + 0x0F120282, /*026E awbb_OutdoorGrZones_m_BGrid[8]*/ + 0x0F1202DC, /*028A awbb_OutdoorGrZones_m_BGrid[9]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[10]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[11]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[12]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[13]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[14]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[15]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[16]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[17]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[18]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[19]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[20]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[21]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[22]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[23]*/ + /* param_end awbb_OutdoorGrZones_m_BGrid*/ + 0x0F120005, /*awbb_OutdoorGrZones_m_Gri*/ + 0x002A0D70, + 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/ + 0x002A0D74, + 0x0F1201EB, /*awbb_OutdoorGrZones_m_Bof*/ + /* param_start awbb_LowBrGrZones_m_BGrid*/ + 0x002A0D78, + 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/ + 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/ + 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/ + 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/ + 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/ + 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/ + 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/ + 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/ + 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/ + 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/ + 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/ + 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/ + 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/ + 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/ + 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/ + 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/ + 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/ + 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/ + 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/ + 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/ + /* param_end awbb_LowBrGrZones_m_BGrid*/ + 0x0F120006, /*awbb_LowBrGrZones_m_GridS*/ + 0x002A0DB0, + 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/ + /*===================================================================*/ + /*AWB Scene Detection*/ + /*===================================================================*/ + 0x002A0E50, + 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B 2 70000DD0*/ + 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B 2 70000DD2*/ + 0x0F120E74, /*awbb_SCDetectionMap_SEC_SunnyNB 2 70000DD4*/ + 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB 2 70000DD6*/ + 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B 2 70000DD8*/ + 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone 2 70000DDA*/ + 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone + 2 70000DDC*/ + 0x002A0E14, + 0x0F120000, /*#awbb_SCDetectionMap_SEC 0000 + WRITE 70000D94 0000 + awbb_SCDetectionMap_SEC_SceneDetectionMap*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__2_ + WRITE 70000D96 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__4_ + WRITE 70000D98 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__1_ + WRITE 70000D9A 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__3_ + WRITE 70000D9C 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__0_ + WRITE 70000D9E 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__2_ + WRITE 70000DA0 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__4_ + WRITE 70000DA2 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__1_ + WRITE 70000DA4 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__3_ + WRITE 70000DA6 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__0_ + WRITE 70000DA8 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__2_ + WRITE 70000DAA 0000*/ + 0x0F120500, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__4_ + WRITE 70000DAC 0500*/ + 0x0F125555, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__1_ + WRITE 70000DAE 5555*/ + 0x0F125455, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__3_ + WRITE 70000DB0 5455*/ + 0x0F12AA55, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__0_ + WRITE 70000DB2 AA55*/ + 0x0F12AAAA, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__2_ + WRITE 70000DB4 AAAA*/ + 0x0F12BF54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__4_ + WRITE 70000DB6 BF54*/ + 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__1_ + WRITE 70000DB8 FFFF*/ + 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__3_ + WRITE 70000DBA 54FE*/ + 0x0F12FF6F, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__0_ + WRITE 70000DBC FF6F*/ + 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__2_ + WRITE 70000DBE FEFF*/ + 0x0F121B54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__4_ + WRITE 70000DC0 1B54*/ + 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__1_ + WRITE 70000DC2 FFFF*/ + 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__3_ + WRITE 70000DC4 54FE*/ + 0x0F12FF06, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__0_ + WRITE 70000DC6 FF06*/ + 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__2_ + WRITE 70000DC8 FEFF*/ + 0x0F120154, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__4_ + WRITE 70000DCA 0154*/ + 0x0F12BFBF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__1_ + WRITE 70000DCC BFBF*/ + 0x0F1254BE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__3_ + WRITE 70000DCE 54BE*/ + 0x002A0F86, + 0x0F120074, /*E0 awbb_Use_Filters e4*/ + 0x002A0F8E, + 0x0F12001E, /*awbb_WpFilterMinThr 1e*/ + /*===================================================================*/ + /*AWB - GridCorrection*/ + /*===================================================================*/ + 0x002A0F98, + 0x0F120002, /*awbb_GridEnable 2 70000F18*/ + 0x002A0F60, + 0x0F1202E2, /*awbb_GridConst_1[0] 2 70000EE0*/ + 0x0F12034B, /*awbb_GridConst_1[1] 2 70000EE2*/ + 0x0F120399, /*awbb_GridConst_1[2] 2 70000EE4*/ + 0x0F12102D, /*awbb_GridConst_2[0] 2 70000EE6*/ + 0x0F1210DE, /*awbb_GridConst_2[1] 2 70000EE8*/ + 0x0F12116E, /*awbb_GridConst_2[2] 2 70000EEA*/ + 0x0F12117B, /*awbb_GridConst_2[3] 2 70000EEC*/ + 0x0F121206, /*awbb_GridConst_2[4] 2 70000EEE*/ + 0x0F12127F, /*awbb_GridConst_2[5] 2 70000EF0*/ + 0x0F1202C4, /*awbb_GridCoeff_R_1 2 70000EF2*/ + 0x0F1202E4, /*awbb_GridCoeff_B_1 2 70000EF4*/ + 0x0F1200C3, /*awbb_GridCoeff_R_2 2 70000EF6*/ + 0x0F1200A6, /*awbb_GridCoeff_B_2 2 70000EF8*/ + 0x002A0ED0, + 0x0F12000A, /*awbb_GridCorr_R[0][0] 2 70000ED0*/ + 0x0F120028, /*awbb_GridCorr_R[0][1] 2 70000ED2*/ + 0x0F120028, /*awbb_GridCorr_R[0][2] 2 70000ED4*/ + 0x0F12FFEC, /*awbb_GridCorr_R[0][3] 2 70000ED6*/ + 0x0F12FFEC, /*awbb_GridCorr_R[0][4] 2 70000ED8*/ + 0x0F12001E, /*awbb_GridCorr_R[0][5] 2 70000EDA*/ + 0x0F12000A, /*awbb_GridCorr_R[1][0] 2 70000EDC*/ + 0x0F120028, /*awbb_GridCorr_R[1][1] 2 70000EDE*/ + 0x0F120028, /*awbb_GridCorr_R[1][2] 2 70000EE0*/ + 0x0F12FFEC, /*awbb_GridCorr_R[1][3] 2 70000EE2*/ + 0x0F12FFEC, /*awbb_GridCorr_R[1][4] 2 70000EE4*/ + 0x0F12001E, /*awbb_GridCorr_R[1][5] 2 70000EE6*/ + 0x0F12000A, /*awbb_GridCorr_R[2][0] 2 70000EE8*/ + 0x0F120028, /*awbb_GridCorr_R[2][1] 2 70000EEA*/ + 0x0F120028, /*awbb_GridCorr_R[2][2] 2 70000EEC*/ + 0x0F12FFEC, /*awbb_GridCorr_R[2][3] 2 70000EEE*/ + 0x0F12FFEC, /*awbb_GridCorr_R[2][4] 2 70000EF0*/ + 0x0F12001E, /*awbb_GridCorr_R[2][5] 2 70000EF2*/ + 0x0F12FFD8, /*awbb_GridCorr_B[0][0] 2 70000EF4*/ + 0x0F12003C, /*awbb_GridCorr_B[0][1] 2 70000EF6*/ + 0x0F12003C, /*awbb_GridCorr_B[0][2] 2 70000EF8*/ + 0x0F120000, /*awbb_GridCorr_B[0][3] 2 70000EFA*/ + 0x0F120000, /*awbb_GridCorr_B[0][4] 2 70000EFC*/ + 0x0F12001E, /*awbb_GridCorr_B[0][5] 2 70000EFE*/ + 0x0F12FFD8, /*awbb_GridCorr_B[1][0] 2 70000F00*/ + 0x0F12003C, /*awbb_GridCorr_B[1][1] 2 70000F02*/ + 0x0F12003C, /*awbb_GridCorr_B[1][2] 2 70000F04*/ + 0x0F120000, /*awbb_GridCorr_B[1][3] 2 70000F06*/ + 0x0F120000, /*awbb_GridCorr_B[1][4] 2 70000F08*/ + 0x0F12001E, /*awbb_GridCorr_B[1][5] 2 70000F0A*/ + 0x0F12FFD8, /*awbb_GridCorr_B[2][0] 2 70000F0C*/ + 0x0F12003C, /*awbb_GridCorr_B[2][1] 2 70000F0E*/ + 0x0F12003C, /*awbb_GridCorr_B[2][2] 2 70000F10*/ + 0x0F120000, /*awbb_GridCorr_B[2][3] 2 70000F12*/ + 0x0F120000, /*awbb_GridCorr_B[2][4] 2 70000F14*/ + 0x0F12001E, /*awbb_GridCorr_B[2][5] 2 70000F16*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][0] 2 70000F18*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1] 2 70000F1A*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][2] 2 70000F1C*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][3] 2 70000F1E*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][4] 2 70000F20*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][5] 2 70000F22*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][0] 2 70000F24*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1] 2 70000F26*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][2] 2 70000F28*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][3] 2 70000F2A*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][4] 2 70000F2C*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][5] 2 70000F2E*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][0] 2 70000F30*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1] 2 70000F32*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][2] 2 70000F34*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][3] 2 70000F36*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][4] 2 70000F38*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][5] 2 70000F3A*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][0] 2 70000F3C*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1] 2 70000F3E*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][2] 2 70000F40*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][3] 2 70000F42*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][4] 2 70000F44*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][5] 2 70000F46*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][0] 2 70000F48*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1] 2 70000F4A*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][2] 2 70000F4C*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][3] 2 70000F4E*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][4] 2 70000F50*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][5] 2 70000F52*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][0] 2 70000F54*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1] 2 70000F56*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][2] 2 70000F58*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][3] 2 70000F5A*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][4] 2 70000F5C*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][5] 2 70000F5E*/ + /*===================================================================*/ + /*CCM*/ + /*===================================================================*/ + 0x002A05D2, + 0x0F1200E4, /*#SARR_AwbCcmCord 2 70000552*/ + 0x0F1200F0, /*#SARR_AwbCcmCord_1_ 2 70000554*/ + 0x0F120100, /*#SARR_AwbCcmCord_2_ 2 70000556*/ + 0x0F120120, /*#SARR_AwbCcmCord_3_ 2 70000558*/ + 0x0F120150, /*#SARR_AwbCcmCord_4_ 2 7000055A*/ + 0x0F120180, /*#SARR_AwbCcmCord_5_ 2 7000055C*/ + /* param_start TVAR_wbt_pBaseCcms*/ + 0x002A05C4, + 0x0F123800, + 0x0F127000, + 0x002A3800, + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[36]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[37]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[38]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[39]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[40]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[41]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[42]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[43]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[44]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[45]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[46]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[47]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[48]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[49]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[50]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[51]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[52]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[53]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[54]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[55]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[56]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[57]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[58]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[59]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[60]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[61]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[62]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[63]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[64]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[65]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[66]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[67]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[68]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[69]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[70]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[71]*/ + 0x0F1201BF, /*TVAR_wbt_pBaseCcms[72]*/ + 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[73]*/ + 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[74]*/ + 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[75]*/ + 0x0F1201B4, /*TVAR_wbt_pBaseCcms[76]*/ + 0x0F12FF66, /*TVAR_wbt_pBaseCcms[77]*/ + 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[78]*/ + 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[79]*/ + 0x0F12017B, /*TVAR_wbt_pBaseCcms[80]*/ + 0x0F120136, /*TVAR_wbt_pBaseCcms[81]*/ + 0x0F120132, /*TVAR_wbt_pBaseCcms[82]*/ + 0x0F12FF85, /*TVAR_wbt_pBaseCcms[83]*/ + 0x0F12018B, /*TVAR_wbt_pBaseCcms[84]*/ + 0x0F12FF73, /*TVAR_wbt_pBaseCcms[85]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[86]*/ + 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[87]*/ + 0x0F12015B, /*TVAR_wbt_pBaseCcms[88]*/ + 0x0F1200D0, /*TVAR_wbt_pBaseCcms[89]*/ + 0x0F1201BF, /*TVAR_wbt_pBaseCcms[90]*/ + 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[91]*/ + 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[92]*/ + 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[93]*/ + 0x0F1201B4, /*TVAR_wbt_pBaseCcms[94]*/ + 0x0F12FF66, /*TVAR_wbt_pBaseCcms[95]*/ + 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[96]*/ + 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[97]*/ + 0x0F12017B, /*TVAR_wbt_pBaseCcms[98]*/ + 0x0F120136, /*TVAR_wbt_pBaseCcms[99]*/ + 0x0F120132, /*TVAR_wbt_pBaseCcms[100]*/ + 0x0F12FF85, /*TVAR_wbt_pBaseCcms[101]*/ + 0x0F12018B, /*TVAR_wbt_pBaseCcms[102]*/ + 0x0F12FF73, /*TVAR_wbt_pBaseCcms[103]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[104]*/ + 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[105]*/ + 0x0F12015B, /*TVAR_wbt_pBaseCcms[106]*/ + 0x0F1200D0, /*TVAR_wbt_pBaseCcms[107]*/ + /* param_end TVAR_wbt_pBaseCcms*/ + /* param_start TVAR_wbt_pOutdoorCcm*/ + 0x002A05CC, + 0x0F1238D8, /*#TVAR_wbt_pOutdoorCcm*/ + 0x0F127000, + 0x002A38D8, + 0x0F120235, /*TVAR_wbt_pOutdoorCcm[0]*/ + 0x0F12FFEF, /*TVAR_wbt_pOutdoorCcm[1]*/ + 0x0F120014, /*TVAR_wbt_pOutdoorCcm[2]*/ + 0x0F12FF67, /*TVAR_wbt_pOutdoorCcm[3]*/ + 0x0F12027D, /*TVAR_wbt_pOutdoorCcm[4]*/ + 0x0F12FFBA, /*TVAR_wbt_pOutdoorCcm[5]*/ + 0x0F12000D, /*TVAR_wbt_pOutdoorCcm[6]*/ + 0x0F120062, /*TVAR_wbt_pOutdoorCcm[7]*/ + 0x0F1202A7, /*TVAR_wbt_pOutdoorCcm[8]*/ + 0x0F1200C9, /*TVAR_wbt_pOutdoorCcm[9]*/ + 0x0F120123, /*TVAR_wbt_pOutdoorCcm[10]*/ + 0x0F12FF36, /*TVAR_wbt_pOutdoorCcm[11]*/ + 0x0F1201AD, /*TVAR_wbt_pOutdoorCcm[12]*/ + 0x0F12FFC8, /*TVAR_wbt_pOutdoorCcm[13]*/ + 0x0F120202, /*TVAR_wbt_pOutdoorCcm[14]*/ + 0x0F12FFCF, /*TVAR_wbt_pOutdoorCcm[15]*/ + 0x0F120257, /*TVAR_wbt_pOutdoorCcm[16]*/ + 0x0F12022C, /*TVAR_wbt_pOutdoorCcm[17]*/ + /* param_end TVAR_wbt_pOutdoorCcm*/ + 0x002A2404, + 0x0F120001, /*#MVAR_AAIO_bFIT*/ + 0x002A2408, + 0x0F120001, /*#MVAR_AAIO_bAutoCCMandASH*/ + 0x002A23DC, + 0x0F1201DD, /*#Mon_AAIO_PrevFrmData_NormBr*/ + /*===================================================================*/ + /*AFIT*/ + /*===================================================================*/ + /* param_start afit_uNoiseIndInDoor*/ + 0x002A065C, + 0x0F12004A, /*#afit_uNoiseIndInDoor_0_*/ + 0x0F12005F, /*#afit_uNoiseIndInDoor_1_*/ + 0x0F1200CB, /*#afit_uNoiseIndInDoor_2_*/ + 0x0F1201E0, /*#afit_uNoiseIndInDoor_3_*/ + 0x0F120220, /*#afit_uNoiseIndInDoor_4_*/ + /* param_end afit_uNoiseIndInDoor*/ + /* param_start TVAR_afit_pBaseVals*/ + 0x002A06BC, + 0x0F120000, /*#AfitBaseVals AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_0__1_ AFIT16_CONTRAST*/ + 0x0F120014, /*#AfitBaseVals_0__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_0__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_0__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_0__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_0__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_0__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_0__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_0__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_0__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_0__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*#AfitBaseVals_0__12_ AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_0__13_ AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_0__14_ AFIT16_demsharpmix1_iLowSat*/ + 0x0F12005A, /*#AfitBaseVals_0__15_ AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_0__16_ AFIT16_demsharpmix1_iTune*/ + 0x0F12001E, /*#AfitBaseVals_0__17_ AFIT16_demsharpmix1_iHystThLow*/ + 0x0F12001E, /*#AfitBaseVals_0__18_ AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201F4, /*#AfitBaseVals_0__19_ AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*#AfitBaseVals_0__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120046, /*#AfitBaseVals_0__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120005, /*#AfitBaseVals_0__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120005, /*#AfitBaseVals_0__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F12003C, /*#AfitBaseVals_0__24_AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_0__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F12003C, /*#AfitBaseVals_0__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_0__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12003C, /*#AfitBaseVals_0__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F12001E, /*#AfitBaseVals_0__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_0__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_0__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_0__32_AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_0__33_AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__34_AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__35_AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__36_AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_0__37_AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F120A3B, /*#AfitBaseVals_0__38_AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_0__40_AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_0__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_0__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_0__43_ + AFIT8_Demosaicing_iDesatThresh[7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_0__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_0__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_0__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F12001E, /*#AfitBaseVals_0__47_AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120002, /*#AfitBaseVals_0__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_0__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*#AfitBaseVals_0__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*#AfitBaseVals_0__51_AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_0__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_0__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_0__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*#AfitBaseVals_0__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128003, /*#AfitBaseVals_0__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F121982, /*#AfitBaseVals_0__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120A80, /*#AfitBaseVals_0__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_0__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_0__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F124601, /*#AfitBaseVals_0__62_AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F126444, /*#AfitBaseVals_0__63_AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F129650, /*#AfitBaseVals_0__64_AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*#AfitBaseVals_0__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F121E00, /*#AfitBaseVals_0__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120714, /*#AfitBaseVals_0__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121464, /*#AfitBaseVals_0__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121404, /*#AfitBaseVals_0__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F120F14, /*#AfitBaseVals_0__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_0__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_0__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F121403, /*#AfitBaseVals_0__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_0__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_0__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F124446, /*#AfitBaseVals_0__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F125064, /*#AfitBaseVals_0__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_0__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_0__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F12141E, /*#AfitBaseVals_0__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F126407, /*#AfitBaseVals_0__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120414, /*#AfitBaseVals_0__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_0__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_0__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_0__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_0__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F124601, /*#AfitBaseVals_0__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F126E44, /*#AfitBaseVals_0__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122864, /*#AfitBaseVals_0__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_0__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_0__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121E00, /*#AfitBaseVals_0__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F120714, /*#AfitBaseVals_0__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_0__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*#AfitBaseVals_0__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120F00, /*#AfitBaseVals_0__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_0__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_0__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_0__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_1__0_ AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_1__1_ AFIT16_CONTRAST*/ + 0x0F120014, /*#AfitBaseVals_1__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_1__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_1__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_1__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_1__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_1__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_1__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_1__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_1__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_1__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*#AfitBaseVals_1__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_1__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_1__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F12005A, /*#AfitBaseVals_1__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_1__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*#AfitBaseVals_1__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_1__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*#AfitBaseVals_1__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*#AfitBaseVals_1__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120046, /*#AfitBaseVals_1__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_1__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_1__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F120064, /*#AfitBaseVals_1__24_AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_1__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F120064, /*#AfitBaseVals_1__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_1__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12003C, /*#AfitBaseVals_1__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F12001E, /*#AfitBaseVals_1__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_1__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_1__31_AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_1__32_AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_1__33_AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_1__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*#AfitBaseVals_1__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_1__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_1__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_1__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_1__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_1__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_1__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_1__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_1__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120005, /*#AfitBaseVals_1__47_AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120002, /*#AfitBaseVals_1__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_1__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*#AfitBaseVals_1__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*#AfitBaseVals_1__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_1__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_1__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_1__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*#AfitBaseVals_1__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128003, /*#AfitBaseVals_1__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120A6E, /*#AfitBaseVals_1__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_1__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_1__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_1__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_1__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F122801, /*#AfitBaseVals_1__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F12231E, /*#AfitBaseVals_1__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12961E, /*#AfitBaseVals_1__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*#AfitBaseVals_1__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A02, /*#AfitBaseVals_1__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120764, /*#AfitBaseVals_1__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F12143C, /*#AfitBaseVals_1__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121401, /*#AfitBaseVals_1__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F120F14, /*#AfitBaseVals_1__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_1__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_1__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*#AfitBaseVals_1__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_1__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_1__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F121E28, /*#AfitBaseVals_1__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12140F, /*#AfitBaseVals_1__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_1__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_1__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120200, /*#AfitBaseVals_1__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*#AfitBaseVals_1__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123C07, /*#AfitBaseVals_1__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_1__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121414, /*#AfitBaseVals_1__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_1__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_1__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_1__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121E1E, /*#AfitBaseVals_1__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_1__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F123C01, /*#AfitBaseVals_1__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F125A3A, /*#AfitBaseVals_1__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122858, /*#AfitBaseVals_1__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_1__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_1__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121E00, /*#AfitBaseVals_1__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F120714, /*#AfitBaseVals_1__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_1__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*#AfitBaseVals_1__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120F00, /*#AfitBaseVals_1__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_1__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_1__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_1__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_2__0_AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_2__1_AFIT16_CONTRAST*/ + 0x0F120000, /*#AfitBaseVals_2__2_AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_2__3_AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_2__4_AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_2__5_AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_2__6_AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_2__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_2__8_AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_2__9_AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_2__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_2__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*#AfitBaseVals_2__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_2__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_2__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F12005A, /*#AfitBaseVals_2__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_2__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*#AfitBaseVals_2__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_2__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*#AfitBaseVals_2__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*#AfitBaseVals_2__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120032, /*#AfitBaseVals_2__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_2__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_2__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F1200B4, /*#AfitBaseVals_2__24_AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_2__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F1200B4, /*#AfitBaseVals_2__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_2__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12003C, /*#AfitBaseVals_2__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F12001E, /*#AfitBaseVals_2__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_2__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_2__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_2__32_ + AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_2__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__35_AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__36_AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_2__37_AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*#AfitBaseVals_2__38_AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_2__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_2__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_2__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_2__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_2__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_2__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_2__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_2__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120005, /*#AfitBaseVals_2__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120001, /*#AfitBaseVals_2__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_2__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*#AfitBaseVals_2__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*#AfitBaseVals_2__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_2__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_2__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_2__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*#AfitBaseVals_2__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128002, /*#AfitBaseVals_2__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120080, /*#AfitBaseVals_2__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_2__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_2__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_2__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_2__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*#AfitBaseVals_2__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*#AfitBaseVals_2__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*#AfitBaseVals_2__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122A03, /*#AfitBaseVals_2__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A02, /*#AfitBaseVals_2__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120864, /*#AfitBaseVals_2__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*#AfitBaseVals_2__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F129601, /*#AfitBaseVals_2__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F122814, /*#AfitBaseVals_2__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400A, /*#AfitBaseVals_2__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_2__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*#AfitBaseVals_2__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_2__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_2__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*#AfitBaseVals_2__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120D0F, /*#AfitBaseVals_2__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_2__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_2__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*#AfitBaseVals_2__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*#AfitBaseVals_2__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123208, /*#AfitBaseVals_2__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_2__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121450, /*#AfitBaseVals_2__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120A28, /*#AfitBaseVals_2__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_2__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_2__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F122828, /*#AfitBaseVals_2__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_2__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F122401, /*#AfitBaseVals_2__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F123622, /*#AfitBaseVals_2__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122832, /*#AfitBaseVals_2__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_2__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121003, /*#AfitBaseVals_2__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121E04, /*#AfitBaseVals_2__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F120714, /*#AfitBaseVals_2__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_2__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125004, /*#AfitBaseVals_2__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120F40, /*#AfitBaseVals_2__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_2__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_2__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_2__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_3__0_AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_3__1_AFIT16_CONTRAST*/ + 0x0F120000, /*#AfitBaseVals_3__2_AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_3__3_AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_3__4_AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_3__5_AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_3__6_AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_3__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_3__8_AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_3__9_AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_3__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_3__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F1200C8, /*#AfitBaseVals_3__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_3__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_3__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F120050, /*#AfitBaseVals_3__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_3__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*#AfitBaseVals_3__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_3__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*#AfitBaseVals_3__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*#AfitBaseVals_3__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120032, /*#AfitBaseVals_3__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_3__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_3__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F1200B4, /*#AfitBaseVals_3__24_ + AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_3__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F1200B4, /*#AfitBaseVals_3__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_3__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12002D, /*#AfitBaseVals_3__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F120019, /*#AfitBaseVals_3__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_3__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_3__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_3__32_ + AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_3__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_3__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*#AfitBaseVals_3__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_3__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_3__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_3__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_3__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_3__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_3__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_3__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_3__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120005, /*#AfitBaseVals_3__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120001, /*#AfitBaseVals_3__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_3__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*#AfitBaseVals_3__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*#AfitBaseVals_3__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_3__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_3__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_3__ + 54_AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*#AfitBaseVals_3__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128002, /*#AfitBaseVals_3__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120080, /*#AfitBaseVals_3__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_3__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_3__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_3__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_3__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*#AfitBaseVals_3__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*#AfitBaseVals_3__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*#AfitBaseVals_3__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122003, /*#AfitBaseVals_3__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A02, /*#AfitBaseVals_3__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120864, /*#AfitBaseVals_3__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*#AfitBaseVals_3__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*#AfitBaseVals_3__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F122814, /*#AfitBaseVals_3__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400A, /*#AfitBaseVals_3__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_3__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*#AfitBaseVals_3__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_3__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_3__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*#AfitBaseVals_3__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120D0F, /*#AfitBaseVals_3__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_3__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_3__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*#AfitBaseVals_3__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*#AfitBaseVals_3__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123208, /*#AfitBaseVals_3__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_3__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121450, /*#AfitBaseVals_3__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120A28, /*#AfitBaseVals_3__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_3__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_3__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F123C3C, /*#AfitBaseVals_3__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_3__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121E01, /*#AfitBaseVals_3__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12221C, /*#AfitBaseVals_3__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F12281E, /*#AfitBaseVals_3__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_3__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*#AfitBaseVals_3__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121402, /*#AfitBaseVals_3__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F12060E, /*#AfitBaseVals_3__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_3__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*#AfitBaseVals_3__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120C40, /*#AfitBaseVals_3__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F124015, /*#AfitBaseVals_3__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_3__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_3__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_4__0_AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_4__1_AFIT16_CONTRAST*/ + 0x0F120000, /*#AfitBaseVals_4__2_AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_4__3_AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_4__4_AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_4__5_AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_4__6_AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_4__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_4__8_AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_4__9_AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_4__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_4__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F120032, /*#AfitBaseVals_4__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F12028A, /*#AfitBaseVals_4__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120032, /*#AfitBaseVals_4__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F1201F4, /*#AfitBaseVals_4__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_4__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120002, /*#AfitBaseVals_4__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_4__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201AA, /*#AfitBaseVals_4__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F12003C, /*#AfitBaseVals_4__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120050, /*#AfitBaseVals_4__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_4__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_4__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F1200B4, /*#AfitBaseVals_4__24_ + AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_4__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F1200B4, /*#AfitBaseVals_4__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_4__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F120046, /*#AfitBaseVals_4__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F120019, /*#AfitBaseVals_4__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_4__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_4__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_4__32_ + AFIT8_sddd8a_sat_thr[7:0], AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F120503, /*#AfitBaseVals_4__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F12080F, /*#AfitBaseVals_4__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120808, /*#AfitBaseVals_4__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_4__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_4__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12022D, /*#AfitBaseVals_4__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_4__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_4__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_4__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12061E, /*#AfitBaseVals_4__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_4__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120606, /*#AfitBaseVals_4__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A03, /*#AfitBaseVals_4__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120028, /*#AfitBaseVals_4__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120002, /*#AfitBaseVals_4__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120001, /*#AfitBaseVals_4__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_4__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*#AfitBaseVals_4__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*#AfitBaseVals_4__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_4__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_4__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_4__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*#AfitBaseVals_4__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128001, /*#AfitBaseVals_4__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120080, /*#AfitBaseVals_4__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_4__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_4__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_4__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_4__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*#AfitBaseVals_4__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F121219, /*#AfitBaseVals_4__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12320D, /*#AfitBaseVals_4__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120A0A, /*#AfitBaseVals_4__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122304, /*#AfitBaseVals_4__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A08, /*#AfitBaseVals_4__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120832, /*#AfitBaseVals_4__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*#AfitBaseVals_4__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*#AfitBaseVals_4__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F122A0A, /*#AfitBaseVals_4__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F124006, /*#AfitBaseVals_4__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120604, /*#AfitBaseVals_4__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125006, /*#AfitBaseVals_4__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_4__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_4__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*#AfitBaseVals_4__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120D0F, /*#AfitBaseVals_4__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120A28, /*#AfitBaseVals_4__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F12040A, /*#AfitBaseVals_4__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120820, /*#AfitBaseVals_4__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F12280A, /*#AfitBaseVals_4__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123208, /*#AfitBaseVals_4__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_4__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A64, /*#AfitBaseVals_4__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F12062A, /*#AfitBaseVals_4__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_4__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120606, /*#AfitBaseVals_4__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F124646, /*#AfitBaseVals_4__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_4__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121801, /*#AfitBaseVals_4__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12191C, /*#AfitBaseVals_4__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122818, /*#AfitBaseVals_4__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_4__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*#AfitBaseVals_4__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121405, /*#AfitBaseVals_4__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F12050C, /*#AfitBaseVals_4__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_4__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*#AfitBaseVals_4__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F121440, /*#AfitBaseVals_4__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F124015, /*#AfitBaseVals_4__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_4__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_4__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + /* param_end TVAR_afit_pBaseVals*/ + /* param_start afit_pConstBaseVals*/ + 0x0F127DFA, /*#ConstAfitBaseVals Because of Edge, + disable the iGradientWide*/ + 0x0F12FFBD, /*#ConstAfitBaseVals_1_*/ + 0x0F1226FE, /*#ConstAfitBaseVals_2_*/ + 0x0F12F7BC, /*#ConstAfitBaseVals_3_*/ + 0x0F127E06, /*#ConstAfitBaseVals_4_*/ + 0x0F1200D3, /*#ConstAfitBaseVals_5_*/ + /* param_end afit_pConstBaseVals*/ + /* AFIT by Normalized Brightness Tuning parameter*/ + 0x002A3780, + 0x0F120000, /* on/off AFIT by NB option 0000 : Ni 0001:Nb*/ + 0x0F120014, /* NormBR[0]*/ + 0x002A3782, + 0x0F1200D2, /* NormBR[1]*/ + 0x002A3782, + 0x0F120384, /* NormBR[2]*/ + 0x002A3782, + 0x0F1207D0, /* NormBR[3]*/ + 0x002A3782, + 0x0F121388, /* NormBR[4]*/ +}; + + +/* Set-data based on Samsung Reliabilty Group standard +* ,when using WIFI. 15fps +*/ +static const u32 s5k5bbgx_vt_wifi_common[] = { + 0xFCFCD000, + /*===================================================================*/ + /* Reset*/ + /*===================================================================*/ + 0x00100001, /*sw_reset*/ + 0x10300000, /*contint_host_int*/ + 0x00140001, /*sw_load_complete-Release CORE (Arm) from reset state*/ + 0x01520084, /*make alive voltage low*/ + 0xFFFF000A, + /* Start of Patch data*/ + 0x00287000, + 0x002A2744, + 0x0F12B510, /* 70002744*/ + 0x0F124A12, /* 70002746*/ + 0x0F12217B, /* 70002748*/ + 0x0F124812, /* 7000274A*/ + 0x0F12C004, /* 7000274C*/ + 0x0F126001, /* 7000274E*/ + 0x0F124911, /* 70002750*/ + 0x0F124812, /* 70002752*/ + 0x0F12F000, /* 70002754*/ + 0x0F12F926, /* 70002756*/ + 0x0F124911, /* 70002758*/ + 0x0F124812, /* 7000275A*/ + 0x0F12F000, /* 7000275C*/ + 0x0F12F922, /* 7000275E*/ + 0x0F124911, /* 70002760*/ + 0x0F124812, /* 70002762*/ + 0x0F12F000, /* 70002764*/ + 0x0F12F91E, /* 70002766*/ + 0x0F124911, /* 70002768*/ + 0x0F124812, /* 7000276A*/ + 0x0F12F000, /* 7000276C*/ + 0x0F12F91A, /* 7000276E*/ + 0x0F124911, /* 70002770*/ + 0x0F124812, /* 70002772*/ + 0x0F12F000, /* 70002774*/ + 0x0F12F916, /* 70002776*/ + 0x0F124911, /* 70002778*/ + 0x0F124812, /* 7000277A*/ + 0x0F12F000, /* 7000277C*/ + 0x0F12F912, /* 7000277E*/ + 0x0F124911, /* 70002780*/ + 0x0F124812, /* 70002782*/ + 0x0F12F000, /* 70002784*/ + 0x0F12F90E, /* 70002786*/ + 0x0F12BC10, /* 70002788*/ + 0x0F12BC08, /* 7000278A*/ + 0x0F124718, /* 7000278C*/ + 0x0F120000, /* 7000278E*/ + 0x0F120000, /* 70002790*/ + 0x0F125BB1, /* 70002792*/ + 0x0F121770, /* 70002794*/ + 0x0F127000, /* 70002796*/ + 0x0F1227D1, /* 70002798*/ + 0x0F127000, /* 7000279A*/ + 0x0F12C0BB, /* 7000279C*/ + 0x0F120000, /* 7000279E*/ + 0x0F12280F, /* 700027A0*/ + 0x0F127000, /* 700027A2*/ + 0x0F123609, /* 700027A4*/ + 0x0F120000, /* 700027A6*/ + 0x0F122827, /* 700027A8*/ + 0x0F127000, /* 700027AA*/ + 0x0F1277C7, /* 700027AC*/ + 0x0F120000, /* 700027AE*/ + 0x0F1228B3, /* 700027B0*/ + 0x0F127000, /* 700027B2*/ + 0x0F12727D, /* 700027B4*/ + 0x0F120000, /* 700027B6*/ + 0x0F1228CD, /* 700027B8*/ + 0x0F127000, /* 700027BA*/ + 0x0F129919, /* 700027BC*/ + 0x0F120000, /* 700027BE*/ + 0x0F12290B, /* 700027C0*/ + 0x0F127000, /* 700027C2*/ + 0x0F121C63, /* 700027C4*/ + 0x0F120000, /* 700027C6*/ + 0x0F12296B, /* 700027C8*/ + 0x0F127000, /* 700027CA*/ + 0x0F1204CB, /* 700027CC*/ + 0x0F120000, /* 700027CE*/ + 0x0F12B4F0, /* 700027D0*/ + 0x0F126801, /* 700027D2*/ + 0x0F12468C, /* 700027D4*/ + 0x0F126846, /* 700027D6*/ + 0x0F122200, /* 700027D8*/ + 0x0F124968, /* 700027DA*/ + 0x0F122000, /* 700027DC*/ + 0x0F122724, /* 700027DE*/ + 0x0F124357, /* 700027E0*/ + 0x0F12183B, /* 700027E2*/ + 0x0F124664, /* 700027E4*/ + 0x0F125CE5, /* 700027E6*/ + 0x0F12005C, /* 700027E8*/ + 0x0F125B34, /* 700027EA*/ + 0x0F12072D, /* 700027EC*/ + 0x0F120F2D, /* 700027EE*/ + 0x0F12800D, /* 700027F0*/ + 0x0F12804C, /* 700027F2*/ + 0x0F12808B, /* 700027F4*/ + 0x0F122301, /* 700027F6*/ + 0x0F1280CB, /* 700027F8*/ + 0x0F122300, /* 700027FA*/ + 0x0F1280CB, /* 700027FC*/ + 0x0F121C40, /* 700027FE*/ + 0x0F122824, /* 70002800*/ + 0x0F12D3EE, /* 70002802*/ + 0x0F121C52, /* 70002804*/ + 0x0F122A04, /* 70002806*/ + 0x0F12D3E8, /* 70002808*/ + 0x0F12BCF0, /* 7000280A*/ + 0x0F124770, /* 7000280C*/ + 0x0F12B510, /* 7000280E*/ + 0x0F12F000, /* 70002810*/ + 0x0F12F8D0, /* 70002812*/ + 0x0F12485A, /* 70002814*/ + 0x0F127A81, /* 70002816*/ + 0x0F12485A, /* 70002818*/ + 0x0F126B00, /* 7000281A*/ + 0x0F12F000, /* 7000281C*/ + 0x0F12F8D2, /* 7000281E*/ + 0x0F12BC10, /* 70002820*/ + 0x0F12BC08, /* 70002822*/ + 0x0F124718, /* 70002824*/ + 0x0F12B5F8, /* 70002826*/ + 0x0F126805, /* 70002828*/ + 0x0F126844, /* 7000282A*/ + 0x0F124E56, /* 7000282C*/ + 0x0F128861, /* 7000282E*/ + 0x0F128AB0, /* 70002830*/ + 0x0F128A72, /* 70002832*/ + 0x0F122301, /* 70002834*/ + 0x0F124368, /* 70002836*/ + 0x0F121889, /* 70002838*/ + 0x0F1217C2, /* 7000283A*/ + 0x0F120E12, /* 7000283C*/ + 0x0F121810, /* 7000283E*/ + 0x0F121202, /* 70002840*/ + 0x0F128820, /* 70002842*/ + 0x0F12029B, /* 70002844*/ + 0x0F1218C0, /* 70002846*/ + 0x0F12F000, /* 70002848*/ + 0x0F12F8C4, /* 7000284A*/ + 0x0F129000, /* 7000284C*/ + 0x0F128AF6, /* 7000284E*/ + 0x0F124268, /* 70002850*/ + 0x0F12210A, /* 70002852*/ + 0x0F124370, /* 70002854*/ + 0x0F12F000, /* 70002856*/ + 0x0F12F8C5, /* 70002858*/ + 0x0F12436E, /* 7000285A*/ + 0x0F120007, /* 7000285C*/ + 0x0F12210A, /* 7000285E*/ + 0x0F120030, /* 70002860*/ + 0x0F12F000, /* 70002862*/ + 0x0F12F8BF, /* 70002864*/ + 0x0F129A00, /* 70002866*/ + 0x0F120039, /* 70002868*/ + 0x0F12F000, /* 7000286A*/ + 0x0F12F8C1, /* 7000286C*/ + 0x0F120002, /* 7000286E*/ + 0x0F128820, /* 70002870*/ + 0x0F121880, /* 70002872*/ + 0x0F128020, /* 70002874*/ + 0x0F124845, /* 70002876*/ + 0x0F1288C1, /* 70002878*/ + 0x0F124843, /* 7000287A*/ + 0x0F123820, /* 7000287C*/ + 0x0F128B40, /* 7000287E*/ + 0x0F124240, /* 70002880*/ + 0x0F124350, /* 70002882*/ + 0x0F12F000, /* 70002884*/ + 0x0F12F8AE, /* 70002886*/ + 0x0F128861, /* 70002888*/ + 0x0F121840, /* 7000288A*/ + 0x0F128060, /* 7000288C*/ + 0x0F12BCF8, /* 7000288E*/ + 0x0F12BC08, /* 70002890*/ + 0x0F124718, /* 70002892*/ + 0x0F12B570, /* 70002894*/ + 0x0F124C3C, /* 70002896*/ + 0x0F123C20, /* 70002898*/ + 0x0F128B20, /* 7000289A*/ + 0x0F12F000, /* 7000289C*/ + 0x0F12F8B0, /* 7000289E*/ + 0x0F124D3A, /* 700028A0*/ + 0x0F1280E8, /* 700028A2*/ + 0x0F128B60, /* 700028A4*/ + 0x0F12F000, /* 700028A6*/ + 0x0F12F8B3, /* 700028A8*/ + 0x0F128128, /* 700028AA*/ + 0x0F12BC70, /* 700028AC*/ + 0x0F12BC08, /* 700028AE*/ + 0x0F124718, /* 700028B0*/ + 0x0F12B510, /* 700028B2*/ + 0x0F124836, /* 700028B4*/ + 0x0F12214D, /* 700028B6*/ + 0x0F128201, /* 700028B8*/ + 0x0F122196, /* 700028BA*/ + 0x0F128281, /* 700028BC*/ + 0x0F12211D, /* 700028BE*/ + 0x0F128301, /* 700028C0*/ + 0x0F12F7FF, /* 700028C2*/ + 0x0F12FFE7, /* 700028C4*/ + 0x0F12F000, /* 700028C6*/ + 0x0F12F8AB, /* 700028C8*/ + 0x0F12E7A9, /* 700028CA*/ + 0x0F12B570, /* 700028CC*/ + 0x0F120004, /* 700028CE*/ + 0x0F126820, /* 700028D0*/ + 0x0F126865, /* 700028D2*/ + 0x0F12F000, /* 700028D4*/ + 0x0F12F8AC, /* 700028D6*/ + 0x0F120402, /* 700028D8*/ + 0x0F12482E, /* 700028DA*/ + 0x0F120C12, /* 700028DC*/ + 0x0F128142, /* 700028DE*/ + 0x0F12482D, /* 700028E0*/ + 0x0F128801, /* 700028E2*/ + 0x0F122900, /* 700028E4*/ + 0x0F12D008, /* 700028E6*/ + 0x0F12492C, /* 700028E8*/ + 0x0F12002B, /* 700028EA*/ + 0x0F126D8A, /* 700028EC*/ + 0x0F122105, /* 700028EE*/ + 0x0F121C80, /* 700028F0*/ + 0x0F12F000, /* 700028F2*/ + 0x0F12F8A5, /* 700028F4*/ + 0x0F126020, /* 700028F6*/ + 0x0F12E005, /* 700028F8*/ + 0x0F124829, /* 700028FA*/ + 0x0F12002B, /* 700028FC*/ + 0x0F122105, /* 700028FE*/ + 0x0F12F000, /* 70002900*/ + 0x0F12F89E, /* 70002902*/ + 0x0F126020, /* 70002904*/ + 0x0F126820, /* 70002906*/ + 0x0F12E7D0, /* 70002908*/ + 0x0F12B5F8, /* 7000290A*/ + 0x0F124923, /* 7000290C*/ + 0x0F122200, /* 7000290E*/ + 0x0F123160, /* 70002910*/ + 0x0F1283CA, /* 70002912*/ + 0x0F126800, /* 70002914*/ + 0x0F124669, /* 70002916*/ + 0x0F12F000, /* 70002918*/ + 0x0F12F89A, /* 7000291A*/ + 0x0F12466B, /* 7000291C*/ + 0x0F128818, /* 7000291E*/ + 0x0F12F000, /* 70002920*/ + 0x0F12F86E, /* 70002922*/ + 0x0F120005, /* 70002924*/ + 0x0F12466B, /* 70002926*/ + 0x0F128858, /* 70002928*/ + 0x0F12F000, /* 7000292A*/ + 0x0F12F871, /* 7000292C*/ + 0x0F120004, /* 7000292E*/ + 0x0F122101, /* 70002930*/ + 0x0F121928, /* 70002932*/ + 0x0F1202C9, /* 70002934*/ + 0x0F121A08, /* 70002936*/ + 0x0F120286, /* 70002938*/ + 0x0F120029, /* 7000293A*/ + 0x0F120030, /* 7000293C*/ + 0x0F12F000, /* 7000293E*/ + 0x0F12F88F, /* 70002940*/ + 0x0F120005, /* 70002942*/ + 0x0F122701, /* 70002944*/ + 0x0F1202BF, /* 70002946*/ + 0x0F120021, /* 70002948*/ + 0x0F120030, /* 7000294A*/ + 0x0F12F000, /* 7000294C*/ + 0x0F12F888, /* 7000294E*/ + 0x0F124912, /* 70002950*/ + 0x0F124A0E, /* 70002952*/ + 0x0F123140, /* 70002954*/ + 0x0F123AC0, /* 70002956*/ + 0x0F12800D, /* 70002958*/ + 0x0F128395, /* 7000295A*/ + 0x0F12804F, /* 7000295C*/ + 0x0F1283D7, /* 7000295E*/ + 0x0F128088, /* 70002960*/ + 0x0F120011, /* 70002962*/ + 0x0F123120, /* 70002964*/ + 0x0F128008, /* 70002966*/ + 0x0F12E791, /* 70002968*/ + 0x0F12B510, /* 7000296A*/ + 0x0F12480A, /* 7000296C*/ + 0x0F128980, /* 7000296E*/ + 0x0F122800, /* 70002970*/ + 0x0F12D001, /* 70002972*/ + 0x0F12F000, /* 70002974*/ + 0x0F12F87A, /* 70002976*/ + 0x0F12E752, /* 70002978*/ + 0x0F120000, /* 7000297A*/ + 0x0F124140, /* 7000297C*/ + 0x0F12D000, /* 7000297E*/ + 0x0F1219DC, /* 70002980*/ + 0x0F127000, /* 70002982*/ + 0x0F121B60, /* 70002984*/ + 0x0F127000, /* 70002986*/ + 0x0F120DD4, /* 70002988*/ + 0x0F127000, /* 7000298A*/ + 0x0F1222AC, /* 7000298C*/ + 0x0F127000, /* 7000298E*/ + 0x0F121E8C, /* 70002990*/ + 0x0F127000, /* 70002992*/ + 0x0F121A10, /* 70002994*/ + 0x0F127000, /* 70002996*/ + 0x0F123780, /* 70002998*/ + 0x0F127000, /* 7000299A*/ + 0x0F122384, /* 7000299C*/ + 0x0F127000, /* 7000299E*/ + 0x0F12065C, /* 700029A0*/ + 0x0F127000, /* 700029A2*/ + 0x0F124778, /* 700029A4*/ + 0x0F1246C0, /* 700029A6*/ + 0x0F12C000, /* 700029A8*/ + 0x0F12E59F, /* 700029AA*/ + 0x0F12FF1C, /* 700029AC*/ + 0x0F12E12F, /* 700029AE*/ + 0x0F12CE77, /* 700029B0*/ + 0x0F120000, /* 700029B2*/ + 0x0F124778, /* 700029B4*/ + 0x0F1246C0, /* 700029B6*/ + 0x0F12C000, /* 700029B8*/ + 0x0F12E59F, /* 700029BA*/ + 0x0F12FF1C, /* 700029BC*/ + 0x0F12E12F, /* 700029BE*/ + 0x0F123609, /* 700029C0*/ + 0x0F120000, /* 700029C2*/ + 0x0F124778, /* 700029C4*/ + 0x0F1246C0, /* 700029C6*/ + 0x0F12C000, /* 700029C8*/ + 0x0F12E59F, /* 700029CA*/ + 0x0F12FF1C, /* 700029CC*/ + 0x0F12E12F, /* 700029CE*/ + 0x0F129F91, /* 700029D0*/ + 0x0F120000, /* 700029D2*/ + 0x0F124778, /* 700029D4*/ + 0x0F1246C0, /* 700029D6*/ + 0x0F12C000, /* 700029D8*/ + 0x0F12E59F, /* 700029DA*/ + 0x0F12FF1C, /* 700029DC*/ + 0x0F12E12F, /* 700029DE*/ + 0x0F122AE3, /* 700029E0*/ + 0x0F120000, /* 700029E2*/ + 0x0F124778, /* 700029E4*/ + 0x0F1246C0, /* 700029E6*/ + 0x0F12F004, /* 700029E8*/ + 0x0F12E51F, /* 700029EA*/ + 0x0F12D1DC, /* 700029EC*/ + 0x0F120000, /* 700029EE*/ + 0x0F124778, /* 700029F0*/ + 0x0F1246C0, /* 700029F2*/ + 0x0F12C000, /* 700029F4*/ + 0x0F12E59F, /* 700029F6*/ + 0x0F12FF1C, /* 700029F8*/ + 0x0F12E12F, /* 700029FA*/ + 0x0F126869, /* 700029FC*/ + 0x0F120000, /* 700029FE*/ + 0x0F124778, /* 70002A00*/ + 0x0F1246C0, /* 70002A02*/ + 0x0F12C000, /* 70002A04*/ + 0x0F12E59F, /* 70002A06*/ + 0x0F12FF1C, /* 70002A08*/ + 0x0F12E12F, /* 70002A0A*/ + 0x0F1268BD, /* 70002A0C*/ + 0x0F120000, /* 70002A0E*/ + 0x0F124778, /* 70002A10*/ + 0x0F1246C0, /* 70002A12*/ + 0x0F12C000, /* 70002A14*/ + 0x0F12E59F, /* 70002A16*/ + 0x0F12FF1C, /* 70002A18*/ + 0x0F12E12F, /* 70002A1A*/ + 0x0F1268DB, /* 70002A1C*/ + 0x0F120000, /* 70002A1E*/ + 0x0F124778, /* 70002A20*/ + 0x0F1246C0, /* 70002A22*/ + 0x0F12C000, /* 70002A24*/ + 0x0F12E59F, /* 70002A26*/ + 0x0F12FF1C, /* 70002A28*/ + 0x0F12E12F, /* 70002A2A*/ + 0x0F1271B9, /* 70002A2C*/ + 0x0F120000, /* 70002A2E*/ + 0x0F124778, /* 70002A30*/ + 0x0F1246C0, /* 70002A32*/ + 0x0F12C000, /* 70002A34*/ + 0x0F12E59F, /* 70002A36*/ + 0x0F12FF1C, /* 70002A38*/ + 0x0F12E12F, /* 70002A3A*/ + 0x0F1298CD, /* 70002A3C*/ + 0x0F120000, /* 70002A3E*/ + 0x0F124778, /* 70002A40*/ + 0x0F1246C0, /* 70002A42*/ + 0x0F12C000, /* 70002A44*/ + 0x0F12E59F, /* 70002A46*/ + 0x0F12FF1C, /* 70002A48*/ + 0x0F12E12F, /* 70002A4A*/ + 0x0F12987F, /* 70002A4C*/ + 0x0F120000, /* 70002A4E*/ + 0x0F124778, /* 70002A50*/ + 0x0F1246C0, /* 70002A52*/ + 0x0F12C000, /* 70002A54*/ + 0x0F12E59F, /* 70002A56*/ + 0x0F12FF1C, /* 70002A58*/ + 0x0F12E12F, /* 70002A5A*/ + 0x0F121BC9, /* 70002A5C*/ + 0x0F120000, /* 70002A5E*/ + 0x0F124778, /* 70002A60*/ + 0x0F1246C0, /* 70002A62*/ + 0x0F12F004, /* 70002A64*/ + 0x0F12E51F, /* 70002A66*/ + 0x0F12D378, /* 70002A68*/ + 0x0F120000, /* 70002A6A*/ + 0x0F124778, /* 70002A6C*/ + 0x0F1246C0, /* 70002A6E*/ + 0x0F12C000, /* 70002A70*/ + 0x0F12E59F, /* 70002A72*/ + 0x0F12FF1C, /* 70002A74*/ + 0x0F12E12F, /* 70002A76*/ + 0x0F1204CB, /* 70002A78*/ + 0x0F120000, /* 70002A7A*/ + 0x002A378C, + 0x0F120000, /* On/off register bUseOTP*/ + 0x002A0DCC, + 0x0F120138, /*awbb_IntcR*/ + 0x0F12011C, /*awbb_IntcB*/ + /*===================================================================*/ + /*Analog & APS Control*/ + /*===================================================================*/ + 0x0028D000, + 0x002AF404, + 0x0F120038, /* aig_adc_sat[7:0] : 850mV, revised by Ana 20100524*/ + 0x0F120001, /* aig_ms[2:0] : revised by Ana 20100202*/ + 0x0F12000C, /* aig_sig_mx[5:0]*/ + 0x0F120006, /* aig_rst_mx[5:0]*/ + 0x0F120008, /* aig_rmp_option[3] SL_Low_PWR_SAVE On : + revised by Ana 20100204*/ + 0x002AF418, + 0x0F120003, /* aig_dbr_clk_sel[1:0] : revised by Ana 20100201*/ + 0x002AF41C, + 0x0F120140, /* aig_bist_sig_width_e[10:0]*/ + 0x0F120140, /* aig_bist_sig_width_o[10:0]*/ + 0x0F120066, /* aig_bist_sig_width_o[10:0]*/ + 0x0F120005, /* aig_pix_bias[3:0]*/ + 0x002AF426, + 0x0F1200D4, /* aig_clp_lvl[7:0]*/ + 0x002AF42A, + 0x0F120001, /* aig_ref_option[0] SL_Low_PWR_SAVE On : + revised by Ana 20100204*/ + 0x002AF430, + 0x0F120001, /* aig_pd_cp_rosc[0] : revised by Ana 20100201*/ + 0x0F120001, /* aig_pd_ncp_rosc[0] : revised by Ana 20100201*/ + 0x002AF43A, + 0x0F120000, /* aig_pd_fblv[0] : revised by Ana 20100203*/ + 0x002AF440, + 0x0F120044, /* aig_rosc_tune_ncp[7:4]*/ + /* aig_rosc_tune_cp[3:0]*/ + 0x002AF44A, + 0x0F120000, /* aig_fb_lv[1:0] : revised by Ana 20100204*/ + 0x002AF45C, + 0x0F120000, /* aig_dshut_en[0] : revised by APS 20100223*/ + 0x0F120000, /* aig_srx_en[0]*/ + 0x002AF462, + 0x0F120001, /* aig_pdb_atop[0]*/ + 0x002AF46E, + 0x0F121F02, /* aig_cds_test[15:0]*/ + 0x002AF474, + 0x0F12000E, /* aig_stx_gap[4:0]*/ + 0x002AE42E, + 0x0F120004, /* adlc_qec[2:0] : revised by Dithered L-ADLC Designer + 20100203*/ + 0x00287000, + 0x002A13E0, + 0x0F120000, /*700013E0 SRX OFF*/ + 0x002A13C8, + 0x0F120001, /*700013C8 AAC Enable*/ + 0x002A12D8, + 0x0F120464, /*700012d8*/ + 0x0F120468, /*700012da*/ + 0x002A12F6, + 0x0F120000, /*700012f6*/ + 0x002A13CC, + 0x0F121FC0, /* [12:0] : Write tuning value to E404 register*/ + 0x002A13EC, + 0x0F120001, + 0x002A184C, + 0x0F121EE1, + 0x0028D000, + 0x002A1000, + 0x0F120001, + 0x00287000, + 0x002A040E, + 0x0F120003, /*STBY TnP enable setting STBY TnP enable setting [0] + bit STBY enable,[1] bit STBY ø TnP ? on/off bit*/ + 0xFFFF000A, + /*H-Digital binning & V-PLA*/ + 0x002A1218, + 0x0F120002, /*subsampling number.*/ + 0x0F120002, /*subsampling number.*/ + 0x002A0C9A, + 0x0F120001, /* setot_bUseDigitalHbin 0 : do not use bin block*/ + /* 1 : use binning block*/ + 0x002A1438, + 0x0F12F468, /* senHal_TuneStr_AngTuneData1[0] : tuning register + setting.*/ + 0x0F120000, /* not use binninb block 0x0000 ,use binnin blcok + 0x0000*/ + 0x0F120008, /* not use binninb block 0x000A ,use binnin blcok + 0x0008*/ + 0x0F120006, /* not use binninb block 0x0005 , use binnin blcok + 0x0006*/ + 0x0F120000, /* 0x0000 , 0x0000*/ + 0xFFFF000A, + /* Backup Register*/ + 0x002A0416, + 0x0F12F400, + 0x0F120074, + 0x0F12E42E, + 0x0F120030, + /*clk Settings*/ + 0x00287000, + 0x002A00F4, + 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs 2 700000F4*/ + /*0x0F120000*/ /*REG_TC_IPRM_InClockMSBs 2 700000F6*/ + 0x002A0110, + 0x0F120003, /*REG_TC_IPRM_UseNPviClocks 2 70000110*/ + 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc 2 70000112*/ + /*SYSTEM CLOCK*/ + 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 2 70000114 + 35000Khz/4=HEX()*/ + 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0 2 70000116*/ + 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0 2 70000118*/ + 0x0F121117, /*1770 REG_TC_IPRM_OpClk4KHz_1 2 7000011A + 24000Khz/4*/ + 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1 2 7000011C + 36000khz/4 =2328hex*/ + 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1 2 7000011E*/ + 0x0F120BB8, /*REG_TC_IPRM_OpClk4KHz_2 2 70000120 + 12000Khz*/ + 0x0F1205DC, /*REG_TC_IPRM_MinOutRate4KHz_2 2 70000122*/ + 0x0F121770, /*REG_TC_IPRM_MaxOutRate4KHz_2 2 70000124*/ + 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated 2 70000126*/ + 0xFFFF0064, + 0x002A1218, + 0x0F120002, + /*===================================================================*/ + /*Preview0 1600x1200 system 32M PCLK 70M From APS*/ + /*===================================================================*/ + 0x002A0144, + 0x0F120640, + 0x0F1204B0, + 0x0F120000, + 0x0F120000, + /*Preview0 for 7.5~15fps*/ + 0x002A0170, + 0x0F120280, /*REG_0TC_PCFG_usWidth 2 70000170*/ + 0x0F1201e0, /*REG_0TC_PCFG_usHeight 2 70000172*/ + 0x0F120005, /*REG_0TC_PCFG_Format 2 70000174*/ + 0x0F12222E, /*REG_0TC_PCFG_usMaxOut4KHzRate 2 70000176*/ + 0x0F12222E, /*REG_0TC_PCFG_usMinOut4KHzRate 2 70000178*/ + 0x0F120042, /*REG_0TC_PCFG_PVIMask 2 7000017A*/ + 0x0F120010, /*REG_0TC_PCFG_OIFMask 2 7000017C*/ + 0x0F120001, /*REG_0TC_PCFG_uClockInd 2 7000017E*/ + 0x0F120002, /*REG_0TC_PCFG_usFrTimeType 2 70000180 + 0b : dynamic 01:fix not accurate 02b: fixed_Accurate*/ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType 2 70000182 + 1b: FR (bin) 2b: Quality (no-bin)*/ + 0x0F12029a, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 2 70000184 + max frame time : 30fps 014D 15fps 029a; a6a - + 3.75 fps; 0535 - 7.5FPS*/ + 0x0F12029A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 2 70000186*/ + 0x0F120000, /*REG_0TC_PCFG_bSmearOutput 2 70000188*/ + 0x0F120000, /*REG_0TC_PCFG_sSaturation 2 7000018A*/ + 0x0F120000, /*REG_0TC_PCFG_sSharpBlur 2 7000018C*/ + 0x0F120000, /*REG_0TC_PCFG_sColorTemp 2 7000018E*/ + 0x0F120000, /*REG_0TC_PCFG_uDeviceGammaIndex 2 70000190*/ + 0x0F120000, /*REG_0TC_PCFG_uPrevMirror 2 70000192*/ + 0x0F120000, /*REG_0TC_PCFG_uCaptureMirror 2 70000194*/ + 0x0F120000, /*REG_0TC_PCFG_uRotation 2 70000196*/ + /*Preview1 for fixed 15fps*/ + 0x0F120280, /*REG_1TC_PCFG_usWidth 2 70000198*/ + 0x0F1201e0, /*REG_1TC_PCFG_usHeight 2 7000019A*/ + 0x0F120005, /*REG_1TC_PCFG_Format 2 7000019C*/ + 0x0F12222E, /*REG_1TC_PCFG_usMaxOut4KHzRate 2 7000019E*/ + 0x0F12222E, /*REG_1TC_PCFG_usMinOut4KHzRate 2 700001A0*/ + 0x0F120042, /*REG_1TC_PCFG_PVIMask 2 700001A2*/ + 0x0F120010, /*REG_1TC_PCFG_OIFMask 2 700001A4*/ + 0x0F120001, /*REG_1TC_PCFG_uClockInd 2 700001A6*/ + 0x0F120000, /*REG_1TC_PCFG_usFrTimeType 2 700001A8*/ + 0x0F120001, /*REG_1TC_PCFG_FrRateQualityType 2 700001AA*/ + 0x0F12029A, /*REG_1TC_PCFG_usMaxFrTimeMsecMult10 2 700001AC*/ + 0x0F12029A, /*REG_1TC_PCFG_usMinFrTimeMsecMult10 2 700001AE*/ + 0x0F120000, /*REG_1TC_PCFG_bSmearOutput 2 700001B0*/ + 0x0F120000, /*REG_1TC_PCFG_sSaturation 2 700001B2*/ + 0x0F120000, /*REG_1TC_PCFG_sSharpBlur 2 700001B4*/ + 0x0F120000, /*REG_1TC_PCFG_sColorTemp 2 700001B6*/ + 0x0F120000, /*REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/ + 0x0F120000, /*REG_1TC_PCFG_uPrevMirror 2 700001BA*/ + 0x0F120000, /*REG_1TC_PCFG_uCaptureMirror 2 700001BC*/ + 0x0F120000, /*REG_1TC_PCFG_uRotation 2 700001BE*/ + /*Preview2 for nightshot*/ + 0x0F120320, /*REG_2TC_PCFG_usWidth 2 700001C0*/ + 0x0F120258, /*REG_2TC_PCFG_usHeight 2 700001C2*/ + 0x0F120005, /*REG_2TC_PCFG_Format 2 700001C4*/ + 0x0F12222E, /*REG_2TC_PCFG_usMaxOut4KHzRate 2 700001C6*/ + 0x0F12222E, /*REG_2TC_PCFG_usMinOut4KHzRate 2 700001C8*/ + 0x0F120042, /*REG_2TC_PCFG_PVIMask 2 700001CA*/ + 0x0F120010, /*REG_2TC_PCFG_OIFMask 2 700001CC*/ + 0x0F120000, /*REG_2TC_PCFG_uClockInd 2 700001CE*/ + 0x0F120000, /*REG_2TC_PCFG_usFrTimeType 2 700001D0*/ + 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 2 700001D2 + 1b: FR (bin) 2b: Quality (no-bin)*/ + 0x0F12014D, /*REG_2TC_PCFG_usMaxFrTimeMsecMult10 2 700001D4 + max frame time : 30fps 014D 15fps 029a; a6a - + 3.75 fps; 0535 - 7.5FPS*/ + 0x0F12014D, /*REG_2TC_PCFG_usMinFrTimeMsecMult10 2 700001D6*/ + 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/ + 0x0F120000, /*REG_2TC_PCFG_sSaturation 2 700001DA*/ + 0x0F120000, /*REG_2TC_PCFG_sSharpBlur 2 700001DC*/ + 0x0F120000, /*REG_2TC_PCFG_sColorTemp 2 700001DE*/ + 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/ + 0x0F120000, /*REG_2TC_PCFG_uPrevMirror 2 700001E2 + [0] : x [1]: Y [2] Stat X [3] Stat Y*/ + 0x0F120000, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/ + 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/ + 0x002A0238, + 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/ + 0x0F120640, /*REG_0TC_CCFG_usWidth 2 7000023A*/ + 0x0F1204B0, /*REG_0TC_CCFG_usHeight 2 7000023C*/ + 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/ + 0x0F12222E, /*REG_0TC_CCFG_usMaxOut4KHzRate 2 70000240*/ + 0x0F12222E, /*REG_0TC_CCFG_usMinOut4KHzRate 2 70000242*/ + 0x0F120042, /*REG_0TC_CCFG_PVIMask 2 70000244*/ + 0x0F120000, /*REG_0TC_CCFG_OIFMask 2 70000246*/ + 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/ + 0x0F120000, /*REG_0TC_CCFG_usFrTimeType 2 7000024A*/ + 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/ + 0x0F1205D0, /*REG_0TC_CCFG_usMaxFrTimeMsecMult10 2 7000024E*/ + 0x0F1204D0, /*REG_0TC_CCFG_usMinFrTimeMsecMult10 2 70000250*/ + 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/ + 0x0F120000, /*REG_0TC_CCFG_sSaturation 2 70000254*/ + 0x0F120000, /*REG_0TC_CCFG_sSharpBlur 2 70000256*/ + 0x0F120000, /*REG_0TC_CCFG_sColorTemp 2 70000258*/ + 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/ + 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/ + 0x0F120640, /*REG_1TC_CCFG_usWidth 2 7000025E*/ + 0x0F1204B0, /*REG_1TC_CCFG_usHeight 2 70000260*/ + 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/ + 0x0F12222E, /*REG_1TC_CCFG_usMaxOut4KHzRate 2 70000264*/ + 0x0F12222E, /*REG_1TC_CCFG_usMinOut4KHzRate 2 70000266*/ + 0x0F120042, /*REG_1TC_CCFG_PVIMask 2 70000268*/ + 0x0F120000, /*REG_1TC_CCFG_OIFMask 2 7000026A*/ + 0x0F120001, /*REG_1TC_CCFG_uClockInd 2 7000026C*/ + 0x0F120000, /*REG_1TC_CCFG_usFrTimeType 2 7000026E*/ + 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/ + 0x0F121388, /*REG_1TC_CCFG_usMaxFrTimeMsecMult10 2 70000272*/ + 0x0F121388, /*REG_1TC_CCFG_usMinFrTimeMsecMult10 2 70000274*/ + 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/ + 0x0F120000, /*REG_1TC_CCFG_sSaturation 2 70000278*/ + 0x0F120000, /*REG_1TC_CCFG_sSharpBlur 2 7000027A*/ + 0x0F120000, /*REG_1TC_CCFG_sColorTemp 2 7000027C*/ + 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/ + 0x002A1218, + 0x0F120002, + /*PREVIEW*/ + 0x002A0156, + 0x0F120001, + 0x002A015E, + 0x0F120000, + 0x002A015A, + 0x0F120001, + 0x002A0142, + 0x0F120001, + 0x002A0158, + 0x0F120001, + 0x002A0160, + 0x0F120001, + 0x002A013A, + 0x0F120001, + 0x0F120001, + 0xFFFF0064, + /*===================================================================*/ + /*AFC*/ + /*===================================================================*/ + /*Auto*/ + 0x00287000, + 0x002A0CC0, + 0x0F120001, /*AFC_Default60Hz 01:60hz 00:50Hz*/ + 0x002A0374, + 0x0F12067F, /*REG_TC_DBG_AutoAlgEnBits*/ + /*===================================================================*/ + /*Shading*/ + /*===================================================================*/ + /* TVAR_ash_pGAS_high*/ + 0x00287000, + 0x002A0AD8, + 0x0F120F00, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + /* TVAR_ash_pGAS_low*/ + 0x0F128608, + 0x0F12E960, + 0x0F120243, + 0x0F12128B, + 0x0F12F073, + 0x0F120270, + 0x0F12DF47, + 0x0F12F226, + 0x0F121A31, + 0x0F12DFDA, + 0x0F121200, + 0x0F1205A9, + 0x0F120F16, + 0x0F120F5E, + 0x0F12DF10, + 0x0F1225BF, + 0x0F12FCF0, + 0x0F12DE1B, + 0x0F12025B, + 0x0F12FA8B, + 0x0F12163B, + 0x0F12DF44, + 0x0F12FB2D, + 0x0F1230E6, + 0x0F12FE07, + 0x0F12F47C, + 0x0F1209F2, + 0x0F120AED, + 0x0F12FA09, + 0x0F12E70E, + 0x0F120158, + 0x0F121110, + 0x0F12E28C, + 0x0F120DFB, + 0x0F12074B, + 0x0F12FBE5, + 0x0F12961C, + 0x0F12E21A, + 0x0F120ADF, + 0x0F120A67, + 0x0F12F8A6, + 0x0F12FDC3, + 0x0F12D590, + 0x0F12FA69, + 0x0F1208D5, + 0x0F12F635, + 0x0F12057E, + 0x0F12043B, + 0x0F12155C, + 0x0F1200C6, + 0x0F12F042, + 0x0F12176A, + 0x0F12F818, + 0x0F12F1F3, + 0x0F12026F, + 0x0F1208F6, + 0x0F120CCF, + 0x0F12E42D, + 0x0F120A92, + 0x0F1210EC, + 0x0F12005F, + 0x0F12F02C, + 0x0F120672, + 0x0F1209BF, + 0x0F12F4B5, + 0x0F12FC22, + 0x0F12FD50, + 0x0F120C26, + 0x0F12EED3, + 0x0F1207C3, + 0x0F12080F, + 0x0F12F6CF, + 0x0F127A3B, + 0x0F12E9DC, + 0x0F12088E, + 0x0F1201C8, + 0x0F12043C, + 0x0F12F7E2, + 0x0F12E391, + 0x0F12F3C4, + 0x0F121422, + 0x0F12E845, + 0x0F120D16, + 0x0F1206CA, + 0x0F120DEB, + 0x0F121324, + 0x0F12E814, + 0x0F1216B7, + 0x0F1202AC, + 0x0F12DE4D, + 0x0F1201EA, + 0x0F12F0C2, + 0x0F120E06, + 0x0F12EC6D, + 0x0F12FDF0, + 0x0F122B46, + 0x0F120710, + 0x0F12F84C, + 0x0F120E52, + 0x0F120675, + 0x0F12F0D7, + 0x0F12ED40, + 0x0F12F3AD, + 0x0F12179A, + 0x0F12DE9B, + 0x0F1210BA, + 0x0F120825, + 0x0F12FE0A, + 0x0F1288E9, + 0x0F12E9E0, + 0x0F12043D, + 0x0F120A17, + 0x0F12FC21, + 0x0F12FB58, + 0x0F12DCE0, + 0x0F12F24C, + 0x0F121A19, + 0x0F12E011, + 0x0F1211A3, + 0x0F120649, + 0x0F120D04, + 0x0F120E15, + 0x0F12E112, + 0x0F1227BD, + 0x0F12F7AA, + 0x0F12E06A, + 0x0F120A16, + 0x0F12FD23, + 0x0F121226, + 0x0F12DA34, + 0x0F1207A4, + 0x0F122AD3, + 0x0F12FE27, + 0x0F12EE64, + 0x0F120CAD, + 0x0F1211C5, + 0x0F12EC55, + 0x0F12ED98, + 0x0F12F88A, + 0x0F121842, + 0x0F12E1D5, + 0x0F1208FD, + 0x0F120FB6, + 0x0F12F801, + 0x002A0378, + 0x0F120001, /*REG_TC_DBG_RelnitCmd*/ + /*===================================================================*/ + /*Shading - Alpha*/ + /*===================================================================*/ + 0x002A05E8, + 0x0F1200E4, /*TVAR_ash_AwbAshCord[0] 2 70000568*/ + 0x0F1200F0, /*TVAR_ash_AwbAshCord[1] 2 7000056A*/ + 0x0F120100, /*TVAR_ash_AwbAshCord[2] 2 7000056C*/ + 0x0F120120, /*TVAR_ash_AwbAshCord[3] 2 7000056E*/ + 0x0F120150, /*TVAR_ash_AwbAshCord[4] 2 70000570*/ + 0x0F120180, /*TVAR_ash_AwbAshCord[5] 2 70000572*/ + 0x0F1201A0, /*TVAR_ash_AwbAshCord[6] 2 70000574*/ + 0x0F124000, /*TVAR_ash_GASAlpha[0][1] 2 70000580*/ + 0x0F124000, /*TVAR_ash_GASAlpha[0][2] 2 70000582*/ + 0x0F124000, /*TVAR_ash_GASAlpha[0][3] 2 70000584*/ + 0x0F123800, /*TVAR_ash_GASAlpha[1][0] 2 70000586*/ + 0x0F124000, /*TVAR_ash_GASAlpha[1][1] 2 70000588*/ + 0x0F124000, /*TVAR_ash_GASAlpha[1][2] 2 7000058A*/ + 0x0F124000, /*TVAR_ash_GASAlpha[1][3] 2 7000058C*/ + 0x0F123800, /*TVAR_ash_GASAlpha[2][0] 2 7000058E*/ + 0x0F124000, /*TVAR_ash_GASAlpha[2][1] 2 70000590*/ + 0x0F124000, /*TVAR_ash_GASAlpha[2][2] 2 70000592*/ + 0x0F124000, /*TVAR_ash_GASAlpha[2][3] 2 70000594*/ + 0x0F123800, /*TVAR_ash_GASAlpha[3][0] 2 70000596*/ + 0x0F124000, /*TVAR_ash_GASAlpha[3][1] 2 70000598*/ + 0x0F124000, /*TVAR_ash_GASAlpha[3][2] 2 7000059A*/ + 0x0F124000, /*TVAR_ash_GASAlpha[3][3] 2 7000059C*/ + 0x0F123800, /*TVAR_ash_GASAlpha[4][0] 2 7000059E*/ + 0x0F124000, /*TVAR_ash_GASAlpha[4][1] 2 700005A0*/ + 0x0F124000, /*TVAR_ash_GASAlpha[4][2] 2 700005A2*/ + 0x0F124000, /*TVAR_ash_GASAlpha[4][3] 2 700005A4*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][0] 2 700005A6*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][1] 2 700005A8*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][2] 2 700005AA*/ + 0x0F124000, /*TVAR_ash_GASAlpha[5][3] 2 700005AC*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][0] 2 700005AE*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][1] 2 700005B0*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][2] 2 700005B2*/ + 0x0F124000, /*TVAR_ash_GASAlpha[6][3] 2 700005B4*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[0] 2 700005B6*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[1] 2 700005B8*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[2] 2 700005BA*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[3] 2 700005BC*/ + /*===================================================================*/ + /*Gamma*/ + /*===================================================================*/ + /* param_start SARR_usGammaLutRGBIndoor*/ + 0x002A0460, + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/ + /*===================================================================*/ + /*AE - shutter*/ + /*===================================================================*/ + /*AE_Target*/ + 0x002A10C0, + 0x0F120045, /*TVAR_ae_BrAve*/ + 0x002A10C6, + 0x0F12000F, /*ae_StatMode 2 70001046*/ + /*AE_state*/ + 0x002A03B2, + 0x0F12010E, /*#lt_uLimitHigh*/ + 0x0F1200F5, /*#lt_uLimitLow*/ + /*For 60Hz*/ + 0x002A03C4, + 0x0F123415, /*#lt_uMaxExp1*/ + 0x002A03C8, + 0x0F12681F, /*#lt_uMaxExp2*/ + 0x002A03CC, + 0x0F128227, /*#lt_uMaxExp3*/ + 0x002A03D0, + 0x0F120D40, /*C350 #lt_uMaxExp4*/ + 0x0F120003, /*0000 #lt_uMaxExp4*/ + 0x002A03D4, + 0x0F123415, /*#lt_uCapMaxExp1*/ + 0x002A03D8, + 0x0F12681F, /*#lt_uCapMaxExp2*/ + 0x002A03DC, + 0x0F128227, /*#lt_uCapMaxExp3*/ + 0x002A03E0, + 0x0F120D40, /*C350 #lt_uCapMaxExp4*/ + 0x0F120003, /*0000 #lt_uCapMaxExp4*/ + 0x002A03E4, + 0x0F1201C0, /*0230 #lt_uMaxAnGain1*/ + 0x0F1201D0, /*0260 #lt_uMaxAnGain2*/ + 0x0F1202D0, /*0380 #lt_uMaxAnGain3*/ + 0x0F120700, /*#lt_uMaxAnGain4*/ + 0x0F120100, /*#lt_uMaxDigGain*/ + 0x0F128000, /*#lt_uMaxTotGain Total-gain is limited by + #lt_uMaxTotGain*/ + 0x0F1201C0, /*#lt_uCapMaxAnGain1*/ + 0x0F1201D0, /*#lt_uCapMaxAnGain2*/ + 0x0F1202D0, /*#lt_uCapMaxAnGain3*/ + 0x0F120700, /*#lt_uCapMaxAnGain4*/ + 0x0F120100, /*#lt_uCapMaxDigGain*/ + 0x0F128000, /*#lt_uCapMaxTotGain Total-gain is limited by + #lt_uMaxTotGain*/ + /*===================================================================*/ + /*AE - Weights*/ + /*===================================================================*/ + 0x002A10CE, + 0x0F120000, /*ae_WeightTbl_16[0] 2 7000104E*/ + 0x0F120101, /*ae_WeightTbl_16[1] 2 70001050*/ + 0x0F120101, /*ae_WeightTbl_16[2] 2 70001052*/ + 0x0F120000, /*ae_WeightTbl_16[3] 2 70001054*/ + 0x0F120101, /*ae_WeightTbl_16[4] 2 70001056*/ + 0x0F120101, /*ae_WeightTbl_16[5] 2 70001058*/ + 0x0F120101, /*ae_WeightTbl_16[6] 2 7000105A*/ + 0x0F120101, /*ae_WeightTbl_16[7] 2 7000105C*/ + 0x0F120201, /*ae_WeightTbl_16[8] 2 7000105E*/ + 0x0F120303, /*ae_WeightTbl_16[9] 2 70001060*/ + 0x0F120303, /*ae_WeightTbl_16[10] 2 70001062*/ + 0x0F120102, /*ae_WeightTbl_16[11] 2 70001064*/ + 0x0F120201, /*ae_WeightTbl_16[12] 2 70001066*/ + 0x0F120403, /*ae_WeightTbl_16[13] 2 70001068*/ + 0x0F120304, /*ae_WeightTbl_16[14] 2 7000106A*/ + 0x0F120102, /*ae_WeightTbl_16[15] 2 7000106C*/ + 0x0F120201, /*ae_WeightTbl_16[16] 2 7000106E*/ + 0x0F120403, /*ae_WeightTbl_16[17] 2 70001070*/ + 0x0F120304, /*ae_WeightTbl_16[18] 2 70001072*/ + 0x0F120102, /*ae_WeightTbl_16[19] 2 70001074*/ + 0x0F120201, /*ae_WeightTbl_16[20] 2 70001076*/ + 0x0F120403, /*ae_WeightTbl_16[21] 2 70001078*/ + 0x0F120304, /*ae_WeightTbl_16[22] 2 7000107A*/ + 0x0F120102, /*ae_WeightTbl_16[23] 2 7000107C*/ + 0x0F120201, /*ae_WeightTbl_16[24] 2 7000107E*/ + 0x0F120303, /*ae_WeightTbl_16[25] 2 70001080*/ + 0x0F120303, /*ae_WeightTbl_16[26] 2 70001082*/ + 0x0F120102, /*ae_WeightTbl_16[27] 2 70001084*/ + 0x0F120201, /*ae_WeightTbl_16[28] 2 70001086*/ + 0x0F120202, /*ae_WeightTbl_16[29] 2 70001088*/ + 0x0F120202, /*ae_WeightTbl_16[30] 2 7000108A*/ + 0x0F120102, /*ae_WeightTbl_16[31] 2 7000108C*/ + /*===================================================================*/ + /*AWB-BASIC setting*/ + /*===================================================================*/ + 0x002A0DCC, + 0x0F120138, /*awbb_IntcR*/ + 0x0F12011C, /*awbb_IntcB*/ + 0x0F1202A7, /*awbb_GLocusR*/ + 0x0F120343, /*awbb_GLocusB*/ + 0x002A0DB4, + 0x0F12036C, /*awbb_CrclLowT_R_c*/ + 0x002A0DB8, + 0x0F12011D, /*awbb_CrclLowT_B_c*/ + 0x002A0DBC, + 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/ + 0x002A0DEC, + 0x0F1205F0, /*awbb_GamutWidthThr1*/ + 0x0F1201F4, /*awbb_GamutHeightThr1*/ + 0x0F12006C, /*awbb_GamutWidthThr2*/ + 0x0F120038, /*awbb_GamutHeightThr2*/ + 0x002A0DD8, + 0x0F12000C, /*awbb_MinNumOfFinalPatches*/ + 0x0F12001E, /*awbb_MinNumOfLowBrFinalPatches*/ + 0x0F120046, /*awbb_MinNumOfLowBr0_FinalPatches*/ + 0x002A22BA, + 0x0F120006, /* #Mon_AWB_ByPassMode [0]Outdoor [1]LowBr [2]LowTemp*/ + 0x002A0F7A, + 0x0F120000, /*awbb_RGainOff 2 70000EFA*/ + 0x0F120000, /*awbb_BGainOff 2 70000EFC*/ + 0x0F120000, /*awbb_GGainOff 2 70000EFE*/ + 0x0F1200C2, /*awbb_Alpha_Comp_Mode 2 70000F00*/ + 0x0F120002, /*awbb_Rpl_InvalidOutDoor 2 70000F02*/ + 0x0F120001, /*awbb_UseGrThrCorr 2 70000F04*/ + 0x0F1200E4, /*awbb_Use_Filters 2 70000F06*/ + 0x0F12053C, /*awbb_GainsInit[0] 2 70000F08*/ + 0x0F120400, /*awbb_GainsInit[1] 2 70000F0A*/ + 0x0F12055C, /*awbb_GainsInit[2] 2 70000F0C*/ + 0x0F12001E, /*awbb_WpFilterMinThr 2 70000F0E*/ + 0x0F120190, /*awbb_WpFilterMaxThr 2 70000F10*/ + 0x0F1200A0, /*awbb_WpFilterCoef 2 70000F12*/ + 0x0F120004, /*awbb_WpFilterSize 2 70000F14*/ + 0x0F120001, /*awbb_otp_disable 2 70000F16*/ + /*===================================================================*/ + /*AWB-Zone*/ + /*===================================================================*/ + /* param_start awbb_IndoorGrZones_m_BGrid*/ + 0x002A0CE0, + 0x0F1203F8, /*03B5 awbb_IndoorGrZones_m_BGrid[0]*/ + 0x0F120422, /*03DF awbb_IndoorGrZones_m_BGrid[1]*/ + 0x0F1203B4, /*032D awbb_IndoorGrZones_m_BGrid[2]*/ + 0x0F120408, /*03D5 awbb_IndoorGrZones_m_BGrid[3]*/ + 0x0F120370, /*0303 awbb_IndoorGrZones_m_BGrid[4]*/ + 0x0F1203EE, /*03BB awbb_IndoorGrZones_m_BGrid[5]*/ + 0x0F12032C, /*02DB awbb_IndoorGrZones_m_BGrid[6]*/ + 0x0F1203D4, /*0397 awbb_IndoorGrZones_m_BGrid[7]*/ + 0x0F120302, /*02B1 awbb_IndoorGrZones_m_BGrid[8]*/ + 0x0F1203BA, /*036B awbb_IndoorGrZones_m_BGrid[9]*/ + 0x0F1202DA, /*0289 awbb_IndoorGrZones_m_BGrid[10]*/ + 0x0F120374, /*0349 awbb_IndoorGrZones_m_BGrid[11]*/ + 0x0F1202B0, /*026F awbb_IndoorGrZones_m_BGrid[12]*/ + 0x0F120328, /*0329 awbb_IndoorGrZones_m_BGrid[13]*/ + 0x0F120288, /*0257 awbb_IndoorGrZones_m_BGrid[14]*/ + 0x0F120300, /*0309 awbb_IndoorGrZones_m_BGrid[15]*/ + 0x0F120270, /*0241 awbb_IndoorGrZones_m_BGrid[16]*/ + 0x0F1202DE, /*02DD awbb_IndoorGrZones_m_BGrid[17]*/ + 0x0F120258, /*0227 awbb_IndoorGrZones_m_BGrid[18]*/ + 0x0F1202BE, /*02C3 awbb_IndoorGrZones_m_BGrid[19]*/ + 0x0F120240, /*0213 awbb_IndoorGrZones_m_BGrid[20]*/ + 0x0F1202A0, /*02AF awbb_IndoorGrZones_m_BGrid[21]*/ + 0x0F120228, /*0209 awbb_IndoorGrZones_m_BGrid[22]*/ + 0x0F120296, /*0295 awbb_IndoorGrZones_m_BGrid[23]*/ + 0x0F120212, /*020D awbb_IndoorGrZones_m_BGrid[24]*/ + 0x0F120284, /*0285 awbb_IndoorGrZones_m_BGrid[25]*/ + 0x0F120208, /*0223 awbb_IndoorGrZones_m_BGrid[26]*/ + 0x0F120274, /*0261 awbb_IndoorGrZones_m_BGrid[27]*/ + 0x0F12020C, /*0000 awbb_IndoorGrZones_m_BGrid[28]*/ + 0x0F12026E, /*0000 awbb_IndoorGrZones_m_BGrid[29]*/ + 0x0F120222, /*0000 awbb_IndoorGrZones_m_BGrid[30]*/ + 0x0F120260, /*0000 awbb_IndoorGrZones_m_BGrid[31]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[32]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[33]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[34]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[35]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[36]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[37]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[38]*/ + 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[39]*/ + /* param_end awbb_IndoorGrZones_m_BGrid*/ + 0x0F120005, /*awbb_IndoorGrZones_m_Grid*/ + 0x002A0D38, + 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/ + /* param_start awbb_OutdoorGrZones_m_BGrid*/ + 0x002A0D3C, + 0x0F1202B8, /*029F awbb_OutdoorGrZones_m_BGrid[0]*/ + 0x0F1202F2, /*02CE awbb_OutdoorGrZones_m_BGrid[1]*/ + 0x0F12028E, /*0282 awbb_OutdoorGrZones_m_BGrid[2]*/ + 0x0F12030A, /*02DA awbb_OutdoorGrZones_m_BGrid[3]*/ + 0x0F12027A, /*026D awbb_OutdoorGrZones_m_BGrid[4]*/ + 0x0F12030A, /*02C2 awbb_OutdoorGrZones_m_BGrid[5]*/ + 0x0F120274, /*0256 awbb_OutdoorGrZones_m_BGrid[6]*/ + 0x0F1202FE, /*02A6 awbb_OutdoorGrZones_m_BGrid[7]*/ + 0x0F120282, /*026E awbb_OutdoorGrZones_m_BGrid[8]*/ + 0x0F1202DC, /*028A awbb_OutdoorGrZones_m_BGrid[9]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[10]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[11]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[12]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[13]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[14]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[15]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[16]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[17]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[18]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[19]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[20]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[21]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[22]*/ + 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[23]*/ + /* param_end awbb_OutdoorGrZones_m_BGrid*/ + 0x0F120005, /*awbb_OutdoorGrZones_m_Gri*/ + 0x002A0D70, + 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/ + 0x002A0D74, + 0x0F1201EB, /*awbb_OutdoorGrZones_m_Bof*/ + /* param_start awbb_LowBrGrZones_m_BGrid*/ + 0x002A0D78, + 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/ + 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/ + 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/ + 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/ + 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/ + 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/ + 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/ + 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/ + 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/ + 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/ + 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/ + 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/ + 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/ + 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/ + 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/ + 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/ + 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/ + 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/ + 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/ + 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/ + /* param_end awbb_LowBrGrZones_m_BGrid*/ + 0x0F120006, /*awbb_LowBrGrZones_m_GridS*/ + 0x002A0DB0, + 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/ + /*===================================================================*/ + /*AWB Scene Detection*/ + /*===================================================================*/ + 0x002A0E50, + 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B 2 70000DD0*/ + 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B 2 70000DD2*/ + 0x0F120E74, /*awbb_SCDetectionMap_SEC_SunnyNB 2 70000DD4*/ + 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB 2 70000DD6*/ + 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B 2 70000DD8*/ + 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone 2 70000DDA*/ + 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone 2 70000DDC*/ + 0x002A0E14, + 0x0F120000, /*#awbb_SCDetectionMap_SEC 0000 + WRITE 70000D94 + 0000 awbb_SCDetectionMap_SEC_SceneDetectionMap*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__2_ + WRITE 70000D96 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__4_ + WRITE 70000D98 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__1_ + WRITE 70000D9A 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__3_ + WRITE 70000D9C 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__0_ + WRITE 70000D9E 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__2_ + WRITE 70000DA0 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__4_ + WRITE 70000DA2 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__1_ + WRITE 70000DA4 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__3_ + WRITE 70000DA6 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__0_ + WRITE 70000DA8 0000*/ + 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__2_ + WRITE 70000DAA 0000*/ + 0x0F120500, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__4_ + WRITE 70000DAC 0500*/ + 0x0F125555, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__1_ + WRITE 70000DAE 5555*/ + 0x0F125455, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__3_ + WRITE 70000DB0 5455*/ + 0x0F12AA55, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__0_ + WRITE 70000DB2 AA55*/ + 0x0F12AAAA, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__2_ + WRITE 70000DB4 AAAA*/ + 0x0F12BF54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__4_ + WRITE 70000DB6 BF54*/ + 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__1_ + WRITE 70000DB8 FFFF*/ + 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__3_ + WRITE 70000DBA 54FE*/ + 0x0F12FF6F, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__0_ + WRITE 70000DBC FF6F*/ + 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__2_ + WRITE 70000DBE FEFF*/ + 0x0F121B54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__4_ + WRITE 70000DC0 1B54*/ + 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__1_ + WRITE 70000DC2 FFFF*/ + 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__3_ + WRITE 70000DC4 54FE*/ + 0x0F12FF06, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__0_ + WRITE 70000DC6 FF06*/ + 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__2_ + WRITE 70000DC8 FEFF*/ + 0x0F120154, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__4_ + WRITE 70000DCA 0154*/ + 0x0F12BFBF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__1_ + WRITE 70000DCC BFBF*/ + 0x0F1254BE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__3_ + WRITE 70000DCE 54BE*/ + 0x002A0F86, + 0x0F120074, /*E0 awbb_Use_Filters e4*/ + 0x002A0F8E, + 0x0F12001E, /*awbb_WpFilterMinThr 1e*/ + /*===================================================================*/ + /*AWB - GridCorrection*/ + /*===================================================================*/ + 0x002A0F98, + 0x0F120002, /*awbb_GridEnable 2 70000F18*/ + 0x002A0F60, + 0x0F1202E2, /*awbb_GridConst_1[0] 2 70000EE0*/ + 0x0F12034B, /*awbb_GridConst_1[1] 2 70000EE2*/ + 0x0F120399, /*awbb_GridConst_1[2] 2 70000EE4*/ + 0x0F12102D, /*awbb_GridConst_2[0] 2 70000EE6*/ + 0x0F1210DE, /*awbb_GridConst_2[1] 2 70000EE8*/ + 0x0F12116E, /*awbb_GridConst_2[2] 2 70000EEA*/ + 0x0F12117B, /*awbb_GridConst_2[3] 2 70000EEC*/ + 0x0F121206, /*awbb_GridConst_2[4] 2 70000EEE*/ + 0x0F12127F, /*awbb_GridConst_2[5] 2 70000EF0*/ + 0x0F1202C4, /*awbb_GridCoeff_R_1 2 70000EF2*/ + 0x0F1202E4, /*awbb_GridCoeff_B_1 2 70000EF4*/ + 0x0F1200C3, /*awbb_GridCoeff_R_2 2 70000EF6*/ + 0x0F1200A6, /*awbb_GridCoeff_B_2 2 70000EF8*/ + 0x002A0ED0, + 0x0F12000A, /*awbb_GridCorr_R[0][0] 2 70000ED0*/ + 0x0F120028, /*awbb_GridCorr_R[0][1] 2 70000ED2*/ + 0x0F120028, /*awbb_GridCorr_R[0][2] 2 70000ED4*/ + 0x0F12FFEC, /*awbb_GridCorr_R[0][3] 2 70000ED6*/ + 0x0F12FFEC, /*awbb_GridCorr_R[0][4] 2 70000ED8*/ + 0x0F12001E, /*awbb_GridCorr_R[0][5] 2 70000EDA*/ + 0x0F12000A, /*awbb_GridCorr_R[1][0] 2 70000EDC*/ + 0x0F120028, /*awbb_GridCorr_R[1][1] 2 70000EDE*/ + 0x0F120028, /*awbb_GridCorr_R[1][2] 2 70000EE0*/ + 0x0F12FFEC, /*awbb_GridCorr_R[1][3] 2 70000EE2*/ + 0x0F12FFEC, /*awbb_GridCorr_R[1][4] 2 70000EE4*/ + 0x0F12001E, /*awbb_GridCorr_R[1][5] 2 70000EE6*/ + 0x0F12000A, /*awbb_GridCorr_R[2][0] 2 70000EE8*/ + 0x0F120028, /*awbb_GridCorr_R[2][1] 2 70000EEA*/ + 0x0F120028, /*awbb_GridCorr_R[2][2] 2 70000EEC*/ + 0x0F12FFEC, /*awbb_GridCorr_R[2][3] 2 70000EEE*/ + 0x0F12FFEC, /*awbb_GridCorr_R[2][4] 2 70000EF0*/ + 0x0F12001E, /*awbb_GridCorr_R[2][5] 2 70000EF2*/ + 0x0F12FFD8, /*awbb_GridCorr_B[0][0] 2 70000EF4*/ + 0x0F12003C, /*awbb_GridCorr_B[0][1] 2 70000EF6*/ + 0x0F12003C, /*awbb_GridCorr_B[0][2] 2 70000EF8*/ + 0x0F120000, /*awbb_GridCorr_B[0][3] 2 70000EFA*/ + 0x0F120000, /*awbb_GridCorr_B[0][4] 2 70000EFC*/ + 0x0F12001E, /*awbb_GridCorr_B[0][5] 2 70000EFE*/ + 0x0F12FFD8, /*awbb_GridCorr_B[1][0] 2 70000F00*/ + 0x0F12003C, /*awbb_GridCorr_B[1][1] 2 70000F02*/ + 0x0F12003C, /*awbb_GridCorr_B[1][2] 2 70000F04*/ + 0x0F120000, /*awbb_GridCorr_B[1][3] 2 70000F06*/ + 0x0F120000, /*awbb_GridCorr_B[1][4] 2 70000F08*/ + 0x0F12001E, /*awbb_GridCorr_B[1][5] 2 70000F0A*/ + 0x0F12FFD8, /*awbb_GridCorr_B[2][0] 2 70000F0C*/ + 0x0F12003C, /*awbb_GridCorr_B[2][1] 2 70000F0E*/ + 0x0F12003C, /*awbb_GridCorr_B[2][2] 2 70000F10*/ + 0x0F120000, /*awbb_GridCorr_B[2][3] 2 70000F12*/ + 0x0F120000, /*awbb_GridCorr_B[2][4] 2 70000F14*/ + 0x0F12001E, /*awbb_GridCorr_B[2][5] 2 70000F16*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][0] 2 70000F18*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1] 2 70000F1A*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][2] 2 70000F1C*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][3] 2 70000F1E*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][4] 2 70000F20*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][5] 2 70000F22*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][0] 2 70000F24*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1] 2 70000F26*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][2] 2 70000F28*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][3] 2 70000F2A*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][4] 2 70000F2C*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][5] 2 70000F2E*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][0] 2 70000F30*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1] 2 70000F32*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][2] 2 70000F34*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][3] 2 70000F36*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][4] 2 70000F38*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][5] 2 70000F3A*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][0] 2 70000F3C*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1] 2 70000F3E*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][2] 2 70000F40*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][3] 2 70000F42*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][4] 2 70000F44*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][5] 2 70000F46*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][0] 2 70000F48*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1] 2 70000F4A*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][2] 2 70000F4C*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][3] 2 70000F4E*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][4] 2 70000F50*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][5] 2 70000F52*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][0] 2 70000F54*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1] 2 70000F56*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][2] 2 70000F58*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][3] 2 70000F5A*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][4] 2 70000F5C*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][5] 2 70000F5E*/ + /*===================================================================*/ + /*CCM*/ + /*===================================================================*/ + 0x002A05D2, + 0x0F1200E4, /*#SARR_AwbCcmCord 2 70000552*/ + 0x0F1200F0, /*#SARR_AwbCcmCord_1_ 2 70000554*/ + 0x0F120100, /*#SARR_AwbCcmCord_2_ 2 70000556*/ + 0x0F120120, /*#SARR_AwbCcmCord_3_ 2 70000558*/ + 0x0F120150, /*#SARR_AwbCcmCord_4_ 2 7000055A*/ + 0x0F120180, /*#SARR_AwbCcmCord_5_ 2 7000055C*/ + /* param_start TVAR_wbt_pBaseCcms*/ + 0x002A05C4, + 0x0F123800, + 0x0F127000, + 0x002A3800, + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[36]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[37]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[38]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[39]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[40]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[41]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[42]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[43]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[44]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[45]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[46]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[47]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[48]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[49]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[50]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[51]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[52]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[53]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[54]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[55]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[56]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[57]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[58]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[59]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[60]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[61]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[62]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[63]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[64]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[65]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[66]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[67]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[68]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[69]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[70]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[71]*/ + 0x0F1201BF, /*TVAR_wbt_pBaseCcms[72]*/ + 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[73]*/ + 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[74]*/ + 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[75]*/ + 0x0F1201B4, /*TVAR_wbt_pBaseCcms[76]*/ + 0x0F12FF66, /*TVAR_wbt_pBaseCcms[77]*/ + 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[78]*/ + 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[79]*/ + 0x0F12017B, /*TVAR_wbt_pBaseCcms[80]*/ + 0x0F120136, /*TVAR_wbt_pBaseCcms[81]*/ + 0x0F120132, /*TVAR_wbt_pBaseCcms[82]*/ + 0x0F12FF85, /*TVAR_wbt_pBaseCcms[83]*/ + 0x0F12018B, /*TVAR_wbt_pBaseCcms[84]*/ + 0x0F12FF73, /*TVAR_wbt_pBaseCcms[85]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[86]*/ + 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[87]*/ + 0x0F12015B, /*TVAR_wbt_pBaseCcms[88]*/ + 0x0F1200D0, /*TVAR_wbt_pBaseCcms[89]*/ + 0x0F1201BF, /*TVAR_wbt_pBaseCcms[90]*/ + 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[91]*/ + 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[92]*/ + 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[93]*/ + 0x0F1201B4, /*TVAR_wbt_pBaseCcms[94]*/ + 0x0F12FF66, /*TVAR_wbt_pBaseCcms[95]*/ + 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[96]*/ + 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[97]*/ + 0x0F12017B, /*TVAR_wbt_pBaseCcms[98]*/ + 0x0F120136, /*TVAR_wbt_pBaseCcms[99]*/ + 0x0F120132, /*TVAR_wbt_pBaseCcms[100]*/ + 0x0F12FF85, /*TVAR_wbt_pBaseCcms[101]*/ + 0x0F12018B, /*TVAR_wbt_pBaseCcms[102]*/ + 0x0F12FF73, /*TVAR_wbt_pBaseCcms[103]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[104]*/ + 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[105]*/ + 0x0F12015B, /*TVAR_wbt_pBaseCcms[106]*/ + 0x0F1200D0, /*TVAR_wbt_pBaseCcms[107]*/ + /* param_end TVAR_wbt_pBaseCcms*/ + /* param_start TVAR_wbt_pOutdoorCcm*/ + 0x002A05CC, + 0x0F1238D8, /*#TVAR_wbt_pOutdoorCcm*/ + 0x0F127000, + 0x002A38D8, + 0x0F120235, /*TVAR_wbt_pOutdoorCcm[0]*/ + 0x0F12FFEF, /*TVAR_wbt_pOutdoorCcm[1]*/ + 0x0F120014, /*TVAR_wbt_pOutdoorCcm[2]*/ + 0x0F12FF67, /*TVAR_wbt_pOutdoorCcm[3]*/ + 0x0F12027D, /*TVAR_wbt_pOutdoorCcm[4]*/ + 0x0F12FFBA, /*TVAR_wbt_pOutdoorCcm[5]*/ + 0x0F12000D, /*TVAR_wbt_pOutdoorCcm[6]*/ + 0x0F120062, /*TVAR_wbt_pOutdoorCcm[7]*/ + 0x0F1202A7, /*TVAR_wbt_pOutdoorCcm[8]*/ + 0x0F1200C9, /*TVAR_wbt_pOutdoorCcm[9]*/ + 0x0F120123, /*TVAR_wbt_pOutdoorCcm[10]*/ + 0x0F12FF36, /*TVAR_wbt_pOutdoorCcm[11]*/ + 0x0F1201AD, /*TVAR_wbt_pOutdoorCcm[12]*/ + 0x0F12FFC8, /*TVAR_wbt_pOutdoorCcm[13]*/ + 0x0F120202, /*TVAR_wbt_pOutdoorCcm[14]*/ + 0x0F12FFCF, /*TVAR_wbt_pOutdoorCcm[15]*/ + 0x0F120257, /*TVAR_wbt_pOutdoorCcm[16]*/ + 0x0F12022C, /*TVAR_wbt_pOutdoorCcm[17]*/ + /* param_end TVAR_wbt_pOutdoorCcm*/ + 0x002A2404, + 0x0F120001, /*#MVAR_AAIO_bFIT*/ + 0x002A2408, + 0x0F120001, /*#MVAR_AAIO_bAutoCCMandASH*/ + 0x002A23DC, + 0x0F1201DD, /*#Mon_AAIO_PrevFrmData_NormBr*/ + /*===================================================================*/ + /*AFIT*/ + /*===================================================================*/ + /* param_start afit_uNoiseIndInDoor*/ + 0x002A065C, + 0x0F12004A, /*#afit_uNoiseIndInDoor_0_*/ + 0x0F12005F, /*#afit_uNoiseIndInDoor_1_*/ + 0x0F1200CB, /*#afit_uNoiseIndInDoor_2_*/ + 0x0F1201E0, /*#afit_uNoiseIndInDoor_3_*/ + 0x0F120220, /*#afit_uNoiseIndInDoor_4_*/ + /* param_end afit_uNoiseIndInDoor*/ + /* param_start TVAR_afit_pBaseVals*/ + 0x002A06BC, + 0x0F120000, /*#AfitBaseVals AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_0__1_ AFIT16_CONTRAST*/ + 0x0F120014, /*#AfitBaseVals_0__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_0__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_0__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_0__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_0__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_0__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_0__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_0__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_0__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_0__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*#AfitBaseVals_0__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_0__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_0__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F12005A, /*#AfitBaseVals_0__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_0__16_AFIT16_demsharpmix1_iTune*/ + 0x0F12001E, /*#AfitBaseVals_0__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F12001E, /*#AfitBaseVals_0__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201F4, /*#AfitBaseVals_0__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*#AfitBaseVals_0__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120046, /*#AfitBaseVals_0__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120005, /*#AfitBaseVals_0__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120005, /*#AfitBaseVals_0__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F12003C, /*#AfitBaseVals_0__24_AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_0__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F12003C, /*#AfitBaseVals_0__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_0__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12003C, /*#AfitBaseVals_0__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F12001E, /*#AfitBaseVals_0__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_0__30_AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_0__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_0__32_ + AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_0__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_0__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F120A3B, /*#AfitBaseVals_0__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_0__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_0__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_0__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_0__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_0__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_0__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_0__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F12001E, /*#AfitBaseVals_0__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120002, /*#AfitBaseVals_0__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_0__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*#AfitBaseVals_0__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*#AfitBaseVals_0__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_0__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_0__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_0__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*#AfitBaseVals_0__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128003, /*#AfitBaseVals_0__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F121982, /*#AfitBaseVals_0__57_AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120A80, /*#AfitBaseVals_0__58_AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_0__59_AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__60_AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_0__61_AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F124601, /*#AfitBaseVals_0__62_AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F126444, /*#AfitBaseVals_0__63_AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F129650, /*#AfitBaseVals_0__64_AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*#AfitBaseVals_0__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F121E00, /*#AfitBaseVals_0__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120714, /*#AfitBaseVals_0__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121464, /*#AfitBaseVals_0__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121404, /*#AfitBaseVals_0__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F120F14, /*#AfitBaseVals_0__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_0__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_0__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F121403, /*#AfitBaseVals_0__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_0__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_0__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F124446, /*#AfitBaseVals_0__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F125064, /*#AfitBaseVals_0__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_0__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_0__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120000, /*#AfitBaseVals_0__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F12141E, /*#AfitBaseVals_0__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F126407, /*#AfitBaseVals_0__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120414, /*#AfitBaseVals_0__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_0__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_0__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_0__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121414, /*#AfitBaseVals_0__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_0__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F124601, /*#AfitBaseVals_0__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F126E44, /*#AfitBaseVals_0__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122864, /*#AfitBaseVals_0__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_0__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_0__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121E00, /*#AfitBaseVals_0__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F120714, /*#AfitBaseVals_0__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_0__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*#AfitBaseVals_0__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120F00, /*#AfitBaseVals_0__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_0__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_0__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_0__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_1__0_ AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_1__1_ AFIT16_CONTRAST*/ + 0x0F120014, /*#AfitBaseVals_1__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_1__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_1__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_1__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_1__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_1__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_1__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_1__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_1__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_1__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*#AfitBaseVals_1__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_1__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_1__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F12005A, /*#AfitBaseVals_1__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_1__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*#AfitBaseVals_1__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_1__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*#AfitBaseVals_1__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*#AfitBaseVals_1__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120046, /*#AfitBaseVals_1__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_1__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_1__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F120064, /*#AfitBaseVals_1__24_ + AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_1__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F120064, /*#AfitBaseVals_1__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_1__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12003C, /*#AfitBaseVals_1__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F12001E, /*#AfitBaseVals_1__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_1__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_1__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_1__32_ + AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_1__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_1__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*#AfitBaseVals_1__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_1__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_1__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_1__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_1__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_1__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_1__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_1__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_1__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120005, /*#AfitBaseVals_1__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120002, /*#AfitBaseVals_1__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_1__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*#AfitBaseVals_1__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*#AfitBaseVals_1__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_1__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_1__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_1__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*#AfitBaseVals_1__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128003, /*#AfitBaseVals_1__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120A6E, /*#AfitBaseVals_1__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_1__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_1__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_1__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_1__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F122801, /*#AfitBaseVals_1__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F12231E, /*#AfitBaseVals_1__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12961E, /*#AfitBaseVals_1__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_1__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*#AfitBaseVals_1__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A02, /*#AfitBaseVals_1__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120764, /*#AfitBaseVals_1__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F12143C, /*#AfitBaseVals_1__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121401, /*#AfitBaseVals_1__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F120F14, /*#AfitBaseVals_1__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_1__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_1__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*#AfitBaseVals_1__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_1__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_1__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F121E28, /*#AfitBaseVals_1__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12140F, /*#AfitBaseVals_1__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_1__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_1__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120200, /*#AfitBaseVals_1__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*#AfitBaseVals_1__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123C07, /*#AfitBaseVals_1__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_1__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121414, /*#AfitBaseVals_1__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_1__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_1__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_1__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121E1E, /*#AfitBaseVals_1__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_1__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F123C01, /*#AfitBaseVals_1__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F125A3A, /*#AfitBaseVals_1__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122858, /*#AfitBaseVals_1__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_1__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_1__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121E00, /*#AfitBaseVals_1__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F120714, /*#AfitBaseVals_1__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_1__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*#AfitBaseVals_1__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120F00, /*#AfitBaseVals_1__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_1__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_1__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_1__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_2__0_ AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_2__1_ AFIT16_CONTRAST*/ + 0x0F120000, /*#AfitBaseVals_2__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_2__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_2__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_2__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_2__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_2__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_2__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_2__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_2__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_2__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*#AfitBaseVals_2__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_2__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_2__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F12005A, /*#AfitBaseVals_2__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_2__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*#AfitBaseVals_2__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_2__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*#AfitBaseVals_2__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*#AfitBaseVals_2__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120032, /*#AfitBaseVals_2__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_2__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_2__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F1200B4, /*#AfitBaseVals_2__24_ + AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_2__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F1200B4, /*#AfitBaseVals_2__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_2__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12003C, /*#AfitBaseVals_2__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F12001E, /*#AfitBaseVals_2__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_2__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_2__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_2__32_ + AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_2__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_2__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*#AfitBaseVals_2__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_2__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_2__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_2__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_2__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_2__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_2__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_2__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_2__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120005, /*#AfitBaseVals_2__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120001, /*#AfitBaseVals_2__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_2__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*#AfitBaseVals_2__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*#AfitBaseVals_2__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_2__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_2__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_2__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*#AfitBaseVals_2__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128002, /*#AfitBaseVals_2__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120080, /*#AfitBaseVals_2__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_2__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_2__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_2__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_2__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*#AfitBaseVals_2__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*#AfitBaseVals_2__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*#AfitBaseVals_2__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_2__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122A03, /*#AfitBaseVals_2__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A02, /*#AfitBaseVals_2__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120864, /*#AfitBaseVals_2__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*#AfitBaseVals_2__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F129601, /*#AfitBaseVals_2__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F122814, /*#AfitBaseVals_2__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400A, /*#AfitBaseVals_2__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_2__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*#AfitBaseVals_2__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_2__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_2__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*#AfitBaseVals_2__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120D0F, /*#AfitBaseVals_2__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_2__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_2__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*#AfitBaseVals_2__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*#AfitBaseVals_2__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123208, /*#AfitBaseVals_2__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_2__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121450, /*#AfitBaseVals_2__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120A28, /*#AfitBaseVals_2__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_2__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_2__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F122828, /*#AfitBaseVals_2__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_2__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F122401, /*#AfitBaseVals_2__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F123622, /*#AfitBaseVals_2__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122832, /*#AfitBaseVals_2__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_2__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121003, /*#AfitBaseVals_2__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121E04, /*#AfitBaseVals_2__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F120714, /*#AfitBaseVals_2__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_2__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125004, /*#AfitBaseVals_2__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120F40, /*#AfitBaseVals_2__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F12400F, /*#AfitBaseVals_2__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_2__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_2__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_3__0_ AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_3__1_ AFIT16_CONTRAST*/ + 0x0F120000, /*#AfitBaseVals_3__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_3__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_3__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_3__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_3__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_3__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_3__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_3__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_3__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_3__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F1200C8, /*#AfitBaseVals_3__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*#AfitBaseVals_3__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*#AfitBaseVals_3__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F120050, /*#AfitBaseVals_3__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_3__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*#AfitBaseVals_3__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_3__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*#AfitBaseVals_3__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*#AfitBaseVals_3__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120032, /*#AfitBaseVals_3__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_3__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_3__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F1200B4, /*#AfitBaseVals_3__24_ + AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_3__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F1200B4, /*#AfitBaseVals_3__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_3__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F12002D, /*#AfitBaseVals_3__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F120019, /*#AfitBaseVals_3__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_3__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_3__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_3__32_ + AFIT8_sddd8a_sat_thr[7:0],AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*#AfitBaseVals_3__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_3__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*#AfitBaseVals_3__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_3__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_3__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_3__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*#AfitBaseVals_3__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_3__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*#AfitBaseVals_3__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_3__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*#AfitBaseVals_3__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120005, /*#AfitBaseVals_3__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120001, /*#AfitBaseVals_3__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_3__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*#AfitBaseVals_3__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*#AfitBaseVals_3__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_3__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_3__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_3__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*#AfitBaseVals_3__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128002, /*#AfitBaseVals_3__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120080, /*#AfitBaseVals_3__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_3__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_3__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_3__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_3__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*#AfitBaseVals_3__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*#AfitBaseVals_3__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*#AfitBaseVals_3__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*#AfitBaseVals_3__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122003, /*#AfitBaseVals_3__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A02, /*#AfitBaseVals_3__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120864, /*#AfitBaseVals_3__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*#AfitBaseVals_3__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*#AfitBaseVals_3__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F122814, /*#AfitBaseVals_3__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F12400A, /*#AfitBaseVals_3__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*#AfitBaseVals_3__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*#AfitBaseVals_3__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_3__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_3__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*#AfitBaseVals_3__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120D0F, /*#AfitBaseVals_3__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*#AfitBaseVals_3__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*#AfitBaseVals_3__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*#AfitBaseVals_3__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*#AfitBaseVals_3__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123208, /*#AfitBaseVals_3__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_3__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F121450, /*#AfitBaseVals_3__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F120A28, /*#AfitBaseVals_3__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_3__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120302, /*#AfitBaseVals_3__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F123C3C, /*#AfitBaseVals_3__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_3__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121E01, /*#AfitBaseVals_3__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12221C, /*#AfitBaseVals_3__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F12281E, /*#AfitBaseVals_3__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_3__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*#AfitBaseVals_3__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121402, /*#AfitBaseVals_3__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F12060E, /*#AfitBaseVals_3__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_3__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*#AfitBaseVals_3__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F120C40, /*#AfitBaseVals_3__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F124015, /*#AfitBaseVals_3__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_3__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_3__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*#AfitBaseVals_4__0_ AFIT16_BRIGHTNESS*/ + 0x0F120000, /*#AfitBaseVals_4__1_ AFIT16_CONTRAST*/ + 0x0F120000, /*#AfitBaseVals_4__2_ AFIT16_SATURATION*/ + 0x0F120000, /*#AfitBaseVals_4__3_ AFIT16_SHARP_BLUR*/ + 0x0F120000, /*#AfitBaseVals_4__4_ AFIT16_GLAMOUR*/ + 0x0F1200C1, /*#AfitBaseVals_4__5_ AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*#AfitBaseVals_4__6_ AFIT16_Demosaicing_iSatVal*/ + 0x0F12009C, /*#AfitBaseVals_4__7_ + AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*#AfitBaseVals_4__8_ AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*#AfitBaseVals_4__9_ AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*#AfitBaseVals_4__10_ + AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*#AfitBaseVals_4__11_ + AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F120032, /*#AfitBaseVals_4__12_AFIT16_demsharpmix1_iLowBright*/ + 0x0F12028A, /*#AfitBaseVals_4__13_AFIT16_demsharpmix1_iHighBright*/ + 0x0F120032, /*#AfitBaseVals_4__14_AFIT16_demsharpmix1_iLowSat*/ + 0x0F1201F4, /*#AfitBaseVals_4__15_AFIT16_demsharpmix1_iHighSat*/ + 0x0F120070, /*#AfitBaseVals_4__16_AFIT16_demsharpmix1_iTune*/ + 0x0F120002, /*#AfitBaseVals_4__17_AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*#AfitBaseVals_4__18_AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201AA, /*#AfitBaseVals_4__19_AFIT16_demsharpmix1_iHystCenter*/ + 0x0F12003C, /*#AfitBaseVals_4__20_ + AFIT16_YUV422_DENOISE_iUVLowThresh*/ + 0x0F120050, /*#AfitBaseVals_4__21_ + AFIT16_YUV422_DENOISE_iUVHighThresh*/ + 0x0F120000, /*#AfitBaseVals_4__22_ + AFIT16_YUV422_DENOISE_iYLowThresh*/ + 0x0F120000, /*#AfitBaseVals_4__23_ + AFIT16_YUV422_DENOISE_iYHighThresh*/ + 0x0F1200B4, /*#AfitBaseVals_4__24_ + AFIT16_Sharpening_iLowSharpClamp*/ + 0x0F120014, /*#AfitBaseVals_4__25_ + AFIT16_Sharpening_iHighSharpClamp*/ + 0x0F1200B4, /*#AfitBaseVals_4__26_ + AFIT16_Sharpening_iLowSharpClamp_Bin*/ + 0x0F120014, /*#AfitBaseVals_4__27_ + AFIT16_Sharpening_iHighSharpClamp_Bin*/ + 0x0F120046, /*#AfitBaseVals_4__28_ + AFIT16_Sharpening_iLowSharpClamp_sBin*/ + 0x0F120019, /*#AfitBaseVals_4__29_ + AFIT16_Sharpening_iHighSharpClamp_sBin*/ + 0x0F120A24, /*#AfitBaseVals_4__30_ + AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*#AfitBaseVals_4__31_ + AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*#AfitBaseVals_4__32_ + AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F120503, /*#AfitBaseVals_4__33_ + AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/ + 0x0F12080F, /*#AfitBaseVals_4__34_ + AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120808, /*#AfitBaseVals_4__35_ + AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*#AfitBaseVals_4__36_ + AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_4__37_ + AFIT8_sddd8a_iSatSat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12022D, /*#AfitBaseVals_4__38_ + AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*#AfitBaseVals_4__39_ + AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/ + 0x0F120301, /*#AfitBaseVals_4__40_ + AFIT8_sddd8a_iLowSlopeThresh[7:0], + AFIT8_sddd8a_iHighSlopeThresh [15:8]*/ + 0x0F12FF07, /*#AfitBaseVals_4__41_ + AFIT8_sddd8a_iSquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12061E, /*#AfitBaseVals_4__42_ + AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*#AfitBaseVals_4__43_ + AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120606, /*#AfitBaseVals_4__44_ + AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A03, /*#AfitBaseVals_4__45_ + AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120028, /*#AfitBaseVals_4__46_ + AFIT8_Sharpening_iMSharpen [7:0], + AFIT8_Sharpening_iMShThresh [15:8]*/ + 0x0F120002, /*#AfitBaseVals_4__47_ + AFIT8_Sharpening_iWSharpen [7:0], + AFIT8_Sharpening_iWShThresh [15:8]*/ + 0x0F120001, /*#AfitBaseVals_4__48_ + AFIT8_Sharpening_nSharpWidth [7:0], + AFIT8_Sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*#AfitBaseVals_4__49_ + AFIT8_Sharpening_iShDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*#AfitBaseVals_4__50_ + AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*#AfitBaseVals_4__51_ + AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*#AfitBaseVals_4__52_ + AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*#AfitBaseVals_4__53_ + AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*#AfitBaseVals_4__54_ + AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*#AfitBaseVals_4__55_ + AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/ + 0x0F128001, /*#AfitBaseVals_4__56_ + AFIT8_YUV422_DENOISE_iYSupport [7:0], + AFIT8_byr_cgras_iShadingPower [15:8]*/ + 0x0F120080, /*#AfitBaseVals_4__57_ + AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*#AfitBaseVals_4__58_ + AFIT8_ccm_oscar_iSaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*#AfitBaseVals_4__59_ + AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_iSaturation [15:8]*/ + 0x0F125050, /*#AfitBaseVals_4__60_ + AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*#AfitBaseVals_4__61_ + AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*#AfitBaseVals_4__62_ + AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F121219, /*#AfitBaseVals_4__63_ + AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12320D, /*#AfitBaseVals_4__64_ + AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120A0A, /*#AfitBaseVals_4__65_ + AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122304, /*#AfitBaseVals_4__66_ + AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemSharpenLow [15:8]*/ + 0x0F120A08, /*#AfitBaseVals_4__67_ + AFIT8_Demosaicing_iDemSharpenHigh[7:0], + AFIT8_Demosaicing_iDemSharpThresh [15:8]*/ + 0x0F120832, /*#AfitBaseVals_4__68_ + AFIT8_Demosaicing_iDemShLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*#AfitBaseVals_4__69_ + AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*#AfitBaseVals_4__70_ + AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_Sharpening_iLowSharpPower [15:8]*/ + 0x0F122A0A, /*#AfitBaseVals_4__71_ + AFIT8_Sharpening_iHighSharpPower[7:0], + AFIT8_Sharpening_iLowShDenoise [15:8]*/ + 0x0F124006, /*#AfitBaseVals_4__72_ + AFIT8_Sharpening_iHighShDenoise [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120604, /*#AfitBaseVals_4__73_ + AFIT8_Sharpening_iReduceEdgeSlope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125006, /*#AfitBaseVals_4__74_ + AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*#AfitBaseVals_4__75_ + AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_4__76_ + AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*#AfitBaseVals_4__77_ + AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120D0F, /*#AfitBaseVals_4__78_ + AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120A28, /*#AfitBaseVals_4__79_ + AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F12040A, /*#AfitBaseVals_4__80_ + AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120820, /*#AfitBaseVals_4__81_ + AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/ + 0x0F12280A, /*#AfitBaseVals_4__82_ + AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/ + 0x0F123208, /*#AfitBaseVals_4__83_ + AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*#AfitBaseVals_4__84_ + AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A64, /*#AfitBaseVals_4__85_ + AFIT8_Sharpening_iLowSharpPower_Bin [7:0], + AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/ + 0x0F12062A, /*#AfitBaseVals_4__86_ + AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/ + 0x0F120440, /*#AfitBaseVals_4__87_ + AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/ + 0x0F120606, /*#AfitBaseVals_4__88_ + AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F124646, /*#AfitBaseVals_4__89_ + AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*#AfitBaseVals_4__90_ + AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121801, /*#AfitBaseVals_4__91_ + AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12191C, /*#AfitBaseVals_4__92_ + AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122818, /*#AfitBaseVals_4__93_ + AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*#AfitBaseVals_4__94_ + AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*#AfitBaseVals_4__95_ + AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/ + 0x0F121405, /*#AfitBaseVals_4__96_ + AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/ + 0x0F12050C, /*#AfitBaseVals_4__97_ + AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*#AfitBaseVals_4__98_ + AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*#AfitBaseVals_4__99_ + AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/ + 0x0F121440, /*#AfitBaseVals_4__100_ + AFIT8_Sharpening_iHighSharpPower_sBin [7:0], + AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/ + 0x0F124015, /*#AfitBaseVals_4__101_ + AFIT8_Sharpening_iHighShDenoise_sBin [7:0], + AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*#AfitBaseVals_4__102_ + AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*#AfitBaseVals_4__103_ + AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + /* param_end TVAR_afit_pBaseVals*/ + /* param_start afit_pConstBaseVals*/ + 0x0F127DFA, /*#ConstAfitBaseVals Because of Edge, + disable the iGradientWide*/ + 0x0F12FFBD, /*#ConstAfitBaseVals_1_*/ + 0x0F1226FE, /*#ConstAfitBaseVals_2_*/ + 0x0F12F7BC, /*#ConstAfitBaseVals_3_*/ + 0x0F127E06, /*#ConstAfitBaseVals_4_*/ + 0x0F1200D3, /*#ConstAfitBaseVals_5_*/ + /* param_end afit_pConstBaseVals*/ + /* AFIT by Normalized Brightness Tuning parameter*/ + 0x002A3780, + 0x0F120000, /* on/off AFIT by NB option 0000 : Ni 0001:Nb*/ + 0x0F120014, /* NormBR[0]*/ + 0x002A3782, + 0x0F1200D2, /* NormBR[1]*/ + 0x002A3782, + 0x0F120384, /* NormBR[2]*/ + 0x002A3782, + 0x0F1207D0, /* NormBR[3]*/ + 0x002A3782, + 0x0F121388, /* NormBR[4]*/ + +}; + +/*=========================================== +* CAMERA_PREVIEW - ? ? * +============================================*/ + +static const u32 s5k5bbgx_preview[] = { + /*PREVIEW*/ + 0xFCFCD000, + 0x00287000, + 0x002A0156, /*#REG_TC_GP_ActivePrevConfig*/ + 0x0F120000, + 0x002A015E, /*#REG_TC_GP_ActiveCapConfig*/ + 0x0F120000, + 0x002A015A, /*#REG_TC_GP_PrevOpenAfterChange*/ + 0x0F120001, + 0x002A0142, /*#REG_TC_GP_NewConfigSync*/ + 0x0F120001, + 0x002A0158, /*#REG_TC_GP_PrevConfigChanged*/ + 0x0F120001, + 0x002A0160, /*#REG_TC_GP_CapConfigChanged*/ + 0x0F120001, + 0x002A013A, /*#REG_TC_GP_EnablePreview*/ + 0x0F120001, + 0x002A013C, /*#REG_TC_GP_EnablePreviewChanged*/ + 0x0F120001, + 0xffff0096, /* 150ms */ +}; + +/*=========================================== +* CAMERA_SNAPSHOT - ? * +============================================*/ + +static const u32 s5k5bbgx_capture[] = { + /*Capture*/ + 0xFCFCD000, + 0x00287000, + 0x002A015E, /*#REG_TC_GP_ActiveCapConfig*/ + 0x0F120000, + 0x002A0142, /*#REG_TC_GP_NewConfigSync*/ + 0x0F120001, + 0x002A0160, /*#REG_TC_GP_CapConfigChanged*/ + 0x0F120001, + 0x002A013E, /*#REG_TC_GP_EnableCapture*/ + 0x0F120001, + 0x002A0140, /*#REG_TC_GP_EnableCaptureChanged*/ + 0x0F120001, + 0xffff0096, /* 150ms */ +}; + +static const u32 s5k5bbgx_mode_check_capture_staus[] = { + 0x002C7000, + 0x002E0142, +}; + +static const u32 s5k5bbgx_recording_common[] = { + 0xFCFCD000, + 0x00100001, /*S/W Reset*/ + 0x10300000, /*contint_host_int*/ + 0x00140001, /*sw_load_complete - Release CORE (Arm) from reset state*/ + 0xFFFF000A, + + /*0x0028D000,*/ /*Driving Current*/ + /*0x002A1082,*/ + /*0x0F1203ff,*/ /*cregs_d0_d4_cd10 D4[9:8], D3[7:6], D2[5:4], + D1[3:2], D0[1:0]*/ + /*0x002A1084,*/ + /*0x0F1203ff,*/ /*cregs_d5_d9_cd10 D9[9:8], D8[7:6], D7[5:4], + D6[3:2], D5[1:0]*/ + /*0x002A1088,*/ + /*0x0F120fcf,*/ /*cregs_clks_output_cd10 SDA[11:10], SCL[9:8], + PCLK[7:6], VSYNC[3:2], HSYNC[1:0]*/ + + 0x0028D000, + 0x002AF404, + 0x0F120038, /*aig_adc_sat[7:0] : 850mV*/ + 0x0F120001, /*ms[2:0]; 2h@Normal, 2h@PLA, 1h@CNT.AVG*/ + 0x0F12000C, /*aig_sig_mx[5:0]*/ + 0x0F120006, /*aig_rst_mx[5:0]*/ + 0x0F120008, /*rmp_option[7:0]; [3]SL_Low_PWR_SAVE On*/ + 0x002AF418, + 0x0F120003, /*aig_dbr_clk_sel[1:0]*/ + 0x002AF41C, + 0x0F120140, /*aig_bist_sig_width_e[10:0]*/ + 0x0F120140, /*aig_bist_sig_width_o[10:0]*/ + 0x0F120066, /*aig_bist_sig_width_o[10:0]*/ + 0x0F120005, /*aig_pix_bias[3:0]*/ + 0x002AF426, + 0x0F1200D4, /*aig_clp_lvl[7:0]*/ + 0x002AF42A, + 0x0F120001, /*aig_ref_option[0] SL_Low_PWR_SAVE On*/ + 0x002AF430, + 0x0F120001, /*aig_pd_cp_rosc[0]*/ + 0x0F120001, /*aig_pd_ncp_rosc[0]*/ + 0x002AF43A, + 0x0F120000, /*aig_pd_fblv[0]*/ + 0x002AF440, + 0x0F120044, /*aig_rosc_tune_ncp[7:4] aig_rosc_tune_cp[3:0]*/ + 0x002AF44A, + 0x0F120000, /*aig_fb_lv[1:0]*/ + 0x002AF45C, + 0x0F120000, /*aig_dshut_en[0]*/ + 0x0F120000, /*aig_srx_en[0]*/ + 0x002AF462, + 0x0F120001, /*aig_pdb_atop[0]*/ + 0x002AF46E, + 0x0F121F02, /*aig_cds_test[15:0]*/ + 0x002AF474, + 0x0F12000E, /*aig_stx_gap[4:0]*/ + 0x002AE42E, + 0x0F120004, /*adlc_qec[2:0]*/ + 0x00287000, + 0x002A13E0, + 0x0F120000, /*senHal_bSRX SRX OFF*/ + 0x002A13C8, + 0x0F120001, /*senHal_bSenAAC AAC Enable*/ + 0x002A12D8, + 0x0F120464, /*senHal_ContPtrs_senModesDataArr[78]*/ + 0x0F120468, /*senHal_ContPtrs_senModesDataArr[79]*/ + 0x002A12F6, + 0x0F120000, /*senHal_ContPtrs_senModesDataArr[93]*/ + 0x002A13CC, + 0x0F121FC0, /*senHal_bSen11ADLC [12:0] : Write tuning value to E404 + register*/ + 0x002A13EC, + 0x0F120001, /*senHal_DarklevelTuneMode*/ + 0x002A184C, + 0x0F121EE1, + 0x00287000, + 0x002A040E, + 0x0F120003, /*skl_usConfigStbySettings*/ + 0xFFFF000A, + 0x002A1218, + 0x0F120002, /*senHal_SenBinFactor*/ + 0x0F120002, /*senHal_SamplingType*/ + 0x002A0C9A, + 0x0F120001, /*setot_bUseDigitalHbin*/ + 0x002A1438, + 0x0F12F468, /*senHal_TuneStr_AngTuneData1[0]*/ + 0x0F120000, /*senHal_TuneStr_AngTuneData1[1] not use binninb block + 0x0000 ,use binnin blcok 0x0000*/ + 0x0F120008, /*senHal_TuneStr_AngTuneData1[2] not use binninb block + 0x000A ,use binnin blcok 0x0008*/ + 0x0F120006, /*senHal_TuneStr_AngTuneData1[3] not use binninb block + 0x0005 ,use binnin blcok 0x0006*/ + 0x0F120000, /*senHal_TuneStr_AngTuneData1[4]*/ + 0xFFFF000A, + 0x002A0416, + 0x0F12F400, /*skl_usStbyBackupReg[0][0]*/ + 0x0F120074, /*skl_usStbyBackupReg[0][1]*/ + 0x0F12E42E, /*skl_usStbyBackupReg[1][0]*/ + 0x0F120030, /*skl_usStbyBackupReg[1][1]*/ + 0x002A378C, + 0x0F120000, /* On/off regiSter bUSeOTP*/ + 0x002A0AD8, + 0x0F120F00, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F00, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120F00, + 0x0F12000F, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120000, + 0x0F120000, + 0x0F12000F, + 0x0F120F0F, + 0x0F120F00, + 0x0F120F00, + 0x0F120000, + 0x0F120F0F, + 0x0F120000, + 0x0F120F0F, + 0x0F12000F, + 0x0F12000F, + 0x0F120F00, + 0x0F128608, + 0x0F12E960, + 0x0F120243, + 0x0F12128B, + 0x0F12F073, + 0x0F120270, + 0x0F12DF47, + 0x0F12F226, + 0x0F121A31, + 0x0F12DFDA, + 0x0F121200, + 0x0F1205A9, + 0x0F120F16, + 0x0F120F5E, + 0x0F12DF10, + 0x0F1225BF, + 0x0F12FCF0, + 0x0F12DE1B, + 0x0F12025B, + 0x0F12FA8B, + 0x0F12163B, + 0x0F12DF44, + 0x0F12FB2D, + 0x0F1230E6, + 0x0F12FE07, + 0x0F12F47C, + 0x0F1209F2, + 0x0F120AED, + 0x0F12FA09, + 0x0F12E70E, + 0x0F120158, + 0x0F121110, + 0x0F12E28C, + 0x0F120DFB, + 0x0F12074B, + 0x0F12FBE5, + 0x0F12961C, + 0x0F12E21A, + 0x0F120ADF, + 0x0F120A67, + 0x0F12F8A6, + 0x0F12FDC3, + 0x0F12D590, + 0x0F12FA69, + 0x0F1208D5, + 0x0F12F635, + 0x0F12057E, + 0x0F12043B, + 0x0F12155C, + 0x0F1200C6, + 0x0F12F042, + 0x0F12176A, + 0x0F12F818, + 0x0F12F1F3, + 0x0F12026F, + 0x0F1208F6, + 0x0F120CCF, + 0x0F12E42D, + 0x0F120A92, + 0x0F1210EC, + 0x0F12005F, + 0x0F12F02C, + 0x0F120672, + 0x0F1209BF, + 0x0F12F4B5, + 0x0F12FC22, + 0x0F12FD50, + 0x0F120C26, + 0x0F12EED3, + 0x0F1207C3, + 0x0F12080F, + 0x0F12F6CF, + 0x0F127A3B, + 0x0F12E9DC, + 0x0F12088E, + 0x0F1201C8, + 0x0F12043C, + 0x0F12F7E2, + 0x0F12E391, + 0x0F12F3C4, + 0x0F121422, + 0x0F12E845, + 0x0F120D16, + 0x0F1206CA, + 0x0F120DEB, + 0x0F121324, + 0x0F12E814, + 0x0F1216B7, + 0x0F1202AC, + 0x0F12DE4D, + 0x0F1201EA, + 0x0F12F0C2, + 0x0F120E06, + 0x0F12EC6D, + 0x0F12FDF0, + 0x0F122B46, + 0x0F120710, + 0x0F12F84C, + 0x0F120E52, + 0x0F120675, + 0x0F12F0D7, + 0x0F12ED40, + 0x0F12F3AD, + 0x0F12179A, + 0x0F12DE9B, + 0x0F1210BA, + 0x0F120825, + 0x0F12FE0A, + 0x0F1288E9, + 0x0F12E9E0, + 0x0F12043D, + 0x0F120A17, + 0x0F12FC21, + 0x0F12FB58, + 0x0F12DCE0, + 0x0F12F24C, + 0x0F121A19, + 0x0F12E011, + 0x0F1211A3, + 0x0F120649, + 0x0F120D04, + 0x0F120E15, + 0x0F12E112, + 0x0F1227BD, + 0x0F12F7AA, + 0x0F12E06A, + 0x0F120A16, + 0x0F12FD23, + 0x0F121226, + 0x0F12DA34, + 0x0F1207A4, + 0x0F122AD3, + 0x0F12FE27, + 0x0F12EE64, + 0x0F120CAD, + 0x0F1211C5, + 0x0F12EC55, + 0x0F12ED98, + 0x0F12F88A, + 0x0F121842, + 0x0F12E1D5, + 0x0F1208FD, + 0x0F120FB6, + 0x0F12F801, + 0x002A0378, + 0x0F120001, /*REG_TC_DBG_RelnitCmd*/ + 0x002A05E8, + 0x0F1200E4, /*TVAR_ash_AwbAshCord_0_ Horizon*/ + 0x0F1200F0, /*TVAR_ash_AwbAshCord_1_ IncandA*/ + 0x0F120100, /*TVAR_ash_AwbAshCord_2_ WW*/ + 0x0F120120, /*TVAR_ash_AwbAshCord_3_ CW*/ + 0x0F120150, /*TVAR_ash_AwbAshCord_4_ D50*/ + 0x0F120180, /*TVAR_ash_AwbAshCord_5_ D65*/ + 0x0F1201A0, /*TVAR_ash_AwbAshCord_6_ D75*/ + 0x002A05FE, + 0x0F123800, /*TVAR_ash_GASAlpha_0__0_ Horizon*/ + 0x0F124000, /*TVAR_ash_GASAlpha_0__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_0__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_0__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_1__0_ IncandA*/ + 0x0F124000, /*TVAR_ash_GASAlpha_1__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_1__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_1__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_2__0_ WW*/ + 0x0F124000, /*TVAR_ash_GASAlpha_2__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_2__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_2__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_3__0_ CW*/ + 0x0F124000, /*TVAR_ash_GASAlpha_3__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_3__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_3__3_*/ + 0x0F123800, /*TVAR_ash_GASAlpha_4__0_ D50*/ + 0x0F124000, /*TVAR_ash_GASAlpha_4__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_4__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_4__3_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__0_ D65*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_5__3_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__0_ D75*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__1_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__2_*/ + 0x0F124000, /*TVAR_ash_GASAlpha_6__3_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_0_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_1_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_2_*/ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_3_*/ + 0x00287000, + 0x002A2744, + 0x0F12B510, /* 70002744*/ + 0x0F124A1C, /* 70002746*/ + 0x0F1221FB, /* 70002748*/ + 0x0F12481C, /* 7000274A*/ + 0x0F12C004, /* 7000274C*/ + 0x0F126001, /* 7000274E*/ + 0x0F12491B, /* 70002750*/ + 0x0F12481C, /* 70002752*/ + 0x0F12F000, /* 70002754*/ + 0x0F12FA0E, /* 70002756*/ + 0x0F12491B, /* 70002758*/ + 0x0F12481C, /* 7000275A*/ + 0x0F12F000, /* 7000275C*/ + 0x0F12FA0A, /* 7000275E*/ + 0x0F12491B, /* 70002760*/ + 0x0F12481C, /* 70002762*/ + 0x0F12F000, /* 70002764*/ + 0x0F12FA06, /* 70002766*/ + 0x0F12491B, /* 70002768*/ + 0x0F12481C, /* 7000276A*/ + 0x0F12F000, /* 7000276C*/ + 0x0F12FA02, /* 7000276E*/ + 0x0F12491B, /* 70002770*/ + 0x0F12481C, /* 70002772*/ + 0x0F12F000, /* 70002774*/ + 0x0F12F9FE, /* 70002776*/ + 0x0F12491B, /* 70002778*/ + 0x0F12481C, /* 7000277A*/ + 0x0F12F000, /* 7000277C*/ + 0x0F12F9FA, /* 7000277E*/ + 0x0F12491B, /* 70002780*/ + 0x0F12481C, /* 70002782*/ + 0x0F12F000, /* 70002784*/ + 0x0F12F9F6, /* 70002786*/ + 0x0F12481B, /* 70002788*/ + 0x0F122130, /* 7000278A*/ + 0x0F128001, /* 7000278C*/ + 0x0F1221C0, /* 7000278E*/ + 0x0F128041, /* 70002790*/ + 0x0F122104, /* 70002792*/ + 0x0F128081, /* 70002794*/ + 0x0F122100, /* 70002796*/ + 0x0F1280C1, /* 70002798*/ + 0x0F128101, /* 7000279A*/ + 0x0F124917, /* 7000279C*/ + 0x0F122016, /* 7000279E*/ + 0x0F1283C8, /* 700027A0*/ + 0x0F124917, /* 700027A2*/ + 0x0F124817, /* 700027A4*/ + 0x0F12F000, /* 700027A6*/ + 0x0F12F9E5, /* 700027A8*/ + 0x0F124917, /* 700027AA*/ + 0x0F124817, /* 700027AC*/ + 0x0F12F000, /* 700027AE*/ + 0x0F12F9E1, /* 700027B0*/ + 0x0F12BC10, /* 700027B2*/ + 0x0F12BC08, /* 700027B4*/ + 0x0F124718, /* 700027B6*/ + 0x0F120000, /* 700027B8*/ + 0x0F125BB1, /* 700027BA*/ + 0x0F121770, /* 700027BC*/ + 0x0F127000, /* 700027BE*/ + 0x0F122811, /* 700027C0*/ + 0x0F127000, /* 700027C2*/ + 0x0F12C0BB, /* 700027C4*/ + 0x0F120000, /* 700027C6*/ + 0x0F12284F, /* 700027C8*/ + 0x0F127000, /* 700027CA*/ + 0x0F123609, /* 700027CC*/ + 0x0F120000, /* 700027CE*/ + 0x0F122867, /* 700027D0*/ + 0x0F127000, /* 700027D2*/ + 0x0F1277C7, /* 700027D4*/ + 0x0F120000, /* 700027D6*/ + 0x0F1228F3, /* 700027D8*/ + 0x0F127000, /* 700027DA*/ + 0x0F12727D, /* 700027DC*/ + 0x0F120000, /* 700027DE*/ + 0x0F122949, /* 700027E0*/ + 0x0F127000, /* 700027E2*/ + 0x0F129919, /* 700027E4*/ + 0x0F120000, /* 700027E6*/ + 0x0F122987, /* 700027E8*/ + 0x0F127000, /* 700027EA*/ + 0x0F121C63, /* 700027EC*/ + 0x0F120000, /* 700027EE*/ + 0x0F1229E7, /* 700027F0*/ + 0x0F127000, /* 700027F2*/ + 0x0F1204CB, /* 700027F4*/ + 0x0F120000, /* 700027F6*/ + 0x0F122C7C, /* 700027F8*/ + 0x0F127000, /* 700027FA*/ + 0x0F120CA8, /* 700027FC*/ + 0x0F127000, /* 700027FE*/ + 0x0F122B1D, /* 70002800*/ + 0x0F127000, /* 70002802*/ + 0x0F1250AF, /* 70002804*/ + 0x0F120000, /* 70002806*/ + 0x0F122B2D, /* 70002808*/ + 0x0F127000, /* 7000280A*/ + 0x0F125623, /* 7000280C*/ + 0x0F120000, /* 7000280E*/ + 0x0F12B4F0, /* 70002810*/ + 0x0F126801, /* 70002812*/ + 0x0F12468C, /* 70002814*/ + 0x0F126846, /* 70002816*/ + 0x0F122200, /* 70002818*/ + 0x0F1249C7, /* 7000281A*/ + 0x0F122000, /* 7000281C*/ + 0x0F122724, /* 7000281E*/ + 0x0F124357, /* 70002820*/ + 0x0F12183B, /* 70002822*/ + 0x0F124664, /* 70002824*/ + 0x0F125CE5, /* 70002826*/ + 0x0F12005C, /* 70002828*/ + 0x0F125B34, /* 7000282A*/ + 0x0F12072D, /* 7000282C*/ + 0x0F120F2D, /* 7000282E*/ + 0x0F12800D, /* 70002830*/ + 0x0F12804C, /* 70002832*/ + 0x0F12808B, /* 70002834*/ + 0x0F122301, /* 70002836*/ + 0x0F1280CB, /* 70002838*/ + 0x0F122300, /* 7000283A*/ + 0x0F1280CB, /* 7000283C*/ + 0x0F121C40, /* 7000283E*/ + 0x0F122824, /* 70002840*/ + 0x0F12D3EE, /* 70002842*/ + 0x0F121C52, /* 70002844*/ + 0x0F122A04, /* 70002846*/ + 0x0F12D3E8, /* 70002848*/ + 0x0F12BCF0, /* 7000284A*/ + 0x0F124770, /* 7000284C*/ + 0x0F12B510, /* 7000284E*/ + 0x0F12F000, /* 70002850*/ + 0x0F12F998, /* 70002852*/ + 0x0F1248B9, /* 70002854*/ + 0x0F127A81, /* 70002856*/ + 0x0F1248B9, /* 70002858*/ + 0x0F126B00, /* 7000285A*/ + 0x0F12F000, /* 7000285C*/ + 0x0F12F99A, /* 7000285E*/ + 0x0F12BC10, /* 70002860*/ + 0x0F12BC08, /* 70002862*/ + 0x0F124718, /* 70002864*/ + 0x0F12B5F8, /* 70002866*/ + 0x0F126805, /* 70002868*/ + 0x0F126844, /* 7000286A*/ + 0x0F124EB5, /* 7000286C*/ + 0x0F128861, /* 7000286E*/ + 0x0F128AB0, /* 70002870*/ + 0x0F128A72, /* 70002872*/ + 0x0F122301, /* 70002874*/ + 0x0F124368, /* 70002876*/ + 0x0F121889, /* 70002878*/ + 0x0F1217C2, /* 7000287A*/ + 0x0F120E12, /* 7000287C*/ + 0x0F121810, /* 7000287E*/ + 0x0F121202, /* 70002880*/ + 0x0F128820, /* 70002882*/ + 0x0F12029B, /* 70002884*/ + 0x0F1218C0, /* 70002886*/ + 0x0F12F000, /* 70002888*/ + 0x0F12F98C, /* 7000288A*/ + 0x0F129000, /* 7000288C*/ + 0x0F128AF6, /* 7000288E*/ + 0x0F124268, /* 70002890*/ + 0x0F12210A, /* 70002892*/ + 0x0F124370, /* 70002894*/ + 0x0F12F000, /* 70002896*/ + 0x0F12F98D, /* 70002898*/ + 0x0F12436E, /* 7000289A*/ + 0x0F120007, /* 7000289C*/ + 0x0F12210A, /* 7000289E*/ + 0x0F120030, /* 700028A0*/ + 0x0F12F000, /* 700028A2*/ + 0x0F12F987, /* 700028A4*/ + 0x0F129A00, /* 700028A6*/ + 0x0F120039, /* 700028A8*/ + 0x0F12F000, /* 700028AA*/ + 0x0F12F989, /* 700028AC*/ + 0x0F120002, /* 700028AE*/ + 0x0F128820, /* 700028B0*/ + 0x0F121880, /* 700028B2*/ + 0x0F128020, /* 700028B4*/ + 0x0F1248A4, /* 700028B6*/ + 0x0F1288C1, /* 700028B8*/ + 0x0F1248A2, /* 700028BA*/ + 0x0F123820, /* 700028BC*/ + 0x0F128B40, /* 700028BE*/ + 0x0F124240, /* 700028C0*/ + 0x0F124350, /* 700028C2*/ + 0x0F12F000, /* 700028C4*/ + 0x0F12F976, /* 700028C6*/ + 0x0F128861, /* 700028C8*/ + 0x0F121840, /* 700028CA*/ + 0x0F128060, /* 700028CC*/ + 0x0F12BCF8, /* 700028CE*/ + 0x0F12BC08, /* 700028D0*/ + 0x0F124718, /* 700028D2*/ + 0x0F12B570, /* 700028D4*/ + 0x0F124C9B, /* 700028D6*/ + 0x0F123C20, /* 700028D8*/ + 0x0F128B20, /* 700028DA*/ + 0x0F12F000, /* 700028DC*/ + 0x0F12F978, /* 700028DE*/ + 0x0F124D99, /* 700028E0*/ + 0x0F1280E8, /* 700028E2*/ + 0x0F128B60, /* 700028E4*/ + 0x0F12F000, /* 700028E6*/ + 0x0F12F97B, /* 700028E8*/ + 0x0F128128, /* 700028EA*/ + 0x0F12BC70, /* 700028EC*/ + 0x0F12BC08, /* 700028EE*/ + 0x0F124718, /* 700028F0*/ + 0x0F12B508, /* 700028F2*/ + 0x0F124895, /* 700028F4*/ + 0x0F124669, /* 700028F6*/ + 0x0F12F000, /* 700028F8*/ + 0x0F12F97A, /* 700028FA*/ + 0x0F124894, /* 700028FC*/ + 0x0F12214D, /* 700028FE*/ + 0x0F128201, /* 70002900*/ + 0x0F122196, /* 70002902*/ + 0x0F128281, /* 70002904*/ + 0x0F12211D, /* 70002906*/ + 0x0F128301, /* 70002908*/ + 0x0F12F7FF, /* 7000290A*/ + 0x0F12FFE3, /* 7000290C*/ + 0x0F12F000, /* 7000290E*/ + 0x0F12F977, /* 70002910*/ + 0x0F12466B, /* 70002912*/ + 0x0F128818, /* 70002914*/ + 0x0F128859, /* 70002916*/ + 0x0F121A40, /* 70002918*/ + 0x0F12498E, /* 7000291A*/ + 0x0F126348, /* 7000291C*/ + 0x0F12488A, /* 7000291E*/ + 0x0F129900, /* 70002920*/ + 0x0F123876, /* 70002922*/ + 0x0F12F000, /* 70002924*/ + 0x0F12F974, /* 70002926*/ + 0x0F12466B, /* 70002928*/ + 0x0F12488A, /* 7000292A*/ + 0x0F128819, /* 7000292C*/ + 0x0F123080, /* 7000292E*/ + 0x0F1284C1, /* 70002930*/ + 0x0F128859, /* 70002932*/ + 0x0F128501, /* 70002934*/ + 0x0F124987, /* 70002936*/ + 0x0F122000, /* 70002938*/ + 0x0F123920, /* 7000293A*/ + 0x0F127088, /* 7000293C*/ + 0x0F123140, /* 7000293E*/ + 0x0F127388, /* 70002940*/ + 0x0F12B001, /* 70002942*/ + 0x0F12BC08, /* 70002944*/ + 0x0F124718, /* 70002946*/ + 0x0F12B570, /* 70002948*/ + 0x0F120004, /* 7000294A*/ + 0x0F126820, /* 7000294C*/ + 0x0F126865, /* 7000294E*/ + 0x0F12F000, /* 70002950*/ + 0x0F12F966, /* 70002952*/ + 0x0F120402, /* 70002954*/ + 0x0F124880, /* 70002956*/ + 0x0F120C12, /* 70002958*/ + 0x0F128142, /* 7000295A*/ + 0x0F12487F, /* 7000295C*/ + 0x0F128801, /* 7000295E*/ + 0x0F122900, /* 70002960*/ + 0x0F12D008, /* 70002962*/ + 0x0F12497E, /* 70002964*/ + 0x0F12002B, /* 70002966*/ + 0x0F126D8A, /* 70002968*/ + 0x0F122105, /* 7000296A*/ + 0x0F121C80, /* 7000296C*/ + 0x0F12F000, /* 7000296E*/ + 0x0F12F95F, /* 70002970*/ + 0x0F126020, /* 70002972*/ + 0x0F12E005, /* 70002974*/ + 0x0F12487B, /* 70002976*/ + 0x0F12002B, /* 70002978*/ + 0x0F122105, /* 7000297A*/ + 0x0F12F000, /* 7000297C*/ + 0x0F12F958, /* 7000297E*/ + 0x0F126020, /* 70002980*/ + 0x0F126820, /* 70002982*/ + 0x0F12E7B2, /* 70002984*/ + 0x0F12B5F8, /* 70002986*/ + 0x0F124975, /* 70002988*/ + 0x0F122200, /* 7000298A*/ + 0x0F123160, /* 7000298C*/ + 0x0F1283CA, /* 7000298E*/ + 0x0F126800, /* 70002990*/ + 0x0F124669, /* 70002992*/ + 0x0F12F000, /* 70002994*/ + 0x0F12F92C, /* 70002996*/ + 0x0F12466B, /* 70002998*/ + 0x0F128818, /* 7000299A*/ + 0x0F12F000, /* 7000299C*/ + 0x0F12F918, /* 7000299E*/ + 0x0F120005, /* 700029A0*/ + 0x0F12466B, /* 700029A2*/ + 0x0F128858, /* 700029A4*/ + 0x0F12F000, /* 700029A6*/ + 0x0F12F91B, /* 700029A8*/ + 0x0F120004, /* 700029AA*/ + 0x0F122101, /* 700029AC*/ + 0x0F121928, /* 700029AE*/ + 0x0F1202C9, /* 700029B0*/ + 0x0F121A08, /* 700029B2*/ + 0x0F120286, /* 700029B4*/ + 0x0F120029, /* 700029B6*/ + 0x0F120030, /* 700029B8*/ + 0x0F12F000, /* 700029BA*/ + 0x0F12F941, /* 700029BC*/ + 0x0F120005, /* 700029BE*/ + 0x0F122701, /* 700029C0*/ + 0x0F1202BF, /* 700029C2*/ + 0x0F120021, /* 700029C4*/ + 0x0F120030, /* 700029C6*/ + 0x0F12F000, /* 700029C8*/ + 0x0F12F93A, /* 700029CA*/ + 0x0F124964, /* 700029CC*/ + 0x0F124A61, /* 700029CE*/ + 0x0F123140, /* 700029D0*/ + 0x0F1232A0, /* 700029D2*/ + 0x0F12800D, /* 700029D4*/ + 0x0F128395, /* 700029D6*/ + 0x0F12804F, /* 700029D8*/ + 0x0F1283D7, /* 700029DA*/ + 0x0F128088, /* 700029DC*/ + 0x0F120011, /* 700029DE*/ + 0x0F123120, /* 700029E0*/ + 0x0F128008, /* 700029E2*/ + 0x0F12E773, /* 700029E4*/ + 0x0F12B510, /* 700029E6*/ + 0x0F12485C, /* 700029E8*/ + 0x0F128980, /* 700029EA*/ + 0x0F122800, /* 700029EC*/ + 0x0F12D001, /* 700029EE*/ + 0x0F12F000, /* 700029F0*/ + 0x0F12F92C, /* 700029F2*/ + 0x0F12E734, /* 700029F4*/ + 0x0F12B5FE, /* 700029F6*/ + 0x0F122600, /* 700029F8*/ + 0x0F12495B, /* 700029FA*/ + 0x0F122000, /* 700029FC*/ + 0x0F126108, /* 700029FE*/ + 0x0F1260C8, /* 70002A00*/ + 0x0F12485A, /* 70002A02*/ + 0x0F128901, /* 70002A04*/ + 0x0F124852, /* 70002A06*/ + 0x0F123020, /* 70002A08*/ + 0x0F1288C0, /* 70002A0A*/ + 0x0F129000, /* 70002A0C*/ + 0x0F120840, /* 70002A0E*/ + 0x0F129002, /* 70002A10*/ + 0x0F124856, /* 70002A12*/ + 0x0F128800, /* 70002A14*/ + 0x0F129001, /* 70002A16*/ + 0x0F124853, /* 70002A18*/ + 0x0F123040, /* 70002A1A*/ + 0x0F128B05, /* 70002A1C*/ + 0x0F122900, /* 70002A1E*/ + 0x0F12D01F, /* 70002A20*/ + 0x0F124E52, /* 70002A22*/ + 0x0F122700, /* 70002A24*/ + 0x0F1280F7, /* 70002A26*/ + 0x0F122400, /* 70002A28*/ + 0x0F12E016, /* 70002A2A*/ + 0x0F12494E, /* 70002A2C*/ + 0x0F120060, /* 70002A2E*/ + 0x0F1239C0, /* 70002A30*/ + 0x0F121841, /* 70002A32*/ + 0x0F122020, /* 70002A34*/ + 0x0F125E08, /* 70002A36*/ + 0x0F129902, /* 70002A38*/ + 0x0F121840, /* 70002A3A*/ + 0x0F129900, /* 70002A3C*/ + 0x0F12F000, /* 70002A3E*/ + 0x0F12F8FF, /* 70002A40*/ + 0x0F124B4A, /* 70002A42*/ + 0x0F120202, /* 70002A44*/ + 0x0F1200A1, /* 70002A46*/ + 0x0F12330C, /* 70002A48*/ + 0x0F12505A, /* 70002A4A*/ + 0x0F120002, /* 70002A4C*/ + 0x0F124342, /* 70002A4E*/ + 0x0F120210, /* 70002A50*/ + 0x0F121DDA, /* 70002A52*/ + 0x0F1232F9, /* 70002A54*/ + 0x0F125050, /* 70002A56*/ + 0x0F121C64, /* 70002A58*/ + 0x0F1242A5, /* 70002A5A*/ + 0x0F12DCE6, /* 70002A5C*/ + 0x0F128137, /* 70002A5E*/ + 0x0F12E042, /* 70002A60*/ + 0x0F122400, /* 70002A62*/ + 0x0F12E031, /* 70002A64*/ + 0x0F124940, /* 70002A66*/ + 0x0F120060, /* 70002A68*/ + 0x0F1239C0, /* 70002A6A*/ + 0x0F121841, /* 70002A6C*/ + 0x0F122020, /* 70002A6E*/ + 0x0F125E08, /* 70002A70*/ + 0x0F129902, /* 70002A72*/ + 0x0F121840, /* 70002A74*/ + 0x0F129900, /* 70002A76*/ + 0x0F12F000, /* 70002A78*/ + 0x0F12F8E2, /* 70002A7A*/ + 0x0F124A3B, /* 70002A7C*/ + 0x0F1200A1, /* 70002A7E*/ + 0x0F12320C, /* 70002A80*/ + 0x0F125853, /* 70002A82*/ + 0x0F123A0C, /* 70002A84*/ + 0x0F128852, /* 70002A86*/ + 0x0F124353, /* 70002A88*/ + 0x0F123380, /* 70002A8A*/ + 0x0F120A1F, /* 70002A8C*/ + 0x0F1223FF, /* 70002A8E*/ + 0x0F121C5B, /* 70002A90*/ + 0x0F121A9B, /* 70002A92*/ + 0x0F12469C, /* 70002A94*/ + 0x0F124343, /* 70002A96*/ + 0x0F1218FF, /* 70002A98*/ + 0x0F124B34, /* 70002A9A*/ + 0x0F12330C, /* 70002A9C*/ + 0x0F12505F, /* 70002A9E*/ + 0x0F120003, /* 70002AA0*/ + 0x0F124343, /* 70002AA2*/ + 0x0F124660, /* 70002AA4*/ + 0x0F124343, /* 70002AA6*/ + 0x0F124831, /* 70002AA8*/ + 0x0F125840, /* 70002AAA*/ + 0x0F124350, /* 70002AAC*/ + 0x0F123080, /* 70002AAE*/ + 0x0F124A2F, /* 70002AB0*/ + 0x0F120A00, /* 70002AB2*/ + 0x0F121818, /* 70002AB4*/ + 0x0F125050, /* 70002AB6*/ + 0x0F120039, /* 70002AB8*/ + 0x0F124379, /* 70002ABA*/ + 0x0F123180, /* 70002ABC*/ + 0x0F120A09, /* 70002ABE*/ + 0x0F124281, /* 70002AC0*/ + 0x0F12D201, /* 70002AC2*/ + 0x0F121A40, /* 70002AC4*/ + 0x0F121986, /* 70002AC6*/ + 0x0F121C64, /* 70002AC8*/ + 0x0F1242A5, /* 70002ACA*/ + 0x0F12DCCB, /* 70002ACC*/ + 0x0F120868, /* 70002ACE*/ + 0x0F121980, /* 70002AD0*/ + 0x0F120029, /* 70002AD2*/ + 0x0F12F000, /* 70002AD4*/ + 0x0F12F8B4, /* 70002AD6*/ + 0x0F123008, /* 70002AD8*/ + 0x0F120900, /* 70002ADA*/ + 0x0F129A01, /* 70002ADC*/ + 0x0F124923, /* 70002ADE*/ + 0x0F124290, /* 70002AE0*/ + 0x0F12D901, /* 70002AE2*/ + 0x0F128888, /* 70002AE4*/ + 0x0F1280C8, /* 70002AE6*/ + 0x0F124920, /* 70002AE8*/ + 0x0F1288C8, /* 70002AEA*/ + 0x0F122800, /* 70002AEC*/ + 0x0F12D001, /* 70002AEE*/ + 0x0F121E40, /* 70002AF0*/ + 0x0F1280C8, /* 70002AF2*/ + 0x0F129801, /* 70002AF4*/ + 0x0F122800, /* 70002AF6*/ + 0x0F12D00D, /* 70002AF8*/ + 0x0F124A1B, /* 70002AFA*/ + 0x0F123AC0, /* 70002AFC*/ + 0x0F127B90, /* 70002AFE*/ + 0x0F122802, /* 70002B00*/ + 0x0F12D001, /* 70002B02*/ + 0x0F122803, /* 70002B04*/ + 0x0F12D106, /* 70002B06*/ + 0x0F1288C9, /* 70002B08*/ + 0x0F122900, /* 70002B0A*/ + 0x0F12D003, /* 70002B0C*/ + 0x0F122100, /* 70002B0E*/ + 0x0F120040, /* 70002B10*/ + 0x0F121880, /* 70002B12*/ + 0x0F128081, /* 70002B14*/ + 0x0F12BCFE, /* 70002B16*/ + 0x0F12BC08, /* 70002B18*/ + 0x0F124718, /* 70002B1A*/ + 0x0F12B510, /* 70002B1C*/ + 0x0F126800, /* 70002B1E*/ + 0x0F12F000, /* 70002B20*/ + 0x0F12F89C, /* 70002B22*/ + 0x0F124911, /* 70002B24*/ + 0x0F122001, /* 70002B26*/ + 0x0F128108, /* 70002B28*/ + 0x0F12E699, /* 70002B2A*/ + 0x0F12B510, /* 70002B2C*/ + 0x0F12F000, /* 70002B2E*/ + 0x0F12F89D, /* 70002B30*/ + 0x0F12F7FF, /* 70002B32*/ + 0x0F12FF60, /* 70002B34*/ + 0x0F12E693, /* 70002B36*/ + 0x0F124140, /* 70002B38*/ + 0x0F12D000, /* 70002B3A*/ + 0x0F1219DC, /* 70002B3C*/ + 0x0F127000, /* 70002B3E*/ + 0x0F121B60, /* 70002B40*/ + 0x0F127000, /* 70002B42*/ + 0x0F120DD4, /* 70002B44*/ + 0x0F127000, /* 70002B46*/ + 0x0F1222AC, /* 70002B48*/ + 0x0F127000, /* 70002B4A*/ + 0x0F120F88, /* 70002B4C*/ + 0x0F127000, /* 70002B4E*/ + 0x0F121E8C, /* 70002B50*/ + 0x0F127000, /* 70002B52*/ + 0x0F12214C, /* 70002B54*/ + 0x0F127000, /* 70002B56*/ + 0x0F121A10, /* 70002B58*/ + 0x0F127000, /* 70002B5A*/ + 0x0F123780, /* 70002B5C*/ + 0x0F127000, /* 70002B5E*/ + 0x0F122384, /* 70002B60*/ + 0x0F127000, /* 70002B62*/ + 0x0F12065C, /* 70002B64*/ + 0x0F127000, /* 70002B66*/ + 0x0F121C8C, /* 70002B68*/ + 0x0F127000, /* 70002B6A*/ + 0x0F122C7C, /* 70002B6C*/ + 0x0F127000, /* 70002B6E*/ + 0x0F122D88, /* 70002B70*/ + 0x0F127000, /* 70002B72*/ + 0x0F124778, /* 70002B74*/ + 0x0F1246C0, /* 70002B76*/ + 0x0F12C000, /* 70002B78*/ + 0x0F12E59F, /* 70002B7A*/ + 0x0F12FF1C, /* 70002B7C*/ + 0x0F12E12F, /* 70002B7E*/ + 0x0F12CE77, /* 70002B80*/ + 0x0F120000, /* 70002B82*/ + 0x0F124778, /* 70002B84*/ + 0x0F1246C0, /* 70002B86*/ + 0x0F12C000, /* 70002B88*/ + 0x0F12E59F, /* 70002B8A*/ + 0x0F12FF1C, /* 70002B8C*/ + 0x0F12E12F, /* 70002B8E*/ + 0x0F123609, /* 70002B90*/ + 0x0F120000, /* 70002B92*/ + 0x0F124778, /* 70002B94*/ + 0x0F1246C0, /* 70002B96*/ + 0x0F12C000, /* 70002B98*/ + 0x0F12E59F, /* 70002B9A*/ + 0x0F12FF1C, /* 70002B9C*/ + 0x0F12E12F, /* 70002B9E*/ + 0x0F129F91, /* 70002BA0*/ + 0x0F120000, /* 70002BA2*/ + 0x0F124778, /* 70002BA4*/ + 0x0F1246C0, /* 70002BA6*/ + 0x0F12C000, /* 70002BA8*/ + 0x0F12E59F, /* 70002BAA*/ + 0x0F12FF1C, /* 70002BAC*/ + 0x0F12E12F, /* 70002BAE*/ + 0x0F122AE3, /* 70002BB0*/ + 0x0F120000, /* 70002BB2*/ + 0x0F124778, /* 70002BB4*/ + 0x0F1246C0, /* 70002BB6*/ + 0x0F12F004, /* 70002BB8*/ + 0x0F12E51F, /* 70002BBA*/ + 0x0F12D1DC, /* 70002BBC*/ + 0x0F120000, /* 70002BBE*/ + 0x0F124778, /* 70002BC0*/ + 0x0F1246C0, /* 70002BC2*/ + 0x0F12C000, /* 70002BC4*/ + 0x0F12E59F, /* 70002BC6*/ + 0x0F12FF1C, /* 70002BC8*/ + 0x0F12E12F, /* 70002BCA*/ + 0x0F126869, /* 70002BCC*/ + 0x0F120000, /* 70002BCE*/ + 0x0F124778, /* 70002BD0*/ + 0x0F1246C0, /* 70002BD2*/ + 0x0F12C000, /* 70002BD4*/ + 0x0F12E59F, /* 70002BD6*/ + 0x0F12FF1C, /* 70002BD8*/ + 0x0F12E12F, /* 70002BDA*/ + 0x0F1268BD, /* 70002BDC*/ + 0x0F120000, /* 70002BDE*/ + 0x0F124778, /* 70002BE0*/ + 0x0F1246C0, /* 70002BE2*/ + 0x0F12C000, /* 70002BE4*/ + 0x0F12E59F, /* 70002BE6*/ + 0x0F12FF1C, /* 70002BE8*/ + 0x0F12E12F, /* 70002BEA*/ + 0x0F1268DB, /* 70002BEC*/ + 0x0F120000, /* 70002BEE*/ + 0x0F124778, /* 70002BF0*/ + 0x0F1246C0, /* 70002BF2*/ + 0x0F12C000, /* 70002BF4*/ + 0x0F12E59F, /* 70002BF6*/ + 0x0F12FF1C, /* 70002BF8*/ + 0x0F12E12F, /* 70002BFA*/ + 0x0F121BC9, /* 70002BFC*/ + 0x0F120000, /* 70002BFE*/ + 0x0F124778, /* 70002C00*/ + 0x0F1246C0, /* 70002C02*/ + 0x0F12C000, /* 70002C04*/ + 0x0F12E59F, /* 70002C06*/ + 0x0F12FF1C, /* 70002C08*/ + 0x0F12E12F, /* 70002C0A*/ + 0x0F1271B9, /* 70002C0C*/ + 0x0F120000, /* 70002C0E*/ + 0x0F124778, /* 70002C10*/ + 0x0F1246C0, /* 70002C12*/ + 0x0F12C000, /* 70002C14*/ + 0x0F12E59F, /* 70002C16*/ + 0x0F12FF1C, /* 70002C18*/ + 0x0F12E12F, /* 70002C1A*/ + 0x0F127249, /* 70002C1C*/ + 0x0F120000, /* 70002C1E*/ + 0x0F124778, /* 70002C20*/ + 0x0F1246C0, /* 70002C22*/ + 0x0F12C000, /* 70002C24*/ + 0x0F12E59F, /* 70002C26*/ + 0x0F12FF1C, /* 70002C28*/ + 0x0F12E12F, /* 70002C2A*/ + 0x0F1298CD, /* 70002C2C*/ + 0x0F120000, /* 70002C2E*/ + 0x0F124778, /* 70002C30*/ + 0x0F1246C0, /* 70002C32*/ + 0x0F12C000, /* 70002C34*/ + 0x0F12E59F, /* 70002C36*/ + 0x0F12FF1C, /* 70002C38*/ + 0x0F12E12F, /* 70002C3A*/ + 0x0F12987F, /* 70002C3C*/ + 0x0F120000, /* 70002C3E*/ + 0x0F124778, /* 70002C40*/ + 0x0F1246C0, /* 70002C42*/ + 0x0F12F004, /* 70002C44*/ + 0x0F12E51F, /* 70002C46*/ + 0x0F12D378, /* 70002C48*/ + 0x0F120000, /* 70002C4A*/ + 0x0F124778, /* 70002C4C*/ + 0x0F1246C0, /* 70002C4E*/ + 0x0F12C000, /* 70002C50*/ + 0x0F12E59F, /* 70002C52*/ + 0x0F12FF1C, /* 70002C54*/ + 0x0F12E12F, /* 70002C56*/ + 0x0F1204CB, /* 70002C58*/ + 0x0F120000, /* 70002C5A*/ + 0x0F124778, /* 70002C5C*/ + 0x0F1246C0, /* 70002C5E*/ + 0x0F12C000, /* 70002C60*/ + 0x0F12E59F, /* 70002C62*/ + 0x0F12FF1C, /* 70002C64*/ + 0x0F12E12F, /* 70002C66*/ + 0x0F1250AF, /* 70002C68*/ + 0x0F120000, /* 70002C6A*/ + 0x0F124778, /* 70002C6C*/ + 0x0F1246C0, /* 70002C6E*/ + 0x0F12C000, /* 70002C70*/ + 0x0F12E59F, /* 70002C72*/ + 0x0F12FF1C, /* 70002C74*/ + 0x0F12E12F, /* 70002C76*/ + 0x0F125623, /* 70002C78*/ + 0x0F120000, /* 70002C7A*/ + 0x0028D000, + 0x002A1000, + 0x0F120001, + 0x00287000, + 0x002A00F4, + 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs*/ + 0x0F120000, /*REG_TC_IPRM_InClockMSBs 5DC0h=24000d=24Mhz*/ + 0x002A0110, + 0x0F120002, /*REG_TC_IPRM_UseNPviClocks*/ + 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc*/ + 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 222Eh=8750d*4=35000d=35Mhz*/ + 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0 + 445CEh=8750d*4=35000d=35Mhz*/ + 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0 + 445Ch=8750d*4=35000d=35Mhz*/ + 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_1*/ + 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1*/ + 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1*/ + 0x002A0126, + 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated*/ + /*0x002A0144,*/ + /*0x0F120640,*/ /*REG_TC_GP_PrevReqInputWidth 640h=1600d*/ + /*0x0F1204B0,*/ /*REG_TC_GP_PrevReqInputHeight 4b0h=1200d*/ + /*0x0F120000,*/ /*REG_TC_GP_PrevInputWidthOfs*/ + /*0x0F120000,*/ /*REG_TC_GP_PrevInputHeightOfs*/ + /*0x0F120640,*/ /*REG_TC_GP_CapReqInputWidth 640h=1600d*/ + /*0x0F1204B0,*/ /*REG_TC_GP_CapReqInputHeight 4b0h=1200d*/ + /*0x0F120000,*/ /*REG_TC_GP_CapInputWidthOfs*/ + /*0x0F120000,*/ /*REG_TC_GP_CapInputHeightOfs*/ + /*0x002A0164,*/ + /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInPre*/ + /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInCap*/ + /*0x002A0310,*/ + /*0x0F120640,*/ /*REG_TC_PZOOM_ZoomInputWidth 640h=1600d*/ + /*0x0F1204b0,*/ /*REG_TC_PZOOM_ZoomInputHeight 4b0h=1200d*/ + /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputWidthOfs*/ + /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputHeightOfs*/ + 0x002A0170, + 0x0F120280, /*0500 0320 REG_0TC_PCFG_usWidth*/ + 0x0F1201E0, /*03C0 0258 REG_0TC_PCFG_usHeight*/ + 0x0F120005, /*0005 0005 REG_0TC_PCFG_Format 0 RGB565; + 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; 7 Bayer*/ + 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMaxOut4KHzRate*/ + 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMinOut4KHzRate*/ + 0x0F120042, /*0042 0042 REG_0TC_PCFG_PVIMask*/ + 0x0F120010, /*0010 0010 REG_0TC_PCFG_OIFMask*/ + 0x0F120001, /*0000 0001 REG_0TC_PCFG_uClockInd*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_usFrTimeType 0: dynamic 1: + fix not accurate 2: fixed_Accurate*/ + 0x0F120001, /*0000 0001 REG_0TC_PCFG_FrRateQualityType 1b: FR + (bin) 2b: Quality (no-bin)*/ + 0x0F120535, /*0535 0535 REG_0TC_PCFG_uSMaxFrTimeMSecMult10 max + frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F1202bb, /*029A 029A REG_0TC_PCFG_uSMinFrTimeMSecMult10 + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_bSmearOutput*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSaturation*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSharpBlur*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_SColorTemp*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_uDeviceGammaIndex 1:Mirror + (X) 2:Mirror(Y) 4:STAT Mirror(X) 8:STAT Mirror(Y)*/ + 0x0F120003, /*0000 0001 REG_0TC_PCFG_uPrevMirror*/ + 0x0F120003, /*0000 0001 REG_0TC_PCFG_uCaptureMirror*/ + 0x0F120000, /*0000 0000 REG_0TC_PCFG_uRotation*/ + 0x002A0198, + 0x0F120280, /*0280 REG_1TC_PCFG_uSWidth 2 70000198 + 640*/ + 0x0F1201E0, /*01E0 REG_1TC_PCFG_uSHeight 2 7000019A + 480*/ + 0x0F120005, /*0005 REG_1TC_PCFG_Format 2 7000019C + 0 RGB565; 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; + 7 Bayer*/ + 0x0F12222E, /*222E REG_1TC_PCFG_uSMaxOut4KHzRate 2 7000019E*/ + 0x0F12222E, /*222E REG_1TC_PCFG_uSMinOut4KHzRate 2 700001A0*/ + 0x0F120042, /*0042 REG_1TC_PCFG_PVIMaSk 2 700001A2*/ + 0x0F120010, /*0010 REG_1TC_PCFG_OIFMaSk 2 700001A4*/ + 0x0F120001, /*0001 REG_1TC_PCFG_uClockInd 2 700001A6*/ + 0x0F120002, /*0000 REG_1TC_PCFG_uSFrTimeType 2 700001A8 + 0: dynamic 1:fix not accurate 2: fixed_Accurate*/ + 0x0F120001, /*0001 REG_1TC_PCFG_FrRateQualityType 2 700001AA*/ + 0x0F12014D, /*01A0 REG_1TC_PCFG_uSMaxFrTimeMSecMult10 2 700001AC + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F12014D, /*014D REG_1TC_PCFG_uSMinFrTimeMSecMult10 2 700001AE + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*0000 REG_1TC_PCFG_bSmearOutput 2 700001B0*/ + 0x0F120000, /*0000 REG_1TC_PCFG_SSaturation 2 700001B2*/ + 0x0F120000, /*0000 REG_1TC_PCFG_SSharpBlur 2 700001B4*/ + 0x0F120000, /*0000 REG_1TC_PCFG_SColorTemp 2 700001B6*/ + 0x0F120000, /*0000 REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/ + 0x0F120003, /*0000 REG_1TC_PCFG_uPrevMirror 2 700001BA*/ + 0x0F120003, /*0000 REG_1TC_PCFG_uCaptureMirror 2 700001BC*/ + 0x0F120000, /*0000 REG_1TC_PCFG_uRotation 2 700001BE*/ + 0x002A01C0, + 0x0F120280, /*0320 REG_2TC_PCFG_uSWidth*/ + 0x0F1201e0, /*0258 REG_2TC_PCFG_uSHeight*/ + 0x0F120005, /*REG_2TC_PCFG_Format*/ + 0x0F12222E, /*REG_2TC_PCFG_uSMaxOut4KHzRate*/ + 0x0F12222E, /*REG_2TC_PCFG_uSMinOut4KHzRate*/ + 0x0F120042, /*REG_2TC_PCFG_PVIMaSk*/ + 0x0F120010, /*REG_2TC_PCFG_OIFMaSk*/ + 0x0F120001, /*REG_2TC_PCFG_uClockInd*/ + 0x0F120000, /*REG_2TC_PCFG_uSFrTimeType*/ + 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 1b: FR (bin) 2b: + Quality (no-bin)*/ + 0x0F1207D0, /*REG_2TC_PCFG_uSMaxFrTimeMSecMult10max frame time : + 30fpS 014D; 15fpS 029a; a6a - 3.75 fpS; 0535 - 7.5FPS*/ + 0x0F12029A, /*REG_2TC_PCFG_uSMinFrTimeMSecMult10 2 700001D6*/ + 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/ + 0x0F120000, /*REG_2TC_PCFG_SSaturation 2 700001DA*/ + 0x0F120000, /*REG_2TC_PCFG_SSharpBlur 2 700001DC*/ + 0x0F120000, /*REG_2TC_PCFG_SColorTemp 2 700001DE*/ + 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/ + 0x0F120003, /*REG_2TC_PCFG_uPrevMirror 2 700001E2 + [0] : x [1]: Y [2] Stat X [3] Stat Y*/ + 0x0F120003, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/ + 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/ + 0x002A01E8, + 0x0F120280, /*0320 REG_3TC_PCFG_uSWidth 2 700001E8*/ + 0x0F1201e0, /*0258 REG_3TC_PCFG_uSHeight 2 700001EA*/ + 0x0F120005, /*REG_3TC_PCFG_Format 2 700001EC*/ + 0x0F12222E, /*REG_3TC_PCFG_uSMaxOut4KHzRate 2 700001EE*/ + 0x0F12222E, /*REG_3TC_PCFG_uSMinOut4KHzRate 2 700001F0*/ + 0x0F120042, /*REG_3TC_PCFG_PVIMaSk 2 700001F2*/ + 0x0F120010, /*REG_3TC_PCFG_OIFMaSk 2 700001F4*/ + 0x0F120001, /*REG_3TC_PCFG_uClockInd 2 700001F6*/ + 0x0F120002, /*REG_3TC_PCFG_uSFrTimeType 2 700001F8 + 0: dynamic 1:fix not accurate 2: fixed_Accurate*/ + 0x0F120001, /*REG_3TC_PCFG_FrRateQualityType 2 700001FA*/ + 0x0F120190, /*REG_3TC_PCFG_uSMaxFrTimeMSecMult10 2 700001FC + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*REG_3TC_PCFG_uSMinFrTimeMSecMult10 2 700001FE + max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535 + 3.75fpS:a6a*/ + 0x0F120000, /*REG_3TC_PCFG_bSmearOutput 2 70000200*/ + 0x0F120000, /*REG_3TC_PCFG_SSaturation 2 70000202*/ + 0x0F120000, /*REG_3TC_PCFG_SSharpBlur 2 70000204*/ + 0x0F120000, /*REG_3TC_PCFG_SColorTemp 2 70000206*/ + 0x0F120000, /*REG_3TC_PCFG_uDeviceGammaIndex 2 70000208*/ + 0x0F120003, /*REG_3TC_PCFG_uPrevMirror 2 7000020A*/ + 0x0F120003, /*REG_3TC_PCFG_uCaptureMirror 2 7000020C*/ + 0x0F120000, /*REG_3TC_PCFG_uRotation 2 7000020E*/ + 0x002A0238, + 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/ + 0x0F120640, /*REG_0TC_CCFG_uSWidth 2 7000023A*/ + 0x0F1204B0, /*REG_0TC_CCFG_uSHeight 2 7000023C*/ + 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/ + 0x0F12222E, /*REG_0TC_CCFG_uSMaxOut4KHzRate 2 70000240*/ + 0x0F12222E, /*REG_0TC_CCFG_uSMinOut4KHzRate 2 70000242*/ + 0x0F120042, /*REG_0TC_CCFG_PVIMaSk 2 70000244*/ + 0x0F120000, /*REG_0TC_CCFG_OIFMaSk 2 70000246*/ + 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/ + 0x0F120002, /*REG_0TC_CCFG_uSFrTimeType 2 7000024A*/ + 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/ + 0x0F120514, /*0535 REG_0TC_CCFG_uSMaxFrTimeMSecMult10 2 7000024E*/ + 0x0F120514, /*0535 REG_0TC_CCFG_uSMinFrTimeMSecMult10 2 70000250*/ + 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/ + 0x0F120000, /*REG_0TC_CCFG_SSaturation 2 70000254*/ + 0x0F120000, /*REG_0TC_CCFG_SSharpBlur 2 70000256*/ + 0x0F120000, /*REG_0TC_CCFG_SColorTemp 2 70000258*/ + 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/ + 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/ + 0x0F120640, /*REG_1TC_CCFG_uSWidth 2 7000025E*/ + 0x0F1204B0, /*REG_1TC_CCFG_uSHeight 2 70000260*/ + 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/ + 0x0F12445C, /*222E REG_1TC_CCFG_uSMaxOut4KHzRate 2 70000264*/ + 0x0F12445C, /*222E REG_1TC_CCFG_uSMinOut4KHzRate 2 70000266*/ + 0x0F120042, /*REG_1TC_CCFG_PVIMaSk 2 70000268*/ + 0x0F120010, /*0000 REG_1TC_CCFG_OIFMaSk 2 7000026A*/ + 0x0F120000,/*0001 REG_1TC_CCFG_uClockInd 2 7000026C*/ + 0x0F120000, /*REG_1TC_CCFG_uSFrTimeType 2 7000026E*/ + 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/ + 0x0F121388, /*REG_1TC_CCFG_uSMaxFrTimeMSecMult10 2 70000272*/ + 0x0F121388, /*REG_1TC_CCFG_uSMinFrTimeMSecMult10 2 70000274*/ + 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/ + 0x0F120000, /*REG_1TC_CCFG_SSaturation 2 70000278*/ + 0x0F120000, /*REG_1TC_CCFG_SSharpBlur 2 7000027A*/ + 0x0F120000, /*REG_1TC_CCFG_SColorTemp 2 7000027C*/ + 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/ + 0x002A1218, + 0x0F120002, /*SenHal_SenBinFactor*/ + 0xFFFF0064, + 0x00287000, + 0x002A0CC0, + 0x0F120001, /*AFC_Default BIT[0] 1:60Hz 0:50Hz*/ + 0x002A0374, + 0x0F12067F, /*REG_TC_DBG BIT[5] : Auto Flicker Disable*/ + + /*Int Time limit*/ + 0x00287000, + 0x002A1220, + 0x0F1201B7, /*senHal_ExpMinPixels*/ + + 0x002A10C0, + 0x0F120040, /*TVAR_ae_BrAve*/ + 0x002A10C6, + 0x0F12000F, /*ae_StatMode*/ + 0x002A03B2, + 0x0F12010E, /*lt_uLimitHigh*/ + 0x0F1200F5, /*lt_uLimitLow*/ + 0x002A03C4, + 0x0F123415, /*lt_uMaxExp1 3415h=13333d/400d=33.3325ms*/ + 0x002A03C8, + 0x0F12681F, /*lt_uMaxExp2 681Fh=26655d/400d=66.6375ms*/ + 0x002A03CC, + 0x0F128227, /*lt_uMaxExp3 8227h=33319d/400d=83.2975ms*/ + 0x002A03D0, + 0x0F120D40, /*lt_uMaxExp4 30D40h=50000d/400d=500ms*/ + 0x0F120003, + 0x002A03D4, + 0x0F123415, /*lt_uCapMaxExp1 3415h=13333d/400d=33.3325ms*/ + 0x002A03D8, + 0x0F12681F, /*lt_uCapMaxExp2 681Fh=26655d/400d=66.6375ms*/ + 0x002A03DC, + 0x0F128227, /*lt_uCapMaxExp3 8227h=33319d/400d=83.2975ms*/ + 0x002A03E0, + 0x0F120D40, /*lt_uCapMaxExp4 30D40h=50000d/400d=500ms*/ + 0x0F120003, + 0x002A03E4, + 0x0F120230, /*lt_uMaxAnGain1 0230h=0560d/256d=x2.1875*/ + 0x0F120260, /*lt_uMaxAnGain2 0260h=0608d/256d=x2.375*/ + 0x0F120370, /*lt_uMaxAnGain3 0370h=0704d/256d=x3.4375*/ + 0x0F120880, /*lt_uMaxAnGain4 0710h=2176d/256d=x8.5*/ + 0x0F120100, /*lt_uMaxDigGain*/ + 0x0F128000, /*lt_uMaxTotGain*/ + 0x0F120230, /*lt_uCapMaxAnGain1 0230h=0560d/256d=x2.1875*/ + 0x0F120260, /*lt_uCapMaxAnGain2 0260h=0608d/256d=x2.375*/ + 0x0F120380, /*lt_uCapMaxAnGain3 0370h=0704d/256d=x3.4375*/ + 0x0F120880, /*lt_uCapMaxAnGain4 0710h=2176d/256d=x8.5*/ + 0x0F120100, /*lt_uCapMaxDigGain*/ + 0x0F128000, /*lt_uCapMaxTotGain*/ + 0x002A10CE, + 0x0F120000, /*ae_WeightTbl_16[0]*/ + 0x0F120101, /*ae_WeightTbl_16[1]*/ + 0x0F120101, /*ae_WeightTbl_16[2]*/ + 0x0F120000, /*ae_WeightTbl_16[3]*/ + 0x0F120101, /*ae_WeightTbl_16[4]*/ + 0x0F120101, /*ae_WeightTbl_16[5]*/ + 0x0F120101, /*ae_WeightTbl_16[6]*/ + 0x0F120101, /*ae_WeightTbl_16[7]*/ + 0x0F120201, /*ae_WeightTbl_16[8]*/ + 0x0F120303, /*ae_WeightTbl_16[9]*/ + 0x0F120303, /*ae_WeightTbl_16[10]*/ + 0x0F120102, /*ae_WeightTbl_16[11]*/ + 0x0F120201, /*ae_WeightTbl_16[12]*/ + 0x0F120403, /*ae_WeightTbl_16[13]*/ + 0x0F120304, /*ae_WeightTbl_16[14]*/ + 0x0F120102, /*ae_WeightTbl_16[15]*/ + 0x0F120201, /*ae_WeightTbl_16[16]*/ + 0x0F120403, /*ae_WeightTbl_16[17]*/ + 0x0F120304, /*ae_WeightTbl_16[18]*/ + 0x0F120102, /*ae_WeightTbl_16[19]*/ + 0x0F120201, /*ae_WeightTbl_16[20]*/ + 0x0F120403, /*ae_WeightTbl_16[21]*/ + 0x0F120304, /*ae_WeightTbl_16[22]*/ + 0x0F120102, /*ae_WeightTbl_16[23]*/ + 0x0F120201, /*ae_WeightTbl_16[24]*/ + 0x0F120303, /*ae_WeightTbl_16[25]*/ + 0x0F120303, /*ae_WeightTbl_16[26]*/ + 0x0F120102, /*ae_WeightTbl_16[27]*/ + 0x0F120201, /*ae_WeightTbl_16[28]*/ + 0x0F120202, /*ae_WeightTbl_16[29]*/ + 0x0F120202, /*ae_WeightTbl_16[30]*/ + 0x0F120102, /*ae_WeightTbl_16[31]*/ + 0x002A0DCC, /*AWB Init White Locus*/ + 0x0F120138, /*awbb_IntcR*/ + 0x0F12011C, /*awbb_IntcB*/ + 0x0F1202A7, /*awbb_GLocusR*/ + 0x0F120343, /*awbb_GLocusB*/ + 0x002A0DEC, + 0x0F1205F0, /*awbb_GamutWidthThr1*/ + 0x0F1201F4, /*awbb_GamutHeightThr1*/ + 0x0F12006C, /*awbb_GamutWidthThr2*/ + 0x0F120038, /*awbb_GamutHeightThr2*/ + 0x002A0DD8, + 0x0F12000C, /*awbb_MinNumOfFinalPatches*/ + 0x002A0E50, + 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B*/ + 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B*/ + 0x0F120640, /*awbb_SCDetectionMap_SEC_SunnyNB*/ + 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB*/ + 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B*/ + 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone*/ + 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone*/ + 0x002A0DB4, /*LowTemp Zone*/ + 0x0F12036C, /*awbb_CrclLowT_R_c*/ + 0x002A0DB8, + 0x0F12011D, /*awbb_CrclLowT_B_c*/ + 0x002A0DBC, + 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/ + 0x002A22BA, + 0x0F120006, /*Mon_AWB_ByPassMode*/ + 0x002A0DEA, + 0x0F120000, /*awbb_movingscale10*/ + 0x002A0F7A, + 0x0F120000, /*awbb_RGainOff*/ + 0x0F120000, /*awbb_BGainOff*/ + 0x0F120000, /*awbb_GGainOff*/ + 0x0F1200C2, /*awbb_Alpha_Comp_Mode*/ + 0x0F120002, /*awbb_Rpl_InvalidOutDoor*/ + 0x0F120001, /*awbb_UseGrThrCorr*/ + 0x0F1200E4, /*awbb_Use_Filters*/ + + 0x0F12053C, /*awbb_GainsInit[0]*/ + 0x0F120400, /*awbb_GainsInit[1]*/ + 0x0F1207ac, /*7AC, 55C, *awbb_GainsInit[2]*/ + + 0x0F12001E, /*awbb_WpFilterMinThr*/ + 0x0F120190, /*awbb_WpFilterMaxThr*/ + 0x0F120010, /*awbb_WpFilterCoef*/ + 0x0F120004, /*awbb_WpFilterSize*/ + 0x0F120001, /*awbb_otp_disable*/ + 0x0F120002, /*awbb_GridEnable*/ + 0x002A0CE0, + 0x0F1203F8, /*03F8 03B5 awbb_IndoorGrZones_m_BGrid[0]*/ + 0x0F120422, /*0422 03DF awbb_IndoorGrZones_m_BGrid[1]*/ + 0x0F120390, /*03B4 032D awbb_IndoorGrZones_m_BGrid[2]*/ + 0x0F12042A, /*0408 03D5 awbb_IndoorGrZones_m_BGrid[3]*/ + 0x0F120352, /*0370 0303 awbb_IndoorGrZones_m_BGrid[4]*/ + 0x0F12041E, /*03EE 03BB awbb_IndoorGrZones_m_BGrid[5]*/ + 0x0F120318, /*032C 02DB awbb_IndoorGrZones_m_BGrid[6]*/ + 0x0F1203DC, /*03FC, 03D4 0397 awbb_IndoorGrZones_m_BGrid[7]*/ + 0x0F1202E4, /*02E4, 0302 02B1 awbb_IndoorGrZones_m_BGrid[8]*/ + 0x0F12039C, /*03BA, 03BA 036B awbb_IndoorGrZones_m_BGrid[9]*/ + 0x0F1202B8, /*02B8, 02DA 0289 awbb_IndoorGrZones_m_BGrid[10]*/ + 0x0F120368, /*037E, 0374 0349 awbb_IndoorGrZones_m_BGrid[11]*/ + 0x0F120290, /*0290, 02B0 026F awbb_IndoorGrZones_m_BGrid[12]*/ + 0x0F12033E, /*034A, 0328 0329 awbb_IndoorGrZones_m_BGrid[13]*/ + 0x0F120274, /*0274, 0288 0257 awbb_IndoorGrZones_m_BGrid[14]*/ + 0x0F120316, /*031A, 0300 0309 awbb_IndoorGrZones_m_BGrid[15]*/ + 0x0F120252, /*0270 0241 awbb_IndoorGrZones_m_BGrid[16]*/ + 0x0F1202F8, /*02DE 02DD awbb_IndoorGrZones_m_BGrid[17]*/ + 0x0F120232, /*0258 0227 awbb_IndoorGrZones_m_BGrid[18]*/ + 0x0F1202E0, /*02BE 02C3 awbb_IndoorGrZones_m_BGrid[19]*/ + 0x0F12021E, /*0240 0213 awbb_IndoorGrZones_m_BGrid[20]*/ + 0x0F1202C8, /*02A0 02AF awbb_IndoorGrZones_m_BGrid[21]*/ + 0x0F120206, /*0228 0209 awbb_IndoorGrZones_m_BGrid[22]*/ + 0x0F1202B2, /*0296 0295 awbb_IndoorGrZones_m_BGrid[23]*/ + 0x0F1201FA, /*0212 020D awbb_IndoorGrZones_m_BGrid[24]*/ + 0x0F1202A2, /*0284 0285 awbb_IndoorGrZones_m_BGrid[25]*/ + 0x0F1201F4, /*0208 0223 awbb_IndoorGrZones_m_BGrid[26]*/ + 0x0F120294, /*0274 0261 awbb_IndoorGrZones_m_BGrid[27]*/ + 0x0F120200, /*020C 0000 awbb_IndoorGrZones_m_BGrid[28]*/ + 0x0F120288, /*026E 0000 awbb_IndoorGrZones_m_BGrid[29]*/ + 0x0F120214, /*0222 0000 awbb_IndoorGrZones_m_BGrid[30]*/ + 0x0F120250, /*0260 0000 awbb_IndoorGrZones_m_BGrid[31]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[32]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[33]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[34]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[35]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[36]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[37]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[38]*/ + 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[39]*/ + 0x0F120005, /*awbb_IndoorGrZones_m_GridStep*/ + 0x002A0D34, + 0x0F120010, /*awbb_IndoorGrZones_ZInfo_m_GridSz*/ + 0x002A0D38, + 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/ + 0x002A0D3C, + 0x0F120294, /*0294 02A4 02B0 02B6 02B8 02A2 02B8 + 029F awbb_OutdoorGrZones_m_BGrid[0]*/ + 0x0F1202F2, /*02F2 02F2 02F0 02F2 02F2 02D4 02F2 + 02CE awbb_OutdoorGrZones_m_BGrid[1]*/ + 0x0F120276, /*0276 0276 028A 0276 028E 0282 028E + 0282 awbb_OutdoorGrZones_m_BGrid[2]*/ + 0x0F12030A, /*030A 030A 02FC 030A 030A 02EE 030A + 02DA awbb_OutdoorGrZones_m_BGrid[3]*/ + 0x0F120258, /*0258 0258 026C 0258 026E 027A 027A + 026D awbb_OutdoorGrZones_m_BGrid[4]*/ + 0x0F12030A, /*0302 0302 030A 0302 030A 030A 030A + 02C2 awbb_OutdoorGrZones_m_BGrid[5]*/ + 0x0F120246, /*0246 0246 0258 0246 025E 027A 0274 + 0256 awbb_OutdoorGrZones_m_BGrid[6]*/ + 0x0F1202FA, /*02EA 02EA 0302 02EA 02FE 030A 02FE + 02A6 awbb_OutdoorGrZones_m_BGrid[7]*/ + 0x0F120256, /*0256 0256 0246 0256 0264 0274 0282 + 026E awbb_OutdoorGrZones_m_BGrid[8]*/ + 0x0F1202DC, /*02B8 02B8 02EA 02B8 02D0 02FE 02DC + 028A awbb_OutdoorGrZones_m_BGrid[9]*/ + 0x0F120000, /*0000 0000 0256 0000 0000 0282 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[10]*/ + 0x0F120000, /*0000 0000 02B8 0000 0000 02DC 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[11]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[12]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[13]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[14]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[15]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[16]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[17]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[18]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[19]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[20]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[21]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[22]*/ + 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000 + 0000 awbb_OutdoorGrZones_m_BGrid[23]*/ + 0x0F120005, /*awbb_OutdoorGrZones_m_GridStep*/ + 0x002A0D70, + 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/ + 0x002A0D74, + 0x0F1201EB, /*awbb_OutdoorGrZones_m_Boffs*/ + 0x002A0D78, + 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/ + 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/ + 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/ + 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/ + 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/ + 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/ + 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/ + 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/ + 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/ + 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/ + 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/ + 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/ + 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/ + 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/ + 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/ + 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/ + 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/ + 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/ + 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/ + 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/ + 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/ + 0x0F120006, /*awbb_LowBrGrZones_m_GridStep*/ + 0x002A0DAC, + 0x0F12000A, /*awbb_LowBrGrZones_ZInfo_m_GridSz*/ + 0x002A0DB0, + 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/ + 0x002A0F60, + 0x0F1202E2, /*awbb_GridConst_1[0]*/ + 0x0F12034B, /*awbb_GridConst_1[1]*/ + 0x0F120399, /*awbb_GridConst_1[2]*/ + 0x0F12102D, /*awbb_GridConst_2[0]*/ + 0x0F1210DE, /*awbb_GridConst_2[1]*/ + 0x0F12116E, /*awbb_GridConst_2[2]*/ + 0x0F12117B, /*awbb_GridConst_2[3]*/ + 0x0F12120A, /*11FF awbb_GridConst_2[4]*/ + 0x0F121247, /*awbb_GridConst_2[5]*/ + 0x0F1202C4, /*awbb_GridCoeff_R_1*/ + 0x0F1202E4, /*awbb_GridCoeff_B_1*/ + 0x0F1200C3, /*awbb_GridCoeff_R_2*/ + 0x0F1200A6, /*awbb_GridCoeff_B_2*/ + 0x002A0ED0, + 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[0][0]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][1]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][2]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][3]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][4]*/ + 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[0][5]*/ + 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[1][0]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][1]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][2]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][3]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][4]*/ + 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[1][5]*/ + 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[2][0]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][1]*/ + 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][2]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][3]*/ + 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][4]*/ + 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[2][5]*/ + 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[0][0]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][1]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][2]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][3]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][4]*/ + 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[0][5]*/ + 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[1][0]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][1]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][2]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][3]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][4]*/ + 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[1][5]*/ + 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[2][0]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][1]*/ + 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][2]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][3]*/ + 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][4]*/ + 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[2][5]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][0]*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][2]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][3]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][4]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[0][5]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][0]*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][2]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][3]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][4]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[1][5]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][0]*/ + 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][2]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][3]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][4]*/ + 0x0F120000, /*awbb_GridCorr_R_Out[2][5]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][0]*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][2]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][3]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][4]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[0][5]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][0]*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][2]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][3]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][4]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[1][5]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][0]*/ + 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][2]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][3]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][4]*/ + 0x0F120000, /*awbb_GridCorr_B_Out[2][5]*/ + 0x002A05D2, + 0x0F1200E4, /*SARR_AwbCcmCord[0]*/ + 0x0F1200F0, /*SARR_AwbCcmCord[1]*/ + 0x0F120100, /*SARR_AwbCcmCord[2]*/ + 0x0F120120, /*SARR_AwbCcmCord[3]*/ + 0x0F120150, /*SARR_AwbCcmCord[4]*/ + 0x0F120180, /*SARR_AwbCcmCord[5]*/ + 0x002A05C4, + 0x0F123800, /*TVAR_wbt_pBaseCcms*/ + 0x0F127000, + 0x002A05CC, + 0x0F1238D8, /*TVAR_wbt_pOutdoorCcm*/ + 0x0F127000, + 0x002A3800, + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/ + 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/ + 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/ + 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/ + 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/ + 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/ + 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/ + 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/ + 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/ + 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/ + 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/ + 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/ + 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/ + 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/ + 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/ + 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/ + 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/ + 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/ + 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/ + 0x0F1201C4, /*01D3 01D0 TVAR_wbt_pBaseCcms[36]*/ + 0x0F12FFAC, /*FFBB FFA1 TVAR_wbt_pBaseCcms[37]*/ + 0x0F12FFFB, /*FFDD FFFA TVAR_wbt_pBaseCcms[38]*/ + 0x0F12FF6F, /*FF6F FF6F TVAR_wbt_pBaseCcms[39]*/ + 0x0F120140, /*0140 0140 TVAR_wbt_pBaseCcms[40]*/ + 0x0F12FF49, /*FF49 FF49 TVAR_wbt_pBaseCcms[41]*/ + 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[42]*/ + 0x0F12001F, /*001F 001F TVAR_wbt_pBaseCcms[43]*/ + 0x0F1201BD, /*01BD 01BD TVAR_wbt_pBaseCcms[44]*/ + 0x0F12013F, /*013F 013F TVAR_wbt_pBaseCcms[45]*/ + 0x0F1200E1, /*00E1 00E1 TVAR_wbt_pBaseCcms[46]*/ + 0x0F12FF43, /*FF43 FF43 TVAR_wbt_pBaseCcms[47]*/ + 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[48]*/ + 0x0F12FFC0, /*FFC0 FFC0 TVAR_wbt_pBaseCcms[49]*/ + 0x0F1201B7, /*01B7 01B7 TVAR_wbt_pBaseCcms[50]*/ + 0x0F12FF30, /*FF30 FF30 TVAR_wbt_pBaseCcms[51]*/ + 0x0F12015F, /*015F 015F TVAR_wbt_pBaseCcms[52]*/ + 0x0F120106, /*0106 0106 TVAR_wbt_pBaseCcms[53]*/ + 0x0F1201B5, /*01C6, 01D0 TVAR_wbt_pBaseCcms[54]*/ + 0x0F12FFC6, /*FFBE, FFA1 TVAR_wbt_pBaseCcms[55]*/ + 0x0F12FFEF, /*FFE6, FFFA TVAR_wbt_pBaseCcms[56]*/ + 0x0F12FF6F, /*FF6F, FF6F TVAR_wbt_pBaseCcms[57]*/ + 0x0F120140, /*0140, 0140 TVAR_wbt_pBaseCcms[58]*/ + 0x0F12FF49, /*FF49, FF49 TVAR_wbt_pBaseCcms[59]*/ + 0x0F12FFC1, /*FFC1, FFC1 TVAR_wbt_pBaseCcms[60]*/ + 0x0F12001F, /*001F, 001F TVAR_wbt_pBaseCcms[61]*/ + 0x0F1201BD, /*01BD, 01BD TVAR_wbt_pBaseCcms[62]*/ + 0x0F12013F, /*013F, 013F TVAR_wbt_pBaseCcms[63]*/ + 0x0F1200E1, /*00E1, 00E1 TVAR_wbt_pBaseCcms[64]*/ + 0x0F12FF43, /*FF43, FF43 TVAR_wbt_pBaseCcms[65]*/ + 0x0F120191, /*0191, 0191 TVAR_wbt_pBaseCcms[66]*/ + 0x0F12FFC0, /*FFC0, FFC0 TVAR_wbt_pBaseCcms[67]*/ + 0x0F1201B7, /*01B7, 01B7 TVAR_wbt_pBaseCcms[68]*/ + 0x0F12FF30, /*FF30, FF30 TVAR_wbt_pBaseCcms[69]*/ + 0x0F12015F, /*015F, 015F TVAR_wbt_pBaseCcms[70]*/ + 0x0F120106, /*0106, 0106 TVAR_wbt_pBaseCcms[71]*/ + 0x0F1201B7, /*C8 01BF TVAR_wbt_pBaseCcms[72]*/ + 0x0F12FFC4, /*FFBA FFBF TVAR_wbt_pBaseCcms[73]*/ + 0x0F120001, /*FFE8 FFFE TVAR_wbt_pBaseCcms[74]*/ + 0x0F12FF6D, /*FF6D FF6F FF6D TVAR_wbt_pBaseCcms[75]*/ + 0x0F1201B4, /*01B4 0140 01B4 TVAR_wbt_pBaseCcms[76]*/ + 0x0F12FF66, /*FF66 FF49 FF66 TVAR_wbt_pBaseCcms[77]*/ + 0x0F12FFCA, /*FFCA FFC1 FFCA TVAR_wbt_pBaseCcms[78]*/ + 0x0F12FFCE, /*FFCE 001F FFCE TVAR_wbt_pBaseCcms[79]*/ + 0x0F12017B, /*017B 01BD 017B TVAR_wbt_pBaseCcms[80]*/ + 0x0F120136, /*0136 013F 0136 TVAR_wbt_pBaseCcms[81]*/ + 0x0F120132, /*0132 00E1 0132 TVAR_wbt_pBaseCcms[82]*/ + 0x0F12FF85, /*FF85 FF43 FF85 TVAR_wbt_pBaseCcms[83]*/ + 0x0F12018B, /*018B 0191 018B TVAR_wbt_pBaseCcms[84]*/ + 0x0F12FF73, /*FF73 FFC0 FF73 TVAR_wbt_pBaseCcms[85]*/ + 0x0F120191, /*0191 01B7 0191 TVAR_wbt_pBaseCcms[86]*/ + 0x0F12FF3F, /*FF3F FF30 FF3F TVAR_wbt_pBaseCcms[87]*/ + 0x0F12015B, /*015B 015F 015B TVAR_wbt_pBaseCcms[88]*/ + 0x0F1200D0, /*00D0 0106 00D0 TVAR_wbt_pBaseCcms[89]*/ + 0x0F1201CA, /*01CA 01C1 TVAR_wbt_pBaseCcms[90]*/ + 0x0F12FFBE, /*FFBE FFC5 TVAR_wbt_pBaseCcms[91]*/ + 0x0F12FFF1, /*FFF1 FFF5 TVAR_wbt_pBaseCcms[92]*/ + 0x0F12FEFB, /*FF15 FF3B TVAR_wbt_pBaseCcms[93]*/ + 0x0F12021C, /*01F3 0217 TVAR_wbt_pBaseCcms[94]*/ + 0x0F12FF6B, /*FF7B FF32 TVAR_wbt_pBaseCcms[95]*/ + 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[96]*/ + 0x0F12FFC5, /*FFC5 FFC5 TVAR_wbt_pBaseCcms[97]*/ + 0x0F12018A, /*018A 018B TVAR_wbt_pBaseCcms[98]*/ + 0x0F1200FB, /*00FB 0136 TVAR_wbt_pBaseCcms[99]*/ + 0x0F120167, /*0167 0132 TVAR_wbt_pBaseCcms[100]*/ + 0x0F12FF8C, /*FF8C FF85 TVAR_wbt_pBaseCcms[101]*/ + 0x0F12018B, /*018B 018B TVAR_wbt_pBaseCcms[102]*/ + 0x0F12FF73, /*FF73 FF73 TVAR_wbt_pBaseCcms[103]*/ + 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[104]*/ + 0x0F12FF3F, /*FF3F FF3F TVAR_wbt_pBaseCcms[105]*/ + 0x0F12015B, /*015B 015B TVAR_wbt_pBaseCcms[106]*/ + 0x0F1200D0, /*00D0 00D0 TVAR_wbt_pBaseCcms[107]*/ + 0x002A38D8, + 0x0F120221, /*022C 0235 TVAR_wbt_pOutdoorCcm[0]*/ + 0x0F120005, /*FFD8 FFEF TVAR_wbt_pOutdoorCcm[1]*/ + 0x0F120012, /*0034 0014 TVAR_wbt_pOutdoorCcm[2]*/ + 0x0F12FF67, /*FF67 FF67 TVAR_wbt_pOutdoorCcm[3]*/ + 0x0F12027D, /*027D 027D TVAR_wbt_pOutdoorCcm[4]*/ + 0x0F12FFBA, /*FFBA FFBA TVAR_wbt_pOutdoorCcm[5]*/ + 0x0F12000D, /*000D 000D TVAR_wbt_pOutdoorCcm[6]*/ + 0x0F120062, /*0062 0062 TVAR_wbt_pOutdoorCcm[7]*/ + 0x0F1202A7, /*02A7 02A7 TVAR_wbt_pOutdoorCcm[8]*/ + 0x0F1200C7, /*00C7 00C9 TVAR_wbt_pOutdoorCcm[9]*/ + 0x0F12011F, /*011F 0123 TVAR_wbt_pOutdoorCcm[10]*/ + 0x0F12FF3C, /*FF3C FF36 TVAR_wbt_pOutdoorCcm[11]*/ + 0x0F1201AD, /*01AD 01AD TVAR_wbt_pOutdoorCcm[12]*/ + 0x0F12FFC8, /*FFC8 FFC8 TVAR_wbt_pOutdoorCcm[13]*/ + 0x0F120202, /*0202 0202 TVAR_wbt_pOutdoorCcm[14]*/ + 0x0F12FFCF, /*FFCF FFCF TVAR_wbt_pOutdoorCcm[15]*/ + 0x0F120257, /*0257 0257 TVAR_wbt_pOutdoorCcm[16]*/ + 0x0F12022C, /*022C 022C TVAR_wbt_pOutdoorCcm[17]*/ + 0x002A23DC, + 0x0F1201DD, /*Mon_AAIO_PrevFrmData_NormBr*/ + 0x002A0460, + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/ + 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/ + 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/ + 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/ + 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/ + 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/ + 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/ + 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/ + 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/ + 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/ + 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/ + 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/ + 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/ + 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/ + 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/ + 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/ + 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/ + 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/ + 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/ + 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/ + 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/ + 0x002A065C, + 0x0F12003F, /*afit_uNoiseIndInDoor_0_*/ + 0x0F120041, /*afit_uNoiseIndInDoor_1_*/ + 0x0F1200CB, /*afit_uNoiseIndInDoor_2_*/ + 0x0F1201E0, /*afit_uNoiseIndInDoor_3_*/ + 0x0F120220, /*afit_uNoiseIndInDoor_4_*/ + 0x002A3780, + 0x0F120000, /*on/off AFIT by NB option*/ + 0x0F120014, /*SARR_uNormBrInDoor*/ + 0x0F1200D2, /*SARR_uNormBrInDoor*/ + 0x0F120384, /*SARR_uNormBrInDoor*/ + 0x0F1207D0, /*SARR_uNormBrInDoor*/ + 0x0F121388, /*SARR_uNormBrInDoor*/ + 0x002A06BC, + 0x0F120000, /*AFIT16_BRIGHTNESS*/ + 0x0F120000, /*AFIT16_CONTRAST*/ + 0x0F120014, /*AFIT16_SATURATION*/ + 0x0F120000, /*AFIT16_SHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_Sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F12001E, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F12001E, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201F4, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F120A3B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F12001E, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F121982, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120B80, /*0A80 AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F126444, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F129650, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121464, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121404, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F121403, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120114, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F124446, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F122832, /*5064 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F12141E, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F126407, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120414, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F126E44, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122864, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120014, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120A6E, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F122801, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F12231E, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12961E, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120764, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F12143C, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F121401, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F121E28, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F120A0C, /*1419 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120200, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123C07, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F121E1E, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F123C01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F125A3A, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122858, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120000, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122A03, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F129601, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F122828, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F122401, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F123622, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122832, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121E04, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120F40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120000, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F1200C8, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F120050, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F12002D, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F123C3C, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121E01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12221C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F12281E, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121402, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F12060E, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F120C40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F120000, /*AFIT16_BRIGHTNEss*/ + 0x0F120000, /*AFIT16_CONTRAsT*/ + 0x0F120000, /*AFIT16_sATURATION*/ + 0x0F120000, /*AFIT16_sHARP_BLUR*/ + 0x0F120000, /*AFIT16_GLAMOUR*/ + 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/ + 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/ + 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/ + 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/ + 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/ + 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/ + 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/ + 0x0F120032, /*AFIT16_demsharpmix1_iLowBright*/ + 0x0F12028A, /*AFIT16_demsharpmix1_iHighBright*/ + 0x0F120032, /*AFIT16_demsharpmix1_iLowsat*/ + 0x0F1201F4, /*AFIT16_demsharpmix1_iHighsat*/ + 0x0F120070, /*AFIT16_demsharpmix1_iTune*/ + 0x0F120002, /*AFIT16_demsharpmix1_iHystThLow*/ + 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/ + 0x0F1201AA, /*AFIT16_demsharpmix1_iHystCenter*/ + 0x0F12003C, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/ + 0x0F120050, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/ + 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/ + 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/ + 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/ + 0x0F120046, /*AFIT16_sharpening_iLowsharpClamp_sBin*/ + 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/ + 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0], + AFIT8_sddd8a_repl_thresh [15:8]*/ + 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0], + AFIT8_sddd8a_sat_level [15:8]*/ + 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0], + AFIT8_sddd8a_sat_mpl [15:8]*/ + 0x0F120503, /*AFIT8_sddd8a_sat_noise[7:0], + AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/ + 0x0F12080F, /*AFIT8_sddd8a_iHotThreshHigh[7:0], + AFIT8_sddd8a_iHotThreshLow [15:8]*/ + 0x0F120808, /*AFIT8_sddd8a_iColdThreshHigh[7:0], + AFIT8_sddd8a_iColdThreshLow [15:8]*/ + 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0], + AFIT8_sddd8a_AddNoisePower2 [15:8]*/ + 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0], + AFIT8_sddd8a_iRadialTune [15:8]*/ + 0x0F12022D, /*AFIT8_sddd8a_iRadialLimit [7:0], + AFIT8_sddd8a_iRadialPower [15:8]*/ + 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0], + AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/ + 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0], + AFIT8_sddd8a_iHighslopeThresh [15:8]*/ + 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0], + AFIT8_Demosaicing_iCentGrad [15:8]*/ + 0x0F12061E, /*AFIT8_Demosaicing_iMonochrom [7:0], + AFIT8_Demosaicing_iDecisionThresh [15:8]*/ + 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0], + AFIT8_Demosaicing_iEnhThresh [15:8]*/ + 0x0F120606, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0], + AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/ + 0x0F120A03, /*AFIT8_Demosaicing_iNearGrayDesat[7:0], + AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/ + 0x0F120028, /*AFIT8_sharpening_iMsharpen [7:0], + AFIT8_sharpening_iMshThresh [15:8]*/ + 0x0F120002, /*AFIT8_sharpening_iWsharpen [7:0], + AFIT8_sharpening_iWshThresh [15:8]*/ + 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0], + AFIT8_sharpening_iReduceNegative [15:8]*/ + 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0], + AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/ + 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0], + AFIT8_demsharpmix1_iBCoeff [15:8]*/ + 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0], + AFIT8_demsharpmix1_iWideMult [15:8]*/ + 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0], + AFIT8_demsharpmix1_iHystFalloff [15:8]*/ + 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0], + AFIT8_demsharpmix1_iHystWidth [15:8]*/ + 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0], + AFIT8_demsharpmix1_iHystFallHigh [15:8]*/ + 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0], + * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/ + 0x0F128001, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0], + AFIT8_byr_cgras_ishadingPower [15:8]*/ + 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0], + AFIT8_RGBGamma2_iDarkReduce [15:8]*/ + 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0], + AFIT8_RGB2YUV_iYOffset [15:8]*/ + 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0], + AFIT8_RGB2YUV_isaturation [15:8]*/ + 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0], + AFIT8_sddd8a_iClustThresh_C [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0], + AFIT8_sddd8a_iClustMulT_C [15:8]*/ + 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0], + AFIT8_sddd8a_DispTH_Low [15:8]*/ + 0x0F121219, /*AFIT8_sddd8a_DispTH_High [7:0], + AFIT8_sddd8a_iDenThreshLow [15:8]*/ + 0x0F12320D, /*AFIT8_sddd8a_iDenThreshHigh[7:0], + AFIT8_Demosaicing_iEdgeDesat [15:8]*/ + 0x0F120A0A, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/ + 0x0F122304, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0], + AFIT8_Demosaicing_iDemsharpenLow [15:8]*/ + 0x0F120A08, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0], + AFIT8_Demosaicing_iDemsharpThresh [15:8]*/ + 0x0F120832, /*AFIT8_Demosaicing_iDemshLowLimit [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/ + 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0], + AFIT8_Demosaicing_iDemBlurHigh [15:8]*/ + 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0], + AFIT8_sharpening_iLowsharpPower [15:8]*/ + 0x0F122A0A, /*AFIT8_sharpening_iHighsharpPower[7:0], + AFIT8_sharpening_iLowshDenoise [15:8]*/ + 0x0F124006, /*AFIT8_sharpening_iHighshDenoise [7:0], + AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/ + 0x0F120604, /*AFIT8_sharpening_iReduceEdgeslope [7:0], + AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/ + 0x0F125006, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0], + AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/ + 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0], + AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0], + AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/ + 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0], + AFIT8_sddd8a_DispTH_High_Bin [15:8]*/ + 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0], + AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/ + 0x0F120A28, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0], + AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/ + 0x0F12040A, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0], + AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/ + 0x0F120820, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0], + AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/ + 0x0F12280A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0], + AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/ + 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0], + AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/ + 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0], + AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/ + 0x0F120532, /*0A64 AFIT8_Sharpening_iLowsharpPower_Bin [7:0], + AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/ + 0x0F12062A, /*AFIT8_Sharpening_iLowShDenoise_Bin [7:0], + AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/ + 0x0F120440, /*AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0], + AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/ + 0x0F120606, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0], + AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/ + 0x0F124646, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0], + AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/ + 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0], + AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/ + 0x0F121801, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0], + AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/ + 0x0F12191C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0], + AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/ + 0x0F122818, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0], + AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/ + 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0], + AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/ + 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0], + AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/ + 0x0F121405, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0], + AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/ + 0x0F12050C, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0], + AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/ + 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0], + AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/ + 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0], + AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/ + 0x0F121440, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0], + AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/ + 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0], + AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/ + 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0], + AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/ + 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/ + 0x0F127DFA, /*ConstAfitBaseVals*/ + 0x0F12FFBD, /*ConstAfitBaseVals_1_*/ + 0x0F1226FE, /*ConstAfitBaseVals_2_*/ + 0x0F12F7BC, /*ConstAfitBaseVals_3_*/ + 0x0F127E06, /*ConstAfitBaseVals_4_*/ + 0x0F1200D3, /*ConstAfitBaseVals_5_*/ + + 0x002A0156, + 0x0F120003, /*REG_TC_GP_ActivePrevConfig*/ + 0x002A015E, + 0x0F120000, /*REG_TC_GP_ActiveCapConfig*/ + 0x002A015A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange*/ + 0x002A0142, + 0x0F120001, /*REG_TC_GP_NewConfigSync*/ + 0x002A0158, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged*/ + 0x002A0160, + 0x0F120001, /*REG_TC_GP_CapConfigChanged*/ + 0x002A013A, + 0x0F120001, /*REG_TC_GP_EnablePreview*/ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged*/ + 0xFFFF0096, +}; + +static const u32 s5k5bbgx_stream_stop[] = { + 0xFCFCD000, + 0x00287000, + 0x002A01F0, + 0x0F120000, /* REG_TC_GP_EnablePreview */ + 0x0F120001, /* REG_TC_GP_EnablePreviewChanged*/ + /*0xffff0096, 150ms*/ +}; + +#if (0) +static const u32 s5k5bbgx_stream_start[] = { + 0xFCFCD000, + 0x002AB00C, + 0x0F120001, +}; +#endif + +/*================================= +* CAMERA_BRIGHTNESS_1 (1/9) M4 * +==================================*/ +static const u32 s5k5bbgx_bright_m4[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F12FF00, +}; + +/*================================= +* CAMERA_BRIGHTNESS_2 (2/9) M3 * +==================================*/ + +static const u32 s5k5bbgx_bright_m3[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F12FF00, +}; + +/*================================= + CAMERA_BRIGHTNESS_3 (3/9) M2 +==================================*/ +static const u32 s5k5bbgx_bright_m2[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F12FF9B, +}; + +/*================================= + CAMERA_BRIGHTNESS_4 (4/9) M1 +==================================*/ + +static const u32 s5k5bbgx_bright_m1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F12FF9D, +}; + +/*================================= + CAMERA_BRIGHTNESS_5 (5/9) Default +==================================*/ +static const u32 s5k5bbgx_bright_default[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F120000, +}; + +/*================================= + CAMERA_BRIGHTNESS_6 (6/9) P1 +==================================*/ +static const u32 s5k5bbgx_bright_p1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F120020, +}; + +/*================================= + CAMERA_BRIGHTNESS_7 (7/9) P2 +==================================*/ +static const u32 s5k5bbgx_bright_p2[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F120040, +}; + +/*================================= + CAMERA_BRIGHTNESS_8 (8/9) P3 +==================================*/ +static const u32 s5k5bbgx_bright_p3[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F120060, +}; + +/*================================= + CAMERA_BRIGHTNESS_9 (9/9) P4 +==================================*/ +static const u32 s5k5bbgx_bright_p4[] = { + 0xFCFCD000, + 0x00287000, + 0x002A012A, + 0x0F120080, +}; + +/******************************************************* +* CAMERA_VT_PRETTY_0 Default +* 200s self cam pretty +*******************************************************/ +static const u32 s5k5bbgx_vt_pretty_default[] = { + /* 0xffff000A, */ + 0xFCFCD000, + 0x00287000, + 0x002A04CC, + + 0x0F120000, + 0x0F120002, + 0x0F120008, + 0x0F120018, + 0x0F12005A, + 0x0F1200DF, + 0x0F12013F, + 0x0F120186, + 0x0F1201E6, + 0x0F120236, + 0x0F1202BA, + 0x0F12032A, + 0x0F120385, + 0x0F1203C2, + 0x0F1203EA, + 0x0F1203FF, + + 0x0F120000, + 0x0F120002, + 0x0F120008, + 0x0F120018, + 0x0F12005A, + 0x0F1200DF, + 0x0F12013F, + 0x0F120186, + 0x0F1201E6, + 0x0F120236, + 0x0F1202BA, + 0x0F12032A, + 0x0F120385, + 0x0F1203C2, + 0x0F1203EA, + 0x0F1203FF, + + 0x0F120000, + 0x0F120002, + 0x0F120008, + 0x0F120018, + 0x0F12005A, + 0x0F1200DF, + 0x0F12013F, + 0x0F120186, + 0x0F1201E6, + 0x0F120236, + 0x0F1202BA, + 0x0F12032A, + 0x0F120385, + 0x0F1203C2, + 0x0F1203EA, + 0x0F1203FF, +}; + + +/******************************************************* +* CAMERA_VT_PRETTY_1 +*******************************************************/ +static const u32 s5k5bbgx_vt_pretty_1[] = { + /*0xffff000A,*/ + 0xFCFCD000, + 0x00287000, + 0x002A04CC, + + 0x0F120000, + 0x0F12000D, + 0x0F12001B, + 0x0F120046, + 0x0F1200AA, + 0x0F120120, + 0x0F120190, + 0x0F1201E0, + 0x0F120250, + 0x0F1202A5, + 0x0F120320, + 0x0F120370, + 0x0F1203B0, + 0x0F1203D8, + 0x0F1203F2, + 0x0F120400, + + 0x0F120000, + 0x0F12000D, + 0x0F12001B, + 0x0F120046, + 0x0F1200AA, + 0x0F120120, + 0x0F120190, + 0x0F1201E0, + 0x0F120250, + 0x0F1202A5, + 0x0F120320, + 0x0F120370, + 0x0F1203B0, + 0x0F1203D8, + 0x0F1203F2, + 0x0F120400, + + 0x0F120000, + 0x0F12000D, + 0x0F12001B, + 0x0F120046, + 0x0F1200AA, + 0x0F120120, + 0x0F120190, + 0x0F1201E0, + 0x0F120250, + 0x0F1202A5, + 0x0F120320, + 0x0F120370, + 0x0F1203B0, + 0x0F1203D8, + 0x0F1203F2, + 0x0F120400, +}; + + +/******************************************************* +* CAMERA_VT_PRETTY_2 * +*******************************************************/ +static const u32 s5k5bbgx_vt_pretty_2[] = { + /* 0xffff000A, */ + 0xFCFCD000, + 0x00287000, + 0x002A04CC, + + 0x0F120000, /* 0000 */ + 0x0F12000D, /* 000D */ + 0x0F12001B, /* 001B */ + 0x0F120055, /* 0050 */ + 0x0F1200C0, /* 00B4 */ + 0x0F120164, /* 0154 */ + 0x0F1201C0, /* 01B8 */ + 0x0F120220, /* 0212 */ + 0x0F1202A0, /* 0294 */ + 0x0F1202F0, /* 02E4 */ + 0x0F120365, /* 0352 */ + 0x0F1203A0, /* 0398 */ + 0x0F1203D4, /* 03D4 */ + 0x0F1203E8, /* 03E8 */ + 0x0F1203F7, /* 03F7 */ + 0x0F120400, /* 0400 */ + + 0x0F120000, /* 0000 */ + 0x0F12000D, /* 000D */ + 0x0F12001B, /* 001B */ + 0x0F120055, /* 0050 */ + 0x0F1200C0, /* 00B4 */ + 0x0F120164, /* 0154 */ + 0x0F1201C0, /* 01B8 */ + 0x0F120220, /* 0212 */ + 0x0F1202A0, /* 0294 */ + 0x0F1202F0, /* 02E4 */ + 0x0F120365, /* 0352 */ + 0x0F1203A0, /* 0398 */ + 0x0F1203D4, /* 03D4 */ + 0x0F1203E8, /* 03E8 */ + 0x0F1203F7, /* 03F7 */ + 0x0F120400, /* 0400 */ + + 0x0F120000, /* 0000 */ + 0x0F12000D, /* 000D */ + 0x0F12001B, /* 001B */ + 0x0F120055, /* 0050 */ + 0x0F1200C0, /* 00B4 */ + 0x0F120164, /* 0154 */ + 0x0F1201C0, /* 01B8 */ + 0x0F120220, /* 0212 */ + 0x0F1202A0, /* 0294 */ + 0x0F1202F0, /* 02E4 */ + 0x0F120365, /* 0352 */ + 0x0F1203A0, /* 0398 */ + 0x0F1203D4, /* 03D4 */ + 0x0F1203E8, /* 03E8 */ + 0x0F1203F7, /* 03F7 */ + 0x0F120400, /* 0400 */ +}; + + +/******************************************************* +* CAMERA_VT_PRETTY_3 +*******************************************************/ +static const u32 s5k5bbgx_vt_pretty_3[] = { + /* 0xffff000A, */ + 0xFCFCD000, + 0x00287000, + 0x002A04CC, + + 0x0F120000, /* 0000, 0000, */ + 0x0F12000D, /* 000D, 000D, */ + 0x0F12001B, /* 001B, 001B, */ + 0x0F120064, /* 0064, 0064, */ + 0x0F1200E5, /* 00E5, 00DC, */ + 0x0F120190, /* 95, 0195, 0186, */ + 0x0F1201F5, /* 01F5, 01EA, */ + 0x0F120260, /* 0265, 024E, */ + 0x0F1202E5, /* 02F0, 02DA, */ + 0x0F12032A, /* 30, 0335, 0320, */ + 0x0F12038A, /* 90, 0395, 038E, */ + 0x0F1203C5, /* CA, 03D0, 03CA, / */ + 0x0F1203E0, /* E5, 03E8, 03E8, */ + 0x0F1203EC, /* F0, 03F2, 03F2, */ + 0x0F1203F7, /* 03F7, 03F7, */ + 0x0F120400, /* 0400, 0400, */ + + 0x0F120000, /* 0000, 0000, 0000, */ + 0x0F12000D, /* 000D, 000D, 000D, */ + 0x0F12001B, /* 001B, 001B, 001B, */ + 0x0F120064, /* 0064, 0064, 0064, */ + 0x0F1200E5, /* 00E5, 00E5, 00DC, */ + 0x0F120190, /* 0195, 0195, 0186, */ + 0x0F1201F5, /* 01F5, 01F5, 01EA, */ + 0x0F120260, /* 0260, 0265, 024E, */ + 0x0F1202E5, /* 02E5, 02F0, 02DA, */ + 0x0F12032A, /* 0330, 0335, 0320, */ + 0x0F12038A, /* 0390, 0395, 038E, */ + 0x0F1203C5, /* 03CA, 03D0, 03CA, */ + 0x0F1203E0, /* 03E5, 03E8, 03E8, */ + 0x0F1203EC, /* 03F0, 03F2, 03F2, */ + 0x0F1203F7, /* 03F7, 03F7, 03F7, */ + 0x0F120400, /* 0400, 0400, 0400, */ + + 0x0F120000, /* 0000, 0000, 0000, */ + 0x0F12000D, /* 000D, 000D, 000D, */ + 0x0F12001B, /* 001B, 001B, 001B, */ + 0x0F120064, /* 0064, 0064, 0064, */ + 0x0F1200E5, /* 00E5, 00E5, 00DC, */ + 0x0F120190, /* 0195, 0195, 0186, */ + 0x0F1201F5, /* 01F5, 01F5, 01EA, */ + 0x0F120260, /* 0260, 0265, 024E, */ + 0x0F1202E5, /* 02E5, 02F0, 02DA, */ + 0x0F12032A, /* 0330, 0335, 0320, */ + 0x0F12038A, /* 0390, 0395, 038E, */ + 0x0F1203C5, /* 03CA, 03D0, 03CA, */ + 0x0F1203E0, /* 03E5, 03E8, 03E8, */ + 0x0F1203EC, /* 03F0, 03F2, 03F2, */ + 0x0F1203F7, /* 03F7, 03F7, 03F7, */ + 0x0F120400, /* 0400, 0400, 0400, */ +}; + +static const u32 s5k5bbgx_vt_7fps[] = { + /* Fixed 7fps Mode */ + 0xFCFCD000, + 0x00287000, + + 0x002A0252, + 0x0F120000, /* FrRateQualityType */ + 0x002A0250, + 0x0F120002, /* usFrTimeType */ + 0x002A0254, + 0x0F120535, /* 7fps */ + 0x0F120000, + + 0x002A021C, + 0x0F120000, /* REG_TC_GP_ActivePrevConfig */ + 0x002A0220, + 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */ + 0x002A01F8, + 0x0F120001, /* REG_TC_GP_NewConfigSync */ + 0x002A021E, + 0x0F120001, /* REG_TC_GP_PrevConfigChanged */ + 0x002A01F0, + 0x0F120001, /* REG_TC_GP_EnablePreview */ + 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */ + + 0xffff0096, /* delay 150ms */ + + 0x0028D000, /* mipi */ + 0x002AB0CC, + 0x0F12000B, +}; + +static const u32 s5k5bbgx_vt_10fps[] = { + /* Fixed 10fps Mode */ + 0xFCFCD000, + 0x00287000, + + 0x002A0252, + 0x0F120000, /* FrRateQualityType */ + 0x002A0250, + 0x0F120002, /* usFrTimeType */ + 0x002A0254, + 0x0F1203E8, /* 10fps */ + 0x0F120000, + + 0x002A021C, + 0x0F120000, /* REG_TC_GP_ActivePrevConfig */ + 0x002A0220, + 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */ + 0x002A01F8, + 0x0F120001, /* REG_TC_GP_NewConfigSync */ + 0x002A021E, + 0x0F120001, /* REG_TC_GP_PrevConfigChanged */ + 0x002A01F0, + 0x0F120001, /* REG_TC_GP_EnablePreview */ + 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */ + + 0xffff0096, /* delay 150ms */ + + 0x0028D000, /* mipi */ + 0x002AB0CC, + 0x0F12000B, +}; + +static const u32 s5k5bbgx_vt_12fps[] = { + /* Fixed 12fps Mode */ + 0xFCFCD000, + 0x00287000, + + 0x002A0252, + 0x0F120000, /* FrRateQualityType */ + 0x002A0250, + 0x0F120002, /* usFrTimeType */ + 0x002A0254, + 0x0F120341, /* 12fps */ + 0x0F120000, + + 0x002A021C, + 0x0F120000, /* REG_TC_GP_ActivePrevConfig */ + 0x002A0220, + 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */ + 0x002A01F8, + 0x0F120001, /* REG_TC_GP_NewConfigSync */ + 0x002A021E, + 0x0F120001, /* REG_TC_GP_PrevConfigChanged */ + 0x002A01F0, + 0x0F120001, /* REG_TC_GP_EnablePreview */ + 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */ + + 0xffff0096, /* delay 150ms */ + + 0x0028D000, /* mipi */ + 0x002AB0CC, + 0x0F12000B, +}; + +static const u32 s5k5bbgx_vt_15fps[] = { + /* Fixed 15fps Mode */ + 0xFCFCD000, + 0x00287000, + + 0x002A0252, + 0x0F120000, /* FrRateQualityType */ + 0x002A0250, + 0x0F120002, /* usFrTimeType */ + 0x002A0254, + 0x0F12029A, /* 15fps*/ + 0x0F120000, + + 0x002A021C, + 0x0F120000, /* REG_TC_GP_ActivePrevConfig */ + 0x002A0220, + 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */ + 0x002A01F8, + 0x0F120001, /* REG_TC_GP_NewConfigSync */ + 0x002A021E, + 0x0F120001, /* REG_TC_GP_PrevConfigChanged */ + 0x002A01F0, + 0x0F120001, /* REG_TC_GP_EnablePreview */ + 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */ + + 0xffff0096, /* delay 150ms */ + + 0x0028D000, /*mipi */ + 0x002AB0CC, + 0x0F12000B, +}; + +/******************************************************* +* CAMERA_DTP_ON +*******************************************************/ +static const u32 s5k5bbgx_pattern_on[] = { + 0xffff01f4, /* Delay 500ms*/ + + 0xFCFCD000, + 0x0028D000, + 0x002AB054, + 0x0F120005, /*5:8bit Mode, 1:10Bit Mode*/ + + 0xffff0032, /* Delay 50msec */ +}; + +/******************************************************* +* CAMERA_DTP_OFF +*******************************************************/ +static const u32 s5k5bbgx_pattern_off[] = { + 0xFCFCD000, + 0x0028D000, + 0x002AB054, + 0x0F120000, +}; + +#endif /* __S5K5BBGX_SETFILE_H */ diff --git a/drivers/media/video/s5k5ccgx.c b/drivers/media/video/s5k5ccgx.c index 2123304..51ffd6f 100644 --- a/drivers/media/video/s5k5ccgx.c +++ b/drivers/media/video/s5k5ccgx.c @@ -1309,15 +1309,15 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd) break; } - /* We wait for 200ms after pre flash on. - * check whether AE is stable.*/ - msleep(200); - /* Check AE-stable */ if (state->focus.preflash == PREFLASH_ON) { + /* We wait for 200ms after pre flash on. + * check whether AE is stable.*/ + msleep(200); + /* Do checking AE-stable */ for (count = 0; count < AE_STABLE_SEARCH_COUNT; count++) { - if (state->focus.start == AUTO_FOCUS_OFF) { + if (state->focus.cancel) { cam_info("af_start_preflash: \ AF is cancelled!\n"); state->focus.status = AF_RESULT_CANCELLED; @@ -1332,11 +1332,11 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd) if (read_value == 0x0001) { af_dbg("AE-stable success," " count=%d, delay=%dms\n", count, - state->one_frame_delay_ms); + AE_STABLE_SEARCH_DELAY); break; } - msleep(state->one_frame_delay_ms); + msleep(AE_STABLE_SEARCH_DELAY); } /* restore write mode */ @@ -1345,10 +1345,10 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd) if (unlikely(count >= AE_STABLE_SEARCH_COUNT)) { cam_err("%s: ERROR, AE unstable." " count=%d, delay=%dms\n", - __func__, count, state->one_frame_delay_ms); + __func__, count, AE_STABLE_SEARCH_DELAY); /* return -ENODEV; */ } - } else if (state->focus.start == AUTO_FOCUS_OFF) { + } else if (state->focus.cancel) { cam_info("af_start_preflash: AF is cancelled!\n"); state->focus.status = AF_RESULT_CANCELLED; } @@ -1364,6 +1364,7 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd) state->focus.preflash = PREFLASH_NONE; } + state->focus.cancel = 0; if (state->focus.touch) state->focus.touch = 0; } @@ -1408,7 +1409,7 @@ static int s5k5ccgx_do_af(struct v4l2_subdev *sd) /*1st search*/ for (count = 0; count < FIRST_AF_SEARCH_COUNT; count++) { - if (state->focus.start == AUTO_FOCUS_OFF) { + if (state->focus.cancel) { cam_dbg("do_af: AF is cancelled while doing(1st)\n"); state->focus.status = AF_RESULT_CANCELLED; goto check_done; @@ -1423,7 +1424,7 @@ static int s5k5ccgx_do_af(struct v4l2_subdev *sd) if (read_value != 0x01) break; - msleep(state->one_frame_delay_ms); + msleep(AF_SEARCH_DELAY); } if (read_value != 0x02) { @@ -1436,14 +1437,14 @@ static int s5k5ccgx_do_af(struct v4l2_subdev *sd) /*2nd search*/ cam_dbg("AF 2nd search\n"); for (count = 0; count < SECOND_AF_SEARCH_COUNT; count++) { - msleep(state->one_frame_delay_ms); - - if (state->focus.start == AUTO_FOCUS_OFF) { + if (state->focus.cancel) { cam_dbg("do_af: AF is cancelled while doing(2nd)\n"); state->focus.status = AF_RESULT_CANCELLED; goto check_done; } + msleep(AF_SEARCH_DELAY); + read_value = 0x0FFFF; s5k5ccgx_i2c_write_twobyte(client, 0x002C, 0x7000); s5k5ccgx_i2c_write_twobyte(client, 0x002E, 0x1F2F); @@ -1472,11 +1473,12 @@ check_done: * But we now unlock it unconditionally if AF is started, */ if (state->focus.status == AF_RESULT_CANCELLED) { - cam_dbg("%s: Single AF cancelled.\n", __func__); + cam_dbg("do_af: Single AF cancelled\n"); s5k5ccgx_set_lock(sd, AEAWB_UNLOCK, false); + state->focus.cancel = 0; } else { state->focus.start = AUTO_FOCUS_OFF; - cam_dbg("%s: Single AF finished\n", __func__); + cam_dbg("do_af: Single AF finished\n"); } if ((state->focus.preflash == PREFLASH_ON) && @@ -1519,14 +1521,18 @@ static int s5k5ccgx_set_af(struct v4l2_subdev *sd, s32 val) state->focus.start = val; if (val == AUTO_FOCUS_ON) { + state->focus.cancel = 0; err = queue_work(state->workqueue, &state->af_work); - if (likely(err)) - state->focus.status = AF_RESULT_DOING; - else - cam_warn("WARNING, AF is still processing. So new AF cannot start\n"); + if (unlikely(!err)) { + cam_warn("AF is still operating!\n"); + return 0; + } + + state->focus.status = AF_RESULT_DOING; } else { /* Cancel AF */ cam_info("set_af: AF cancel requested!\n"); + state->focus.cancel = 1; } cam_trace("X\n"); @@ -1540,7 +1546,7 @@ static int s5k5ccgx_stop_af(struct v4l2_subdev *sd) int err = 0; cam_trace("E\n"); - mutex_lock(&state->af_lock); + /* mutex_lock(&state->af_lock); */ switch (state->focus.status) { case AF_RESULT_FAILED: @@ -1568,23 +1574,15 @@ static int s5k5ccgx_stop_af(struct v4l2_subdev *sd) break; } - if (!state->focus.touch) { - /* We move lens to default position if af is cancelled.*/ - err = s5k5ccgx_return_focus(sd); - if (unlikely(err)) { - cam_err("%s: ERROR, fail to af_norma_mode (%d)\n", - __func__, err); - goto err_out; - } - } else + if (state->focus.touch) state->focus.touch = 0; - mutex_unlock(&state->af_lock); + /* mutex_unlock(&state->af_lock); */ cam_trace("X\n"); return 0; err_out: - mutex_unlock(&state->af_lock); + /* mutex_unlock(&state->af_lock); */ return err; } @@ -1593,22 +1591,39 @@ static void s5k5ccgx_af_worker(struct work_struct *work) struct s5k5ccgx_state *state = container_of(work, \ struct s5k5ccgx_state, af_work); struct v4l2_subdev *sd = &state->sd; + struct s5k5ccgx_interval *win_stable = &state->focus.win_stable; + u32 touch_win_delay = 0; + s32 interval = 0; int err = -EINVAL; cam_trace("E\n"); mutex_lock(&state->af_lock); + state->focus.reset_done = 0; if (state->sensor_mode == SENSOR_CAMERA) { state->one_frame_delay_ms = ONE_FRAME_DELAY_MS_NORMAL; + touch_win_delay = ONE_FRAME_DELAY_MS_LOW; err = s5k5ccgx_af_start_preflash(sd); if (unlikely(err)) goto out; if (state->focus.status == AF_RESULT_CANCELLED) goto out; - } else { - state->one_frame_delay_ms = 50; + } else + state->one_frame_delay_ms = touch_win_delay = 50; + + /* sleep here for the time needed for af window before do_af. */ + if (state->focus.touch) { + do_gettimeofday(&win_stable->curr_time); + interval = GET_ELAPSED_TIME(win_stable->curr_time, \ + win_stable->before_time) / 1000; + if (interval < touch_win_delay) { + cam_dbg("window stable: %dms + %dms\n", interval, + touch_win_delay - interval); + debug_msleep(sd, touch_win_delay - interval); + } else + cam_dbg("window stable: %dms\n", interval); } s5k5ccgx_do_af(sd); @@ -1623,19 +1638,36 @@ out: static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val) { struct s5k5ccgx_state *state = to_state(sd); - u32 af_cancel = 0; + u32 cancel = 0; + u8 focus_mode = (u8)val; int err = -EINVAL; /* cam_trace("E\n");*/ - cam_dbg("%s val =%d(0x%X)\n", __func__, val, val); if (state->focus.mode == val) return 0; - af_cancel = (u32)val & FOCUS_MODE_DEFAULT; + cancel = (u32)val & FOCUS_MODE_DEFAULT; + + /* Do nothing if cancel request occurs when af is being finished*/ + if (cancel && (state->focus.status == AF_RESULT_DOING)) { + state->focus.cancel = 1; + return 0; + } + + cam_dbg("%s val =%d(0x%X)\n", __func__, val, val); + mutex_lock(&state->af_lock); + if (cancel) { + s5k5ccgx_stop_af(sd); + if (state->focus.reset_done) { + cam_dbg("AF is already cancelled fully\n"); + goto out; + } + state->focus.reset_done = 1; + } - switch (val) { + switch (focus_mode) { case FOCUS_MODE_MACRO: err = s5k5ccgx_set_from_table(sd, "af_macro_mode", &state->regs->af_macro_mode, 1, 0); @@ -1645,7 +1677,7 @@ static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val) goto err_out; } - state->focus.mode = FOCUS_MODE_MACRO; + state->focus.mode = focus_mode; break; case FOCUS_MODE_INFINITY: @@ -1659,7 +1691,7 @@ static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val) goto err_out; } - state->focus.mode = val; + state->focus.mode = focus_mode; break; case FOCUS_MODE_FACEDETECT: @@ -1668,18 +1700,14 @@ static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val) break; default: - if (!af_cancel) { - cam_err("%s: ERROR, invalid val(0x%X)\n:", - __func__, val); - goto err_out; - } + cam_err("%s: ERROR, invalid val(0x%X)\n:", + __func__, val); + goto err_out; break; } - mutex_unlock(&state->af_lock); - - if (af_cancel) - s5k5ccgx_stop_af(sd); +out: + mutex_unlock(&state->af_lock); return 0; err_out: @@ -1820,11 +1848,11 @@ static int s5k5ccgx_set_af_window(struct v4l2_subdev *sd) err |= s5k5ccgx_i2c_write_twobyte(client, 0x002A, 0x023C); err |= s5k5ccgx_i2c_write_twobyte(client, 0x0F12, 0x0001); - debug_msleep(sd, 60); + do_gettimeofday(&state->focus.win_stable.before_time); mutex_unlock(&state->af_lock); CHECK_ERR(err); - cam_dbg("%s: AF window position completed.\n", __func__); + cam_info("AF window position completed.\n"); cam_trace("X\n"); return 0; @@ -1842,17 +1870,15 @@ static int s5k5ccgx_set_touch_af(struct v4l2_subdev *sd, s32 val) if (val) { if (mutex_is_locked(&state->af_lock)) { - cam_warn("%s: WARNING, AF is busy\n", __func__); + cam_warn("%s: AF is still operating!\n", __func__); return 0; } err = queue_work(state->workqueue, &state->af_win_work); if (likely(!err)) cam_warn("WARNING, AF window is still processing\n"); - } else { - err = s5k5ccgx_stop_af(sd); - CHECK_ERR_MSG(err, "val=%d\n", 0) - } + } else + cam_info("set_touch_af: invalid value %d\n", val); cam_trace("X\n"); return 0; @@ -2005,7 +2031,7 @@ static void s5k5ccgx_set_framesize(struct v4l2_subdev *sd, static int s5k5ccgx_wait_steamoff(struct v4l2_subdev *sd) { struct s5k5ccgx_state *state = to_state(sd); - struct s5k5ccgx_stream_time *stream_time = &state->stream_time; + struct s5k5ccgx_interval *stream_time = &state->stream_time; s32 elapsed_msec = 0; cam_trace("E\n"); @@ -2204,6 +2230,8 @@ static inline void s5k5ccgx_get_exif_flash(struct v4l2_subdev *sd, { struct s5k5ccgx_state *state = to_state(sd); + *flash = 0; + switch (state->flash_mode) { case FLASH_MODE_OFF: *flash |= EXIF_FLASH_MODE_SUPPRESSION; @@ -2247,7 +2275,6 @@ static int s5k5ccgx_get_exif(struct v4l2_subdev *sd) s5k5ccgx_get_exif_iso(sd, &state->exif.iso); /* flash */ - state->exif.flash = 0; s5k5ccgx_get_exif_flash(sd, &state->exif.flash); cam_dbg("EXIF: ex_time_den=%d, iso=%d, flash=0x%02X\n", diff --git a/drivers/media/video/s5k5ccgx.h b/drivers/media/video/s5k5ccgx.h index 09657b7..a8ac24c 100644 --- a/drivers/media/video/s5k5ccgx.h +++ b/drivers/media/video/s5k5ccgx.h @@ -245,6 +245,15 @@ struct s5k5ccgx_framesize { #define FRM_RATIO(framesize) \ (((framesize)->width) * 10 / ((framesize)->height)) +struct s5k5ccgx_interval { + struct timeval curr_time; + struct timeval before_time; +}; + +#define GET_ELAPSED_TIME(cur, before) \ + (((cur).tv_sec - (before).tv_sec) * USEC_PER_SEC \ + + ((cur).tv_usec - (before).tv_usec)) + struct s5k5ccgx_fps { u32 index; u32 fps; @@ -312,6 +321,8 @@ struct s5k5ccgx_gps_info { }; struct s5k5ccgx_focus { + struct s5k5ccgx_interval win_stable; + enum v4l2_focusmode mode; enum af_result_status status; enum preflash_status preflash; @@ -323,7 +334,8 @@ struct s5k5ccgx_focus { u32 ae_lock:1; u32 awb_lock:1; u32 touch:1; - u32 af_cancel:1; + u32 reset_done:1; + u32 cancel:1; }; struct s5k5ccgx_exif { @@ -337,8 +349,8 @@ struct s5k5ccgx_exif { /* EXIF - flash filed */ #define EXIF_FLASH_FIRED (0x01) -#define EXIF_FLASH_MODE_FIRING (0x01) -#define EXIF_FLASH_MODE_SUPPRESSION (0x01 << 1) +#define EXIF_FLASH_MODE_FIRING (0x01 << 3) +#define EXIF_FLASH_MODE_SUPPRESSION (0x02 << 3) #define EXIF_FLASH_MODE_AUTO (0x03 << 3) struct s5k5ccgx_regset { @@ -346,15 +358,6 @@ struct s5k5ccgx_regset { u8 *data; }; -struct s5k5ccgx_stream_time { - struct timeval curr_time; - struct timeval before_time; -}; - -#define GET_ELAPSED_TIME(cur, before) \ - (((cur).tv_sec - (before).tv_sec) * USEC_PER_SEC \ - + ((cur).tv_usec - (before).tv_usec)) - #ifdef CONFIG_LOAD_FILE #define DEBUG_WRITE_REGS struct s5k5ccgx_regset_table { @@ -476,7 +479,7 @@ struct s5k5ccgx_state { #if !defined(FEATURE_YUV_CAPTURE) struct s5k5ccgx_jpeg_param jpeg; #endif - struct s5k5ccgx_stream_time stream_time; + struct s5k5ccgx_interval stream_time; const struct s5k5ccgx_regs *regs; struct mutex ctrl_lock; struct mutex af_lock; @@ -555,9 +558,12 @@ static inline void debug_msleep(struct v4l2_subdev *sd, u32 msecs) #define FLASH_LOW_LIGHT_LEVEL 0x4A #endif /* CONFIG_VIDEO_S5K5CCGX_P2 */ -#define FIRST_AF_SEARCH_COUNT 80 -#define SECOND_AF_SEARCH_COUNT 80 -#define AE_STABLE_SEARCH_COUNT 7 /* 4->7. but ae-unstable still occurs. */ +#define FIRST_AF_SEARCH_COUNT 220 +#define SECOND_AF_SEARCH_COUNT 220 +#define AE_STABLE_SEARCH_COUNT 22 + +#define AF_SEARCH_DELAY 33 +#define AE_STABLE_SEARCH_DELAY 33 /* Sensor AF first,second window size. * we use constant values intead of reading sensor register */ diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile index 301cd9a..639d3bc 100644 --- a/drivers/media/video/samsung/Makefile +++ b/drivers/media/video/samsung/Makefile @@ -11,8 +11,27 @@ else obj-$(CONFIG_VIDEO_FIMG2D3X) += fimg2d3x/ obj-$(CONFIG_VIDEO_FIMG2D4X) += fimg2d4x/ endif + +ifeq ($(CONFIG_MACH_U1), y) +obj-$(CONFIG_VIDEO_UMP) += ump/ +else ifeq ($(CONFIG_MACH_SMDKC210), y) obj-$(CONFIG_VIDEO_UMP) += ump/ +else ifeq ($(CONFIG_MACH_SMDKV310), y) +obj-$(CONFIG_VIDEO_UMP) += ump/ +else +obj-$(CONFIG_VIDEO_UMP) += ump/ +endif + obj-$(CONFIG_VIDEO_TSI) += tsi/ + +ifeq ($(CONFIG_MACH_U1), y) +obj-$(CONFIG_VIDEO_MALI400MP) += mali/ +else ifeq ($(CONFIG_MACH_SMDKC210), y) +obj-$(CONFIG_VIDEO_MALI400MP) += mali/ +else ifeq ($(CONFIG_MACH_SMDKV310), y) obj-$(CONFIG_VIDEO_MALI400MP) += mali/ +else +obj-$(CONFIG_VIDEO_MALI400MP) += mali/ +endif EXTRA_CFLAGS += -Idrivers/media/video diff --git a/drivers/media/video/samsung/fimc/Kconfig b/drivers/media/video/samsung/fimc/Kconfig index 68f0b14..2fc4c86 100644 --- a/drivers/media/video/samsung/fimc/Kconfig +++ b/drivers/media/video/samsung/fimc/Kconfig @@ -6,6 +6,15 @@ config VIDEO_FIMC help This is a video4linux driver for Samsung FIMC device. +config USE_FIMC_CMA + bool "Use CMA for FIMC0/1 region (EXPERIMENTAL)" + depends on DMA_CMA + default n + help + This enables the Contiguous Memory Allocator for MFC SECURE region. + + If unsure, say "n". + choice depends on VIDEO_FIMC prompt "Select CSC Range config" diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h index 9527f52..b648965 100644 --- a/drivers/media/video/samsung/fimc/fimc.h +++ b/drivers/media/video/samsung/fimc/fimc.h @@ -25,6 +25,9 @@ #include #include #include +#ifdef CONFIG_SLP_DMABUF +#include +#endif #include #if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) #include @@ -42,7 +45,9 @@ #define FIMC_CMA_NAME "fimc" #define FIMC_CORE_CLK "sclk_fimc" -#define FIMC_CLK_RATE 166750000 + +extern int fimc_clk_rate(void); + #define EXYNOS_BUSFREQ_NAME "exynos-busfreq" #if defined(CONFIG_ARCH_EXYNOS4) @@ -58,7 +63,11 @@ #define FIMC_SUBDEVS 3 #define FIMC_OUTBUFS 3 #define FIMC_INQUEUES 10 +#if defined(CONFIG_SLP) +#define FIMC_MAX_CTXS 8 +#else #define FIMC_MAX_CTXS 4 +#endif #define FIMC_TPID 3 #define FIMC_CAPBUFS 32 #define FIMC_ONESHOT_TIMEOUT 200 @@ -205,12 +214,22 @@ enum cam_mclk_status { CAM_MCLK_ON, }; +enum fimc_plane_num { + PLANE_1 = 0x1, + PLANE_2 = 0x2, + PLANE_3 = 0x3, + PLANE_4 = 0x4, +}; + /* * STRUCTURES */ /* for reserved memory */ struct fimc_meminfo { +#ifdef CONFIG_USE_FIMC_CMA + void *cpu_addr; +#endif dma_addr_t base; /* buffer base */ size_t size; /* total length */ dma_addr_t curr; /* current addr */ @@ -263,6 +282,9 @@ struct fimc_capinfo { /* using c210 */ struct list_head outgoing_q; int nr_bufs; +#ifdef CONFIG_SLP_DMABUF + int nr_plane; +#endif int irq; int lastirq; @@ -326,6 +348,9 @@ struct fimc_ctx { struct fimc_overlay overlay; u32 buf_num; +#ifdef CONFIG_SLP_DMABUF + int nr_plane; +#endif u32 is_requested; struct fimc_buf_set src[FIMC_OUTBUFS]; struct fimc_buf_set dst[FIMC_OUTBUFS]; @@ -477,6 +502,10 @@ struct fimc_control { struct timeval before_time; char cma_name[16]; bool restart; +#ifdef CONFIG_SLP_DMABUF + struct vb2_buffer *out_bufs[VIDEO_MAX_FRAME]; + struct vb2_buffer *cap_bufs[VIDEO_MAX_FRAME]; +#endif }; /* global */ @@ -766,5 +795,16 @@ static inline struct fimc_control *get_fimc_ctrl(int id) { return &fimc_dev->ctrl[id]; } +#ifdef CONFIG_SLP_DMABUF +extern void _fimc_queue_free(struct fimc_control *ctrl, + enum v4l2_buf_type type); +extern int fimc_queue_alloc(struct fimc_control *ctrl, enum v4l2_buf_type type, + enum v4l2_memory memory, unsigned int num_buffers, + unsigned int num_planes); +extern int _qbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb, + struct v4l2_buffer *b); +extern int _dqbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb, + struct v4l2_buffer *b); +#endif #endif /* __FIMC_H */ diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c index fe0878a..7d00c8b 100644 --- a/drivers/media/video/samsung/fimc/fimc_capture.c +++ b/drivers/media/video/samsung/fimc/fimc_capture.c @@ -203,6 +203,9 @@ static const struct v4l2_queryctrl fimc_controls[] = { .default_value = 0, }, }; +#ifdef CONFIG_MACH_GC1 +static bool leave_power; +#endif #ifndef CONFIG_VIDEO_FIMC_MIPI void s3c_csis_start(int csis_id, int lanes, int settle, \ @@ -268,7 +271,12 @@ static int fimc_init_camera(struct fimc_control *ctrl) retry: /* set rate for mclk */ +#ifndef CONFIG_MACH_GC1 if ((clk_get_rate(cam->clk)) && (fimc->mclk_status == CAM_MCLK_OFF)) { +#else + if ((clk_get_rate(cam->clk)) && (fimc->mclk_status == CAM_MCLK_OFF) + && !leave_power) { +#endif clk_set_rate(cam->clk, cam->clk_rate); clk_enable(cam->clk); fimc->mclk_status = CAM_MCLK_ON; @@ -277,7 +285,14 @@ retry: /* enable camera power if needed */ if (cam->cam_power) { +#ifndef CONFIG_MACH_GC1 ret = cam->cam_power(1); +#else + if (!leave_power) + ret = cam->cam_power(1); + + leave_power = false; +#endif if (unlikely(ret < 0)) { fimc_err("\nfail to power on\n"); if (fimc->mclk_status == CAM_MCLK_ON) { @@ -720,11 +735,19 @@ int fimc_release_subdev(struct fimc_control *ctrl) client = v4l2_get_subdevdata(ctrl->cam->sd); i2c_unregister_device(client); ctrl->cam->sd = NULL; +#ifndef CONFIG_MACH_GC1 if (ctrl->cam->cam_power) +#else + if (ctrl->cam->cam_power && !leave_power) +#endif ctrl->cam->cam_power(0); /* shutdown the MCLK */ +#ifndef CONFIG_MACH_GC1 if (fimc->mclk_status == CAM_MCLK_ON) { +#else + if (fimc->mclk_status == CAM_MCLK_ON && !leave_power) { +#endif clk_disable(ctrl->cam->clk); fimc->mclk_status = CAM_MCLK_OFF; } @@ -801,9 +824,13 @@ static int fimc_configure_subdev(struct fimc_control *ctrl) ret = fimc_init_camera(ctrl); if (ret < 0) { fimc_err("%s: fail to initialize subdev\n", __func__); + +#ifndef CONFIG_MACH_GC1 client = v4l2_get_subdevdata(sd); i2c_unregister_device(client); ctrl->cam->sd = NULL; +#endif + return ret; } } @@ -1052,9 +1079,6 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i) } #else ctrl->cam = NULL; -#ifdef CONFIG_MACH_P4NOTE - fimc_release_subdev(ctrl); -#endif /* CONFIG_MACH_P4NOTE */ mutex_unlock(&ctrl->v4l2_lock); fimc_err("%s: Could not register camera" \ " sensor with V4L2.\n", __func__); @@ -1117,20 +1141,43 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i) } ret = v4l2_subdev_call(ctrl->is.sd, core, s_power, 1); if (ret < 0) { - fimc_dbg("FIMC-IS init failed"); + fimc_err("FIMC-IS init s_power failed"); mutex_unlock(&ctrl->v4l2_lock); return -ENODEV; } ret = v4l2_subdev_call(ctrl->is.sd, core, load_fw); if (ret < 0) { - fimc_dbg("FIMC-IS init failed"); + fimc_err("FIMC-IS init load_fw failed"); mutex_unlock(&ctrl->v4l2_lock); + if (!cap) { + cap = kzalloc(sizeof(*cap), GFP_KERNEL); + if (!cap) { + fimc_err("%s: no memory for " + "capture device info\n", __func__); + return -ENOMEM; + } + + /* assign to ctrl */ + ctrl->cap = cap; + } return -ENODEV; } ret = v4l2_subdev_call(ctrl->is.sd, core, init, ctrl->cam->sensor_index); if (ret < 0) { - fimc_dbg("FIMC-IS init failed"); + fimc_err("FIMC-IS init failed"); mutex_unlock(&ctrl->v4l2_lock); + if (!cap) { + cap = kzalloc(sizeof(*cap), GFP_KERNEL); + if (!cap) { + fimc_err("%s: no memory for " + "capture device info\n", __func__); + return -ENOMEM; + } + + /* assign to ctrl */ + ctrl->cap = cap; + } + return -ENODEV; } } @@ -1188,6 +1235,81 @@ int fimc_enum_fmt_vid_capture(struct file *file, void *fh, return 0; } +#ifdef CONFIG_SLP_DMABUF +/* + * figures out the depth of requested format + */ +static int fimc_fmt_depth_mplane(struct fimc_control *ctrl, + struct v4l2_format *f, int depth[]) +{ + int ret = 0; + + /* handles only supported pixelformats */ + switch (f->fmt.pix_mp.pixelformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_NV21: + f->fmt.pix_mp.num_planes = 2; + depth[0] = 8; + depth[1] = 4; + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + f->fmt.pix_mp.num_planes = 3; + depth[0] = 8; + depth[1] = 2; + depth[2] = 2; + break; + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_INTERLEAVED: + f->fmt.pix_mp.num_planes = 1; + depth[0] = -1; + fimc_dbg("Compressed format.\n"); + break; + default: + fimc_dbg("why am I here?\n"); + ret = -EINVAL; + break; + } + + return ret; +} +static int fimc_g_fmt_vid_capture_mplane(struct fimc_control *ctrl, + struct v4l2_format *f) +{ + int depth[VIDEO_MAX_PLANES]; + int ret; + int i; + + /* + * Note that expecting format only can be with + * available output format from FIMC + * Following items should be handled in driver + * bytesperline = width * depth / 8 + * sizeimage = bytesperline * height + */ + + f->fmt.pix_mp.pixelformat = ctrl->cap->fmt.pixelformat; + f->fmt.pix_mp.width = ctrl->cap->fmt.width; + f->fmt.pix_mp.height = ctrl->cap->fmt.height; + + ret = fimc_fmt_depth_mplane(ctrl, f, depth); + if (ret < 0) { + fimc_err("Invaild format\n"); + return ret; + } + for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) { + f->fmt.pix_mp.plane_fmt[i].bytesperline = (f->fmt.pix_mp.width * + depth[i]) >> 3; + f->fmt.pix_mp.plane_fmt[i].sizeimage = + (f->fmt.pix_mp.plane_fmt[i].bytesperline * + f->fmt.pix_mp.width); + } + + return 0; +} +#endif + int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) { struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; @@ -1201,8 +1323,20 @@ int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) mutex_lock(&ctrl->v4l2_lock); +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) + if (fimc_g_fmt_vid_capture_mplane(ctrl, f) < 0) { + mutex_unlock(&ctrl->v4l2_lock); + return -EINVAL; + } + else { + memset(&f->fmt.pix, 0, sizeof(f->fmt.pix)); + memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix)); + } +#else memset(&f->fmt.pix, 0, sizeof(f->fmt.pix)); memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix)); +#endif mutex_unlock(&ctrl->v4l2_lock); @@ -1308,7 +1442,7 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f) */ mbus_fmt->field = pix->field; #endif -#if (defined(CONFIG_MACH_S2PLUS) || defined(CONFIG_MACH_GC1)) +#if defined(CONFIG_MACH_GC1) mbus_fmt->field = pix->priv; #endif printk(KERN_INFO "%s mbus_fmt->width = %d, height = %d,\n", @@ -1392,7 +1526,17 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) mutex_lock(&ctrl->v4l2_lock); memset(&cap->fmt, 0, sizeof(cap->fmt)); +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) { + cap->fmt.pixelformat = f->fmt.pix_mp.pixelformat; + cap->fmt.width = f->fmt.pix_mp.width; + cap->fmt.height = f->fmt.pix_mp.height; + cap->fmt.pixelformat = f->fmt.pix_mp.pixelformat; + } else + memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt)); +#else memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt)); +#endif /* * Note that expecting format only can be with @@ -1434,7 +1578,11 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) Fimc scaler input Hsize is restricted to 4224 pixels. So, GC1 has to bypass fimc scaler to use more than 12M YUV. */ - ctrl->sc.bypass = 1; + if (cap->fmt.width > ctrl->limit->pre_dst_w) + ctrl->sc.bypass = 1; + else + ctrl->sc.bypass = 0; + #else ctrl->sc.bypass = 0; #endif @@ -1636,6 +1784,43 @@ static void fimc_free_buffers(struct fimc_control *ctrl) ctrl->mem.curr = ctrl->mem.base; } +#ifdef CONFIG_SLP_DMABUF +static int fimc_set_cap_num_plane(struct fimc_control *ctrl) +{ + struct fimc_capinfo *cap = ctrl->cap; + + switch (cap->fmt.pixelformat) { + case V4L2_PIX_FMT_RGB32: /* fall through */ + case V4L2_PIX_FMT_RGB565: /* fall through */ + case V4L2_PIX_FMT_YUYV: /* fall through */ + case V4L2_PIX_FMT_UYVY: /* fall through */ + case V4L2_PIX_FMT_VYUY: /* fall through */ + case V4L2_PIX_FMT_YVYU: /* fall through */ + case V4L2_PIX_FMT_NV16: /* fall through */ + case V4L2_PIX_FMT_NV61: /* fall through */ + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_INTERLEAVED: + return PLANE_1; + + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + return PLANE_2; + + case V4L2_PIX_FMT_YUV422P: /* fall through */ + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + return PLANE_3; + + default: + fimc_err("%s: Undefined format\n", __func__); + break; + } + + return 0; +} +#endif + int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b) { struct fimc_control *ctrl = fh; @@ -1825,7 +2010,10 @@ int fimc_reqbufs_capture_userptr(void *fh, struct v4l2_requestbuffers *b) fimc_streamoff_capture(fh); fimc_free_buffers(ctrl); - +#ifdef CONFIG_SLP_DMABUF + if (b->memory == V4L2_MEMORY_DMABUF) + _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_CAPTURE); +#endif mutex_unlock(&ctrl->v4l2_lock); return 0; } @@ -1837,6 +2025,19 @@ int fimc_reqbufs_capture_userptr(void *fh, struct v4l2_requestbuffers *b) } cap->nr_bufs = b->count; +#ifdef CONFIG_SLP_DMABUF + if (b->memory == V4L2_MEMORY_DMABUF) { + int num_planes; + + num_planes = fimc_set_cap_num_plane(ctrl); + if (!num_planes) { + mutex_unlock(&ctrl->v4l2_lock); + return 0; + } + fimc_queue_alloc(ctrl, b->type, b->memory, + cap->nr_bufs, num_planes); + } +#endif #if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)) if (ctrl->power_status == FIMC_POWER_OFF) { @@ -1996,33 +2197,45 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c) switch (c->id) { #ifdef CONFIG_MACH_GC1 - case V4L2_CID_CAM_UPDATE_FW: - if (fimc->mclk_status == CAM_MCLK_ON) { - if (ctrl->cam->cam_power) - ctrl->cam->cam_power(0); + case V4L2_CID_CAMERA_HOLD_LENS: + leave_power = true; + ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c); + break; - /* shutdown the MCLK */ - clk_disable(ctrl->cam->clk); - fimc->mclk_status = CAM_MCLK_OFF; + case V4L2_CID_CAM_UPDATE_FW: + if (c->value == FW_MODE_UPDATE || c->value == FW_MODE_DUMP) { + if (fimc->mclk_status == CAM_MCLK_ON) { + if (ctrl->cam->cam_power) + ctrl->cam->cam_power(0); - mdelay(5); - } + /* shutdown the MCLK */ + clk_disable(ctrl->cam->clk); + fimc->mclk_status = CAM_MCLK_OFF; - if ((clk_get_rate(ctrl->cam->clk)) && (fimc->mclk_status == CAM_MCLK_OFF)) { - clk_set_rate(ctrl->cam->clk, ctrl->cam->clk_rate); - clk_enable(ctrl->cam->clk); - fimc->mclk_status = CAM_MCLK_ON; - fimc_info1("clock for camera: %d\n", ctrl->cam->clk_rate); + mdelay(5); + } - if (ctrl->cam->cam_power) - ctrl->cam->cam_power(1); - } + if ((clk_get_rate(ctrl->cam->clk)) && + (fimc->mclk_status == CAM_MCLK_OFF)) { + clk_set_rate(ctrl->cam->clk, + ctrl->cam->clk_rate); + clk_enable(ctrl->cam->clk); + fimc->mclk_status = CAM_MCLK_ON; + fimc_info1("clock for camera: %d\n", + ctrl->cam->clk_rate); + + if (ctrl->cam->cam_power) + ctrl->cam->cam_power(1); + } - if (c->value == FW_MODE_UPDATE) - ret = v4l2_subdev_call(ctrl->cam->sd, core, load_fw); + if (c->value == FW_MODE_UPDATE) + ret = v4l2_subdev_call(ctrl->cam->sd, core, load_fw); + else + ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c); - else + } else { ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c); + } break; #endif case V4L2_CID_CAMERA_RESET: @@ -2206,6 +2419,12 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c) break; #endif + case V4L2_CID_CAMERA_SET_DUAL_CAPTURE: + case V4L2_CID_CAMERA_DUAL_CAPTURE: + case V4L2_CID_CAMERA_DUAL_POSTVIEW: + ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c); + break; + case V4L2_CID_IS_CAMERA_FLASH_MODE: case V4L2_CID_CAMERA_SCENE_MODE: default: @@ -2445,6 +2664,9 @@ int fimc_streamon_capture(void *fh) struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev); printk(KERN_INFO "%s++ fimc%d\n", __func__, ctrl->id); +#ifdef CONFIG_SLP + cam_frmsize.index = -1; +#endif cam_frmsize.discrete.width = 0; cam_frmsize.discrete.height = 0; is_ctrl.id = 0; @@ -2617,7 +2839,7 @@ int fimc_streamon_capture(void *fh) if (!ctrl->is.sd && cap->movie_mode && !((cam->width == 880 && cam->height == 720))) { printk(KERN_INFO "\n\n\n%s pm_qos_req is called..\n", __func__ ); - dev_lock(ctrl->bus_dev, ctrl->dev, (unsigned long)400200); + /*dev_lock(ctrl->bus_dev, ctrl->dev, (unsigned long)400200);*/ pm_qos_add_request(&bus_qos_pm_qos_req, PM_QOS_BUS_QOS, 1); /* ioremap for register block */ @@ -2746,6 +2968,15 @@ int fimc_streamoff_capture(void *fh) v4l2_subdev_call(ctrl->cam->sd, video, s_stream, 0); #endif + /* Set FIMD to write back */ + if ((ctrl->cam->id == CAMERA_WB) || (ctrl->cam->id == CAMERA_WB_B)) { + ret = s3cfb_direct_ioctl(0, S3CFB_SET_WRITEBACK, 0); + if (ret) { + fimc_err("failed set writeback\n"); + return ret; + } + } + /* wait for stop hardware */ fimc_wait_disable_capture(ctrl); @@ -2783,7 +3014,7 @@ int fimc_streamoff_capture(void *fh) !(ctrl->cam->width == 880 && ctrl->cam->height == 720)) { printk(KERN_INFO "\n\n\n%s pm_qos_req is removed..\n", __func__ ); pm_qos_remove_request(&bus_qos_pm_qos_req); - dev_unlock(ctrl->bus_dev, ctrl->dev); + /*dev_unlock(ctrl->bus_dev, ctrl->dev);*/ /* ioremap for register block */ qos_regs = ioremap(0x11a00400, 0x10); @@ -2798,14 +3029,6 @@ int fimc_streamoff_capture(void *fh) iounmap(qos_regs); } - /* Set FIMD to write back */ - if ((ctrl->cam->id == CAMERA_WB) || (ctrl->cam->id == CAMERA_WB_B)) { - ret = s3cfb_direct_ioctl(0, S3CFB_SET_WRITEBACK, 0); - if (ret) { - fimc_err("failed set writeback\n"); - return ret; - } - } /* disable camera power */ /* cam power off should call in the subdev release function */ if (fimc_cam_use) { @@ -2904,7 +3127,7 @@ static void fimc_buf2bs(struct fimc_buf_set *bs, struct fimc_buf *buf) int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) { struct fimc_control *ctrl = fh; - struct fimc_buf *buf = (struct fimc_buf *)b->m.userptr; + struct fimc_buf *buf; struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev); struct fimc_capinfo *cap = ctrl->cap; int idx = b->index; @@ -2926,8 +3149,58 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b) return -EINVAL; } else { if (b->memory == V4L2_MEMORY_USERPTR) { + buf = (struct fimc_buf *)b->m.userptr; fimc_buf2bs(&cap->bufs[idx], buf); fimc_hwset_output_address(ctrl, &cap->bufs[idx], idx); +#ifdef CONFIG_SLP_DMABUF + } else if (b->memory == V4L2_MEMORY_DMABUF) { + struct vb2_buffer *vb; + struct sg_table *sg; + struct dma_buf_attachment *dba; + struct fimc_buf fimc_buf; + int ret; + unsigned int size; + + vb = ctrl->cap_bufs[b->index]; + + ret = _qbuf_dmabuf(ctrl, vb, b); + if (ret < 0) { + fimc_err("%s: _qbuf_dmabuf error.\n", + __func__); + mutex_unlock(&ctrl->v4l2_lock); + return -ENODEV; + } + for (i = 0; i < vb->num_planes; i++) { + dba = vb->planes[i].mem_priv; + sg = dba->priv; + if (sg) { + fimc_buf.base[i] = + sg_dma_address(sg->sgl); + fimc_buf.length[i] = + sg_dma_len(sg->sgl); + } else { + fimc_err("%s: Wrong sg value.\n", + __func__); + mutex_unlock(&ctrl->v4l2_lock); + return -ENODEV; + } + } + fimc_buf2bs(&cap->bufs[idx], &fimc_buf); + fimc_hwset_output_address(ctrl, &cap->bufs[idx], + idx); + if (cap->pktdata_enable) { + size = + fimc_buf.length[vb->num_planes-1]; + cap->bufs[b->index].vaddr_pktdata = + phys_to_virt( + cap->bufs[b->index].base + [vb->num_planes-1] + size); + cap->pktdata_plane = vb->num_planes; + + /* Size of packet data is fixed */ + cap->pktdata_size = 0x1000; + } +#endif } fimc_hwset_output_buf_sequence(ctrl, idx, FIMC_FRAMECNT_SEQ_ENABLE); @@ -3040,8 +3313,23 @@ int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b) b->index = bs->id; bs->state = VIDEOBUF_IDLE; - if (b->memory == V4L2_MEMORY_USERPTR) + if (b->memory == V4L2_MEMORY_USERPTR) { fimc_bs2buf(buf, bs); +#ifdef CONFIG_SLP_DMABUF + } else if (b->memory == V4L2_MEMORY_DMABUF) { + struct vb2_buffer *vb; + + vb = ctrl->cap_bufs[b->index]; + ret = _dqbuf_dmabuf(ctrl, vb, b); + if (ret < 0) { + fimc_err("%s: _qbuf_dmabuf error.\n", + __func__); + spin_unlock_irqrestore(&ctrl->outq_lock, + spin_flags); + return -ENODEV; + } +#endif + } list_del(&bs->list); } @@ -3123,6 +3411,12 @@ int fimc_enum_framesizes(struct file *filp, void *fh, struct v4l2_frmsizeenum *f struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int i; u32 index = 0; + +#ifdef CONFIG_SLP + if (ctrl->cam && ctrl->cam->sd) + return v4l2_subdev_call(ctrl->cam->sd, video, + enum_framesizes, fsize); +#endif for (i = 0; i < ARRAY_SIZE(capture_fmts); i++) { if (fsize->pixel_format != capture_fmts[i].pixelformat) continue; diff --git a/drivers/media/video/samsung/fimc/fimc_capture_u1.c b/drivers/media/video/samsung/fimc/fimc_capture_u1.c index d21d877..1855abf 100644 --- a/drivers/media/video/samsung/fimc/fimc_capture_u1.c +++ b/drivers/media/video/samsung/fimc/fimc_capture_u1.c @@ -454,11 +454,7 @@ int fimc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) return 0; mutex_lock(&ctrl->v4l2_lock); -#ifdef CONFIG_MACH_S2PLUS - if (ctrl->id == FIMC0) -#else if (ctrl->id != FIMC2) -#endif ret = subdev_call(ctrl, video, s_parm, a); mutex_unlock(&ctrl->v4l2_lock); @@ -654,11 +650,7 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i) if (!fimc->camera_isvalid[i]) return -EINVAL; -#ifdef CONFIG_MACH_S2PLUS - if (fimc->camera[i]->sd && ctrl->id == FIMC0) { -#else if (fimc->camera[i]->sd && ctrl->id != FIMC2) { -#endif fimc_err("%s: Camera already in use.\n", __func__); return -EBUSY; } @@ -685,18 +677,6 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i) printk(KERN_INFO "fimc_s_input activated subdev = %d\n", i); } -#ifdef CONFIG_MACH_S2PLUS - if (ctrl->id == FIMC1) { - if (i == fimc->active_camera) { - ctrl->cam = fimc->camera[i]; - fimc_info2("fimc_s_input activating subdev FIMC1 %d\n", - ctrl->cam->initialized); - } else { - mutex_unlock(&ctrl->v4l2_lock); - return -EINVAL; - } - } -#else if (ctrl->id == FIMC2) { if (i == fimc->active_camera) { ctrl->cam = fimc->camera[i]; @@ -707,7 +687,6 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i) return -EINVAL; } } -#endif /* * The first time alloc for struct cap_info, and will be @@ -973,11 +952,7 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt)); mbus_fmt = &cap->mbus_fmt; -#ifdef CONFIG_MACH_S2PLUS - if (ctrl->id == FIMC0) { -#else if (ctrl->id != FIMC2) { -#endif if (cap->movie_mode || cap->vt_mode || cap->fmt.priv == V4L2_PIX_FMT_MODE_HDR) { #if defined(CONFIG_MACH_PX) && defined(CONFIG_VIDEO_HD_SUPPORT) @@ -1053,11 +1028,7 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f) return 0; } -#ifdef CONFIG_MACH_S2PLUS - if (ctrl->id == FIMC0) -#else if (ctrl->id != FIMC2) -#endif ret = subdev_call(ctrl, video, s_mbus_fmt, mbus_fmt); mutex_unlock(&ctrl->v4l2_lock); @@ -1637,11 +1608,7 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c) if ((ctrl->cam->id == CAMERA_WB) || \ (ctrl->cam->id == CAMERA_WB_B)) break; -#ifdef CONFIG_MACH_S2PLUS - if (FIMC0 == ctrl->id) -#else if (FIMC2 != ctrl->id) -#endif ret = subdev_call(ctrl, core, s_ctrl, c); else ret = 0; @@ -1844,11 +1811,7 @@ int fimc_streamon_capture(void *fh) cam = ctrl->cam; if ((ctrl->cam->id != CAMERA_WB) && (ctrl->cam->id != CAMERA_WB_B)) { -#ifdef CONFIG_MACH_S2PLUS - if (ctrl->id == FIMC0) { -#else if (ctrl->id != FIMC2) { -#endif ret = subdev_call(ctrl, video, enum_framesizes, &cam_frmsize); if (ret < 0) { dev_err(ctrl->dev, "%s: enum_framesizes failed\n", __func__); @@ -2067,11 +2030,7 @@ int fimc_streamoff_capture(void *fh) #if defined(CONFIG_MACH_PX) #ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF -#ifdef CONFIG_MACH_S2PLUS - if ((ctrl->id == FIMC0) && (ctrl->cam->type == CAM_TYPE_MIPI)) -#else if ((ctrl->id != FIMC2) && (ctrl->cam->type == CAM_TYPE_MIPI)) -#endif v4l2_subdev_call(ctrl->cam->sd, video, s_stream, STREAM_MODE_CAM_OFF); #endif /* CONFIG_VIDEO_IMPROVE_STREAMOFF */ @@ -2090,11 +2049,7 @@ int fimc_streamoff_capture(void *fh) INIT_LIST_HEAD(&cap->inq); ctrl->status = FIMC_STREAMOFF; -#ifdef CONFIG_MACH_S2PLUS - if (ctrl->id == FIMC0) { -#else if (ctrl->id != FIMC2) { -#endif if (ctrl->cam->type == CAM_TYPE_MIPI) { if (ctrl->cam->id == CAMERA_CSI_C) s3c_csis_stop(CSI_CH_0); diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c index a0a91cd..1ed79dd 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev.c +++ b/drivers/media/video/samsung/fimc/fimc_dev.c @@ -32,9 +32,12 @@ #include #include #include +#include #include #include #include +#include +#include #include "fimc.h" @@ -711,20 +714,32 @@ static struct fimc_control *fimc_register_controller(struct platform_device *pde /* In Midas project, FIMC2 reserve memory is used by ION driver. */ if (id != 2) { #endif - sprintf(ctrl->cma_name, "%s%d", FIMC_CMA_NAME, ctrl->id); - err = cma_info(&mem_info, ctrl->dev, 0); - fimc_info1("%s : [cma_info] start_addr : 0x%x, end_addr : 0x%x, " - "total_size : 0x%x, free_size : 0x%x\n", - __func__, mem_info.lower_bound, mem_info.upper_bound, - mem_info.total_size, mem_info.free_size); - if (err) { - fimc_err("%s: get cma info failed\n", __func__); - ctrl->mem.size = 0; +#ifdef CONFIG_USE_FIMC_CMA + if (id == 1) { + ctrl->mem.size = + CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K; ctrl->mem.base = 0; - } else { - ctrl->mem.size = mem_info.total_size; - ctrl->mem.base = (dma_addr_t)cma_alloc - (ctrl->dev, ctrl->cma_name, (size_t)ctrl->mem.size, 0); + } else +#endif + { + sprintf(ctrl->cma_name, "%s%d", + FIMC_CMA_NAME, ctrl->id); + err = cma_info(&mem_info, ctrl->dev, 0); + fimc_info1("%s : [cma_info] start_addr : 0x%x, " + " end_addr : 0x%x, total_size : 0x%x, " + "free_size : 0x%x\n", __func__, + mem_info.lower_bound, mem_info.upper_bound, + mem_info.total_size, mem_info.free_size); + if (err) { + fimc_err("%s: get cma info failed\n", __func__); + ctrl->mem.size = 0; + ctrl->mem.base = 0; + } else { + ctrl->mem.size = mem_info.total_size; + ctrl->mem.base = (dma_addr_t)cma_alloc + (ctrl->dev, ctrl->cma_name, + (size_t)ctrl->mem.size, 0); + } } #ifdef CONFIG_ION_EXYNOS } @@ -813,7 +828,7 @@ static struct fimc_control *fimc_register_controller(struct platform_device *pde clk_put(fimc_src_clk); return NULL; } - clk_set_rate(sclk_fimc_lclk, FIMC_CLK_RATE); + clk_set_rate(sclk_fimc_lclk, fimc_clk_rate()); clk_put(sclk_fimc_lclk); clk_put(fimc_src_clk); @@ -1021,6 +1036,255 @@ static int fimc_mmap(struct file *filp, struct vm_area_struct *vma) return ret; } +#ifdef CONFIG_SLP_DMABUF +/** + * _fimc_dmabuf_put() - release memory associated with + * a DMABUF shared buffer + */ +static void _fimc_dmabuf_put(struct vb2_buffer *vb) +{ + unsigned int plane; + + for (plane = 0; plane < vb->num_planes; ++plane) { + void *mem_priv = vb->planes[plane].mem_priv; + + if (mem_priv) { + dma_buf_detach(vb->planes[plane].dbuf, + vb->planes[plane].mem_priv); + dma_buf_put(vb->planes[plane].dbuf); + vb->planes[plane].dbuf = NULL; + vb->planes[plane].mem_priv = NULL; + } + } +} + +void _fimc_queue_free(struct fimc_control *ctrl, enum v4l2_buf_type type) +{ + unsigned int buffer; + struct vb2_buffer *vb; + + for (buffer = 0; buffer < VIDEO_MAX_FRAME; ++buffer) { + if (V4L2_TYPE_IS_OUTPUT(type)) + vb = ctrl->out_bufs[buffer]; + else + vb = ctrl->cap_bufs[buffer]; + + if (!vb) + continue; + _fimc_dmabuf_put(vb); + kfree(vb); + vb = NULL; + } +} + +int fimc_queue_alloc(struct fimc_control *ctrl, enum v4l2_buf_type type, + enum v4l2_memory memory, unsigned int num_buffers, + unsigned int num_planes) +{ + unsigned int buffer; + struct vb2_buffer *vb; + + for (buffer = 0; buffer < num_buffers; ++buffer) { + vb = kzalloc(sizeof(struct vb2_buffer), GFP_KERNEL); + if (!vb) { + fimc_err("%s: Memory alloc for buffer struct failed\n", + __func__); + break; + } + + if (V4L2_TYPE_IS_MULTIPLANAR(type)) + vb->v4l2_buf.length = num_planes; + + vb->num_planes = num_planes; + vb->v4l2_buf.index = buffer; + vb->v4l2_buf.type = type; + vb->v4l2_buf.memory = memory; + + if (V4L2_TYPE_IS_OUTPUT(type)) + ctrl->out_bufs[buffer] = vb; + else + ctrl->cap_bufs[buffer] = vb; + } + + for (buffer = num_buffers; buffer < VIDEO_MAX_FRAME; ++buffer) { + ctrl->out_bufs[buffer] = NULL; + ctrl->cap_bufs[buffer] = NULL; + } + + return buffer; +} + +static inline int _verify_planes_array(struct vb2_buffer *vb, + const struct v4l2_buffer *b) +{ + if (NULL == b->m.planes) { + printk(KERN_ERR "%s: Multi-planar buffer passwd but planes" + " array not provided\n", __func__); + return -EINVAL; + } + if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) { + printk(KERN_ERR "%s: Incorrect planes array length, " + "expected %d, got %d\n", __func__, + vb->num_planes, b->length); + return -EINVAL; + } + + return 0; +} + +static int _fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, + struct v4l2_plane *v4l2_planes) +{ + int plane; + int ret; + + memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); + b->input = vb->v4l2_buf.input; + b->reserved = vb->v4l2_buf.reserved; + + if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { + ret = _verify_planes_array(vb, b); + if (ret) + return ret; + + memcpy(b->m.planes, vb->v4l2_planes, + b->length * sizeof(struct v4l2_plane)); + + for (plane = 0; plane < vb->num_planes; ++plane) + b->m.planes[plane].m.fd = + vb->v4l2_planes[plane].m.fd; + } else { + b->length = vb->v4l2_planes[0].length; + b->bytesused = vb->v4l2_planes[0].bytesused; + b->m.fd = vb->v4l2_planes[0].m.fd; + } + + return ret; +} + +static int _fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, + struct v4l2_plane *v4l2_planes) +{ + unsigned int plane; + int ret; + + if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { + ret = _verify_planes_array(vb, b); + if (ret) + return ret; + + if (V4L2_TYPE_IS_OUTPUT(b->type)) { + for (plane = 0; plane < vb->num_planes; ++plane) { + v4l2_planes[plane].bytesused = + b->m.planes[plane].bytesused; + v4l2_planes[plane].data_offset = + b->m.planes[plane].data_offset; + } + } + for (plane = 0; plane < vb->num_planes; ++plane) + v4l2_planes[plane].m.fd = + b->m.planes[plane].m.fd; + + } else { + if (V4L2_TYPE_IS_OUTPUT(b->type)) + v4l2_planes[0].bytesused = + b->bytesused; + v4l2_planes[0].m.fd = b->m.fd; + } + + vb->v4l2_buf.field = b->field; + vb->v4l2_buf.timestamp = b->timestamp; + vb->v4l2_buf.input = b->input; + + return 0; +} + +int _qbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb, + struct v4l2_buffer *b) +{ + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + unsigned int plane; + struct sg_table *sg; + struct dma_buf_attachment *dba; + int ret; + + ret = _fill_vb2_buffer(vb, b, planes); + if (ret) + return ret; + + for (plane = 0; plane < vb->num_planes; ++plane) { + struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd); + + if (IS_ERR_OR_NULL(dbuf)) { + fimc_err("dmabuf get error!!! %x\n", plane); + ret = PTR_ERR(dbuf); + goto err; + } + planes[plane].length = dbuf->size; + + /* Skip the plane if already verified */ + if (dbuf == vb->planes[plane].dbuf) { + dma_buf_put(dbuf); + continue; + } + + vb->planes[plane].mem_priv = NULL; + + dba = dma_buf_attach(dbuf, ctrl->dev); + if (IS_ERR(dba)) { + fimc_err("failed to attach dmabuf\n"); + dma_buf_put(dbuf); + ret = PTR_ERR(dba); + goto err; + } + + sg = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL); + if (IS_ERR(sg)) { + fimc_err("qbuf: failed acquiring dmabuf " + "memory for plane\n"); + ret = PTR_ERR(sg); + goto err; + } + dba->priv = sg; + + vb->planes[plane].dbuf = dbuf; + vb->planes[plane].mem_priv = dba; + + vb->v4l2_planes[plane] = planes[plane]; + } + + return 0; + +err: + _fimc_dmabuf_put(vb); + + return ret; +} + +int _dqbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb, + struct v4l2_buffer *b) +{ + struct v4l2_plane planes[VIDEO_MAX_PLANES]; + struct sg_table *sg[VIDEO_MAX_PLANES]; + struct dma_buf_attachment *dba[VIDEO_MAX_PLANES]; + unsigned int plane; + int ret; + + ret = _fill_v4l2_buffer(vb, b, planes); + if (ret) + return ret; + + for (plane = 0; plane < vb->num_planes; ++plane) { + dba[plane] = vb->planes[plane].mem_priv; + sg[plane] = dba[plane]->priv; + dma_buf_unmap_attachment(dba[plane], + sg[plane], DMA_FROM_DEVICE); + } + + return 0; +} +#endif + static u32 fimc_poll(struct file *filp, poll_table *wait) { struct fimc_prv_data *prv_data = @@ -1226,6 +1490,19 @@ static int fimc_open(struct file *filp) goto kzalloc_err; } +#ifdef CONFIG_USE_FIMC_CMA + if (ctrl->id == 1) { + ctrl->mem.cpu_addr = dma_alloc_coherent(ctrl->dev, + ctrl->mem.size, &(ctrl->mem.base), 0); + if (!ctrl->mem.cpu_addr) { + printk(KERN_INFO "FIMC%d: dma_alloc_coherent failed\n", + ctrl->id); + ret = -ENOMEM; + goto dma_alloc_err; + } + } +#endif + if (in_use == 1) { #if (!defined(CONFIG_EXYNOS_DEV_PD) || !defined(CONFIG_PM_RUNTIME)) if (pdata->clk_on) @@ -1276,6 +1553,11 @@ static int fimc_open(struct file *filp) return 0; +#ifdef CONFIG_USE_FIMC_CMA +dma_alloc_err: + kfree(prv_data); +#endif + kzalloc_err: atomic_dec(&ctrl->in_use); @@ -1425,6 +1707,9 @@ static int fimc_release(struct file *filp) } else { ctrl->out->ctx_used[ctx_id] = false; } +#ifdef CONFIG_SLP_DMABUF + _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_OUTPUT); +#endif } if (ctrl->cap) { @@ -1445,6 +1730,9 @@ static int fimc_release(struct file *filp) } kfree(ctrl->cap); ctrl->cap = NULL; +#ifdef CONFIG_SLP_DMABUF + _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_CAPTURE); +#endif } /* @@ -1462,6 +1750,14 @@ static int fimc_release(struct file *filp) ctrl->fb.is_enable = 0; } +#ifdef CONFIG_USE_FIMC_CMA + if (ctrl->id == 1) { + dma_free_coherent(ctrl->dev, ctrl->mem.size, ctrl->mem.cpu_addr, + ctrl->mem.base); + ctrl->mem.base = 0; + ctrl->mem.cpu_addr = NULL; + } +#endif fimc_warn("FIMC%d %d released.\n", ctrl->id, atomic_read(&ctrl->in_use)); @@ -1840,7 +2136,7 @@ static int __devinit fimc_probe(struct platform_device *pdev) ret = device_create_file(&(pdev->dev), &dev_attr_range_mode); if (ret < 0) { fimc_err("failed to add sysfs entries for range mode\n"); - goto err_global; + goto err_create_file; } printk(KERN_INFO "FIMC%d registered successfully\n", ctrl->id); #if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)) @@ -1848,7 +2144,7 @@ static int __devinit fimc_probe(struct platform_device *pdev) ctrl->fimc_irq_wq = create_workqueue(buf); if (ctrl->fimc_irq_wq == NULL) { fimc_err("failed to create_workqueue\n"); - goto err_global; + goto err_wq; } INIT_WORK(&ctrl->work_struct, s3c_fimc_irq_work); @@ -1869,6 +2165,12 @@ static int __devinit fimc_probe(struct platform_device *pdev) return 0; +err_wq: + device_remove_file(&(pdev->dev), &dev_attr_range_mode); + +err_create_file: + device_remove_file(&(pdev->dev), &dev_attr_log_level); + err_global: video_unregister_device(ctrl->vd); diff --git a/drivers/media/video/samsung/fimc/fimc_dev_u1.c b/drivers/media/video/samsung/fimc/fimc_dev_u1.c index f36db5d..762256b 100644 --- a/drivers/media/video/samsung/fimc/fimc_dev_u1.c +++ b/drivers/media/video/samsung/fimc/fimc_dev_u1.c @@ -682,7 +682,7 @@ struct fimc_control *fimc_register_controller(struct platform_device *pdev) clk_put(fimc_src_clk); return NULL; } - clk_set_rate(sclk_fimc_lclk, FIMC_CLK_RATE); + clk_set_rate(sclk_fimc_lclk, fimc_clk_rate()); clk_put(sclk_fimc_lclk); clk_put(fimc_src_clk); @@ -1419,6 +1419,30 @@ static int fimc_init_global(struct platform_device *pdev) return 0; } +#ifdef CONFIG_DRM_EXYNOS_FIMD_WB +static BLOCKING_NOTIFIER_HEAD(fimc_notifier_client_list); + +int fimc_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register( + &fimc_notifier_client_list, nb); +} +EXPORT_SYMBOL(fimc_register_client); + +int fimc_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister( + &fimc_notifier_client_list, nb); +} +EXPORT_SYMBOL(fimc_unregister_client); + +int fimc_send_event(unsigned long val, void *v) +{ + return blocking_notifier_call_chain( + &fimc_notifier_client_list, val, v); +} +#endif + static int fimc_show_log_level(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/media/video/samsung/fimc/fimc_output.c b/drivers/media/video/samsung/fimc/fimc_output.c index 895cb7f..57611e5 100644 --- a/drivers/media/video/samsung/fimc/fimc_output.c +++ b/drivers/media/video/samsung/fimc/fimc_output.c @@ -25,6 +25,9 @@ #include #include #include +#ifdef CONFIG_SLP_DMABUF +#include +#endif #include "fimc.h" #include "fimc-ipc.h" @@ -287,6 +290,33 @@ static void fimc_init_out_buf(struct fimc_ctx *ctx) } } +#ifdef CONFIG_SLP_DMABUF +static int fimc_set_out_num_plane(struct fimc_control *ctrl, + struct fimc_ctx *ctx) +{ + u32 format = ctx->pix.pixelformat; + + switch (format) { + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_RGB565: /* fall through */ + case V4L2_PIX_FMT_UYVY: /* fall through */ + case V4L2_PIX_FMT_YUYV: + return PLANE_1; + case V4L2_PIX_FMT_NV12: /* fall through */ + case V4L2_PIX_FMT_NV21: /* fall through */ + case V4L2_PIX_FMT_NV12T: + return PLANE_2; + case V4L2_PIX_FMT_YUV420: /* fall through */ + return PLANE_3; + default: + fimc_err("%s: Invalid pixelformt : %d\n", __func__, format); + return -EINVAL; + } + + return 0; +} +#endif + static int fimc_outdev_set_src_buf(struct fimc_control *ctrl, struct fimc_ctx *ctx) { @@ -1690,6 +1720,10 @@ int fimc_reqbufs_output(void *fh, struct v4l2_requestbuffers *b) default: break; } +#ifdef CONFIG_SLP_DMABUF + if (b->memory == V4L2_MEMORY_DMABUF) + _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_OUTPUT); +#endif } else { /* initialize source buffers */ if (b->memory == V4L2_MEMORY_MMAP) { @@ -1701,6 +1735,14 @@ int fimc_reqbufs_output(void *fh, struct v4l2_requestbuffers *b) if (mode == FIMC_OVLY_DMA_AUTO || mode == FIMC_OVLY_NOT_FIXED) ctx->overlay.req_idx = FIMC_USERPTR_IDX; +#ifdef CONFIG_SLP_DMABUF + } else if (b->memory == V4L2_MEMORY_DMABUF) { + int num_planes; + + num_planes = fimc_set_out_num_plane(ctrl, ctx); + fimc_queue_alloc(ctrl, b->type, b->memory, b->count, + num_planes); +#endif } ctx->is_requested = 1; @@ -2365,6 +2407,7 @@ static int fimc_outdev_start_operation(struct fimc_control *ctrl, ret = fimc_outdev_start_camif(ctrl); if (ret < 0) { fimc_err("Fail: fimc_start_camif\n"); + spin_unlock_irqrestore(&ctrl->out->slock, spin_flags); return -EINVAL; } @@ -2399,6 +2442,7 @@ static int fimc_qbuf_output_single_buf(struct fimc_control *ctrl, case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: buf_set.base[FIMC_ADDR_Y] = (dma_addr_t)ctx->fbuf.base; break; case V4L2_PIX_FMT_YUV420: @@ -2465,9 +2509,11 @@ static int fimc_qbuf_output_multi_buf(struct fimc_control *ctrl, case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: buf_set.base[FIMC_ADDR_Y] = ctx->dst[idx].base[FIMC_ADDR_Y]; break; case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: /* fall through */ buf_set.base[FIMC_ADDR_Y] = ctx->dst[idx].base[FIMC_ADDR_Y]; buf_set.base[FIMC_ADDR_CB] = ctx->dst[idx].base[FIMC_ADDR_CB]; buf_set.base[FIMC_ADDR_CR] = ctx->dst[idx].base[FIMC_ADDR_CR]; @@ -2680,7 +2726,7 @@ static int fimc_update_in_queue_addr(struct fimc_control *ctrl, int fimc_qbuf_output(void *fh, struct v4l2_buffer *b) { - struct fimc_buf *buf = (struct fimc_buf *)b->m.userptr; + struct fimc_buf *buf; struct fimc_ctx *ctx; struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id; @@ -2716,9 +2762,40 @@ int fimc_qbuf_output(void *fh, struct v4l2_buffer *b) (ctrl->status == FIMC_STREAMON) || (ctrl->status == FIMC_STREAMON_IDLE)) { if (b->memory == V4L2_MEMORY_USERPTR) { + buf = (struct fimc_buf *)b->m.userptr; ret = fimc_update_in_queue_addr(ctrl, ctx, b->index, buf->base); if (ret < 0) return ret; +#ifdef CONFIG_SLP_DMABUF + } else if (b->memory == V4L2_MEMORY_DMABUF) { + struct vb2_buffer *vb; + dma_addr_t addr[3]; + struct sg_table *sg; + struct dma_buf_attachment *dba; + int i; + + vb = ctrl->out_bufs[b->index]; + ret = _qbuf_dmabuf(ctrl, vb, b); + if (ret < 0) { + fimc_err("_qbuf_dmabuf failed ret = %d\n", ret); + return ret; + } + for (i = 0; i < vb->num_planes; i++) { + dba = vb->planes[i].mem_priv; + sg = dba->priv; + if (sg) + addr[i] = sg_dma_address(sg->sgl); + else { + fimc_err("%s: Wrong sg value.\n", + __func__); + return -ENODEV; + } + } + ret = fimc_update_in_queue_addr(ctrl, ctx, b->index, + addr); + if (ret < 0) + return ret; +#endif } #if defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME) @@ -2831,6 +2908,7 @@ int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b) int idx = -1, ret = -1; ctx = &ctrl->out->ctx[ctx_id]; + ret = fimc_pop_outq(ctrl, ctx, &idx); if (ret < 0) { ret = wait_event_timeout(ctrl->wq, (ctx->outq[0] != -1), @@ -2838,7 +2916,6 @@ int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b) if (ret == 0) { fimc_dump_context(ctrl, ctx); fimc_recover_output(ctrl, ctx); - pm_runtime_put_sync(ctrl->dev); fimc_err("[0] out_queue is empty\n"); return -EAGAIN; } else if (ret == -ERESTARTSYS) { @@ -2854,7 +2931,18 @@ int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b) } } } +#ifdef CONFIG_SLP_DMABUF + if (b->memory == V4L2_MEMORY_DMABUF) { + struct vb2_buffer *vb; + vb = ctrl->out_bufs[idx]; + ret = _dqbuf_dmabuf(ctrl, vb, b); + if (ret < 0) { + fimc_err("%s: _qbuf_dmabuf error.\n", __func__); + return -ENODEV; + } + } +#endif b->index = idx; fimc_info2("ctx(%d) dqueued idx = %d\n", ctx->ctx_num, b->index); diff --git a/drivers/media/video/samsung/fimc/fimc_regs.c b/drivers/media/video/samsung/fimc/fimc_regs.c index 332e5db..20888c7 100644 --- a/drivers/media/video/samsung/fimc/fimc_regs.c +++ b/drivers/media/video/samsung/fimc/fimc_regs.c @@ -258,6 +258,9 @@ static void fimc_reset_cfg(struct fimc_control *ctrl) { int i; u32 cfg[][2] = { +#ifdef CONFIG_SLP + { 0x008, 0x20010480 }, +#endif { 0x018, 0x00000000 }, { 0x01c, 0x00000000 }, { 0x020, 0x00000000 }, { 0x024, 0x00000000 }, { 0x028, 0x00000000 }, { 0x02c, 0x00000000 }, @@ -1253,7 +1256,11 @@ int fimc_hwset_disable_capture(struct fimc_control *ctrl) void fimc_wait_disable_capture(struct fimc_control *ctrl) { +#ifdef CONFIG_VIDEO_S5K5BBGX + unsigned long timeo = jiffies + 60; /* more 40 ms */ +#else unsigned long timeo = jiffies + 40; /* timeout of 200 ms */ +#endif u32 cfg; if (!ctrl || !ctrl->cap) return; diff --git a/drivers/media/video/samsung/fimc/fimc_v4l2.c b/drivers/media/video/samsung/fimc/fimc_v4l2.c index 510e2f1..becd16c 100644 --- a/drivers/media/video/samsung/fimc/fimc_v4l2.c +++ b/drivers/media/video/samsung/fimc/fimc_v4l2.c @@ -35,8 +35,15 @@ static int fimc_querycap(struct file *filp, void *fh, sprintf(cap->bus_info, "FIMC AHB-bus"); cap->version = 0; +#ifdef CONFIG_SLP_DMABUF + cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_STREAMING | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_VIDEO_CAPTURE_MPLANE); +#else cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_STREAMING); +#endif return 0; } @@ -47,6 +54,18 @@ static int fimc_reqbufs(struct file *filp, void *fh, struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(b->type)) { + ret = fimc_reqbufs_output(fh, b); + } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_reqbufs_capture(ctrl, b); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_reqbufs_capture(ctrl, b); } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -56,6 +75,7 @@ static int fimc_reqbufs(struct file *filp, void *fh, "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -65,6 +85,18 @@ static int fimc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(b->type)) { + ret = fimc_querybuf_output(fh, b); + } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_querybuf_capture(ctrl, b); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_querybuf_capture(ctrl, b); } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -74,6 +106,7 @@ static int fimc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -148,6 +181,18 @@ static int fimc_cropcap(struct file *filp, void *fh, struct v4l2_cropcap *a) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(a->type)) { + ret = fimc_cropcap_output(fh, a); + } else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_cropcap_capture(ctrl, a); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_cropcap_capture(ctrl, a); } else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -157,6 +202,7 @@ static int fimc_cropcap(struct file *filp, void *fh, struct v4l2_cropcap *a) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -166,6 +212,18 @@ static int fimc_g_crop(struct file *filp, void *fh, struct v4l2_crop *a) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(a->type)) { + ret = fimc_g_crop_output(fh, a); + } else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_g_crop_capture(ctrl, a); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_g_crop_capture(ctrl, a); } else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -175,6 +233,7 @@ static int fimc_g_crop(struct file *filp, void *fh, struct v4l2_crop *a) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -184,6 +243,18 @@ static int fimc_s_crop(struct file *filp, void *fh, struct v4l2_crop *a) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(a->type)) { + ret = fimc_s_crop_output(fh, a); + } else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_s_crop_capture(ctrl, a); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_s_crop_capture(ctrl, a); } else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -193,6 +264,7 @@ static int fimc_s_crop(struct file *filp, void *fh, struct v4l2_crop *a) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -202,6 +274,18 @@ static int fimc_streamon(struct file *filp, void *fh, enum v4l2_buf_type i) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(i)) { + ret = fimc_streamon_output(fh); + } else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE + || i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_streamon_capture(ctrl); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_streamon_capture(ctrl); } else if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -211,6 +295,7 @@ static int fimc_streamon(struct file *filp, void *fh, enum v4l2_buf_type i) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -220,6 +305,18 @@ static int fimc_streamoff(struct file *filp, void *fh, enum v4l2_buf_type i) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(i)) { + ret = fimc_streamoff_output(fh); + } else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE + || i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_streamoff_capture(ctrl); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_streamoff_capture(ctrl); } else if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -229,6 +326,7 @@ static int fimc_streamoff(struct file *filp, void *fh, enum v4l2_buf_type i) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -238,6 +336,18 @@ static int fimc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(b->type)) { + ret = fimc_qbuf_output(fh, b); + } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_qbuf_capture(ctrl, b); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_qbuf_capture(ctrl, b); } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -247,6 +357,7 @@ static int fimc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -256,6 +367,18 @@ static int fimc_dqbuf(struct file *filp, void *fh, struct v4l2_buffer *b) struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl; int ret = -1; +#ifdef CONFIG_SLP_DMABUF + if (V4L2_TYPE_IS_OUTPUT(b->type)) { + ret = fimc_dqbuf_output(fh, b); + } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE + || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = fimc_dqbuf_capture(ctrl, b); + } else { + fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and " + "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); + ret = -EINVAL; + } +#else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { ret = fimc_dqbuf_capture(ctrl, b); } else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { @@ -265,6 +388,7 @@ static int fimc_dqbuf(struct file *filp, void *fh, struct v4l2_buffer *b) "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n"); ret = -EINVAL; } +#endif return ret; } @@ -315,6 +439,12 @@ const struct v4l2_ioctl_ops fimc_v4l2_ops = { .vidioc_querymenu = fimc_querymenu, .vidioc_g_fmt_vid_out = fimc_g_fmt_vid_out, .vidioc_s_fmt_vid_out = fimc_s_fmt_vid_out, +#ifdef CONFIG_SLP_DMABUF + .vidioc_g_fmt_vid_cap_mplane = fimc_g_fmt_vid_capture, + .vidioc_s_fmt_vid_cap_mplane = fimc_s_fmt_vid_capture, + .vidioc_g_fmt_vid_out_mplane = fimc_g_fmt_vid_out, + .vidioc_s_fmt_vid_out_mplane = fimc_s_fmt_vid_out, +#endif .vidioc_try_fmt_vid_out = fimc_try_fmt_vid_out, .vidioc_g_fbuf = fimc_g_fbuf, .vidioc_s_fbuf = fimc_s_fbuf, diff --git a/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c b/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c index 5ccde4a..e0d7d4e 100644 --- a/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c +++ b/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c @@ -477,16 +477,27 @@ static int g2d_remove(struct platform_device *dev) #if defined(CONFIG_HAS_EARLYSUSPEND) void g2d_early_suspend(struct early_suspend *h) { + int i = 0; + atomic_set(&g2d_dev->ready_to_run, 0); /* wait until G2D running is finished */ while(1) { if (!atomic_read(&g2d_dev->in_use)) break; - + msleep_interruptible(2); + + i++; + /* Timeout 1sec */ + if (i > 500) { + g2d_clk_enable(g2d_dev); + g2d_reset(g2d_dev); + g2d_clk_disable(g2d_dev); + break; + } } - + g2d_sysmmu_off(g2d_dev); #if defined(CONFIG_EXYNOS_DEV_PD) @@ -513,25 +524,37 @@ void g2d_late_resume(struct early_suspend *h) #if !defined(CONFIG_HAS_EARLYSUSPEND) static int g2d_suspend(struct platform_device *dev, pm_message_t state) { + int i = 0; + atomic_set(&g2d_dev->ready_to_run, 0); /* wait until G2D running is finished */ while(1) { if (!atomic_read(&g2d_dev->in_use)) break; - + msleep_interruptible(2); + + i++; + /* Timeout 1sec */ + if (i > 500) { + g2d_clk_enable(g2d_dev); + g2d_reset(g2d_dev); + g2d_clk_disable(g2d_dev); + break; + } } - + g2d_sysmmu_off(g2d_dev); - + #if defined(CONFIG_EXYNOS_DEV_PD) /* disable the power domain */ pm_runtime_put(g2d_dev->dev); -#endif +#endif return 0; } + static int g2d_resume(struct platform_device *pdev) { diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h index 2d8f3b7..3bbb194 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h @@ -41,6 +41,15 @@ #define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int) #define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version) #define FIMG2D_BITBLT_SECURE _IOW(FIMG2D_IOCTL_MAGIC, 3, unsigned int) +#define FIMG2D_BITBLT_DBUFFER _IOW(FIMG2D_IOCTL_MAGIC, 4, unsigned long) + +#define SEQ_NO_BLT_SKIA 0x00000001 +#define SEQ_NO_BLT_HWC_SEC 0x00000012 +#define SEQ_NO_BLT_HWC_NOSEC 0x00000002 +#define SEQ_NO_BLT_HDMI 0x00000003 +#define SEQ_NO_CMD_SECURE_ON 0x10000001 +#define SEQ_NO_CMD_SECURE_OFF 0x10000002 +#define SEQ_NO_CMD_SET_DBUFFER 0x10000003 struct fimg2d_version { unsigned int hw; @@ -429,6 +438,7 @@ struct fimg2d_context { atomic_t ncmd; wait_queue_head_t wait_q; struct fimg2d_perf perf[MAX_PERF_DESCS]; + unsigned long *pgd_clone; }; /** @@ -486,6 +496,8 @@ struct fimg2d_control { int irq; unsigned int secure; + unsigned int dbuffer_addr; + unsigned long fault_addr; atomic_t nctx; atomic_t busy; atomic_t active; diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c index fc6016c..1eb8d63 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c @@ -83,7 +83,12 @@ void fimg2d4x_bitblt(struct fimg2d_control *info) goto blitend; if (cmd->image[IDST].addr.type != ADDR_PHYS) { - pgd = (unsigned long *)ctx->mm->pgd; + if ((cmd->image[IDST].addr.type == ADDR_USER_CONTIG) || + (cmd->image[ISRC].addr.type == ADDR_USER_CONTIG)) + pgd = (unsigned long *)ctx->pgd_clone; + else + pgd = (unsigned long *)ctx->mm->pgd; + s5p_sysmmu_enable(info->dev, (unsigned long)virt_to_phys(pgd)); fimg2d_debug("sysmmu enable: pgd %p ctx %p seq_no(%u)\n", pgd, ctx, cmd->seq_no); @@ -98,6 +103,8 @@ void fimg2d4x_bitblt(struct fimg2d_control *info) info->run(info); fimg2d4x_blit_wait(info, cmd); + if (info->fault_addr) + fimg2d_mmutable_value_replace(cmd, info->fault_addr, 0); #ifdef PERF_PROFILE perf_end(cmd->ctx, PERF_BLIT); #endif diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c index 4eb4d04..7835dee 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c @@ -16,6 +16,7 @@ #include "fimg2d.h" #include "fimg2d4x.h" #include "fimg2d_clk.h" +#include "fimg2d_cache.h" #define wr(d, a) writel((d), info->regs + (a)) #define rd(a) readl(info->regs + (a)) @@ -124,7 +125,13 @@ void fimg2d4x_set_src_image(struct fimg2d_control *info, struct fimg2d_image *s) { unsigned long cfg; - wr(FIMG2D_ADDR(s->addr.start), FIMG2D_SRC_BASE_ADDR_REG); + if ((s->addr.type == ADDR_USER_CONTIG) && (s->order < ARGB_ORDER_END)) { + wr(FIMG2D_ADDR(GET_MVA(s->addr.start, s->plane2.start)), + FIMG2D_SRC_BASE_ADDR_REG); + } else { + wr(FIMG2D_ADDR(s->addr.start), FIMG2D_SRC_BASE_ADDR_REG); + } + wr(FIMG2D_STRIDE(s->stride), FIMG2D_SRC_STRIDE_REG); if (s->order < ARGB_ORDER_END) { /* argb */ @@ -173,7 +180,13 @@ void fimg2d4x_set_dst_image(struct fimg2d_control *info, struct fimg2d_image *d) { unsigned long cfg; - wr(FIMG2D_ADDR(d->addr.start), FIMG2D_DST_BASE_ADDR_REG); + if ((d->addr.type == ADDR_USER_CONTIG) && (d->order < ARGB_ORDER_END)) { + wr(FIMG2D_ADDR(GET_MVA(d->addr.start, d->plane2.start)), + FIMG2D_DST_BASE_ADDR_REG); + } else { + wr(FIMG2D_ADDR(d->addr.start), FIMG2D_DST_BASE_ADDR_REG); + } + wr(FIMG2D_STRIDE(d->stride), FIMG2D_DST_STRIDE_REG); if (d->order < ARGB_ORDER_END) { diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c index 43489e4..f5486b1 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c @@ -114,8 +114,48 @@ void fimg2d_clean_outer_pagetable(struct mm_struct *mm, unsigned long vaddr, lv1++; } while (lv1 != lv1end); } + +void fimg2d_clean_outer_pagetable_clone(unsigned long *pgd_clone, + unsigned long vaddr, size_t size) +{ + unsigned long *pgd; + unsigned long *lv1, *lv1end; + unsigned long lv2pa; + + pgd = (unsigned long *)pgd_clone; + + lv1 = pgd + (vaddr >> LV1_SHIFT); + lv1end = pgd + ((vaddr + size + LV1_PT_SIZE-1) >> LV1_SHIFT); + + /* clean level1 page table */ + outer_clean_range(virt_to_phys(lv1), virt_to_phys(lv1end)); + + do { + /* if page size is 4KB, clean level2 page table entry */ + if ((*lv1 & 0x3) == 0x1) { + lv2pa = *lv1 & ~LV2_BASE_MASK; /* lv2 pt base */ + /* clean level2 page table */ + outer_clean_range(lv2pa, lv2pa + LV2_PT_SIZE); + } + lv1++; + } while (lv1 != lv1end); +} #endif /* CONFIG_OUTER_CACHE */ +void fimg2d_clean_inner_pagetable_clone(unsigned long *pgd_clone, + unsigned long vaddr, size_t size) +{ + unsigned long *pgd; + unsigned long *lv1, *lv1end; + + pgd = (unsigned long *)pgd_clone; + + lv1 = pgd + (vaddr >> LV1_SHIFT); + lv1end = pgd + ((vaddr + size + LV1_PT_SIZE-1) >> LV1_SHIFT); + fimg2d_dma_sync_inner((unsigned long)lv1, + (unsigned int)lv1end - (unsigned int)lv1, DMA_TO_DEVICE); +} + enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long vaddr, size_t size) { @@ -166,3 +206,50 @@ enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long vaddr, return PT_NORMAL; } + +#define PT_NS 0x0 // Non Secure +#define PT_AP 0x8c00 // Access permission +#define PT_ENTRY 0x2 // 1MB Page + +enum pt_status fimg2d_migrate_pagetable(unsigned long *pgd_clone, + unsigned long vaddr, unsigned long paddr, size_t size) +{ + unsigned long *pgd; + unsigned long *lv1d; + + pgd = (unsigned long *)pgd_clone; + + size += vaddr & (SZ_1M - 1); + size = ALIGN(size, SZ_1M); + + while ((long)size > 0) { + lv1d = pgd + (vaddr >> LV1_SHIFT); + + *lv1d = (paddr & 0xfff00000) | PT_NS | PT_AP | PT_ENTRY; + + vaddr += SZ_1M; + paddr += SZ_1M; + size -= SZ_1M; + } + return PT_NORMAL; +} + +void fimg2d_mmutable_value_replace(struct fimg2d_bltcmd *cmd, + unsigned long fault_addr, unsigned long l2d_value) +{ + unsigned long *pgd; + unsigned long *lv1d, *lv2d; + + pgd = (unsigned long *)cmd->ctx->mm->pgd; + lv1d = pgd + (fault_addr >> LV1_SHIFT); + + lv2d = (unsigned long *)phys_to_virt(*lv1d & ~LV2_BASE_MASK) + + ((fault_addr & LV2_PT_MASK) >> LV2_SHIFT); + + *lv2d = l2d_value; + + flush_all_cpu_caches(); + fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4); + + printk(KERN_INFO "MMU Level2 value replaced [0x%lx]", l2d_value); +} diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h index f337ea5..7699a37 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h @@ -18,6 +18,10 @@ #define L1_CACHE_SIZE SZ_64K #define L2_CACHE_SIZE SZ_1M #define LINE_FLUSH_THRESHOLD SZ_1K +#define L1_DESCRIPTOR_SIZE SZ_16K + +/* Get Modified virtual address to use 1MB page */ +#define GET_MVA(V, P) ((V & 0xfff00000) | (P & 0x000fffff)) /** * cache_opr - [kernel] cache operation mode @@ -92,5 +96,11 @@ static inline void fimg2d_dma_unsync_inner(unsigned long addr, size_t size, int } void fimg2d_clean_outer_pagetable(struct mm_struct *mm, unsigned long addr, size_t size); +void fimg2d_clean_outer_pagetable_clone(unsigned long *pgd_clone, unsigned long addr, size_t size); +void fimg2d_clean_inner_pagetable_clone(unsigned long *pgd_clone, unsigned long addr, size_t size); void fimg2d_dma_sync_outer(struct mm_struct *mm, unsigned long addr, size_t size, enum cache_opr opr); enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long addr, size_t size); +enum pt_status fimg2d_migrate_pagetable(unsigned long *pgd_clone, + unsigned long vaddr, unsigned long paddr, size_t size); +void fimg2d_mmutable_value_replace(struct fimg2d_bltcmd *cmd, + unsigned long fault_addr, unsigned long l2d_value); diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c index eaa722c..0c6c590 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c @@ -130,6 +130,7 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd) enum pt_status pt; int clip_x, clip_w, clip_h, y, dir, i; unsigned long clip_start; + unsigned long modified_addr; clp = &p->clipping; @@ -155,6 +156,13 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd) pt = fimg2d_check_pagetable(mm, c->addr, c->size); if (pt == PT_FAULT) return -1; + } else if (img->addr.type == ADDR_USER_CONTIG) { + modified_addr = GET_MVA(img->addr.start, img->plane2.start); + pt = fimg2d_migrate_pagetable(cmd->ctx->pgd_clone, + modified_addr, img->plane2.start, img->height * img->stride); + if (pt != PT_NORMAL) { + return -1; + } } if (img->need_cacheopr && i != IMAGE_TMP) { @@ -175,7 +183,25 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd) c = &cmd->dma[i]; r = &img->rect; - if (!img->addr.type || !c->cached) + if (!img->addr.type) + continue; + + if ((cmd->image[IMAGE_SRC].addr.type == ADDR_USER_CONTIG) || + (cmd->image[IMAGE_DST].addr.type == ADDR_USER_CONTIG)) { + if (img->addr.type == ADDR_USER_CONTIG) { + if (i == IMAGE_DST && clp->enable) + modified_addr = GET_MVA(img->addr.start, img->plane2.start) + + (img->stride * clp->y1); + else + modified_addr = GET_MVA(img->addr.start, img->plane2.start) + + (img->stride * r->y1); + } else { + modified_addr = c->addr; + } + fimg2d_clean_inner_pagetable_clone(cmd->ctx->pgd_clone, modified_addr, c->size); + } + + if ( !c->cached) continue; if (i == IMAGE_DST) @@ -226,8 +252,22 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd) continue; /* clean pagetable */ - if (img->addr.type == ADDR_USER) + if ((cmd->image[IMAGE_SRC].addr.type == ADDR_USER_CONTIG) || + (cmd->image[IMAGE_DST].addr.type == ADDR_USER_CONTIG)) { + if (img->addr.type == ADDR_USER_CONTIG) { + if (i == IMAGE_DST && clp->enable) + modified_addr = GET_MVA(img->addr.start, img->plane2.start) + + (img->stride * clp->y1); + else + modified_addr = GET_MVA(img->addr.start, img->plane2.start) + + (img->stride * r->y1); + } else { + modified_addr = c->addr; + } + fimg2d_clean_outer_pagetable_clone(cmd->ctx->pgd_clone, modified_addr, c->size); + } else { fimg2d_clean_outer_pagetable(mm, c->addr, c->size); + } if (!c->cached) continue; @@ -275,14 +315,17 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, int i, ret; struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit); struct fimg2d_bltcmd *cmd; + struct fimg2d_image *img; - if ((blit->dst) && (type == ADDR_USER)) + if ((blit->dst) && (type == ADDR_USER) + && (blit->seq_no == SEQ_NO_BLT_SKIA)) up_write(&page_alloc_slow_rwsem); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) { - if ((blit->dst) && (type == ADDR_USER)) + if ((blit->dst) && (type == ADDR_USER) + && (blit->seq_no == SEQ_NO_BLT_SKIA)) if (!down_write_trylock(&page_alloc_slow_rwsem)) return -EAGAIN; return -ENOMEM; @@ -294,7 +337,8 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, if (copy_from_user(&cmd->image[i], buf[i], sizeof(struct fimg2d_image))) { - if ((blit->dst) && (type == ADDR_USER)) + if ((blit->dst) && (type == ADDR_USER) + && (blit->seq_no == SEQ_NO_BLT_SKIA)) if (!down_write_trylock(&page_alloc_slow_rwsem)) { ret = -EAGAIN; goto err_user; @@ -304,7 +348,8 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, } } - if ((blit->dst) && (type == ADDR_USER)) + if ((blit->dst) && (type == ADDR_USER) + && (blit->seq_no == SEQ_NO_BLT_SKIA)) if (!down_write_trylock(&page_alloc_slow_rwsem)) { ret = -EAGAIN; goto err_user; @@ -329,6 +374,13 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, fimg2d_fixup_params(cmd); + for (i = 0; i < MAX_IMAGES; i++) { + img = &cmd->image[i]; + if (img->addr.type == ADDR_USER_CONTIG) { + memcpy(cmd->ctx->pgd_clone, cmd->ctx->mm->pgd, L1_DESCRIPTOR_SIZE); + } + } + if (fimg2d_check_dma_sync(cmd)) { ret = -EFAULT; goto err_user; diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c index ed14901..84c7db5 100644 --- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c +++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c @@ -46,6 +46,8 @@ #define LV2_PT_MASK 0xff000 #define LV2_SHIFT 12 #define LV1_DESC_MASK 0x3 +#define LV2_VALUE_META 0xc7f +#define LV2_VALUE_BASE_MASK 0xfff static struct fimg2d_control *info; @@ -116,7 +118,12 @@ static int fimg2d_sysmmu_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype, lv2d = (unsigned long *)phys_to_virt(*lv1d & ~LV2_BASE_MASK) + ((fault_addr & LV2_PT_MASK) >> LV2_SHIFT); printk(KERN_ERR " Level 2 descriptor(0x%lx)\n", *lv2d); - fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4); + if (*lv2d == 0) { + fimg2d_mmutable_value_replace(cmd, fault_addr, + (info->dbuffer_addr & ~LV2_VALUE_BASE_MASK) | LV2_VALUE_META); + info->fault_addr = fault_addr; + } else + fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4); next: return 0; @@ -161,6 +168,8 @@ static int fimg2d_open(struct inode *inode, struct file *file) ctx, (unsigned long *)ctx->mm->pgd, (unsigned long *)init_mm.pgd); + ctx->pgd_clone = kzalloc(L1_DESCRIPTOR_SIZE, GFP_KERNEL); + fimg2d_add_context(info, ctx); return 0; } @@ -178,6 +187,7 @@ static int fimg2d_release(struct inode *inode, struct file *file) } fimg2d_del_context(info, ctx); + kfree(ctx->pgd_clone); kfree(ctx); return 0; } @@ -223,7 +233,8 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg) dev_lock(info->bus_dev, info->dev, 160160); #endif #endif - if ((blit.dst) && (dst.addr.type == ADDR_USER)) + if ((blit.dst) && (dst.addr.type == ADDR_USER) + && (blit.seq_no == SEQ_NO_BLT_SKIA)) if (!down_write_trylock(&page_alloc_slow_rwsem)) ret = -EAGAIN; @@ -238,7 +249,9 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg) perf_print(ctx, blit.seq_no); perf_clear(ctx); #endif - if ((blit.dst) && (dst.addr.type == ADDR_USER) && ret != -EAGAIN) + if ((blit.dst) && (dst.addr.type == ADDR_USER) + && (blit.seq_no == SEQ_NO_BLT_SKIA) + && ret != -EAGAIN) up_write(&page_alloc_slow_rwsem); #ifdef CONFIG_BUSFREQ_OPP @@ -246,6 +259,13 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg) dev_unlock(info->bus_dev, info->dev); #endif #endif + + if (info->fault_addr) { + printk(KERN_INFO "Return by G2D fault handler"); + info->fault_addr = 0; + ret = -EFAULT; + } + break; case FIMG2D_BITBLT_SYNC: @@ -281,6 +301,17 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; + case FIMG2D_BITBLT_DBUFFER: + if (copy_from_user(&info->dbuffer_addr, + (unsigned long *)arg, + sizeof(unsigned long))) { + printk(KERN_ERR + "[%s] failed to FIMG2D_BITBLT_DBUFFER: copy_from_user error\n\n", + __func__); + return -EFAULT; + } + break; + default: printk(KERN_ERR "[%s] unknown ioctl\n", __func__); ret = -EFAULT; @@ -315,6 +346,7 @@ static int fimg2d_setup_controller(struct fimg2d_control *info) atomic_set(&info->nctx, 0); atomic_set(&info->active, 0); info->secure = 0; + info->fault_addr = 0; spin_lock_init(&info->bltlock); @@ -384,12 +416,20 @@ static int fimg2d_probe(struct platform_device *pdev) fimg2d_debug("device name: %s base address: 0x%lx\n", pdev->name, (unsigned long)res->start); + /* Clock setup */ + ret = fimg2d_clk_setup(info); + if (ret) { + printk(KERN_ERR "FIMG2D failed to setup clk\n"); + ret = -ENOENT; + goto err_clk; + } + /* irq */ info->irq = platform_get_irq(pdev, 0); if (!info->irq) { printk(KERN_ERR "FIMG2D failed to get irq resource\n"); ret = -ENOENT; - goto err_map; + goto err_irq; } fimg2d_debug("irq: %d\n", info->irq); @@ -400,13 +440,6 @@ static int fimg2d_probe(struct platform_device *pdev) goto err_irq; } - ret = fimg2d_clk_setup(info); - if (ret) { - printk(KERN_ERR "FIMG2D failed to setup clk\n"); - ret = -ENOENT; - goto err_clk; - } - #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(info->dev); fimg2d_debug("enable runtime pm\n"); @@ -432,19 +465,20 @@ static int fimg2d_probe(struct platform_device *pdev) return 0; err_reg: - fimg2d_clk_release(info); - -err_clk: free_irq(info->irq, NULL); err_irq: + fimg2d_clk_release(info); + +err_clk: iounmap(info->regs); err_map: + release_mem_region(res->start, resource_size(res)); kfree(info->mem); err_region: - release_resource(info->mem); + release_resource(res); err_res: destroy_workqueue(info->work_q); diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h b/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h index 6fcc276..086c20a 100644 --- a/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h +++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h @@ -15,27 +15,37 @@ /* Q-table for JPEG */ /* ITU standard Q-table */ -const unsigned int ITU_Q_tbl[4][16] = { +const unsigned int ITU_Q_tbl[6][16] = { { - 0x01010101, 0x01020303, 0x01010101, 0x01030303, /* Y */ - 0x01010101, 0x02030303, 0x01010101, 0x03040403, - 0x01010203, 0x03050504, 0x01020303, 0x04050605, - 0x02030404, 0x05060605, 0x04050505, 0x06050505 + 0x06030303, 0x07070706, 0x03030303, 0x08080804, /* Y QF:97 */ + 0x01010101, 0x03040303, 0x03010101, 0x04050503, + 0x03030101, 0x05060704, 0x04030301, 0x06070605, + 0x05050403, 0x06070706, 0x06060604, 0x06070707 } , { - 0x01010102, 0x05050505, 0x01010103, 0x05050505, /* CbCr */ - 0x01010503, 0x05050505, 0x02030505, 0x05050505, - 0x05050505, 0x05050505, 0x05050505, 0x05050505, - 0x05050505, 0x05050505, 0x05050505, 0x05050505 + 0x06030303, 0x07070706, 0x04030303, 0x08080806, /* CbCr QF:97 */ + 0x06030301, 0x06060606, 0x06060403, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606 } , { - 0x05020205, 0x0a161e25, 0x02020307, 0x0c232521, /* Y */ - 0x0302050a, 0x16222b22, 0x0305090e, 0x1e393326, - 0x06091422, 0x2a384431, 0x0a122118, 0x34454b3c, - 0x1d283238, 0x44525142, 0x2d3c3e40, 0x4a424441 + 0x06030303, 0x0a080706, 0x03030303, 0x090a0904, /* Y QF:92 */ + 0x04030303, 0x090b0906, 0x05040303, 0x0a0d0e08, + 0x09060403, 0x0c10110d, 0x0a090604, 0x0f12110d, + 0x0e0c0a08, 0x10131310, 0x100f0f0c, 0x10101012 } , { - 0x05020205, 0x251e160a, 0x07030202, 0x2125230c, /* CbCr */ - 0x0a050203, 0x222b2216, 0x0e090503, 0x2633391e, - 0x22140906, 0x3144382a, 0x1821120a, 0x3c4b4534, - 0x3832281d, 0x42515244, 0x403e3c2d, 0x4144424a + 0x08040303, 0x10101010, 0x0b040303, 0x10101010, /* CbCr QF:92 */ + 0x10090404, 0x10101010, 0x10100b08, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010 + } , { + 0x06030304, 0x0e0c0a06, 0x05030303, 0x0d0e0e06, /* Y QF:88 */ + 0x06040303, 0x0d110e0a, 0x07050403, 0x0f13150c, + 0x0d090504, 0x12191a10, 0x0f0d0806, 0x161b1913, + 0x15130f0c, 0x181d1d19, 0x18171611, 0x1819181b + } , { + 0x0b060404, 0x18181818, 0x10060504, 0x18181818, /* CbCr QF:88 */ + 0x180d0606, 0x18181818, 0x1818100b, 0x18181818, + 0x18181818, 0x18181818, 0x18181818, 0x18181818, + 0x18181818, 0x18181818, 0x18181818, 0x18181818 } }; diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c b/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c index 1e6b085..eb026ab 100644 --- a/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c +++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c @@ -504,7 +504,7 @@ static void jpeg_device_enc_run(void *priv) jpeg_sw_reset(dev->reg_base); jpeg_set_interrupt(dev->reg_base); jpeg_set_huf_table_enable(dev->reg_base, 1); - jpeg_set_enc_tbl(dev->reg_base); + jpeg_set_enc_tbl(dev->reg_base, enc_param.quality); jpeg_set_encode_tbl_select(dev->reg_base, enc_param.quality); jpeg_set_stream_size(dev->reg_base, enc_param.in_width, enc_param.in_height); @@ -893,12 +893,16 @@ static int jpeg_probe(struct platform_device *pdev) #endif #ifdef CONFIG_JPEG_V2_1 - dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME); - INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker); - atomic_set(&dev->watchdog_cnt, 0); - init_timer(&dev->watchdog_timer); - dev->watchdog_timer.data = (unsigned long)dev; - dev->watchdog_timer.function = jpeg_watchdog; + dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME); + if (!dev->watchdog_workqueue) { + ret = -ENOMEM; + goto err_video_reg; + } + INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker); + atomic_set(&dev->watchdog_cnt, 0); + init_timer(&dev->watchdog_timer); + dev->watchdog_timer.data = (unsigned long)dev; + dev->watchdog_timer.function = jpeg_watchdog; #endif /* clock disable */ clk_disable(dev->clk); @@ -1043,7 +1047,8 @@ static int jpeg_runtime_suspend(struct device *dev) struct jpeg_dev *jpeg_drv = platform_get_drvdata(pdev); #if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) /* lock bus frequency */ - dev_unlock(jpeg_drv->bus_dev, dev); + if (samsung_rev() < EXYNOS4412_REV_2_0) + dev_unlock(jpeg_drv->bus_dev, dev); #endif jpeg_drv->vb2->suspend(jpeg_drv->alloc_ctx); /* clock disable */ @@ -1057,7 +1062,9 @@ static int jpeg_runtime_resume(struct device *dev) struct jpeg_dev *jpeg_drv = platform_get_drvdata(pdev); #if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) /* lock bus frequency */ - dev_lock(jpeg_drv->bus_dev, &jpeg_drv->plat_dev->dev, BUSFREQ_400MHZ); + if (samsung_rev() < EXYNOS4412_REV_2_0) + dev_lock(jpeg_drv->bus_dev, + &jpeg_drv->plat_dev->dev, BUSFREQ_400MHZ); #endif clk_enable(jpeg_drv->clk); jpeg_drv->vb2->resume(jpeg_drv->alloc_ctx); @@ -1104,9 +1111,7 @@ static int __init jpeg_init(void) { printk(KERN_CRIT "Initialize JPEG driver\n"); - platform_driver_register(&jpeg_driver); - - return 0; + return platform_driver_register(&jpeg_driver); } static void __exit jpeg_exit(void) diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h b/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h index d912628..9336bb8 100644 --- a/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h +++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h @@ -33,7 +33,12 @@ extern const struct jpeg_vb2 jpeg_vb2_cma; extern const struct jpeg_vb2 jpeg_vb2_ion; #endif +#if defined(CONFIG_MACH_GC1) +#define MAX_JPEG_WIDTH 4608 +#define MAX_JPEG_HEIGHT 3456 +#else #define MAX_JPEG_WIDTH 3264 #define MAX_JPEG_HEIGHT 2448 +#endif #endif /* __JPEG_MEM_H__ */ diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c index e3300cc..0c9bc4b 100644 --- a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c +++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c @@ -341,28 +341,99 @@ void jpeg_set_enc_out_fmt(void __iomem *base, writel(reg, base + S5P_JPEG_IMG_FMT_REG); } -void jpeg_set_enc_tbl(void __iomem *base) +void jpeg_set_enc_tbl(void __iomem *base, + enum jpeg_img_quality_level level) { int i; - for (i = 0; i < 16; i++) { - writel((unsigned int)ITU_Q_tbl[0][i], - base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04)); - } + switch (level) { + case QUALITY_LEVEL_1: + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[0][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04)); + } - for (i = 0; i < 16; i++) { - writel((unsigned int)ITU_Q_tbl[1][i], - base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04)); - } + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[1][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04)); + } - for (i = 0; i < 16; i++) { - writel((unsigned int)ITU_Q_tbl[2][i], - base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04)); - } + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[0][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[1][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04)); + } + break; + + case QUALITY_LEVEL_2: + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[2][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[3][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04)); + } - for (i = 0; i < 16; i++) { - writel((unsigned int)ITU_Q_tbl[3][i], - base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04)); + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[2][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[3][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04)); + } + break; + + case QUALITY_LEVEL_3: + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[4][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[5][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[4][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[5][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04)); + } + break; + + default: + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[0][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[1][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[0][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04)); + } + + for (i = 0; i < 16; i++) { + writel((unsigned int)ITU_Q_tbl[1][i], + base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04)); + } + break; } for (i = 0; i < 4; i++) { diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h index 535a3f9..1dee4b2 100644 --- a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h +++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h @@ -23,7 +23,7 @@ void jpeg_set_enc_in_fmt(void __iomem *base, enum jpeg_frame_format in_fmt); void jpeg_set_enc_out_fmt(void __iomem *base, enum jpeg_stream_format out_fmt); -void jpeg_set_enc_tbl(void __iomem *base); +void jpeg_set_enc_tbl(void __iomem *base, enum jpeg_img_quality_level level); void jpeg_set_interrupt(void __iomem *base); void jpeg_clean_interrupt(void __iomem *base); unsigned int jpeg_get_int_status(void __iomem *base); diff --git a/drivers/media/video/samsung/mali/Kconfig b/drivers/media/video/samsung/mali/Kconfig index b93bccf..ae9bd7d 100644 --- a/drivers/media/video/samsung/mali/Kconfig +++ b/drivers/media/video/samsung/mali/Kconfig @@ -6,7 +6,7 @@ config VIDEO_MALI400MP bool "Enable MALI integration" depends on VIDEO_SAMSUNG - default n + default y ---help--- This enables MALI integration in the multimedia device driver @@ -39,7 +39,6 @@ int "Dedicated Memory Size" ---help--- This value is dedicated memory size of Mali GPU(unit is MByte). - # For DEBUG config VIDEO_MALI400MP_DEBUG bool "Enables debug messages" @@ -48,13 +47,6 @@ config VIDEO_MALI400MP_DEBUG help This enables Mali driver debug messages. -config VIDEO_MALI400MP_STREAMLINE_PROFILING - bool "Enables mali streamline profiling" - depends on VIDEO_MALI400MP - default n - help - This enables Mali streamline profiling. - config VIDEO_MALI400MP_DVFS bool "Enables DVFS" depends on VIDEO_MALI400MP && PM diff --git a/drivers/media/video/samsung/mali/Makefile b/drivers/media/video/samsung/mali/Makefile index 0ce60a3..db5ce6a 100644 --- a/drivers/media/video/samsung/mali/Makefile +++ b/drivers/media/video/samsung/mali/Makefile @@ -10,7 +10,7 @@ OSKOS :=linux FILES_PREFIX= -MALI_FILE_PREFIX := drivers/media/video/samsung/mali +MALI_INCLUDE_PREFIX := drivers/media/video/samsung/mali/ KBUILDROOT = ifeq ($(CONFIG_MALI_DED_ONLY),y) @@ -54,12 +54,8 @@ ifeq ($(CONFIG_VIDEO_MALI400MP_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 @@ -75,21 +71,47 @@ USING_MALI_PMU ?= 0 USING_GPU_UTILIZATION ?= 0 OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6 USING_PROFILING ?= 0 +USING_INTERNAL_PROFILING ?= 0 USING_TRACEPOINTS ?= 0 USING_MALI_MAJOR_PREDEFINE = 1 -USING_MALI_DVFS_ENABLED ?= 0 +USING_MALI_DVFS_ENABLED ?= 1 TIMESTAMP ?= default BUILD ?= release USING_MALI_PMM_EARLYSUSPEND ?= 0 #USING_KERNEL_WITH_DMA_ALLOC_PHYS_PAGE ?= 0 -CONFIG_MALI_MEM_SIZE ?= 64 +CONFIG_MALI_MEM_SIZE ?= 512 +DISABLE_PP0 ?= 0 +DISABLE_PP1 ?= 0 +DISABLE_PP2 ?= 0 +DISABLE_PP3 ?= 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 +USING_PROFILING = 0 +endif +endif +endif + +ifeq ($(USING_PROFILING),0) +# make sure user hasnt selected incompatible flags +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 $(MALI_FILE_PREFIX)/arch/config.h | grep type | grep -c $(2)) +#submodule_enabled = $(shell gcc $(DEFINES) -E $(FILES_PREFIX)/arch/config.h | grep type | grep -c $(2)) # Inside the kernel build system @@ -111,14 +133,21 @@ 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_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING) +DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING) DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE) 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=1 +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 += -DMALI_REBOOTNOTIFIER +DEFINES += -DDISABLE_PP0=$(DISABLE_PP0) +DEFINES += -DDISABLE_PP1=$(DISABLE_PP1) +DEFINES += -DDISABLE_PP2=$(DISABLE_PP2) +DEFINES += -DDISABLE_PP3=$(DISABLE_PP3) +DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP) +DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED) +DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS) ifeq ($(BUILD),debug) DEFINES += -DDEBUG @@ -130,7 +159,7 @@ DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP # UMP ifeq ($(CONFIG_VIDEO_UMP),y) DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 -DHAVE_UNLOCKED_IOCTL - EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/../ump/include + EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)../ump/include else DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0 endif @@ -141,17 +170,23 @@ obj-$(CONFIG_VIDEO_MALI400MP) += mali.o # Use our defines when compiling # MALI INCLUDES = \ - -I$(MALI_FILE_PREFIX)\ - -I$(MALI_FILE_PREFIX)/platform\ - -I$(MALI_FILE_PREFIX)/common \ - -I$(MALI_FILE_PREFIX)/linux + -I$(MALI_INCLUDE_PREFIX)\ + -I$(MALI_INCLUDE_PREFIX)include \ + -I$(MALI_INCLUDE_PREFIX)platform\ + -I$(MALI_INCLUDE_PREFIX)common \ + -I$(MALI_INCLUDE_PREFIX)linux \ + -I$(MALI_INCLUDE_PREFIX)regs + +ifeq ($(USING_PROFILING),1) +INCLUDES += \ + -I$(MALI_INCLUDE_PREFIX)include +endif EXTRA_CFLAGS += $(INCLUDES)\ $(DEFINES) - -EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/linux/license/gpl -EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/common/pmm +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) @@ -178,11 +213,12 @@ OSKFILES=\ endif #($(CONFIG_VIDEO_UMP),y) ifeq ($(CONFIG_CPU_EXYNOS4210),y) - MALI_PLATFORM_FILE = platform/orion-m400/mali_platform.o + MALI_PLATFORM_DIR = platform/orion-m400 else - MALI_PLATFORM_FILE = platform/pegasus-m400/mali_platform.o + 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 \ @@ -190,85 +226,94 @@ UKKFILES=\ $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.o \ $(FILES_PREFIX)$(OSKOS)/mali_ukk_vsync.o -mali-y := \ - $(KBUILDROOT)common/mali_kernel_core.o \ - $(KBUILDROOT)linux/mali_kernel_linux.o \ - $(KBUILDROOT)linux/mali_osk_indir_mmap.o \ - $(KBUILDROOT)common/mali_kernel_rendercore.o \ - $(KBUILDROOT)common/mali_kernel_descriptor_mapping.o \ - $(KBUILDROOT)common/mali_kernel_vsync.o \ - $(KBUILDROOT)linux/mali_kernel_sysfs.o \ - $(KBUILDROOT)$(MALI_PLATFORM_FILE) \ - $(KBUILDROOT)$(OSKFILES) \ - $(KBUILDROOT)$(UKKFILES) - #__malidrv_build_info.o - ifeq ($(USING_PROFILING),1) -EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/timestamp-default -EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/profiling/include -mali-y += \ - common/mali_kernel_profiling.o \ - timestamp-$(TIMESTAMP)/mali_timestamp.o \ - linux/mali_ukk_profiling.o - -EXTRA_CFLAGS += -I$(KBUILD_EXTMOD)/timestamp-$(TIMESTAMP) +UKKFILES += \ + $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.o endif -ifeq ($(USING_TRACEPOINTS),1) -mali-y += \ - linux/mali_osk_profiling.o -endif +mali-y := \ + common/mali_kernel_core.o \ + linux/mali_kernel_linux.o \ + $(OSKOS)/mali_osk_indir_mmap.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 \ + $(OSKOS)/mali_osk_wait_queue.o \ + $(MALI_PLATFORM_FILE) \ + $(OSKFILES) \ + $(UKKFILES) +# __malidrv_build_info.c # Selecting files to compile by parsing the config file -ifeq ($(USING_PMM),1) -mali-y += \ - common/pmm/mali_pmm.o \ - common/pmm/mali_pmm_policy.o \ - common/pmm/mali_pmm_policy_alwayson.o \ - common/pmm/mali_pmm_policy_jobcontrol.o \ - common/pmm/mali_pmm_state.o \ - linux/mali_kernel_pm.o \ - linux/mali_osk_pm.o \ - linux/mali_device_pause_resume.o +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 -ifeq ($(USING_MALI_PMU),1) -mali-y += \ - common/pmm/mali_pmm_pmu.o +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 -# Mali-400 PP in use -EXTRA_CFLAGS += -DUSING_MALI400 -mali-y += common/mali_kernel_MALI200.o - -# Mali-400 GP in use -mali-y += common/mali_kernel_GP2.o +ifeq ($(USING_MALI_DVFS_ENABLED),1) +mali-y += $(MALI_PLATFORM_DIR)/mali_platform_dvfs.o +endif #($(USING_MALI_DVFS_ENABLED),1) -# Mali MMU in use -mali-y += \ - common/mali_kernel_mem_mmu.o \ - common/mali_kernel_memory_engine.o \ - common/mali_block_allocator.o \ - common/mali_kernel_mem_os.o +EXTRA_CFLAGS += -DUSING_MALI400 # Mali Level2 cache in use EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE -mali-y += common/mali_kernel_l2_cache.o - -ifeq ($(USING_MALI_DVFS_ENABLED),1) -ifeq ($(CONFIG_CPU_EXYNOS4210),y) +mali-y += common/mali_l2_cache.o +# Mali SLP Global lock feature +ifeq ($(USING_MALI_SLP_GLOBAL_LOCK),1) mali-y += \ - platform/orion-m400/mali_platform_dvfs.o -else -mali-y += \ - platform/pegasus-m400/mali_platform_dvfs.o -endif #($(CONFIG_CPU_EXYNOS4210),y) -endif #($(USING_MALI_DVFS_ENABLED),1) + linux/mali_slp_global_lock.o +endif + ifeq ($(PANIC_ON_WATCHDOG_TIMEOUT),1) EXTRA_CFLAGS += -DUSING_KERNEL_PANIC diff --git a/drivers/media/video/samsung/mali/Makefile.common b/drivers/media/video/samsung/mali/Makefile.common deleted file mode 100644 index 53d4e5b..0000000 --- a/drivers/media/video/samsung/mali/Makefile.common +++ /dev/null @@ -1,59 +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. -# - -# Check if a Mali Core sub module should be enabled, true or false returned -submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2)) - -OSKFILES=\ - $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_locks.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_math.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_memory.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_misc.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_time.c \ - $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.c - -UKKFILES=\ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.c \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.c \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_pp.c \ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.c - -ifeq ($(USING_PROFILING),1) -UKKFILES+=\ - $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.c -endif - -ifeq ($(MALI_PLATFORM_FILE),) -MALI_PLATFORM_FILE=platform/default/mali_platform.c -endif - -# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available -SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -qv exported && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null ) -ifeq ($(SVN_REV),) -SVN_REV := $(MALI_RELEASE_NAME) -else -SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV) -endif - -# Common version-string, will be extended by OS-specifc sections -VERSION_STRINGS := -VERSION_STRINGS += CONFIG=$(CONFIG) -VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY) -VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)common\/mali_uk_types.h | cut -d' ' -f 3 ) -VERSION_STRINGS += REPO_URL=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'URL: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^URL: ' | cut -d: -f2- | cut -b2-) -VERSION_STRINGS += REVISION=$(SVN_REV) -VERSION_STRINGS += CHANGED_REVISION=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Rev: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-) -VERSION_STRINGS += CHANGE_DATE=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Date: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-) -VERSION_STRINGS += BUILD_DATE=$(shell date) diff --git a/drivers/media/video/samsung/mali/Makefile_module b/drivers/media/video/samsung/mali/Makefile_module new file mode 100644 index 0000000..4fb0226 --- /dev/null +++ b/drivers/media/video/samsung/mali/Makefile_module @@ -0,0 +1,89 @@ +# +# 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. +# + +USE_UMPV2=0 + +# 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 +# system to actually build the driver. After that point the Kbuild file takes +# over. + +# set up defaults if not defined by the user +ARCH ?= arm + +OSKOS=linux +FILES_PREFIX= + +# 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.") +endif +ifeq ($(CPU)$(KDIR),) +$(error "KDIR or CPU must be specified.") +endif + +ifeq ($(USING_UMP),1) +ifeq ($(USE_UMPV2),1) +UMP_SYMVERS_FILE ?= ../umpv2/Module.symvers +else +UMP_SYMVERS_FILE ?= ../ump/Module.symvers +endif +KBUILD_EXTRA_SYMBOLS = $(realpath $(UMP_SYMVERS_FILE)) +$(warning $(KBUILD_EXTRA_SYMBOLS)) +endif + +# Get any user defined KDIR- 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 ?= 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)) +endif + +# Set up build config +export CONFIG_MALI400=m + +ifeq ($(USING_GPU_UTILIZATION),1) +export EXTRA_DEFINES += -DCONFIG_MALI400_GPU_UTILIZATION=1 +export CONFIG_MALI400_GPU_UTILIZATION := y +endif + +all: $(UMP_SYMVERS_FILE) + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules + @rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o + +clean: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean + +kernelrelease: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease + +export CONFIG KBUILD_EXTRA_SYMBOLS diff --git a/drivers/media/video/samsung/mali/arch b/drivers/media/video/samsung/mali/arch deleted file mode 120000 index 6154ca4..0000000 --- a/drivers/media/video/samsung/mali/arch +++ /dev/null @@ -1 +0,0 @@ -arch-orion-m400 \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/arch-debug/config.h b/drivers/media/video/samsung/mali/arch-debug/config.h new file mode 100644 index 0000000..d5196c3 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-debug/config.h @@ -0,0 +1,154 @@ +/* + * 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-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h deleted file mode 100644 index 5c4d79d..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 = "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-pb-virtex5-m300/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h new file mode 100644 index 0000000..e579526 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h @@ -0,0 +1,85 @@ +/* + * 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 new file mode 100644 index 0000000..3893d72 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h @@ -0,0 +1,92 @@ +/* + * 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 new file mode 100644 index 0000000..d85c090 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __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 new file mode 100644 index 0000000..568ac0a --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h @@ -0,0 +1,77 @@ +/* + * 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 new file mode 100644 index 0000000..98b8059 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h @@ -0,0 +1,91 @@ +/* + * 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 new file mode 100644 index 0000000..7b10925 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h @@ -0,0 +1,105 @@ +/* + * 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 new file mode 100644 index 0000000..a15a6bd --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h @@ -0,0 +1,119 @@ +/* + * 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 new file mode 100644 index 0000000..d5196c3 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h @@ -0,0 +1,154 @@ +/* + * 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/config.h b/drivers/media/video/samsung/mali/arch-release/config.h new file mode 100644 index 0000000..d5196c3 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-release/config.h @@ -0,0 +1,154 @@ +/* + * 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-ve-virtex6-m450-8/config.h b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h new file mode 100644 index 0000000..9b38f35 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_H__ +#define __ARCH_CONFIG_H__ + +/* Configuration for the Versatile Express platform */ + +#define MALI_BASE_ADDRESS 0xFC040000 + +static _mali_osk_resource_t arch_configuration [] = +{ + /* GP cluster */ + { + .type = MALI400L2, + .base = MALI_BASE_ADDRESS + 0x10000, + .description = "Mali-450 L2 cache for GP" + }, + { + .type = MALI400GP, + .description = "Mali-450 GP", + .base = MALI_BASE_ADDRESS, + .irq = -1, + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x3000, + .irq = 70, + .description = "Mali-450 MMU for GP", + }, + + /* PP0-3 cluster */ + { + .type = MALI400L2, + .base = MALI_BASE_ADDRESS + 0x1000, + .description = "Mali-450 L2 cache for PP0-3" + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x8000, + .irq = 70, + .description = "Mali-450 PP0", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x4000, + .irq = 70, + .description = "Mali-450 MMU for PP0", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0xA000, + .irq = 70, + .description = "Mali-450 PP1", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x5000, + .irq = 70, + .description = "Mali-450 MMU for PP1", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0xC000, + .irq = 70, + .description = "Mali-450 PP2", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x6000, + .irq = 70, + .description = "Mali-450 MMU for PP2", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0xE000, + .irq = 70, + .description = "Mali-450 PP3", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x7000, + .irq = 70, + .description = "Mali-450 MMU for PP3", + }, + + /* PP4-7 cluster */ + { + .type = MALI400L2, + .base = MALI_BASE_ADDRESS + 0x11000, + .description = "Mali-450 L2 cache for PP4-7" + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x28000, + .irq = 70, + .description = "Mali-450 PP4", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1C000, + .irq = 70, + .description = "Mali-450 MMU for PP4", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x2A000, + .irq = 70, + .description = "Mali-450 PP5", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1D000, + .irq = 70, + .description = "Mali-450 MMU for PP5", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x2C000, + .irq = 70, + .description = "Mali-450 PP6", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1E000, + .irq = 70, + .description = "Mali-450 MMU for PP6", + }, + { + .type = MALI400PP, + .base = MALI_BASE_ADDRESS + 0x2E000, + .irq = 70, + .description = "Mali-450 PP7", + }, + { + .type = MMU, + .base = MALI_BASE_ADDRESS + 0x1F000, + .irq = 70, + .description = "Mali-450 MMU for PP7", + }, + + /* Memory */ + { + .type = OS_MEMORY, + .description = "Mali OS memory", + .cpu_usage_adjust = 0, + .alloc_order = 0, /* Highest preference for this memory */ + .base = 0x0, + .size = 256 * 1024 * 1024, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE + }, + { + .type = MEM_VALIDATION, + .description = "Framebuffer", + .base = 0xe0000000, + .size = 0x01000000, + .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE + }, +}; + +#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/mali/arch/config.h b/drivers/media/video/samsung/mali/arch/config.h new file mode 100644 index 0000000..d5196c3 --- /dev/null +++ b/drivers/media/video/samsung/mali/arch/config.h @@ -0,0 +1,154 @@ +/* + * 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/common/mali_block_allocator.c b/drivers/media/video/samsung/mali/common/mali_block_allocator.c index 5f421f0..269e662 100644 --- a/drivers/media/video/samsung/mali/common/mali_block_allocator.c +++ b/drivers/media/video/samsung/mali/common/mali_block_allocator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -76,7 +76,7 @@ mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u info = _mali_osk_malloc(sizeof(block_allocator)); if (NULL != info) { - info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, 105); + info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); if (NULL != info->mutex) { info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks); @@ -355,7 +355,7 @@ static void block_allocator_release_page_table_block( mali_page_table_block *pag _mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping ); /** @note This loop handles the case where more than one block_info was linked. - * Probably unnecssary for page table block releasing. */ + * Probably unnecessary for page table block releasing. */ while (block) { next = block->next; diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.c b/drivers/media/video/samsung/mali/common/mali_cluster.c new file mode 100644 index 0000000..f0fb2b6 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_cluster.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_cluster.h" +#include "mali_osk.h" +#include "mali_group.h" +#include "mali_l2_cache.h" +#include "mali_scheduler.h" + +static struct mali_cluster *mali_global_clusters[MALI_MAX_NUMBER_OF_CLUSTERS] = { NULL, NULL, NULL }; +static u32 mali_global_num_clusters = 0; + +/** + * The structure represents a render cluster + * A render cluster is defined by all the cores that share the same Mali L2 cache + */ +struct mali_cluster +{ + struct mali_l2_cache_core *l2; + u32 number_of_groups; + struct mali_group* groups[MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER]; + u32 last_invalidated_id; + mali_bool power_is_enabled; +}; + +struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache) +{ + struct mali_cluster *cluster = NULL; + + if (mali_global_num_clusters >= MALI_MAX_NUMBER_OF_CLUSTERS) + { + MALI_PRINT_ERROR(("Mali cluster: Too many cluster objects created\n")); + return NULL; + } + + cluster = _mali_osk_malloc(sizeof(struct mali_cluster)); + if (NULL != cluster) + { + _mali_osk_memset(cluster, 0, sizeof(struct mali_cluster)); + cluster->l2 = l2_cache; /* This cluster now owns this L2 cache object */ + cluster->last_invalidated_id = 0; + cluster->power_is_enabled = MALI_TRUE; + + mali_global_clusters[mali_global_num_clusters] = cluster; + mali_global_num_clusters++; + + return cluster; + } + + return NULL; +} + +void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled) +{ + cluster->power_is_enabled = power_is_enabled; +} + +mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster) +{ + return cluster->power_is_enabled; +} + + +void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (cluster->number_of_groups < MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER) + { + /* This cluster now owns the group object */ + cluster->groups[cluster->number_of_groups] = group; + cluster->number_of_groups++; + } +} + +void mali_cluster_delete(struct mali_cluster *cluster) +{ + u32 i; + + MALI_DEBUG_ASSERT_POINTER(cluster); + + /* Free all the resources we own */ + for (i = 0; i < cluster->number_of_groups; i++) + { + mali_group_delete(cluster->groups[i]); + } + + if (NULL != cluster->l2) + { + mali_l2_cache_delete(cluster->l2); + } + + for (i = 0; i < mali_global_num_clusters; i++) + { + if (mali_global_clusters[i] == cluster) + { + mali_global_clusters[i] = NULL; + mali_global_num_clusters--; + break; + } + } + + _mali_osk_free(cluster); +} + +void mali_cluster_reset(struct mali_cluster *cluster) +{ + u32 i; + + MALI_DEBUG_ASSERT_POINTER(cluster); + + /* Free all the resources we own */ + for (i = 0; i < cluster->number_of_groups; i++) + { + struct mali_group *group = cluster->groups[i]; + + mali_group_reset(group); + } + + if (NULL != cluster->l2) + { + mali_l2_cache_reset(cluster->l2); + } +} + +struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + return cluster->l2; +} + +struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (index < cluster->number_of_groups) + { + return cluster->groups[index]; + } + + return NULL; +} + +struct mali_cluster *mali_cluster_get_global_cluster(u32 index) +{ + if (MALI_MAX_NUMBER_OF_CLUSTERS > index) + { + return mali_global_clusters[index]; + } + + return NULL; +} + +u32 mali_cluster_get_glob_num_clusters(void) +{ + return mali_global_num_clusters; +} + +mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (NULL != cluster->l2) + { + /* If the last cache invalidation was done by a job with a higher id we + * don't have to flush. Since user space will store jobs w/ their + * corresponding memory in sequence (first job #0, then job #1, ...), + * we don't have to flush for job n-1 if job n has already invalidated + * the cache since we know for sure that job n-1's memory was already + * written when job n was started. */ + if (((s32)id) <= ((s32)cluster->last_invalidated_id)) + { + return MALI_FALSE; + } + else + { + cluster->last_invalidated_id = mali_scheduler_get_new_id(); + } + + mali_l2_cache_invalidate_all(cluster->l2); + } + return MALI_TRUE; +} + +void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster) +{ + MALI_DEBUG_ASSERT_POINTER(cluster); + + if (NULL != cluster->l2) + { + cluster->last_invalidated_id = mali_scheduler_get_new_id(); + mali_l2_cache_invalidate_all(cluster->l2); + } +} + +void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages) +{ + u32 i; + + for (i = 0; i < mali_global_num_clusters; i++) + { + /*additional check for cluster*/ + if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_clusters[i]->l2)) + { + mali_l2_cache_invalidate_pages(mali_global_clusters[i]->l2, pages, num_pages); + } + mali_l2_cache_unlock_power_state(mali_global_clusters[i]->l2); + /*check for failed power locking???*/ + } +} diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.h b/drivers/media/video/samsung/mali/common/mali_cluster.h new file mode 100644 index 0000000..33debdb --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_cluster.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_CLUSTER_H__ +#define __MALI_CLUSTER_H__ + +#include "mali_osk.h" +#include "mali_l2_cache.h" + +/* Maximum 1 GP and 4 PP for a cluster (Mali-400 Quad-core) */ +#define MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER 5 +#define MALI_MAX_NUMBER_OF_CLUSTERS 3 + +struct mali_cluster; +struct mali_group; + +struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache); +void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group); +void mali_cluster_delete(struct mali_cluster *cluster); + +void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled); +mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster); + +void mali_cluster_reset(struct mali_cluster *cluster); + +struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster); +struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index); + +struct mali_cluster *mali_cluster_get_global_cluster(u32 index); +u32 mali_cluster_get_glob_num_clusters(void); + +/* Returns MALI_TRUE if it did the flush */ +mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id); +void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster); +void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages); + +#endif /* __MALI_CLUSTER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c new file mode 100644 index 0000000..6af1279 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** + * @file mali_device_pause_resume.c + * Implementation of the Mali pause/resume functionality + */ + +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_pm.h" + +void mali_dev_pause(mali_bool *power_is_on) +{ + mali_gp_scheduler_suspend(); + mali_pp_scheduler_suspend(); + + /* + * Take and hold the PM lock to be sure we don't change power state as well. + * (it might be unsafe to for instance change frequency if Mali GPU is powered off) + */ + mali_pm_execute_state_change_lock(); + if (NULL != power_is_on) + { + *power_is_on = mali_pm_is_powered_on(); + } +} + +void mali_dev_resume(void) +{ + mali_pm_execute_state_change_unlock(); + mali_gp_scheduler_resume(); + mali_pp_scheduler_resume(); +} + +/* +EXPORT_SYMBOL(mali_dev_pause); +EXPORT_SYMBOL(mali_dev_resume); +*/ diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h new file mode 100644 index 0000000..6be75b0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_DEVICE_PAUSE_RESUME_H__ +#define __MALI_DEVICE_PAUSE_RESUME_H__ + +#include "mali_osk.h" + +/** + * Pause the scheduling and power state changes of Mali device driver. + * mali_dev_resume() must always be called as soon as possible after this function + * in order to resume normal operation of the Mali driver. + * + * @param power_is_on Receives the power current status of Mali GPU. MALI_TRUE if GPU is powered on + */ +void mali_dev_pause(mali_bool *power_is_on); + +/** + * Resume scheduling and allow power changes in Mali device driver. + * This must always be called after mali_dev_pause(). + */ +void mali_dev_resume(void); + +#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.c b/drivers/media/video/samsung/mali/common/mali_dlbu.c new file mode 100644 index 0000000..fcc51fa --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_dlbu.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_dlbu.h" +#include "mali_memory.h" +#include "mali_pp.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "mali_hw_core.h" + +/** + * Size of DLBU registers in bytes + */ +#define MALI_DLBU_SIZE 0x400 + +u32 mali_dlbu_phys_addr = 0; +static mali_io_address mali_dlbu_cpu_addr = 0; + +static u32 mali_dlbu_tile_position; + +/** + * DLBU register numbers + * Used in the register read/write routines. + * See the hardware documentation for more information about each register + */ +typedef enum mali_dlbu_register { + MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR = 0x0000, /**< Master tile list physical base address; + 31:12 Physical address to the page used for the DLBU + 0 DLBU enable - set this bit to 1 enables the AXI bus + between PPs and L2s, setting to 0 disables the router and + no further transactions are sent to DLBU */ + MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR = 0x0004, /**< Master tile list virtual base address; + 31:12 Virtual address to the page used for the DLBU */ + MALI_DLBU_REGISTER_TLLIST_VBASEADDR = 0x0008, /**< Tile list virtual base address; + 31:12 Virtual address to the tile list. This address is used when + calculating the call address sent to PP.*/ + MALI_DLBU_REGISTER_FB_DIM = 0x000C, /**< Framebuffer dimension; + 23:16 Number of tiles in Y direction-1 + 7:0 Number of tiles in X direction-1 */ + MALI_DLBU_REGISTER_TLLIST_CONF = 0x0010, /**< Tile list configuration; + 29:28 select the size of each allocated block: 0=128 bytes, 1=256, 2=512, 3=1024 + 21:16 2^n number of tiles to be binned to one tile list in Y direction + 5:0 2^n number of tiles to be binned to one tile list in X direction */ + MALI_DLBU_REGISTER_START_TILE_POS = 0x0014, /**< Start tile positions; + 31:24 start position in Y direction for group 1 + 23:16 start position in X direction for group 1 + 15:8 start position in Y direction for group 0 + 7:0 start position in X direction for group 0 */ + MALI_DLBU_REGISTER_PP_ENABLE_MASK = 0x0018, /**< PP enable mask; + 7 enable PP7 for load balancing + 6 enable PP6 for load balancing + 5 enable PP5 for load balancing + 4 enable PP4 for load balancing + 3 enable PP3 for load balancing + 2 enable PP2 for load balancing + 1 enable PP1 for load balancing + 0 enable PP0 for load balancing */ +} mali_dlbu_register; + +typedef enum +{ + PP0ENABLE = 0, + PP1ENABLE, + PP2ENABLE, + PP3ENABLE, + PP4ENABLE, + PP5ENABLE, + PP6ENABLE, + PP7ENABLE +} mali_dlbu_pp_enable; + +struct mali_dlbu_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + u32 pp_cores_mask; /**< This is a mask for the PP cores whose operation will be controlled by LBU + see MALI_DLBU_REGISTER_PP_ENABLE_MASK register */ +}; + +_mali_osk_errcode_t mali_dlbu_initialize(void) +{ + + MALI_DEBUG_PRINT(2, ("Dynamic Load Balancing Unit initializing\n")); + + if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr)) + { + MALI_SUCCESS; + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_dlbu_terminate(void) +{ + MALI_DEBUG_PRINT(3, ("Mali DLBU: terminating\n")); + + mali_mmu_release_table_page(mali_dlbu_phys_addr); +} + +struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource) +{ + struct mali_dlbu_core *core = NULL; + + MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description)); + + core = _mali_osk_malloc(sizeof(struct mali_dlbu_core)); + if (NULL != core) + { + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE)) + { + if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core)) + { + mali_hw_core_register_write(&core->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR, MALI_DLB_VIRT_ADDR); + + return core; + } + MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description)); + mali_hw_core_delete(&core->hw_core); + } + + _mali_osk_free(core); + } + else + { + MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n")); + } + + return NULL; +} + +void mali_dlbu_delete(struct mali_dlbu_core *dlbu) +{ + mali_dlbu_reset(dlbu); + mali_hw_core_delete(&dlbu->hw_core); + _mali_osk_free(dlbu); +} + +void mali_dlbu_enable(struct mali_dlbu_core *dlbu) +{ + u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); + + wval |= 0x1; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); +} + +void mali_dlbu_disable(struct mali_dlbu_core *dlbu) +{ + u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR); + + wval |= (wval & 0xFFFFFFFE); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval); +} + +_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val) +{ + u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK); + + if((pp_core_enable < mali_pp_get_glob_num_pp_cores()) && ((0 == val) || (1 == val))) /* check for valid input parameters */ + { + if (val == 1) + { + val = (wval | (pp_core_enable <<= 0x1)); + } + if (val == 0) + { + val = (wval & ~(pp_core_enable << 0x1)); + } + wval |= val; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, wval); + dlbu->pp_cores_mask = wval; + + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu) +{ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask); +} + +void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu) +{ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, 0x0); +} + +void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1) +{ + u32 wval = 0x0; + + /* write the framebuffer dimensions */ + wval = (16 << (u32)fb_ydim) | (u32)fb_xdim; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, wval); + + /* write the tile list configuration */ + wval = 0x0; + wval = (28 << (u32)blocksize) | (16 << (u32)ytilesize) | ((u32)xtilesize); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, wval); + + /* write the start tile position */ + wval = 0x0; + wval = (24 << (u32)ygr1 | (16 << (u32)xgr1) | 8 << (u32)ygr0) | (u32)xgr0; + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, wval); +} + +_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; + MALI_DEBUG_ASSERT_POINTER(dlbu); + + MALI_DEBUG_PRINT(4, ("Mali DLBU: mali_dlbu_reset: %s\n", dlbu->hw_core.description)); + + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, mali_dlbu_phys_addr); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, 0x00); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, 0x00); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, 0x00); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, 0x00); + + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask); + + err = _MALI_OSK_ERR_OK; + + return err; +} + +_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group) +{ + _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; + u32 wval, rval; + struct mali_pp_core *pp_core = mali_group_get_pp_core(group); + + /* find the core id and set the mask */ + + if (NULL != pp_core) + { + wval = mali_pp_core_get_id(pp_core); + rval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK); + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, (wval << 0x1) | rval); + err = _MALI_OSK_ERR_OK; + } + + return err; +} + +void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val) +{ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, val); +} + +void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu) +{ + /* this function to implement (see documentation): + * 1) clear all bits in the enable register + * 2) wait until all PPs have finished - mali_pp_scheduler.c code - this done in interrupts call? + * 3) read the current tile position registers to get current tile positions - + * note that current tile position register is the same as start tile position - perhaps the name should be changed!!! */ + + /* 1) */ + mali_dlbu_disable_all_pp_cores(dlbu); + + /* 3) */ + mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS); +} + +void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu) +{ + /* this function to implement (see the document): + * 1) configure the dynamic load balancing unit as normal + * 2) set the current tile position registers as read when stopping the job + * 3) configure the PPs to start the job as normal - done by another part of the system - scheduler */ + + /* 1) */ + mali_dlbu_reset(dlbu); + /* ++ setup the needed values - see this */ + + /* 2) */ + mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, mali_dlbu_tile_position); +} diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.h b/drivers/media/video/samsung/mali/common/mali_dlbu.h new file mode 100644 index 0000000..e3c3b9d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_dlbu.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_DLBU_H__ +#define __MALI_DLBU_H__ + +#include "mali_osk.h" +#include "mali_group.h" + +#define MALI_DLB_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */ + +extern u32 mali_dlbu_phys_addr; + +struct mali_dlbu_core; + +_mali_osk_errcode_t mali_dlbu_initialize(void); +void mali_dlbu_terminate(void); + +struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource); +void mali_dlbu_delete(struct mali_dlbu_core *dlbu); + +void mali_dlbu_enable(struct mali_dlbu_core *dlbu); +void mali_dlbu_disable(struct mali_dlbu_core *dlbu); + +_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val); +void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu); +void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu); + +_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu); +void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1); + +_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group); +void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val); + +void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu); +void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu); + +#endif /* __MALI_DLBU_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp.c b/drivers/media/video/samsung/mali/common/mali_gp.c new file mode 100644 index 0000000..d03721c --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp.c @@ -0,0 +1,693 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_gp.h" +#include "mali_hw_core.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "regs/mali_gp_regs.h" +#include "mali_kernel_common.h" +#include "mali_kernel_core.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +#endif + +/** + * Definition of the GP core struct + * Used to track a GP core in the system. + */ +struct mali_gp_core +{ + struct mali_hw_core hw_core; /**< Common for all HW cores */ + struct mali_group *group; /**< Parent group for this core */ + _mali_osk_irq_t *irq; /**< IRQ handler */ + struct mali_gp_job *running_job; /**< Current running job */ + _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */ + u32 timeout_job_id; /**< job id for the timed out job - relevant only if gp_core_timed_out == MALI_TRUE */ + mali_bool core_timed_out; /**< if MALI_TRUE, this gp core has timed out; if MALI_FALSE, no timeout on this gp core */ + u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */ + u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */ + u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */ +}; + +static struct mali_gp_core *mali_global_gp_core = NULL; + +/* Interrupt handlers */ +static _mali_osk_errcode_t mali_gp_upper_half(void *data); +static void mali_gp_bottom_half(void *data); +static void mali_gp_irq_probe_trigger(void *data); +static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data); +static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend); +static void mali_gp_timeout(void *data); + +struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group) +{ + struct mali_gp_core* core = NULL; + + MALI_DEBUG_ASSERT(NULL == mali_global_gp_core); + MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description)); + + core = _mali_osk_malloc(sizeof(struct mali_gp_core)); + if (NULL != core) + { + core->group = group; + core->running_job = NULL; + core->counter_src0 = MALI_HW_CORE_NO_COUNTER; + core->counter_src1 = MALI_HW_CORE_NO_COUNTER; + core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; + core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; + if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) + { + _mali_osk_errcode_t ret; + + mali_group_lock(group); + ret = mali_gp_reset(core); + mali_group_unlock(group); + + if (_MALI_OSK_ERR_OK == ret) + { + /* Setup IRQ handlers (which will do IRQ probing if needed) */ + core->irq = _mali_osk_irq_init(resource->irq, + mali_gp_upper_half, + mali_gp_bottom_half, + mali_gp_irq_probe_trigger, + mali_gp_irq_probe_ack, + core, + "mali_gp_irq_handlers"); + if (NULL != core->irq) + { + /* Initialise the timeout timer */ + core->timeout_timer = _mali_osk_timer_init(); + if(NULL != core->timeout_timer) + { + _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core); + MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core)); + mali_global_gp_core = core; + + return core; + } + else + { + MALI_PRINT_ERROR(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description)); + /* Release IRQ handlers */ + _mali_osk_irq_term(core->irq); + } + } + else + { + MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description)); + } + } + mali_hw_core_delete(&core->hw_core); + } + + _mali_osk_free(core); + } + else + { + MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n")); + } + + return NULL; +} + +void mali_gp_delete(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + _mali_osk_timer_term(core->timeout_timer); + _mali_osk_irq_term(core->irq); + mali_hw_core_delete(&core->hw_core); + mali_global_gp_core = NULL; + _mali_osk_free(core); +} + +void mali_gp_stop_bus(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); +} + +_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core) +{ + int i; + const int request_loop_count = 20; + + MALI_DEBUG_ASSERT_POINTER(core); + + /* Send the stop bus command. */ + mali_gp_stop_bus(core); + + /* Wait for bus to be stopped */ + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT; + } + return _MALI_OSK_ERR_OK; +} + +void mali_gp_hard_reset(struct mali_gp_core *core) +{ + const int reset_finished_loop_count = 15; + const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW; + const u32 reset_invalid_value = 0xC0FFE000; + const u32 reset_check_value = 0xC01A0000; + const u32 reset_default_value = 0; + int i; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description)); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_gp_post_process_job(core, MALI_FALSE); + + mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET); + + for (i = 0; i < reset_finished_loop_count; i++) + { + mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value); + if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register)) + { + break; + } + } + + if (i == reset_finished_loop_count) + { + MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n")); + } + + mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */ + /* Re-enable interrupts */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); + +} + +_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core) +{ + int i; + const int request_loop_count = 20; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description)); + MALI_ASSERT_GROUP_LOCKED(core->group); + + mali_gp_post_process_job(core, MALI_FALSE); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ + +#if defined(USING_MALI200) + + /* On Mali-200, stop the bus, then do a hard reset of the core */ + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); + + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali GP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT; + } + + /* the bus was stopped OK, do the hard reset */ + mali_gp_hard_reset(core); + +#elif defined(USING_MALI400) + + /* Mali-300 and Mali-400 have a safe reset command which we use */ + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET); + + for (i = 0; i < request_loop_count; i++) + { + if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) + { + break; + } + _mali_osk_time_ubusydelay(10); + } + + if (request_loop_count == i) + { + MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, unable to recover\n", core->hw_core.description)); + return _MALI_OSK_ERR_FAULT; + } +#else +#error "no supported mali core defined" +#endif + + /* Re-enable interrupts */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); + + return _MALI_OSK_ERR_OK; +} + +void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job) +{ + u32 startcmd = 0; + u32 *frame_registers = mali_gp_job_get_frame_registers(job); + core->counter_src0_used = core->counter_src0; + core->counter_src1_used = core->counter_src1; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (mali_gp_job_has_vs_job(job)) + { + startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS; + } + + if (mali_gp_job_has_plbu_job(job)) + { + startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU; + } + + MALI_DEBUG_ASSERT(0 != startcmd); + + mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME); + + /* This selects which performance counters we are reading */ + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + /* global_config has enabled HW counters, this will override anything specified by user space */ + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + } + else + { + /* Use HW counters from job object, if any */ + u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job); + if (0 != perf_counter_flag) + { + if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) + { + core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + + if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) + { + core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE); + } + } + } + + MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd)); + + /* Barrier to make sure the previous register write is finished */ + _mali_osk_write_mem_barrier(); + + /* This is the command that starts the core. */ + mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd); + + /* Barrier to make sure the previous register write is finished */ + _mali_osk_write_mem_barrier(); + + /* Setup the timeout timer value and save the job id for the job running on the gp core */ + + _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime)); + core->timeout_job_id = mali_gp_job_get_id(job); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, + job->frame_builder_id, job->flush_id, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), job->pid, job->tid, 0, 0, 0); +#endif + + core->running_job = job; +} + +void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr) +{ + u32 irq_readout; + + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT); + + if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG)); + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */ + mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr); + mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr); + + MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n")); + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC); + _mali_osk_write_mem_barrier(); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0); +#endif + } + /* + * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response. + * A timeout or a page fault on Mali-200 PP core can cause this behaviour. + */ +} + +void mali_gp_abort_job(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core)) + { + _mali_osk_timer_del(core->timeout_timer); + } +} + +u32 mali_gp_core_get_version(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION); +} + +mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + core->counter_src0 = counter; + return MALI_TRUE; +} + +mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter) +{ + MALI_DEBUG_ASSERT_POINTER(core); + + core->counter_src1 = counter; + return MALI_TRUE; +} + +u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->counter_src0; +} + +u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core) +{ + MALI_DEBUG_ASSERT_POINTER(core); + return core->counter_src1; +} + +struct mali_gp_core *mali_gp_get_global_gp_core(void) +{ + return mali_global_gp_core; +} + +/* ------------- interrupt handling below ------------------ */ +static _mali_osk_errcode_t mali_gp_upper_half(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + u32 irq_readout; + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); + if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout) + { + /* Mask out all IRQs from this core until IRQ is handled */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); +#endif + + /* We do need to handle this in a bottom half */ + _mali_osk_irq_schedulework(core->irq); + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +static void mali_gp_bottom_half(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + u32 irq_readout; + u32 irq_errors; + +#if MALI_TIMELINE_PROFILING_ENABLED +#if 0 /* Bottom half TLP logging is currently not supported */ + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0); +#endif +#endif + + mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */ + + if ( MALI_FALSE == mali_group_power_is_on(core->group) ) + { + MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description)); + mali_group_unlock(core->group); + return; + } + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED; + MALI_DEBUG_PRINT(4, ("Mali GP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description)); + + if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST)) + { + u32 core_status = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS); + if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE)) + { + mali_gp_post_process_job(core, MALI_FALSE); + MALI_DEBUG_PRINT(4, ("Mali GP: Job completed, calling group handler\n")); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_COMPLETED); /* Will release group lock */ + return; + } + } + + /* + * Now lets look at the possible error cases (IRQ indicating error or timeout) + * END_CMD_LST, HANG and PLBU_OOM interrupts are not considered error. + */ + irq_errors = irq_readout & ~(MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_HANG|MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM); + if (0 != irq_errors) + { + mali_gp_post_process_job(core, MALI_FALSE); + MALI_PRINT_ERROR(("Mali GP: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, core->hw_core.description)); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_FAILED); /* Will release group lock */ + return; + } + else if (MALI_TRUE == core->core_timed_out) /* SW timeout */ + { + if (core->timeout_job_id == mali_gp_job_get_id(core->running_job)) + { + mali_gp_post_process_job(core, MALI_FALSE); + MALI_DEBUG_PRINT(2, ("Mali GP: Job %d timed out\n", mali_gp_job_get_id(core->running_job))); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_TIMED_OUT); + } + core->core_timed_out = MALI_FALSE; + return; + } + else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM) + { + /* GP wants more memory in order to continue. + * + * This must be handled prior to HANG because this actually can + * generate a HANG while waiting for more memory. + * And it must be handled before the completion interrupts, + * since the PLBU can run out of memory after VS is complete; + * in which case the OOM must be handled before to complete the + * PLBU work. + */ + mali_gp_post_process_job(core, MALI_TRUE); + MALI_DEBUG_PRINT(3, ("Mali GP: PLBU needs more heap memory\n")); + mali_group_bottom_half(core->group, GROUP_EVENT_GP_OOM); /* Will release group lock */ + return; + } + else if (irq_readout & MALIGP2_REG_VAL_IRQ_HANG) + { + /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_HANG); + } + + /* + * The only way to get here is if we got a HANG interrupt, which we ignore, or only one of two needed END_CMD_LST interrupts. + * Re-enable interrupts and let core continue to run. + */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); + mali_group_unlock(core->group); + +#if MALI_TIMELINE_PROFILING_ENABLED +#if 0 /* Bottom half TLP logging is currently not supported */ + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0); +#endif +#endif +} + +static void mali_gp_irq_probe_trigger(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* @@@@ This should not be needed */ + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG); + _mali_osk_mem_barrier(); +} + +static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data) +{ + struct mali_gp_core *core = (struct mali_gp_core *)data; + u32 irq_readout; + + irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT); + if (MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout) + { + mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG); + _mali_osk_mem_barrier(); + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +/* ------ local helper functions below --------- */ + +static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend) +{ + MALI_ASSERT_GROUP_LOCKED(core->group); + + if (NULL != core->running_job) + { + u32 val0 = 0; + u32 val1 = 0; +#if MALI_TIMELINE_PROFILING_ENABLED + u32 event_id; +#endif + + if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) + { + val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); + if (mali_gp_job_get_perf_counter_flag(core->running_job) && + _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used) + { + /* We retrieved the counter that user space asked for, so return the value through the job object */ + mali_gp_job_set_perf_counter_value0(core->running_job, val0); + } + else + { + /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ + mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE); + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0); +#endif + + } + + if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) + { + val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); + if (mali_gp_job_get_perf_counter_flag(core->running_job) && + _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used) + { + /* We retrieved the counter that user space asked for, so return the value through the job object */ + mali_gp_job_set_perf_counter_value1(core->running_job, val1); + } + else + { + /* User space asked for a counter, but this is not what we retrieved (overridden by counter src set on core) */ + mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE); + } + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1); +#endif + } + +#if MALI_TIMELINE_PROFILING_ENABLED + if (MALI_TRUE == suspend) + { + event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); + } + else + { + event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); + } + _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0); +#endif + + mali_gp_job_set_current_heap_addr(core->running_job, + mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR)); + + if (MALI_TRUE != suspend) + { + /* We are no longer running a job... */ + core->running_job = NULL; + _mali_osk_timer_del(core->timeout_timer); + } + } +} + +/* callback function for gp core timeout */ +static void mali_gp_timeout(void *data) +{ + struct mali_gp_core * core = ((struct mali_gp_core *)data); + + MALI_DEBUG_PRINT(3, ("Mali GP: TIMEOUT callback \n")); + core->core_timed_out = MALI_TRUE; + _mali_osk_irq_schedulework(core->irq); +} + +#if 0 +void mali_gp_print_state(struct mali_gp_core *core) +{ + MALI_DEBUG_PRINT(2, ("Mali GP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) )); +} +#endif + +#if MALI_STATE_TRACKING +u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description); + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_gp.h b/drivers/media/video/samsung/mali/common/mali_gp.h new file mode 100644 index 0000000..3175b75 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GP_H__ +#define __MALI_GP_H__ + +#include "mali_osk.h" +#include "mali_gp_job.h" + +struct mali_gp_core; +struct mali_group; + +_mali_osk_errcode_t mali_gp_initialize(void); +void mali_gp_terminate(void); + +struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group); +void mali_gp_delete(struct mali_gp_core *core); + +void mali_gp_stop_bus(struct mali_gp_core *core); +_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core); +void mali_gp_hard_reset(struct mali_gp_core *core); +_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core); + +void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job); +void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr); + +void mali_gp_abort_job(struct mali_gp_core *core); + +u32 mali_gp_core_get_version(struct mali_gp_core *core); + +mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter); +mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter); +u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core); +u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core); +struct mali_gp_core *mali_gp_get_global_gp_core(void); + +u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size); + +#endif /* __MALI_GP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.c b/drivers/media/video/samsung/mali/common/mali_gp_job.c new file mode 100644 index 0000000..abe1d93 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_job.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_gp_job.h" +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_uk_types.h" + +struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id) +{ + struct mali_gp_job *job; + + job = _mali_osk_malloc(sizeof(struct mali_gp_job)); + if (NULL != job) + { + _mali_osk_list_init(&job->list); + job->session = session; + job->id = id; + job->user_id = args->user_job_ptr; + _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers)); + job->heap_current_addr = args->frame_registers[4]; + job->perf_counter_flag = args->perf_counter_flag; + job->perf_counter_src0 = args->perf_counter_src0; + job->perf_counter_src1 = args->perf_counter_src1; + job->perf_counter_value0 = 0; + job->perf_counter_value1 = 0; + + job->pid = _mali_osk_get_pid(); + job->tid = _mali_osk_get_tid(); + job->frame_builder_id = args->frame_builder_id; + job->flush_id = args->flush_id; + + return job; + } + + return NULL; +} + +void mali_gp_job_delete(struct mali_gp_job *job) +{ + _mali_osk_free(job); +} diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.h b/drivers/media/video/samsung/mali/common/mali_gp_job.h new file mode 100644 index 0000000..9c29f1c --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_job.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GP_JOB_H__ +#define __MALI_GP_JOB_H__ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_uk_types.h" +#include "mali_session.h" + +/** + * The structure represends a GP job, including all sub-jobs + * (This struct unfortunatly needs to be public because of how the _mali_osk_list_* + * mechanism works) + */ +struct mali_gp_job +{ + _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */ + struct mali_session_data *session; /**< Session which submitted this job */ + u32 id; /**< identifier for this job in kernel space (sequential numbering) */ + u32 user_id; /**< identifier for the job in user space */ + u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< core specific registers associated with this job, see ARM DDI0415A */ + u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */ + u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */ + u32 perf_counter_src0; /**< source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_src1; /**< source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 perf_counter_value0; /**< Value of performance counter 0 (to be returned to user space) */ + u32 perf_counter_value1; /**< Value of performance counter 1 (to be returned to user space) */ + u32 pid; /**< Process ID of submitting process */ + u32 tid; /**< Thread ID of submitting thread */ + u32 frame_builder_id; /**< id of the originating frame builder */ + u32 flush_id; /**< flush id within the originating frame builder */ +}; + +struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id); +void mali_gp_job_delete(struct mali_gp_job *job); + +MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job) +{ + return (NULL == job) ? 0 : job->id; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job) +{ + return job->user_id; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job) +{ + return job->frame_builder_id; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job) +{ + return job->flush_id; +} + +MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job) +{ + return job->frame_registers; +} + +MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job) +{ + return job->session; +} + +MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job) +{ + return (job->frame_registers[0] != job->frame_registers[1]) ? MALI_TRUE : MALI_FALSE; +} + +MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job) +{ + return (job->frame_registers[2] != job->frame_registers[3]) ? MALI_TRUE : MALI_FALSE; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job) +{ + return job->heap_current_addr; +} + +MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr) +{ + job->heap_current_addr = heap_addr; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job) +{ + return job->perf_counter_flag; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job) +{ + return job->perf_counter_src0; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job) +{ + return job->perf_counter_src1; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job) +{ + return job->perf_counter_value0; +} + +MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job) +{ + return job->perf_counter_value1; +} + +MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value) +{ + job->perf_counter_value0 = value; +} + +MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value) +{ + job->perf_counter_value1 = value; +} + +#endif /* __MALI_GP_JOB_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c new file mode 100644 index 0000000..05f00fc --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_gp_scheduler.h" +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_scheduler.h" +#include "mali_gp.h" +#include "mali_gp_job.h" +#include "mali_group.h" +#include "mali_cluster.h" + +enum mali_gp_slot_state +{ + MALI_GP_SLOT_STATE_IDLE, + MALI_GP_SLOT_STATE_WORKING, +}; + +/* A render slot is an entity which jobs can be scheduled onto */ +struct mali_gp_slot +{ + struct mali_group *group; + /* + * We keep track of the state here as well as in the group object + * so we don't need to take the group lock so often (and also avoid clutter with the working lock) + */ + enum mali_gp_slot_state state; + u32 returned_cookie; +}; + +static u32 gp_version = 0; +static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */ +static struct mali_gp_slot slot; + +/* Variables to allow safe pausing of the scheduler */ +static _mali_osk_wait_queue_t *gp_scheduler_working_wait_queue = NULL; +static u32 pause_count = 0; + +static mali_bool mali_gp_scheduler_is_suspended(void); + +static _mali_osk_lock_t *gp_scheduler_lock = NULL; +/* Contains tid of thread that locked the scheduler or 0, if not locked */ + +_mali_osk_errcode_t mali_gp_scheduler_initialize(void) +{ + u32 i; + + _MALI_OSK_INIT_LIST_HEAD(&job_queue); + + gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); + gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); + + if (NULL == gp_scheduler_lock) + { + return _MALI_OSK_ERR_NOMEM; + } + + if (NULL == gp_scheduler_working_wait_queue) + { + _mali_osk_lock_term(gp_scheduler_lock); + return _MALI_OSK_ERR_NOMEM; + } + + /* Find all the available GP cores */ + for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) + { + u32 group_id = 0; + struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); + struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); + while (NULL != group) + { + struct mali_gp_core *gp_core = mali_group_get_gp_core(group); + if (NULL != gp_core) + { + if (0 == gp_version) + { + /* Retrieve GP version */ + gp_version = mali_gp_core_get_version(gp_core); + } + slot.group = group; + slot.state = MALI_GP_SLOT_STATE_IDLE; + break; /* There are only one GP, no point in looking for more */ + } + group_id++; + group = mali_cluster_get_group(curr_cluster, group_id); + } + } + + return _MALI_OSK_ERR_OK; +} + +void mali_gp_scheduler_terminate(void) +{ + _mali_osk_wait_queue_term(gp_scheduler_working_wait_queue); + _mali_osk_lock_term(gp_scheduler_lock); +} + +MALI_STATIC_INLINE void mali_gp_scheduler_lock(void) +{ + if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW)) + { + /* Non-interruptable lock failed: this should never happen. */ + MALI_DEBUG_ASSERT(0); + } + MALI_DEBUG_PRINT(5, ("Mali GP scheduler: GP scheduler lock taken\n")); +} + +MALI_STATIC_INLINE void mali_gp_scheduler_unlock(void) +{ + MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n")); + _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW); +} + +#ifdef DEBUG +MALI_STATIC_INLINE void mali_gp_scheduler_assert_locked(void) +{ + MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock); +} +#define MALI_ASSERT_GP_SCHEDULER_LOCKED() mali_gp_scheduler_assert_locked() +#else +#define MALI_ASSERT_GP_SCHEDULER_LOCKED() +#endif + +static void mali_gp_scheduler_schedule(void) +{ + struct mali_gp_job *job; + + MALI_ASSERT_GP_SCHEDULER_LOCKED(); + + if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue)) + { + MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n", + pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0)); + return; /* Nothing to do, so early out */ + } + + job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list); + + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job)); + if (_MALI_OSK_ERR_OK == mali_group_start_gp_job(slot.group, job)) + { + /* Mark slot as busy */ + slot.state = MALI_GP_SLOT_STATE_WORKING; + + /* Remove from queue of unscheduled jobs */ + _mali_osk_list_del(&job->list); + } + else + { + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n")); + } +} + +static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success) +{ + _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s)); + if (NULL != notobj) + { + _mali_uk_gp_job_finished_s *jobres = notobj->result_buffer; + _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ + jobres->user_job_ptr = mali_gp_job_get_user_id(job); + if (MALI_TRUE == success) + { + jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; + } + else + { + jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; + } + + jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job); + jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job); + jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job); + + mali_session_send_notification(mali_gp_job_get_session(job), notobj); + } + else + { + MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n")); + } + + mali_gp_job_delete(job); +} + + +void mali_gp_scheduler_do_schedule(void) +{ + mali_gp_scheduler_lock(); + + mali_gp_scheduler_schedule(); + + mali_gp_scheduler_unlock(); +} + +void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success) +{ + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) completed (%s)\n", mali_gp_job_get_id(job), job, success ? "success" : "failure")); + + mali_gp_scheduler_lock(); + + /* Mark slot as idle again */ + slot.state = MALI_GP_SLOT_STATE_IDLE; + + /* If paused, then this was the last job, so wake up sleeping workers */ + if (pause_count > 0) + { + _mali_osk_wait_queue_wake_up(gp_scheduler_working_wait_queue); + } + else + { + mali_gp_scheduler_schedule(); + } + + mali_gp_scheduler_unlock(); + + mali_gp_scheduler_return_job_to_user(job, success); +} + +void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job) +{ + _mali_osk_notification_t *notobj; + + notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s)); + + if (NULL != notobj) + { + _mali_uk_gp_job_suspended_s * jobres; + + mali_gp_scheduler_lock(); + + jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer; + + jobres->user_job_ptr = mali_gp_job_get_user_id(job); + jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY; + jobres->cookie = mali_gp_job_get_id(job); + slot.returned_cookie = jobres->cookie; + + mali_session_send_notification(mali_gp_job_get_session(job), notobj); + + mali_gp_scheduler_unlock(); + } + + /* + * If this function failed, then we could return the job to user space right away, + * but there is a job timer anyway that will do that eventually. + * This is not exactly a common case anyway. + */ +} + +void mali_gp_scheduler_suspend(void) +{ + mali_gp_scheduler_lock(); + pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */ + mali_gp_scheduler_unlock(); + + _mali_osk_wait_queue_wait_event(gp_scheduler_working_wait_queue, mali_gp_scheduler_is_suspended); +} + +void mali_gp_scheduler_resume(void) +{ + mali_gp_scheduler_lock(); + pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */ + if (0 == pause_count) + { + mali_gp_scheduler_schedule(); + } + mali_gp_scheduler_unlock(); +} + +_mali_osk_errcode_t _mali_ukk_gp_start_job(_mali_uk_gp_start_job_s *args) +{ + struct mali_session_data *session; + struct mali_gp_job *job; + + MALI_DEBUG_ASSERT_POINTER(args); + + if (NULL == args->ctx) + { + return _MALI_OSK_ERR_INVALID_ARGS; + } + + session = (struct mali_session_data*)args->ctx; + if (NULL == session) + { + return _MALI_OSK_ERR_FAULT; + } + + job = mali_gp_job_create(session, args, mali_scheduler_get_new_id()); + if (NULL == job) + { + return _MALI_OSK_ERR_NOMEM; + } + + mali_gp_scheduler_lock(); + + _mali_osk_list_addtail(&job->list, &job_queue); + + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job)); + + mali_gp_scheduler_schedule(); + + mali_gp_scheduler_unlock(); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores(_mali_uk_get_gp_number_of_cores_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + args->number_of_cores = 1; + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_get_gp_core_version(_mali_uk_get_gp_core_version_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + args->version = gp_version; + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_gp_suspend_response(_mali_uk_gp_suspend_response_s *args) +{ + struct mali_session_data *session; + _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT; + + MALI_DEBUG_ASSERT_POINTER(args); + + if (NULL == args->ctx) + { + return _MALI_OSK_ERR_INVALID_ARGS; + } + + session = (struct mali_session_data*)args->ctx; + if (NULL == session) + { + return _MALI_OSK_ERR_FAULT; + } + + mali_gp_scheduler_lock(); + + /* Make sure that the cookie returned by user space is the same as we provided in the first place */ + if (args->cookie != slot.returned_cookie) + { + MALI_DEBUG_PRINT(2, ("Mali GP scheduler: Got an illegal cookie from user space, expected %u but got %u (job id)\n", slot.returned_cookie, args->cookie)) ; + mali_gp_scheduler_unlock(); + return _MALI_OSK_ERR_FAULT; + } + + mali_gp_scheduler_unlock(); + + switch (args->code) + { + case _MALIGP_JOB_RESUME_WITH_NEW_HEAP: + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Resuming job %u with new heap; 0x%08X - 0x%08X\n", args->cookie, args->arguments[0], args->arguments[1])); + mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]); + ret = _MALI_OSK_ERR_OK; + break; + + case _MALIGP_JOB_ABORT: + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting job %u, no new heap provided\n", args->cookie)); + mali_group_abort_gp_job(slot.group, args->cookie); + ret = _MALI_OSK_ERR_OK; + break; + + default: + MALI_PRINT_ERROR(("Mali GP scheduler: Wrong suspend response from user space\n")); + ret = _MALI_OSK_ERR_FAULT; + break; + } + + return ret; + +} + +void mali_gp_scheduler_abort_session(struct mali_session_data *session) +{ + struct mali_gp_job *job, *tmp; + + mali_gp_scheduler_lock(); + MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session)); + + /* Check queue for jobs and remove */ + _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list) + { + if (mali_gp_job_get_session(job) == session) + { + MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job)); + _mali_osk_list_del(&(job->list)); + mali_gp_job_delete(job); + } + } + + mali_gp_scheduler_unlock(); + + /* Abort running jobs from this session. It is safe to do this outside + * the scheduler lock as there is only one GP core, and the queue has + * already been emptied, as long as there are no new jobs coming in + * from user space. */ + mali_group_abort_session(slot.group, session); +} + +static mali_bool mali_gp_scheduler_is_suspended(void) +{ + mali_bool ret; + + mali_gp_scheduler_lock(); + ret = pause_count > 0 && slot.state == MALI_GP_SLOT_STATE_IDLE; + mali_gp_scheduler_unlock(); + + return ret; +} + + +#if MALI_STATE_TRACKING +u32 mali_gp_scheduler_dump_state(char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "GP\n"); + n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty"); + + n += mali_group_dump_state(slot.group, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", mali_group_gp_state(slot.group)); + n += _mali_osk_snprintf(buf + n, size - n, "\n"); + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h new file mode 100644 index 0000000..ef58509 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GP_SCHEDULER_H__ +#define __MALI_GP_SCHEDULER_H__ + +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_gp_job.h" + +_mali_osk_errcode_t mali_gp_scheduler_initialize(void); +void mali_gp_scheduler_terminate(void); + +void mali_gp_scheduler_do_schedule(void); +void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success); +void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job); +void mali_gp_scheduler_abort_session(struct mali_session_data *session); +u32 mali_gp_scheduler_dump_state(char *buf, u32 size); + +void mali_gp_scheduler_suspend(void); +void mali_gp_scheduler_resume(void); + +#endif /* __MALI_GP_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_group.c b/drivers/media/video/samsung/mali/common/mali_group.c new file mode 100644 index 0000000..9202bc1 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_group.c @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_group.h" +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_mmu.h" +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_pm.h" + +/* + * The group object is the most important object in the device driver, + * and acts as the center of many HW operations. + * The reason for this is that operations on the MMU will affect all + * cores connected to this MMU (a group is defined by the MMU and the + * cores which are connected to this). + * The group lock is thus the most important lock, followed by the + * GP and PP scheduler locks. They must be taken in the following + * order: + * GP/PP lock first, then group lock(s). + */ + +/** + * The structure represents a render group + * A render group is defined by all the cores that share the same Mali MMU + */ + +struct mali_group +{ + struct mali_cluster *cluster; + + struct mali_mmu_core *mmu; + struct mali_session_data *session; + int page_dir_ref_count; + mali_bool power_is_on; +#if defined(USING_MALI200) + mali_bool pagedir_activation_failed; +#endif + + struct mali_gp_core *gp_core; + enum mali_group_core_state gp_state; + struct mali_gp_job *gp_running_job; + + struct mali_pp_core *pp_core; + enum mali_group_core_state pp_state; + struct mali_pp_job *pp_running_job; + u32 pp_running_sub_job; + + _mali_osk_lock_t *lock; +}; + +static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS]; +static u32 mali_global_num_groups = 0; + +enum mali_group_activate_pd_status +{ + MALI_GROUP_ACTIVATE_PD_STATUS_FAILED, + MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD, + MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD, +}; + +/* local helper functions */ +static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session); +static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session); +static void mali_group_recovery_reset(struct mali_group *group); +static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success); + +void mali_group_lock(struct mali_group *group) +{ + if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(group->lock, _MALI_OSK_LOCKMODE_RW)) + { + /* Non-interruptable lock failed: this should never happen. */ + MALI_DEBUG_ASSERT(0); + } + MALI_DEBUG_PRINT(5, ("Mali group: Group lock taken 0x%08X\n", group)); +} + +void mali_group_unlock(struct mali_group *group) +{ + MALI_DEBUG_PRINT(5, ("Mali group: Releasing group lock 0x%08X\n", group)); + _mali_osk_lock_signal(group->lock, _MALI_OSK_LOCKMODE_RW); +} + +#ifdef DEBUG +void mali_group_assert_locked(struct mali_group *group) +{ + MALI_DEBUG_ASSERT_LOCK_HELD(group->lock); +} +#endif + + +struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu) +{ + struct mali_group *group = NULL; + + if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS) + { + MALI_PRINT_ERROR(("Mali group: Too many group objects created\n")); + return NULL; + } + + group = _mali_osk_malloc(sizeof(struct mali_group)); + if (NULL != group) + { + _mali_osk_memset(group, 0, sizeof(struct mali_group)); + group->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_GROUP); + if (NULL != group->lock) + { + group->cluster = cluster; + group->mmu = mmu; /* This group object now owns the MMU object */ + group->session = NULL; + group->page_dir_ref_count = 0; + group->power_is_on = MALI_TRUE; + + group->gp_state = MALI_GROUP_CORE_STATE_IDLE; + group->pp_state = MALI_GROUP_CORE_STATE_IDLE; +#if defined(USING_MALI200) + group->pagedir_activation_failed = MALI_FALSE; +#endif + mali_global_groups[mali_global_num_groups] = group; + mali_global_num_groups++; + + return group; + } + _mali_osk_free(group); + } + + return NULL; +} + +void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core) +{ + /* This group object now owns the GP core object */ + group->gp_core = gp_core; +} + +void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core) +{ + /* This group object now owns the PP core object */ + group->pp_core = pp_core; +} + +void mali_group_delete(struct mali_group *group) +{ + u32 i; + + /* Delete the resources that this group owns */ + if (NULL != group->gp_core) + { + mali_gp_delete(group->gp_core); + } + + if (NULL != group->pp_core) + { + mali_pp_delete(group->pp_core); + } + + if (NULL != group->mmu) + { + mali_mmu_delete(group->mmu); + } + + for (i = 0; i < mali_global_num_groups; i++) + { + if (mali_global_groups[i] == group) + { + mali_global_groups[i] = NULL; + mali_global_num_groups--; + break; + } + } + + _mali_osk_lock_term(group->lock); + + _mali_osk_free(group); +} + +/* Called from mali_cluster_reset() when the system is re-turned on */ +void mali_group_reset(struct mali_group *group) +{ + mali_group_lock(group); + + group->session = NULL; + + if (NULL != group->mmu) + { + mali_mmu_reset(group->mmu); + } + + if (NULL != group->gp_core) + { + mali_gp_reset(group->gp_core); + } + + if (NULL != group->pp_core) + { + mali_pp_reset(group->pp_core); + } + + mali_group_unlock(group); +} + +struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group) +{ + return group->gp_core; +} + +struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group) +{ + return group->pp_core; +} + +_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job) +{ + struct mali_session_data *session; + enum mali_group_activate_pd_status activate_status; + + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + + mali_pm_core_event(MALI_CORE_EVENT_GP_START); + + session = mali_gp_job_get_session(job); + + mali_group_lock(group); + + mali_cluster_l2_cache_invalidate_all(group->cluster, mali_gp_job_get_id(job)); + + activate_status = mali_group_activate_page_directory(group, session); + if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status) + { + /* if session is NOT kept Zapping is done as part of session switch */ + if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status) + { + mali_mmu_zap_tlb_without_stall(group->mmu); + } + mali_gp_job_start(group->gp_core, job); + group->gp_running_job = job; + group->gp_state = MALI_GROUP_CORE_STATE_WORKING; + + mali_group_unlock(group); + + return _MALI_OSK_ERR_OK; + } + +#if defined(USING_MALI200) + group->pagedir_activation_failed = MALI_TRUE; +#endif + + mali_group_unlock(group); + + mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_GP_START */ + return _MALI_OSK_ERR_FAULT; +} + +_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job) +{ + struct mali_session_data *session; + enum mali_group_activate_pd_status activate_status; + + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + + mali_pm_core_event(MALI_CORE_EVENT_PP_START); + + session = mali_pp_job_get_session(job); + + mali_group_lock(group); + + mali_cluster_l2_cache_invalidate_all(group->cluster, mali_pp_job_get_id(job)); + + activate_status = mali_group_activate_page_directory(group, session); + if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status) + { + /* if session is NOT kept Zapping is done as part of session switch */ + if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status) + { + MALI_DEBUG_PRINT(3, ("PP starting job PD_Switch 0 Flush 1 Zap 1\n")); + mali_mmu_zap_tlb_without_stall(group->mmu); + } + mali_pp_job_start(group->pp_core, job, sub_job); + group->pp_running_job = job; + group->pp_running_sub_job = sub_job; + group->pp_state = MALI_GROUP_CORE_STATE_WORKING; + + mali_group_unlock(group); + + return _MALI_OSK_ERR_OK; + } + +#if defined(USING_MALI200) + group->pagedir_activation_failed = MALI_TRUE; +#endif + + mali_group_unlock(group); + + mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_PP_START */ + return _MALI_OSK_ERR_FAULT; +} + +void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr) +{ + mali_group_lock(group); + + if (group->gp_state != MALI_GROUP_CORE_STATE_OOM || + mali_gp_job_get_id(group->gp_running_job) != job_id) + { + mali_group_unlock(group); + return; /* Illegal request or job has already been aborted */ + } + + mali_cluster_l2_cache_invalidate_all_force(group->cluster); + mali_mmu_zap_tlb_without_stall(group->mmu); + + mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr); + group->gp_state = MALI_GROUP_CORE_STATE_WORKING; + + mali_group_unlock(group); +} + +void mali_group_abort_gp_job(struct mali_group *group, u32 job_id) +{ + mali_group_lock(group); + + if (group->gp_state == MALI_GROUP_CORE_STATE_IDLE || + mali_gp_job_get_id(group->gp_running_job) != job_id) + { + mali_group_unlock(group); + return; /* No need to cancel or job has already been aborted or completed */ + } + + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* Will release group lock */ +} + +void mali_group_abort_pp_job(struct mali_group *group, u32 job_id) +{ + mali_group_lock(group); + + if (group->pp_state == MALI_GROUP_CORE_STATE_IDLE || + mali_pp_job_get_id(group->pp_running_job) != job_id) + { + mali_group_unlock(group); + return; /* No need to cancel or job has already been aborted or completed */ + } + + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* Will release group lock */ +} + +void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session) +{ + struct mali_gp_job *gp_job; + struct mali_pp_job *pp_job; + u32 gp_job_id = 0; + u32 pp_job_id = 0; + mali_bool abort_pp = MALI_FALSE; + mali_bool abort_gp = MALI_FALSE; + + mali_group_lock(group); + + gp_job = group->gp_running_job; + pp_job = group->pp_running_job; + + if (gp_job && mali_gp_job_get_session(gp_job) == session) + { + MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session)); + + gp_job_id = mali_gp_job_get_id(gp_job); + abort_gp = MALI_TRUE; + } + + if (pp_job && mali_pp_job_get_session(pp_job) == session) + { + MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session)); + + pp_job_id = mali_pp_job_get_id(pp_job); + abort_pp = MALI_TRUE; + } + + mali_group_unlock(group); + + /* These functions takes and releases the group lock */ + if (0 != abort_gp) + { + mali_group_abort_gp_job(group, gp_job_id); + } + if (0 != abort_pp) + { + mali_group_abort_pp_job(group, pp_job_id); + } + + mali_group_lock(group); + mali_group_remove_session_if_unused(group, session); + mali_group_unlock(group); +} + +enum mali_group_core_state mali_group_gp_state(struct mali_group *group) +{ + return group->gp_state; +} + +enum mali_group_core_state mali_group_pp_state(struct mali_group *group) +{ + return group->pp_state; +} + +/* group lock need to be taken before calling mali_group_bottom_half */ +void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + switch (event) + { + case GROUP_EVENT_PP_JOB_COMPLETED: + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_TRUE); /* PP job SUCCESS */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_PP_JOB_FAILED: + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job FAIL */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_PP_JOB_TIMED_OUT: + mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job TIMEOUT */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_JOB_COMPLETED: + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_TRUE); /* GP job SUCCESS */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_JOB_FAILED: + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job FAIL */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_JOB_TIMED_OUT: + mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job TIMEOUT */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + case GROUP_EVENT_GP_OOM: + group->gp_state = MALI_GROUP_CORE_STATE_OOM; + mali_group_unlock(group); /* Nothing to do on the HW side, so just release group lock right away */ + mali_gp_scheduler_oom(group, group->gp_running_job); + break; + case GROUP_EVENT_MMU_PAGE_FAULT: + mali_group_complete_jobs(group, MALI_TRUE, MALI_TRUE, MALI_FALSE); /* GP and PP job FAIL */ + /* group lock is released by mali_group_complete_jobs() call above */ + break; + default: + break; + } +} + +struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group) +{ + return group->mmu; +} + +struct mali_session_data *mali_group_get_session(struct mali_group *group) +{ + return group->session; +} + +struct mali_group *mali_group_get_glob_group(u32 index) +{ + if(mali_global_num_groups > index) + { + return mali_global_groups[index]; + } + + return NULL; +} + +u32 mali_group_get_glob_num_groups(void) +{ + return mali_global_num_groups; +} + +/* Used to check if scheduler for the other core type needs to be called on job completion. + * + * Used only for Mali-200, where job start may fail if the only MMU is busy + * with another session's address space. + */ +static inline mali_bool mali_group_other_reschedule_needed(struct mali_group *group) +{ + MALI_ASSERT_GROUP_LOCKED(group); + +#if defined(USING_MALI200) + if (group->pagedir_activation_failed) + { + group->pagedir_activation_failed = MALI_FALSE; + return MALI_TRUE; + } + else +#endif + { + return MALI_FALSE; + } +} + +static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session) +{ + enum mali_group_activate_pd_status retval; + MALI_ASSERT_GROUP_LOCKED(group); + + MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group 0x%08X\n", mali_session_get_page_directory(session), session, group)); + MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count); + + if (0 != group->page_dir_ref_count) + { + if (group->session != session) + { + MALI_DEBUG_PRINT(4, ("Mali group: Activating session FAILED: 0x%08x on group 0x%08X. Existing session: 0x%08x\n", session, group, group->session)); + return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED; + } + else + { + MALI_DEBUG_PRINT(4, ("Mali group: Activating session already activated: 0x%08x on group 0x%08X. New Ref: %d\n", session, group, 1+group->page_dir_ref_count)); + retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD; + + } + } + else + { + /* There might be another session here, but it is ok to overwrite it since group->page_dir_ref_count==0 */ + if (group->session != session) + { + mali_bool activate_success; + MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group 0x%08X. Ref: %d\n", session, group->session, group, 1+group->page_dir_ref_count)); + + activate_success = mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session)); + MALI_DEBUG_ASSERT(activate_success); + if ( MALI_FALSE== activate_success ) return MALI_FALSE; + group->session = session; + retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD; + } + else + { + MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group 0x%08X. Ref: %d\n", session->page_directory, group, 1+group->page_dir_ref_count)); + retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD; + } + } + + group->page_dir_ref_count++; + return retval; +} + +static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + MALI_DEBUG_ASSERT(0 < group->page_dir_ref_count); + MALI_DEBUG_ASSERT(session == group->session); + + group->page_dir_ref_count--; + + /* As an optimization, the MMU still points to the group->session even if (0 == group->page_dir_ref_count), + and we do not call mali_mmu_activate_empty_page_directory(group->mmu); */ + MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count); +} + +void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + if (0 == group->page_dir_ref_count) + { + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + + if (group->session == session) + { + MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on); + MALI_DEBUG_PRINT(3, ("Mali group: Deactivating unused session 0x%08X on group %08X\n", session, group)); + mali_mmu_activate_empty_page_directory(group->mmu); + group->session = NULL; + } + } +} + +void mali_group_power_on(void) +{ + int i; + for (i = 0; i < mali_global_num_groups; i++) + { + struct mali_group *group = mali_global_groups[i]; + mali_group_lock(group); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + MALI_DEBUG_ASSERT_POINTER(group->cluster); + group->power_is_on = MALI_TRUE; + mali_cluster_power_is_enabled_set(group->cluster, MALI_TRUE); + mali_group_unlock(group); + } + MALI_DEBUG_PRINT(3,("group: POWER ON\n")); +} + +mali_bool mali_group_power_is_on(struct mali_group *group) +{ + MALI_ASSERT_GROUP_LOCKED(group); + return group->power_is_on; +} + +void mali_group_power_off(void) +{ + int i; + /* It is necessary to set group->session = NULL; so that the powered off MMU is not written to on map /unmap */ + /* It is necessary to set group->power_is_on=MALI_FALSE so that pending bottom_halves does not access powered off cores. */ + for (i = 0; i < mali_global_num_groups; i++) + { + struct mali_group *group = mali_global_groups[i]; + mali_group_lock(group); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state); + MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state); + MALI_DEBUG_ASSERT_POINTER(group->cluster); + group->session = NULL; + MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on); + group->power_is_on = MALI_FALSE; + mali_cluster_power_is_enabled_set(group->cluster, MALI_FALSE); + mali_group_unlock(group); + } + MALI_DEBUG_PRINT(3,("group: POWER OFF\n")); +} + + +static void mali_group_recovery_reset(struct mali_group *group) +{ + MALI_ASSERT_GROUP_LOCKED(group); + + /* Stop cores, bus stop */ + if (NULL != group->pp_core) + { + mali_pp_stop_bus(group->pp_core); + } + if (NULL != group->gp_core) + { + mali_gp_stop_bus(group->gp_core); + } + + /* Flush MMU */ + mali_mmu_activate_fault_flush_page_directory(group->mmu); + mali_mmu_page_fault_done(group->mmu); + + /* Wait for cores to stop bus */ + if (NULL != group->pp_core) + { + mali_pp_stop_bus_wait(group->pp_core); + } + if (NULL != group->gp_core) + { + mali_gp_stop_bus_wait(group->gp_core); + } + + /* Reset cores */ + if (NULL != group->pp_core) + { + mali_pp_hard_reset(group->pp_core); + } + if (NULL != group->gp_core) + { + mali_gp_hard_reset(group->gp_core); + } + + /* Reset MMU */ + mali_mmu_reset(group->mmu); + group->session = NULL; +} + +/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */ +static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success) +{ + mali_bool need_group_reset = MALI_FALSE; + mali_bool gp_success = success; + mali_bool pp_success = success; + + MALI_ASSERT_GROUP_LOCKED(group); + + if (complete_gp && !complete_pp) + { + MALI_DEBUG_ASSERT_POINTER(group->gp_core); + if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core)) + { + struct mali_gp_job *gp_job_to_return = group->gp_running_job; + group->gp_state = MALI_GROUP_CORE_STATE_IDLE; + group->gp_running_job = NULL; + + MALI_DEBUG_ASSERT_POINTER(gp_job_to_return); + + mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); + + if(mali_group_other_reschedule_needed(group)) + { + mali_group_unlock(group); + mali_pp_scheduler_do_schedule(); + } + else + { + mali_group_unlock(group); + } + + mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); + mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + + return; + } + else + { + need_group_reset = MALI_TRUE; + MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n")); + pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */ + } + } + if (complete_pp && !complete_gp) + { + MALI_DEBUG_ASSERT_POINTER(group->pp_core); + if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core)) + { + struct mali_pp_job *pp_job_to_return = group->pp_running_job; + u32 pp_sub_job_to_return = group->pp_running_sub_job; + group->pp_state = MALI_GROUP_CORE_STATE_IDLE; + group->pp_running_job = NULL; + + MALI_DEBUG_ASSERT_POINTER(pp_job_to_return); + + mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); + + if(mali_group_other_reschedule_needed(group)) + { + mali_group_unlock(group); + mali_gp_scheduler_do_schedule(); + } + else + { + mali_group_unlock(group); + } + + mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); + mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + + return; + } + else + { + need_group_reset = MALI_TRUE; + MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n")); + gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */ + } + } + else if (complete_gp && complete_pp) + { + need_group_reset = MALI_TRUE; + } + + if (MALI_TRUE == need_group_reset) + { + struct mali_gp_job *gp_job_to_return = group->gp_running_job; + struct mali_pp_job *pp_job_to_return = group->pp_running_job; + u32 pp_sub_job_to_return = group->pp_running_sub_job; + mali_bool schedule_other = MALI_FALSE; + + MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n")); + + group->gp_state = MALI_GROUP_CORE_STATE_IDLE; + group->gp_running_job = NULL; + if (NULL != gp_job_to_return) + { + mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); + } + + group->pp_state = MALI_GROUP_CORE_STATE_IDLE; + group->pp_running_job = NULL; + if (NULL != pp_job_to_return) + { + mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); + } + + /* The reset has to be done after mali_group_deactivate_page_directory() */ + mali_group_recovery_reset(group); + + if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return)) + { + schedule_other = MALI_TRUE; + } + + mali_group_unlock(group); + + if (NULL != gp_job_to_return) + { + mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); + mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + } + else if (schedule_other) + { + mali_pp_scheduler_do_schedule(); + } + + if (NULL != pp_job_to_return) + { + mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); + mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ + } + else if (schedule_other) + { + mali_gp_scheduler_do_schedule(); + } + + return; + } + + mali_group_unlock(group); +} + +#if MALI_STATE_TRACKING +u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size) +{ + int n = 0; + + n += _mali_osk_snprintf(buf + n, size - n, "Group: %p\n", group); + if (group->gp_core) + { + n += mali_gp_dump_state(group->gp_core, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\tGP state: %d\n", group->gp_state); + n += _mali_osk_snprintf(buf + n, size - n, "\tGP job: %p\n", group->gp_running_job); + } + if (group->pp_core) + { + n += mali_pp_dump_state(group->pp_core, buf + n, size - n); + n += _mali_osk_snprintf(buf + n, size - n, "\tPP state: %d\n", group->pp_state); + n += _mali_osk_snprintf(buf + n, size - n, "\tPP job: %p, subjob %d \n", + group->pp_running_job, group->pp_running_sub_job); + } + + return n; +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_group.h b/drivers/media/video/samsung/mali/common/mali_group.h new file mode 100644 index 0000000..3533d13 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_group.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_GROUP_H__ +#define __MALI_GROUP_H__ + +#include "linux/jiffies.h" +#include "mali_osk.h" +#include "mali_cluster.h" +#include "mali_mmu.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_session.h" + +/* max runtime [ms] for a core job - used by timeout timers */ +#define MAX_RUNTIME 5000 +/** @brief A mali group object represents a MMU and a PP and/or a GP core. + * + */ +#define MALI_MAX_NUMBER_OF_GROUPS 9 + +struct mali_group; + +enum mali_group_event_t +{ + GROUP_EVENT_PP_JOB_COMPLETED, /**< PP job completed successfully */ + GROUP_EVENT_PP_JOB_FAILED, /**< PP job completed with failure */ + GROUP_EVENT_PP_JOB_TIMED_OUT, /**< PP job reached max runtime */ + GROUP_EVENT_GP_JOB_COMPLETED, /**< GP job completed successfully */ + GROUP_EVENT_GP_JOB_FAILED, /**< GP job completed with failure */ + GROUP_EVENT_GP_JOB_TIMED_OUT, /**< GP job reached max runtime */ + GROUP_EVENT_GP_OOM, /**< GP job ran out of heap memory */ + GROUP_EVENT_MMU_PAGE_FAULT, /**< MMU page fault */ +}; + +enum mali_group_core_state +{ + MALI_GROUP_CORE_STATE_IDLE, + MALI_GROUP_CORE_STATE_WORKING, + MALI_GROUP_CORE_STATE_OOM +}; + +/** @brief Create a new Mali group object + * + * @param cluster Pointer to the cluster to which the group is connected. + * @param mmu Pointer to the MMU that defines this group + * @return A pointer to a new group object + */ +struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu); +void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core); +void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core); +void mali_group_delete(struct mali_group *group); + +/** @brief Reset group + * + * This function will reset the entire group, including all the cores present in the group. + * + * @param group Pointer to the group to reset + */ +void mali_group_reset(struct mali_group *group); + +/** @brief Get pointer to GP core object + */ +struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group); + +/** @brief Get pointer to PP core object + */ +struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group); + +/** @brief Lock group object + * + * Most group functions will lock the group object themselves. The expection is + * the group_bottom_half which requires the group to be locked on entry. + * + * @param group Pointer to group to lock + */ +void mali_group_lock(struct mali_group *group); + +/** @brief Unlock group object + * + * @param group Pointer to group to unlock + */ +void mali_group_unlock(struct mali_group *group); +#ifdef DEBUG +void mali_group_assert_locked(struct mali_group *group); +#define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group) +#else +#define MALI_ASSERT_GROUP_LOCKED(group) +#endif + +/** @brief Start GP job + */ +_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job); +/** @brief Start fragment of PP job + */ +_mali_osk_errcode_t mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job); + +/** @brief Resume GP job that suspended waiting for more heap memory + */ +void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr); +/** @brief Abort GP job + * + * Used to abort suspended OOM jobs when user space failed to allocte more memory. + */ +void mali_group_abort_gp_job(struct mali_group *group, u32 job_id); +/** @brief Abort all GP jobs from \a session + * + * Used on session close when terminating all running and queued jobs from \a session. + */ +void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session); + +enum mali_group_core_state mali_group_gp_state(struct mali_group *group); +enum mali_group_core_state mali_group_pp_state(struct mali_group *group); + +/** @brief The common group bottom half interrupt handler + * + * This is only called from the GP and PP bottom halves. + * + * The action taken is dictated by the \a event. + * + * @param event The event code + */ +void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event); + +struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group); +struct mali_session_data *mali_group_get_session(struct mali_group *group); + +void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session_data); + +void mali_group_power_on(void); +void mali_group_power_off(void); +mali_bool mali_group_power_is_on(struct mali_group *group); + +struct mali_group *mali_group_get_glob_group(u32 index); +u32 mali_group_get_glob_num_groups(void); + +u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size); + +#endif /* __MALI_GROUP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.c b/drivers/media/video/samsung/mali/common/mali_hw_core.c new file mode 100644 index 0000000..0b08622 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_hw_core.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_hw_core.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" + +_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size) +{ + core->phys_addr = resource->base; + core->description = resource->description; + core->size = reg_size; + if (_MALI_OSK_ERR_OK == _mali_osk_mem_reqregion(core->phys_addr, core->size, core->description)) + { + core->mapped_registers = _mali_osk_mem_mapioregion(core->phys_addr, core->size, core->description); + if (NULL != core->mapped_registers) + { + return _MALI_OSK_ERR_OK; + } + else + { + MALI_PRINT_ERROR(("Failed to map memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr)); + } + _mali_osk_mem_unreqregion(core->phys_addr, core->size); + } + else + { + MALI_PRINT_ERROR(("Failed to request memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr)); + } + + return _MALI_OSK_ERR_FAULT; +} + +void mali_hw_core_delete(struct mali_hw_core *core) +{ + _mali_osk_mem_unmapioregion(core->phys_addr, core->size, core->mapped_registers); + core->mapped_registers = NULL; + _mali_osk_mem_unreqregion(core->phys_addr, core->size); +} diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.h b/drivers/media/video/samsung/mali/common/mali_hw_core.h new file mode 100644 index 0000000..c797804 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_hw_core.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_HW_CORE_H__ +#define __MALI_HW_CORE_H__ + +#include "mali_osk.h" +#include "mali_kernel_common.h" + +/** + * The common parts for all Mali HW cores (GP, PP, MMU, L2 and PMU) + * This struct is embedded inside all core specific structs. + */ +struct mali_hw_core +{ + u32 phys_addr; /**< Physical address of the registers */ + u32 size; /**< Size of registers */ + mali_io_address mapped_registers; /**< Virtual mapping of the registers */ + const char* description; /**< Name of unit (as specified in device configuration) */ +}; + +#define MALI_HW_CORE_NO_COUNTER ((u32)-1) +#define MALI_HW_CORE_INVALID_VALUE ((u32)-1) + +_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size); +void mali_hw_core_delete(struct mali_hw_core *core); + +MALI_STATIC_INLINE u32 mali_hw_core_register_read(struct mali_hw_core *core, u32 relative_address) +{ + u32 read_val; + read_val = _mali_osk_mem_ioread32(core->mapped_registers, relative_address); + MALI_DEBUG_PRINT(6, ("register_read for core %s, relative addr=0x%04X, val=0x%08X\n", + core->description, relative_address, read_val)); + return read_val; +} + +MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core *core, u32 relative_address, u32 new_val) +{ + MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n", + core->description, relative_address, new_val)); + _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val); +} + +MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val) +{ + MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n", + core->description, relative_address, new_val)); + _mali_osk_mem_iowrite32(core->mapped_registers, relative_address, new_val); +} + +MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs) +{ + u32 i; + MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n", + core->description,relative_address, nr_of_regs)); + + /* Do not use burst writes against the registers */ + for (i = 0; i< nr_of_regs; i++) + { + mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]); + } +} + +#endif /* __MALI_HW_CORE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_GP2.c b/drivers/media/video/samsung/mali/common/mali_kernel_GP2.c deleted file mode 100644 index cfd70f4..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_GP2.c +++ /dev/null @@ -1,1493 +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. - */ -//added for SPI -#include - -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#include "mali_kernel_subsystem.h" -#include "regs/mali_gp_regs.h" -#include "mali_kernel_rendercore.h" -#include "mali_osk.h" -#include "mali_osk_list.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" -#endif -#if defined(USING_MALI400_L2_CACHE) -#include "mali_kernel_l2_cache.h" -#endif -#if USING_MMU -#include "mali_kernel_mem_mmu.h" /* Needed for mali_kernel_mmu_force_bus_reset() */ -#endif - -#if defined(USING_MALI200) -#define MALI_GP_SUBSYSTEM_NAME "MaliGP2" -#define MALI_GP_CORE_TYPE _MALI_GP2 -#elif defined(USING_MALI400) -#define MALI_GP_SUBSYSTEM_NAME "Mali-400 GP" -#define MALI_GP_CORE_TYPE _MALI_400_GP -#else -#error "No supported mali core defined" -#endif - -#define GET_JOB_EMBEDDED_PTR(job) (&((job)->embedded_core_job)) -#define GET_JOBGP2_PTR(job_extern) _MALI_OSK_CONTAINER_OF(job_extern, maligp_job, embedded_core_job) - -/* Initialized when this subsystem is initialized. This is determined by the - * position in subsystems[], and so the value used to initialize this is - * determined at compile time */ -static mali_kernel_subsystem_identifier mali_subsystem_gp_id = -1; - -static mali_core_renderunit * last_gp_core_cookie = NULL; - -/* Describing a maligp job settings */ -typedef struct maligp_job -{ - /* The general job struct common for all mali cores */ - mali_core_job embedded_core_job; - _mali_uk_gp_start_job_s user_input; - - u32 irq_status; - u32 status_reg_on_stop; - u32 perf_counter0; - u32 perf_counter1; - u32 vscl_stop_addr; - u32 plbcl_stop_addr; - u32 heap_current_addr; - - /* The data we will return back to the user */ - _mali_osk_notification_t *notification_obj; - - int is_stalled_waiting_for_more_memory; - - u32 active_mask; - /* progress checking */ - u32 last_vscl; - u32 last_plbcl; - /* extended progress checking, only enabled when we can use one of the performance counters */ - u32 have_extended_progress_checking; - u32 vertices; - -#if defined(USING_MALI400_L2_CACHE) - u32 perf_counter_l2_src0; - u32 perf_counter_l2_src1; - u32 perf_counter_l2_val0; - u32 perf_counter_l2_val1; -#endif - -#if MALI_TIMELINE_PROFILING_ENABLED - u32 pid; - u32 tid; -#endif -} maligp_job; - -/*Functions Exposed to the General External System through - function pointers.*/ - -static _mali_osk_errcode_t maligp_subsystem_startup(mali_kernel_subsystem_identifier id); -#if USING_MMU -static _mali_osk_errcode_t maligp_subsystem_mmu_connect(mali_kernel_subsystem_identifier id); -#endif -static void maligp_subsystem_terminate(mali_kernel_subsystem_identifier id); -static _mali_osk_errcode_t maligp_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); -static void maligp_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot); -static _mali_osk_errcode_t maligp_subsystem_core_system_info_fill(_mali_system_info* info); -static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resource); -#if USING_MMU -static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data); -#endif -#if MALI_STATE_TRACKING -u32 maligp_subsystem_dump_state(char *buf, u32 size); -#endif - -/* Internal support functions */ -static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core ); -static void maligp_raw_reset( mali_core_renderunit *core); -static void maligp_reset_hard(struct mali_core_renderunit * core); -static void maligp_reset(mali_core_renderunit *core); -static void maligp_initialize_registers_mgmt(mali_core_renderunit *core ); - -#ifdef DEBUG -static void maligp_print_regs(int debug_level, mali_core_renderunit *core); -#endif - -/* Functions exposed to mali_core system through functionpointers - in the subsystem struct. */ -static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_core_renderunit * core); -static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core); -static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core); -static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument); -static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_session * session, void * argument); -static void subsystem_maligp_return_job_to_user(mali_core_job * job, mali_subsystem_job_end_code end_status); -static void subsystem_maligp_renderunit_delete(mali_core_renderunit * core); -static void subsystem_maligp_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style ); -static void subsystem_maligp_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core); -static _mali_osk_errcode_t subsystem_maligp_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core); -static void subsystem_maligp_renderunit_stop_bus(struct mali_core_renderunit* core); - -/* Variables */ -static register_address_and_value default_mgmt_regs[] = -{ - { MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED } -}; - - -/* This will be one of the subsystems in the array of subsystems: - static struct mali_kernel_subsystem * subsystems[]; - found in file: mali_kernel_core.c -*/ - -struct mali_kernel_subsystem mali_subsystem_gp2= -{ - maligp_subsystem_startup, /* startup */ - NULL, /*maligp_subsystem_terminate,*/ /* shutdown */ -#if USING_MMU - maligp_subsystem_mmu_connect, /* load_complete */ -#else - NULL, -#endif - maligp_subsystem_core_system_info_fill, /* system_info_fill */ - maligp_subsystem_session_begin, /* session_begin */ - maligp_subsystem_session_end, /* session_end */ -#if USING_MMU - maligp_subsystem_broadcast_notification, /* broadcast_notification */ -#else - NULL, -#endif -#if MALI_STATE_TRACKING - maligp_subsystem_dump_state, /* dump_state */ -#endif -} ; - -static mali_core_subsystem subsystem_maligp ; - -static _mali_osk_errcode_t maligp_subsystem_startup(mali_kernel_subsystem_identifier id) -{ - mali_core_subsystem * subsystem; - - MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_startup\n") ) ; - - mali_subsystem_gp_id = id; - - /* All values get 0 as default */ - _mali_osk_memset(&subsystem_maligp, 0, sizeof(*subsystem)); - - subsystem = &subsystem_maligp; - subsystem->start_job = &subsystem_maligp_start_job; - subsystem->irq_handler_upper_half = &subsystem_maligp_irq_handler_upper_half; - subsystem->irq_handler_bottom_half = &subsystem_maligp_irq_handler_bottom_half; - subsystem->get_new_job_from_user = &subsystem_maligp_get_new_job_from_user; - subsystem->suspend_response = &subsystem_maligp_suspend_response; - subsystem->return_job_to_user = &subsystem_maligp_return_job_to_user; - subsystem->renderunit_delete = &subsystem_maligp_renderunit_delete; - subsystem->reset_core = &subsystem_maligp_renderunit_reset_core; - subsystem->stop_bus = &subsystem_maligp_renderunit_stop_bus; - subsystem->probe_core_irq_trigger = &subsystem_maligp_renderunit_probe_core_irq_trigger; - subsystem->probe_core_irq_acknowledge = &subsystem_maligp_renderunit_probe_core_irq_finished; - - /* Setting variables in the general core part of the subsystem.*/ - subsystem->name = MALI_GP_SUBSYSTEM_NAME; - subsystem->core_type = MALI_GP_CORE_TYPE; - subsystem->id = id; - - /* Initiates the rest of the general core part of the subsystem */ - MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem )); - - /* This will register the function for adding MALIGP2 cores to the subsystem */ -#if defined(USING_MALI200) - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALIGP2, maligp_renderunit_create)); -#endif -#if defined(USING_MALI400) - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400GP, maligp_renderunit_create)); -#endif - - MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_startup\n") ) ; - - MALI_SUCCESS; -} - -#if USING_MMU -static _mali_osk_errcode_t maligp_subsystem_mmu_connect(mali_kernel_subsystem_identifier id) -{ - mali_core_subsystem_attach_mmu(&subsystem_maligp); - MALI_SUCCESS; /* OK */ -} -#endif - -static void maligp_subsystem_terminate(mali_kernel_subsystem_identifier id) -{ - MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_terminate\n") ) ; - mali_core_subsystem_cleanup(&subsystem_maligp); -} - -static _mali_osk_errcode_t maligp_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue) -{ - mali_core_session * session; - - MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_session_begin\n") ) ; - MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(*session) ), _MALI_OSK_ERR_FAULT); - - _mali_osk_memset(session, 0, sizeof(*session) ); - *slot = (mali_kernel_subsystem_session_slot)session; - - session->subsystem = &subsystem_maligp; - - session->notification_queue = queue; - -#if USING_MMU - session->mmu_session = mali_session_data; -#endif - - mali_core_session_begin(session); - - MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_session_begin\n") ) ; - - MALI_SUCCESS; -} - -static void maligp_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot) -{ - mali_core_session * session; - /** @note mali_session_data not needed here */ - - MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_session_end\n") ) ; - if ( NULL==slot || NULL==*slot) - { - MALI_PRINT_ERROR(("Input slot==NULL")); - return; - } - session = (mali_core_session *)*slot; - mali_core_session_close(session); - - _mali_osk_free(session); - *slot = NULL; - - MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_session_end\n") ) ; -} - -/** - * We fill in info about all the cores we have - * @param info Pointer to system info struct to update - * @return _MALI_OSK_ERR_OK on success, or another _mali_osk_errcode_t for errors. - */ -static _mali_osk_errcode_t maligp_subsystem_core_system_info_fill(_mali_system_info* info) -{ - return mali_core_subsystem_system_info_fill(&subsystem_maligp, info); -} - -static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resource) -{ - mali_core_renderunit *core; - int err; - - MALI_DEBUG_PRINT(3, ("Mali GP: maligp_renderunit_create\n") ) ; - /* Checking that the resource settings are correct */ -#if defined(USING_MALI200) - if(MALIGP2 != resource->type) - { - MALI_PRINT_ERROR(("Can not register this resource as a " MALI_GP_SUBSYSTEM_NAME " core.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#elif defined(USING_MALI400) - if(MALI400GP != resource->type) - { - MALI_PRINT_ERROR(("Can not register this resource as a " MALI_GP_SUBSYSTEM_NAME " core.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#endif - if ( 0 != resource->size ) - { - MALI_PRINT_ERROR(("Memory size set to " MALI_GP_SUBSYSTEM_NAME " core should be zero.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - if ( NULL == resource->description ) - { - MALI_PRINT_ERROR(("A " MALI_GP_SUBSYSTEM_NAME " core needs a unique description field")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Create a new core object */ - core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core)); - if ( NULL == core ) - { - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Variables set to be able to open and register the core */ - core->subsystem = &subsystem_maligp ; - core->registers_base_addr = resource->base ; - core->size = MALIGP2_REGISTER_ADDRESS_SPACE_SIZE ; - core->description = resource->description; - core->irq_nr = resource->irq ; -#if USING_MMU - core->mmu_id = resource->mmu_id; - core->mmu = NULL; -#endif -#if USING_MALI_PMM - /* Set up core's PMM id */ - core->pmm_id = MALI_PMM_CORE_GP; -#endif - - err = mali_core_renderunit_init( core ); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n")); - goto exit_on_error0; - } - - /* Map the new core object, setting: core->registers_mapped */ - err = mali_core_renderunit_map_registers(core); - if (_MALI_OSK_ERR_OK != err) goto exit_on_error1; - - /* Check that the register mapping of the core works. - Return 0 if maligp core is present and accessible. */ - if (mali_benchmark) { - core->core_version = MALI_GP_PRODUCT_ID << 16; - } else { - core->core_version = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VERSION); - } - - err = maligp_core_version_legal(core); - if (_MALI_OSK_ERR_OK != err) goto exit_on_error2; - - /* Reset the core. Put the core into a state where it can start to render. */ - maligp_reset(core); - - /* Registering IRQ, init the work_queue_irq_handle */ - /* Adding this core as an available renderunit in the subsystem. */ - err = mali_core_subsystem_register_renderunit(&subsystem_maligp, core); - if (_MALI_OSK_ERR_OK != err) goto exit_on_error2; - -#ifdef DEBUG - MALI_DEBUG_PRINT(4, ("Mali GP: Initial Register settings:\n")); - maligp_print_regs(4, core); -#endif - - MALI_DEBUG_PRINT(6, ("Mali GP: maligp_renderunit_create\n") ) ; - - MALI_SUCCESS; - -exit_on_error2: - mali_core_renderunit_unmap_registers(core); -exit_on_error1: - mali_core_renderunit_term(core); -exit_on_error0: - _mali_osk_free( core ) ; - MALI_PRINT_ERROR(("Renderunit NOT created.")); - MALI_ERROR((_mali_osk_errcode_t)err); -} - -#if USING_MMU -/* Used currently only for signalling when MMU has a pagefault */ -static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data) -{ - mali_core_subsystem_broadcast_notification(&subsystem_maligp, message, data); -} -#endif - -#ifdef DEBUG -static void maligp_print_regs(int debug_level, mali_core_renderunit *core) -{ - if (debug_level <= mali_debug_level) - { - MALI_DEBUG_PRINT(1, (" VS 0x%08X 0x%08X, PLBU 0x%08X 0x%08X ALLOC 0x%08X 0x%08X\n", - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR)) - ); - MALI_DEBUG_PRINT(1, (" IntRaw 0x%08X IntMask 0x%08X, Status 0x%02X Ver: 0x%08X \n", - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_MASK), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VERSION))); - - MALI_DEBUG_PRINT(1, (" PERF_CNT Enbl:%d %d Src: %02d %02d VAL: 0x%08X 0x%08X\n", - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE))); - - MALI_DEBUG_PRINT(1, (" VS_START 0x%08X PLBU_START 0x%08X AXI_ERR 0x%08X\n", - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ), - mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ), - mali_core_renderunit_register_read(core, MALIGP2_CONTR_AXI_BUS_ERROR_STAT))); - } -} -#endif - -static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core ) -{ - u32 mali_type; - - mali_type = core->core_version >> 16; - -#if defined(USING_MALI400) - if ( MALI400_GP_PRODUCT_ID != mali_type && MALI300_GP_PRODUCT_ID != mali_type ) -#else - if ( MALI_GP_PRODUCT_ID != mali_type ) -#endif - { - MALI_PRINT_ERROR(("Error: reading this from maligp version register: 0x%x\n", core->core_version)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - MALI_DEBUG_PRINT(3, ("Mali GP: core_version_legal: Reads correct mali version: %d\n", core->core_version )) ; - MALI_SUCCESS; -} - -static void subsystem_maligp_renderunit_stop_bus(struct mali_core_renderunit* core) -{ - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); -} - -static void maligp_reset( mali_core_renderunit *core ) -{ - if (!mali_benchmark) { - maligp_raw_reset(core); - maligp_initialize_registers_mgmt(core); - } -} - - -static void maligp_reset_hard( mali_core_renderunit *core ) -{ - const int reset_finished_loop_count = 15; - const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW; - const u32 reset_invalid_value = 0xC0FFE000; - const u32 reset_check_value = 0xC01A0000; - const u32 reset_default_value = 0; - int i; - - mali_core_renderunit_register_write(core, reset_wait_target_register, reset_invalid_value); - - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET); - - for (i = 0; i < reset_finished_loop_count; i++) - { - mali_core_renderunit_register_write(core, reset_wait_target_register, reset_check_value); - if (reset_check_value == mali_core_renderunit_register_read(core, reset_wait_target_register)) - { - MALI_DEBUG_PRINT(5, ("Reset loop exiting after %d iterations\n", i)); - break; - } - } - - if (i == reset_finished_loop_count) - { - MALI_DEBUG_PRINT(1, ("The reset loop didn't work\n")); - } - - mali_core_renderunit_register_write(core, reset_wait_target_register, reset_default_value); /* set it back to the default */ - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); - - -} - -static void maligp_raw_reset( mali_core_renderunit *core ) -{ - int i; - const int request_loop_count = 20; - - MALI_DEBUG_PRINT(4, ("Mali GP: maligp_raw_reset: %s\n", core->description)) ; - if (mali_benchmark) return; - - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */ - -#if defined(USING_MALI200) - - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) break; - _mali_osk_time_ubusydelay(10); - } - - MALI_DEBUG_PRINT_IF(1, request_loop_count == i, ("Mali GP: Bus was never stopped during core reset\n")); - - if (request_loop_count==i) - { - /* Could not stop bus connections from core, probably because some of the already pending - bus request has had a page fault, and therefore can not complete before the MMU does PageFault - handling. This can be treated as a heavier reset function - which unfortunately reset all - the cores on this MMU in addition to the MMU itself */ -#if USING_MMU - if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery)) - { - MALI_DEBUG_PRINT(1, ("Mali GP: Forcing MMU bus reset\n")); - mali_kernel_mmu_force_bus_reset(core->mmu); - return; - } -#endif - MALI_PRINT(("A MMU reset did not allow GP to stop its bus, system failure, unable to recover\n")); - return; - } - - /* the bus was stopped OK, complete the reset */ - /* use the hard reset routine to do the actual reset */ - maligp_reset_hard(core); - -#elif defined(USING_MALI400) - - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & /*Bitwise OR*/ - MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) break; - _mali_osk_time_ubusydelay(10); - } - - if ( request_loop_count==i ) - { -#if USING_MMU - /* Could not stop bus connections from core, probably because some of the already pending - bus request has had a page fault, and therefore can not complete before the MMU does PageFault - handling. This can be treated as a heavier reset function - which unfortunately reset all - the cores on this MMU in addition to the MMU itself */ - if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery)) - { - MALI_DEBUG_PRINT(1, ("Mali GP: Forcing Bus reset\n")); - mali_kernel_mmu_force_bus_reset(core->mmu); - return; - } -#endif - MALI_PRINT(("A MMU reset did not allow GP to stop its bus, system failure, unable to recover\n")); - } - else - { - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); - } - -#else -#error "no supported mali core defined" -#endif -} - -/* Sets the registers on maligp according to the const default_mgmt_regs array. */ -static void maligp_initialize_registers_mgmt(mali_core_renderunit *core ) -{ - int i; - - MALI_DEBUG_PRINT(6, ("Mali GP: maligp_initialize_registers_mgmt: %s\n", core->description)) ; - for(i=0 ; i< (sizeof(default_mgmt_regs)/sizeof(*default_mgmt_regs)) ; ++i) - { - mali_core_renderunit_register_write_relaxed(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value); - } - _mali_osk_write_mem_barrier(); -} - - -/* Start this job on this core. Return MALI_TRUE if the job was started. */ -static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_core_renderunit * core) -{ - maligp_job *jobgp; - u32 startcmd; - /* The local extended version of the general structs */ - jobgp = _MALI_OSK_CONTAINER_OF(job, maligp_job, embedded_core_job); - - startcmd = 0; - if ( jobgp->user_input.frame_registers[0] != jobgp->user_input.frame_registers[1] ) - { - startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS; - } - - if ( jobgp->user_input.frame_registers[2] != jobgp->user_input.frame_registers[3] ) - { - startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU; - } - - if(0 == startcmd) - { - MALI_DEBUG_PRINT(4, ("Mali GP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n", - (u32)jobgp->user_input.user_job_ptr)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - -#ifdef DEBUG - MALI_DEBUG_PRINT(4, ("Mali GP: Registers Start\n")); - maligp_print_regs(4, core); -#endif - - - mali_core_renderunit_register_write_array( - core, - MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, - &(jobgp->user_input.frame_registers[0]), - sizeof(jobgp->user_input.frame_registers)/sizeof(jobgp->user_input.frame_registers[0])); - -#if MALI_TRACEPOINTS_ENABLED - jobgp->user_input.perf_counter_flag = 0; - - if( counter_table[7] != 0xFFFFFFFF ) { - jobgp->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE; - jobgp->user_input.perf_counter_src0 = counter_table[7]; - } - if( counter_table[8] != 0xFFFFFFFF ) { - jobgp->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE; - jobgp->user_input.perf_counter_src1 = counter_table[8]; - } -#endif - - /* This selects which performance counters we are reading */ - if ( 0 != jobgp->user_input.perf_counter_flag ) - { - if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) - { - mali_core_renderunit_register_write_relaxed( - core, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, - jobgp->user_input.perf_counter_src0); - - mali_core_renderunit_register_write_relaxed( - core, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, - MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - - if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) - { - mali_core_renderunit_register_write_relaxed( - core, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, - jobgp->user_input.perf_counter_src1); - - mali_core_renderunit_register_write_relaxed( - core, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, - MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - -#if defined(USING_MALI400_L2_CACHE) - if ( jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) ) - { - int force_reset = ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0; - u32 src0 = 0; - u32 src1 = 0; - - if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE ) - { - src0 = jobgp->user_input.perf_counter_l2_src0; - } - if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE ) - { - src1 = jobgp->user_input.perf_counter_l2_src1; - } - - mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */ - - /* Now, retrieve the current values, so we can substract them when the job has completed */ - mali_kernel_l2_cache_get_perf_counters(&jobgp->perf_counter_l2_src0, - &jobgp->perf_counter_l2_val0, - &jobgp->perf_counter_l2_src1, - &jobgp->perf_counter_l2_val1); - } -#endif - } - - if ( 0 == (jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)) - { - /* extended progress checking can be enabled */ - - jobgp->have_extended_progress_checking = 1; - - mali_core_renderunit_register_write_relaxed( - core, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, - MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED - ); - - mali_core_renderunit_register_write_relaxed( - core, - MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, - MALIGP2_REG_VAL_PERF_CNT_ENABLE); - } - - subsystem_flush_mapped_mem_cache(); - - MALI_DEBUG_PRINT(4, ("Mali GP: STARTING GP WITH CMD: 0x%x\n", startcmd)); -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_started); -#endif - - /* This is the command that starts the Core */ - mali_core_renderunit_register_write(core, - MALIGP2_REG_ADDR_MGMT_CMD, - startcmd); - _mali_osk_write_mem_barrier(); - - pr_debug("SPI_GPU_GP Start\n"); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, - jobgp->user_input.frame_builder_id, jobgp->user_input.flush_id, 0, 0, 0); - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0); -#endif - - MALI_SUCCESS; -} - -/* Check if given core has an interrupt pending. Return MALI_TRUE and set mask to 0 if pending */ - -static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core) -{ - u32 irq_readout; - - if (mali_benchmark) { - return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */ - } - - irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT); - - MALI_DEBUG_PRINT(5, ("Mali GP: IRQ: %04x\n", irq_readout)) ; - - if ( MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout ) - { - /* Mask out all IRQs from this core until IRQ is handled */ - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); -#endif - - /* We do need to handle this in a bottom half, return 1 */ - return 1; - } - return 0; -} - -/* This function should check if the interrupt indicates that job was finished. -If so it should update the job-struct, reset the core registers, and return MALI_TRUE, . -If the job is still working after this function it should return MALI_FALSE. -The function must also enable the bits in the interrupt mask for the core. -Called by the bottom half interrupt function. */ -static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core) -{ - mali_core_job * job; - maligp_job * jobgp; - u32 irq_readout; - u32 core_status; - u32 vscl; - u32 plbcl; - - job = core->current_job; - - if (mali_benchmark) { - MALI_DEBUG_PRINT(3, ("MaliGP: Job: Benchmark\n") ); - irq_readout = MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST; - core_status = 0; - } else { - irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED; - core_status = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS); - } - - if (NULL == job) - { - MALI_DEBUG_ASSERT(CORE_IDLE==core->state); - if ( 0 != irq_readout ) - { - MALI_PRINT_ERROR(("Interrupt from a core not running a job. IRQ: 0x%04x Status: 0x%04x", irq_readout, core_status)); - } - return JOB_STATUS_END_UNKNOWN_ERR; - } - MALI_DEBUG_ASSERT(CORE_IDLE!=core->state); - - jobgp = GET_JOBGP2_PTR(job); - - jobgp->heap_current_addr = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR); - - vscl = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR); - plbcl = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR); - - MALI_DEBUG_PRINT(3, ("Mali GP: Job: 0x%08x IRQ RECEIVED Rawstat: 0x%x Status: 0x%x\n", - (u32)jobgp->user_input.user_job_ptr, irq_readout , core_status )) ; - - jobgp->irq_status |= irq_readout; - jobgp->status_reg_on_stop = core_status; - - if ( 0 != jobgp->is_stalled_waiting_for_more_memory ) - { - /* Readback the performance counters */ - if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) ) - { - jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); - jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); - -#if MALI_TRACEPOINTS_ENABLED - //TODO magic numbers should come from mali_linux_trace.h instead - _mali_profiling_add_counter(7, jobgp->perf_counter0); - _mali_profiling_add_counter(8, jobgp->perf_counter1); -#endif - } - -#if defined(USING_MALI400_L2_CACHE) - if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) ) - { - u32 src0; - u32 val0; - u32 src1; - u32 val1; - mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1); - - if (jobgp->perf_counter_l2_src0 == src0) - { - jobgp->perf_counter_l2_val0 = val0 - jobgp->perf_counter_l2_val0; - } - else - { - jobgp->perf_counter_l2_val0 = 0; - } - - if (jobgp->perf_counter_l2_src1 == src1) - { - jobgp->perf_counter_l2_val1 = val1 - jobgp->perf_counter_l2_val1; - } - else - { - jobgp->perf_counter_l2_val1 = 0; - } - } -#endif - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ -#endif - - MALI_DEBUG_PRINT(2, ("Mali GP: Job aborted - userspace would not provide more heap memory.\n")); -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/ - } - /* finished ? */ - else if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE)) - { -#ifdef DEBUG - MALI_DEBUG_PRINT(4, ("Mali GP: Registers On job end:\n")); - maligp_print_regs(4, core); -#endif - MALI_DEBUG_PRINT_IF(5, irq_readout & 0x04, ("OOM when done, ignoring (reg.current = 0x%x, reg.end = 0x%x)\n", - (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR), - (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR)) - ); - - - if (0 != jobgp->user_input.perf_counter_flag ) - { - /* Readback the performance counters */ - if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) ) - { - jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); - jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); - -#if MALI_TRACEPOINTS_ENABLED - //TODO magic numbers should come from mali_linux_trace.h instead - _mali_profiling_add_counter(7, jobgp->perf_counter0); - _mali_profiling_add_counter(8, jobgp->perf_counter1); -#endif - } - -#if defined(USING_MALI400_L2_CACHE) - if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) ) - { - u32 src0; - u32 val0; - u32 src1; - u32 val1; - mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1); - - if (jobgp->perf_counter_l2_src0 == src0) - { - jobgp->perf_counter_l2_val0 = val0 - jobgp->perf_counter_l2_val0; - } - else - { - jobgp->perf_counter_l2_val0 = 0; - } - - if (jobgp->perf_counter_l2_src1 == src1) - { - jobgp->perf_counter_l2_val1 = val1 - jobgp->perf_counter_l2_val1; - } - else - { - jobgp->perf_counter_l2_val1 = 0; - } - } -#endif - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), - jobgp->perf_counter0, jobgp->perf_counter1, - jobgp->user_input.perf_counter_src0 | (jobgp->user_input.perf_counter_src1 << 8) -#if defined(USING_MALI400_L2_CACHE) - | (jobgp->user_input.perf_counter_l2_src0 << 16) | (jobgp->user_input.perf_counter_l2_src1 << 24), - jobgp->perf_counter_l2_val0, - jobgp->perf_counter_l2_val1 -#else - ,0, 0 -#endif - ); -#endif - - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL); - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - pr_debug("SPI_GPU_GP Idle\n"); - return JOB_STATUS_END_SUCCESS; /* core idle */ - } - /* sw watchdog timeout handling or time to do hang checking ? */ - else if ( - (CORE_WATCHDOG_TIMEOUT == core->state) || - ( - (CORE_HANG_CHECK_TIMEOUT == core->state) && - ( - (jobgp->have_extended_progress_checking ? (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE) == jobgp->vertices) : 1/*TRUE*/) && - ((core_status & MALIGP2_REG_VAL_STATUS_VS_ACTIVE) ? (vscl == jobgp->last_vscl) : 1/*TRUE*/) && - ((core_status & MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) ? (plbcl == jobgp->last_plbcl) : 1/*TRUE*/) - ) - ) - ) - { - /* no progress detected, killed by the watchdog */ - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ -#endif - - MALI_PRINT( ("Mali GP: SW-Timeout.\n")); - if (core_status & MALIGP2_REG_VAL_STATUS_VS_ACTIVE) MALI_DEBUG_PRINT(1, ("vscl current = 0x%x last = 0x%x\n", (void*)vscl, (void*)jobgp->last_vscl)); - if (core_status & MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) MALI_DEBUG_PRINT(1, ("plbcl current = 0x%x last = 0x%x\n", (void*)plbcl, (void*)jobgp->last_plbcl)); - if (jobgp->have_extended_progress_checking) MALI_DEBUG_PRINT(1, ("vertices processed = %d, last = %d\n", mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE), - jobgp->vertices)); -#ifdef DEBUG - maligp_print_regs(2, core); -#endif - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - MALI_PANIC("%s Watchdog timeout\n", MALI_GP_SUBSYSTEM_NAME); - return JOB_STATUS_END_HANG; - } - /* if hang timeout checking was enabled and we detected progress, will be fall down to this check */ - /* check for PLBU OOM before the hang check to avoid the race condition of the hw wd trigging while waiting for us to handle the OOM interrupt */ - else if ( 0 != (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)) - { - mali_core_session *session; - _mali_osk_notification_t *notific; - _mali_uk_gp_job_suspended_s * suspended_job; - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ -#endif - - session = job->session; - - MALI_DEBUG_PRINT(4, ("OOM, new heap requested by GP\n")); - MALI_DEBUG_PRINT(4, ("Status when OOM: current = 0x%x, end = 0x%x\n", - (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR), - (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR)) - ); - - notific = _mali_osk_notification_create( - - _MALI_NOTIFICATION_GP_STALLED, - sizeof( _mali_uk_gp_job_suspended_s ) - ); - if ( NULL == notific) - { - MALI_PRINT_ERROR( ("Mali GP: Could not get notification object\n")) ; - return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/ - } - - core->state = CORE_WORKING; - jobgp->is_stalled_waiting_for_more_memory = 1; - suspended_job = (_mali_uk_gp_job_suspended_s *)notific->result_buffer; /* this is ok - result_buffer was malloc'd */ - - suspended_job->user_job_ptr = jobgp->user_input.user_job_ptr; - suspended_job->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY ; - suspended_job->cookie = (u32) core; - last_gp_core_cookie = core; - - _mali_osk_notification_queue_send( session->notification_queue, notific); - -#ifdef DEBUG - maligp_print_regs(4, core); -#endif - - /* stop all active timers */ - _mali_osk_timer_del( core->timer); - _mali_osk_timer_del( core->timer_hang_detection); - MALI_DEBUG_PRINT(4, ("Mali GP: PLBU heap empty, sending memory request to userspace\n")); - /* save to watchdog_jiffies what was remaining WD timeout value when OOM was triggered */ - job->watchdog_jiffies = (long)job->watchdog_jiffies - (long)_mali_osk_time_tickcount(); - /* reuse core->timer as the userspace response timeout handler */ - _mali_osk_timer_add( core->timer, _mali_osk_time_mstoticks(1000) ); /* wait max 1 sec for userspace to respond */ - return JOB_STATUS_CONTINUE_RUN; /* The core is NOT available for new jobs. */ - } - /* hw watchdog is reporting a new hang or an existing progress-during-hang check passed? */ - else if ((CORE_HANG_CHECK_TIMEOUT == core->state) || (irq_readout & jobgp->active_mask & MALIGP2_REG_VAL_IRQ_HANG)) - { - /* check interval in ms */ - u32 timeout = mali_core_hang_check_timeout_get(); - MALI_DEBUG_PRINT(3, ("Mali GP: HW/SW Watchdog triggered, checking for progress in %d ms\n", timeout)); - core->state = CORE_WORKING; - - /* save state for the progress checking */ - jobgp->last_vscl = vscl; - jobgp->last_plbcl = plbcl; - if (jobgp->have_extended_progress_checking) - { - jobgp->vertices = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); - } - /* hw watchdog triggered, set up a progress checker every HANGCHECK ms */ - _mali_osk_timer_add( core->timer_hang_detection, _mali_osk_time_mstoticks(timeout)); - jobgp->active_mask &= ~MALIGP2_REG_VAL_IRQ_HANG; /* ignore the hw watchdog from now on */ - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, irq_readout); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask); - return JOB_STATUS_CONTINUE_RUN; /* not finihsed */ } - /* no errors, but still working */ - else if ( ( 0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ERROR)) && - ( 0 != (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE )) - ) - { - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, irq_readout); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask); - return JOB_STATUS_CONTINUE_RUN; - } - /* Else there must be some error */ - else - { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */ -#endif - - MALI_PRINT( ("Mali GP: Core crashed? *IRQ: 0x%x Status: 0x%x\n", irq_readout, core_status )); - #ifdef DEBUG - MALI_DEBUG_PRINT(1, ("Mali GP: Registers Before reset:\n")); - maligp_print_regs(1, core); - #endif -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - return JOB_STATUS_END_UNKNOWN_ERR; - } -} - - -/* This function is called from the ioctl function and should return a mali_core_job pointer -to a created mali_core_job object with the data given from userspace */ -static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument) -{ - maligp_job *jobgp; - mali_core_job *job = NULL; - mali_core_job *previous_replaced_job; - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_uk_gp_start_job_s * user_ptr_job_input; - - user_ptr_job_input = (_mali_uk_gp_start_job_s *)argument; - - MALI_CHECK_NON_NULL(jobgp = (maligp_job *) _mali_osk_calloc(1, sizeof(maligp_job)), _MALI_OSK_ERR_FAULT); - - /* Copy the job data from the U/K interface */ - if ( NULL == _mali_osk_memcpy(&jobgp->user_input, user_ptr_job_input, sizeof(_mali_uk_gp_start_job_s) ) ) - { - MALI_PRINT_ERROR( ("Mali GP: Could not copy data from U/K interface.\n")) ; - err = _MALI_OSK_ERR_FAULT; - goto function_exit; - } - - MALI_DEBUG_PRINT(3, ("Mali GP: subsystem_maligp_get_new_job_from_user 0x%x\n", (void*)jobgp->user_input.user_job_ptr)); - - MALI_DEBUG_PRINT(3, ("Mali GP: Job Regs: 0x%08X 0x%08X, 0x%08X 0x%08X 0x%08X 0x%08X\n", - jobgp->user_input.frame_registers[0], - jobgp->user_input.frame_registers[1], - jobgp->user_input.frame_registers[2], - jobgp->user_input.frame_registers[3], - jobgp->user_input.frame_registers[4], - jobgp->user_input.frame_registers[5]) ); - - - job = GET_JOB_EMBEDDED_PTR(jobgp); - - job->session = session; - job->flags = MALI_UK_START_JOB_FLAG_DEFAULT; /* Current flags only make sence for PP jobs */ - job_priority_set(job, jobgp->user_input.priority); - job_watchdog_set(job, jobgp->user_input.watchdog_msecs ); - jobgp->heap_current_addr = jobgp->user_input.frame_registers[4]; - - job->abort_id = jobgp->user_input.abort_id; - - jobgp->is_stalled_waiting_for_more_memory = 0; - -#if MALI_TIMELINE_PROFILING_ENABLED - jobgp->pid = _mali_osk_get_pid(); - jobgp->tid = _mali_osk_get_tid(); -#endif - - if (mali_job_queue_full(session)) - { - /* Cause jobgp to free: */ - user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE; - goto function_exit; - } - - /* We now know that we have a job, and a slot to put it in */ - - jobgp->active_mask = MALIGP2_REG_VAL_IRQ_MASK_USED; - - /* Allocating User Return Data */ - jobgp->notification_obj = _mali_osk_notification_create( - _MALI_NOTIFICATION_GP_FINISHED, - sizeof(_mali_uk_gp_job_finished_s) ); - - if ( NULL == jobgp->notification_obj ) - { - MALI_PRINT_ERROR( ("Mali GP: Could not get notification_obj.\n")) ; - err = _MALI_OSK_ERR_NOMEM; - goto function_exit; - } - - _MALI_OSK_INIT_LIST_HEAD( &(job->list) ) ; - - MALI_DEBUG_PRINT(4, ("Mali GP: Job: 0x%08x INPUT from user.\n", (u32)jobgp->user_input.user_job_ptr)) ; - - /* This should not happen since we have the checking of priority above */ - err = mali_core_session_add_job(session, job, &previous_replaced_job); - if ( _MALI_OSK_ERR_OK != err ) - { - MALI_PRINT_ERROR( ("Mali GP: Internal error\n")) ; - /* Cause jobgp to free: */ - user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE; - _mali_osk_notification_delete( jobgp->notification_obj ); - goto function_exit; - } - - /* If MALI_TRUE: This session had a job with lower priority which were removed. - This replaced job is given back to userspace. */ - if ( NULL != previous_replaced_job ) - { - maligp_job *previous_replaced_jobgp; - - previous_replaced_jobgp = GET_JOBGP2_PTR(previous_replaced_job); - - MALI_DEBUG_PRINT(4, ("Mali GP: Replacing job: 0x%08x\n", (u32)previous_replaced_jobgp->user_input.user_job_ptr)) ; - - /* Copy to the input data (which also is output data) the - pointer to the job that were replaced, so that the userspace - driver can put this job in the front of its job-queue */ - user_ptr_job_input->returned_user_job_ptr = previous_replaced_jobgp->user_input.user_job_ptr; - - /** @note failure to 'copy to user' at this point must not free jobgp, - * and so no transaction rollback required in the U/K interface */ - - /* This does not cause jobgp to free: */ - user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED; - MALI_DEBUG_PRINT(5, ("subsystem_maligp_get_new_job_from_user: Job added, prev returned\n")) ; - } - else - { - /* This does not cause jobgp to free: */ - user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED; - MALI_DEBUG_PRINT(5, ("subsystem_maligp_get_new_job_from_user: Job added\n")) ; - } - -function_exit: - if ( _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE == user_ptr_job_input->status - || _MALI_OSK_ERR_OK != err ) - { - _mali_osk_free(jobgp); - } -#if MALI_STATE_TRACKING - if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status) - { - if(job) - { - job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received); - } - } -#endif - - MALI_ERROR(err); -} - - -static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_session * session, void * argument) -{ - mali_core_renderunit *core; - maligp_job *jobgp; - mali_core_job *job; - - _mali_uk_gp_suspend_response_s * suspend_response; - - MALI_DEBUG_PRINT(5, ("subsystem_maligp_suspend_response\n")); - - suspend_response = (_mali_uk_gp_suspend_response_s *)argument; - - /* We read job data from User */ - /* On a single mali_gp system we can only have one Stalled GP, - and therefore one stalled request with a cookie. This checks - that we get the correct cookie */ - if ( last_gp_core_cookie != (mali_core_renderunit *)suspend_response->cookie ) - { - MALI_DEBUG_PRINT(2, ("Mali GP: Got an illegal cookie from Userspace.\n")) ; - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - core = (mali_core_renderunit *)suspend_response->cookie; - last_gp_core_cookie = NULL; - job = core->current_job; - jobgp = GET_JOBGP2_PTR(job); - - switch( suspend_response->code ) - { - case _MALIGP_JOB_RESUME_WITH_NEW_HEAP : - MALI_DEBUG_PRINT(5, ("MALIGP_JOB_RESUME_WITH_NEW_HEAP jiffies: %li\n", _mali_osk_time_tickcount())); - MALI_DEBUG_PRINT(4, ("New Heap addr 0x%08x - 0x%08x\n", suspend_response->arguments[0], suspend_response->arguments[1])); - - jobgp->is_stalled_waiting_for_more_memory = 0; - job->watchdog_jiffies += _mali_osk_time_tickcount(); /* convert to absolute time again */ - _mali_osk_timer_mod( core->timer, job->watchdog_jiffies); /* update the timer */ - - - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG)); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask); - mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]); - mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]); - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC); - _mali_osk_write_mem_barrier(); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); -#endif - - MALI_DEBUG_PRINT(4, ("GP resumed with new heap\n")); - - break; - - case _MALIGP_JOB_ABORT: - MALI_DEBUG_PRINT(3, ("MALIGP_JOB_ABORT on heap extend request\n")); - _mali_osk_irq_schedulework( core->irq ); - break; - - default: - MALI_PRINT_ERROR(("Wrong Suspend response from userspace\n")); - } - MALI_SUCCESS; -} - -/* This function is called from the ioctl function and should write the necessary data -to userspace telling which job was finished and the status and debuginfo for this job. -The function must also free and cleanup the input job object. */ -static void subsystem_maligp_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status ) -{ - maligp_job *jobgp; - _mali_uk_gp_job_finished_s * job_out; - _mali_uk_gp_start_job_s* job_input; - mali_core_session *session; - - - jobgp = _MALI_OSK_CONTAINER_OF(job, maligp_job, embedded_core_job); - job_out = (_mali_uk_gp_job_finished_s *)jobgp->notification_obj->result_buffer; /* OK - this should've been malloc'd */ - job_input= &(jobgp->user_input); - session = job->session; - - MALI_DEBUG_PRINT(5, ("Mali GP: Job: 0x%08x OUTPUT to user. Runtime: %d us, irq readout %x\n", - (u32)jobgp->user_input.user_job_ptr, - job->render_time_usecs, - jobgp->irq_status)) ; - - _mali_osk_memset(job_out, 0 , sizeof(_mali_uk_gp_job_finished_s)); - - job_out->user_job_ptr = job_input->user_job_ptr; - - switch( end_status ) - { - case JOB_STATUS_CONTINUE_RUN: - case JOB_STATUS_END_SUCCESS: - case JOB_STATUS_END_OOM: - case JOB_STATUS_END_ABORT: - case JOB_STATUS_END_TIMEOUT_SW: - case JOB_STATUS_END_HANG: - case JOB_STATUS_END_SEG_FAULT: - case JOB_STATUS_END_ILLEGAL_JOB: - case JOB_STATUS_END_UNKNOWN_ERR: - case JOB_STATUS_END_SHUTDOWN: - case JOB_STATUS_END_SYSTEM_UNUSABLE: - job_out->status = (mali_subsystem_job_end_code) end_status; - break; - default: - job_out->status = JOB_STATUS_END_UNKNOWN_ERR ; - } - - job_out->irq_status = jobgp->irq_status; - job_out->status_reg_on_stop = jobgp->status_reg_on_stop; - job_out->vscl_stop_addr = 0; - job_out->plbcl_stop_addr = 0; - job_out->heap_current_addr = jobgp->heap_current_addr; - job_out->perf_counter0 = jobgp->perf_counter0; - job_out->perf_counter1 = jobgp->perf_counter1; - job_out->perf_counter_src0 = jobgp->user_input.perf_counter_src0 ; - job_out->perf_counter_src1 = jobgp->user_input.perf_counter_src1 ; - job_out->render_time = job->render_time_usecs; -#if defined(USING_MALI400_L2_CACHE) - job_out->perf_counter_l2_src0 = jobgp->perf_counter_l2_src0; - job_out->perf_counter_l2_src1 = jobgp->perf_counter_l2_src1; - job_out->perf_counter_l2_val0 = jobgp->perf_counter_l2_val0; - job_out->perf_counter_l2_val1 = jobgp->perf_counter_l2_val1; -#endif - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&session->jobs_returned); -#endif - _mali_osk_notification_queue_send( session->notification_queue, jobgp->notification_obj); - jobgp->notification_obj = NULL; - - _mali_osk_free(jobgp); - - last_gp_core_cookie = NULL; -} - -static void subsystem_maligp_renderunit_delete(mali_core_renderunit * core) -{ - MALI_DEBUG_PRINT(5, ("Mali GP: maligp_renderunit_delete\n")); - _mali_osk_free(core); -} - -static void subsystem_maligp_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style) -{ - MALI_DEBUG_PRINT(5, ("Mali GP: renderunit_reset_core\n")); - - switch (style) - { - case MALI_CORE_RESET_STYLE_RUNABLE: - maligp_reset(core); - break; - case MALI_CORE_RESET_STYLE_DISABLE: - maligp_raw_reset(core); /* do the raw reset */ - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* then disable the IRQs */ - break; - case MALI_CORE_RESET_STYLE_HARD: - maligp_reset_hard(core); - maligp_initialize_registers_mgmt(core); - break; - default: - MALI_DEBUG_PRINT(1, ("Unknown reset type %d\n", style)); - break; - } -} - -static void subsystem_maligp_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core) -{ - mali_core_renderunit_register_write(core , MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); - mali_core_renderunit_register_write(core , MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG ); - _mali_osk_mem_barrier(); -} - -static _mali_osk_errcode_t subsystem_maligp_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core) -{ - u32 irq_readout; - - irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT); - - if ( MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout ) - { - mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG); - _mali_osk_mem_barrier(); - MALI_SUCCESS; - } - - MALI_ERROR(_MALI_OSK_ERR_FAULT); -} - -_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_start_job(session, args); -} - -_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_number_of_cores_get(session, &args->number_of_cores); -} - -_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_core_version_get(session, &args->version); -} - -_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_suspend_response(session, args); -} - -void _mali_ukk_gp_abort_job( _mali_uk_gp_abort_job_s * args) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - if (NULL == args->ctx) return; - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id); - if (NULL == session) return; - mali_core_subsystem_ioctl_abort_job(session, args->abort_id); - -} - -#if USING_MALI_PMM - -_mali_osk_errcode_t maligp_signal_power_up( mali_bool queue_only ) -{ - MALI_DEBUG_PRINT(4, ("Mali GP: signal power up core - queue_only: %d\n", queue_only )); - - return( mali_core_subsystem_signal_power_up( &subsystem_maligp, 0, queue_only ) ); -} - -_mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only ) -{ - MALI_DEBUG_PRINT(4, ("Mali GP: signal power down core - immediate_only: %d\n", immediate_only )); - - return( mali_core_subsystem_signal_power_down( &subsystem_maligp, 0, immediate_only ) ); -} - -#endif - -#if MALI_STATE_TRACKING -u32 maligp_subsystem_dump_state(char *buf, u32 size) -{ - return mali_core_renderunit_dump_state(&subsystem_maligp, buf, size); -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c b/drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c deleted file mode 100644 index 0f5ebd0..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c +++ /dev/null @@ -1,1304 +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. - */ - -//added for SPI -#include - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_kernel_pp.h" -#include "mali_kernel_subsystem.h" -#include "mali_kernel_core.h" -#include "regs/mali_200_regs.h" -#include "mali_kernel_rendercore.h" -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" -#endif -#ifdef USING_MALI400_L2_CACHE -#include "mali_kernel_l2_cache.h" -#endif -#if USING_MMU -#include "mali_kernel_mem_mmu.h" /* Needed for mali_kernel_mmu_force_bus_reset() */ -#endif - -#include "mali_osk_list.h" - -#if defined(USING_MALI200) -#define MALI_PP_SUBSYSTEM_NAME "Mali200" -#define MALI_PP_CORE_TYPE _MALI_200 -#elif defined(USING_MALI400) -#define MALI_PP_SUBSYSTEM_NAME "Mali-400 PP" -#define MALI_PP_CORE_TYPE _MALI_400_PP -#else -#error "No supported mali core defined" -#endif - -#define GET_JOB_EMBEDDED_PTR(job) (&((job)->embedded_core_job)) -#define GET_JOB200_PTR(job_extern) _MALI_OSK_CONTAINER_OF(job_extern, mali200_job, embedded_core_job) - -/* Initialized when this subsystem is initialized. This is determined by the - * position in subsystems[], and so the value used to initialize this is - * determined at compile time */ -static mali_kernel_subsystem_identifier mali_subsystem_mali200_id = -1; - -/* Describing a mali200 job settings */ -typedef struct mali200_job -{ - /* The general job struct common for all mali cores */ - mali_core_job embedded_core_job; - _mali_uk_pp_start_job_s user_input; - - u32 irq_status; - u32 perf_counter0; - u32 perf_counter1; - u32 last_tile_list_addr; /* Neccessary to continue a stopped job */ - - u32 active_mask; - - /* The data we will return back to the user */ - _mali_osk_notification_t *notification_obj; - -#if defined(USING_MALI400_L2_CACHE) - u32 perf_counter_l2_src0; - u32 perf_counter_l2_src1; - u32 perf_counter_l2_val0; - u32 perf_counter_l2_val1; - u32 perf_counter_l2_val0_raw; - u32 perf_counter_l2_val1_raw; -#endif - -#if MALI_TIMELINE_PROFILING_ENABLED - u32 pid; - u32 tid; -#endif -} mali200_job; - - -/*Functions Exposed to the General External System through - funciont pointers.*/ - -static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id); -#if USING_MMU -static _mali_osk_errcode_t mali200_subsystem_mmu_connect(mali_kernel_subsystem_identifier id); -#endif -static void mali200_subsystem_terminate(mali_kernel_subsystem_identifier id); -static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); -static void mali200_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot); -static _mali_osk_errcode_t mali200_subsystem_core_system_info_fill(_mali_system_info* info); -static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource); -#if USING_MMU -static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data); -#endif -#if MALI_STATE_TRACKING -u32 mali200_subsystem_dump_state(char *buf, u32 size); -#endif - -/* Internal support functions */ -static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core ); -static void mali200_reset(mali_core_renderunit *core); -static void mali200_reset_hard(struct mali_core_renderunit * core); -static void mali200_raw_reset(mali_core_renderunit * core); -static void mali200_initialize_registers_mgmt(mali_core_renderunit *core ); - -/* Functions exposed to mali_core system through functionpointers - in the subsystem struct. */ -static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core); -static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument); -static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status); -static void subsystem_mali200_renderunit_delete(mali_core_renderunit * core); -static void subsystem_mali200_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style); -static void subsystem_mali200_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core); -static _mali_osk_errcode_t subsystem_mali200_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core); - -static void subsystem_mali200_renderunit_stop_bus(struct mali_core_renderunit* core); -static u32 subsystem_mali200_irq_handler_upper_half(struct mali_core_renderunit * core); -static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit* core); - -/* This will be one of the subsystems in the array of subsystems: - static struct mali_kernel_subsystem * subsystems[]; - found in file: mali_kernel_core.c -*/ - -struct mali_kernel_subsystem mali_subsystem_mali200= -{ - mali200_subsystem_startup, /* startup */ - NULL, /*mali200_subsystem_terminate,*/ /* shutdown */ -#if USING_MMU - mali200_subsystem_mmu_connect, /* load_complete */ -#else - NULL, -#endif - mali200_subsystem_core_system_info_fill, /* system_info_fill */ - mali200_subsystem_session_begin, /* session_begin */ - mali200_subsystem_session_end, /* session_end */ -#if USING_MMU - mali200_subsystem_broadcast_notification, /* broadcast_notification */ -#else - NULL, -#endif -#if MALI_STATE_TRACKING - mali200_subsystem_dump_state, /* dump_state */ -#endif -} ; - -static mali_core_subsystem subsystem_mali200 ; - -static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id) -{ - mali_core_subsystem * subsystem; - - MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_startup\n") ) ; - - mali_subsystem_mali200_id = id; - - /* All values get 0 as default */ - _mali_osk_memset(&subsystem_mali200, 0, sizeof(subsystem_mali200)); - - subsystem = &subsystem_mali200; - subsystem->start_job = &subsystem_mali200_start_job; - subsystem->irq_handler_upper_half = &subsystem_mali200_irq_handler_upper_half; - subsystem->irq_handler_bottom_half = &subsystem_mali200_irq_handler_bottom_half; - subsystem->get_new_job_from_user = &subsystem_mali200_get_new_job_from_user; - subsystem->return_job_to_user = &subsystem_mali200_return_job_to_user; - subsystem->renderunit_delete = &subsystem_mali200_renderunit_delete; - subsystem->reset_core = &subsystem_mali200_renderunit_reset_core; - subsystem->stop_bus = &subsystem_mali200_renderunit_stop_bus; - subsystem->probe_core_irq_trigger = &subsystem_mali200_renderunit_probe_core_irq_trigger; - subsystem->probe_core_irq_acknowledge = &subsystem_mali200_renderunit_probe_core_irq_finished; - - /* Setting variables in the general core part of the subsystem.*/ - subsystem->name = MALI_PP_SUBSYSTEM_NAME; - subsystem->core_type = MALI_PP_CORE_TYPE; - subsystem->id = id; - - /* Initiates the rest of the general core part of the subsystem */ - MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem )); - - /* This will register the function for adding MALI200 cores to the subsystem */ -#if defined(USING_MALI200) - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI200, mali200_renderunit_create)); -#endif -#if defined(USING_MALI400) - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400PP, mali200_renderunit_create)); -#endif - - MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_startup\n") ) ; - - MALI_SUCCESS; -} - -#if USING_MMU -static _mali_osk_errcode_t mali200_subsystem_mmu_connect(mali_kernel_subsystem_identifier id) -{ - mali_core_subsystem_attach_mmu(&subsystem_mali200); - MALI_SUCCESS; /* OK */ -} -#endif - -static void mali200_subsystem_terminate(mali_kernel_subsystem_identifier id) -{ - MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_terminate\n") ) ; - mali_core_subsystem_cleanup(&subsystem_mali200); -} - -static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue) -{ - mali_core_session * session; - - MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_begin\n") ) ; - MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(mali_core_session) ), _MALI_OSK_ERR_NOMEM); - - _mali_osk_memset(session, 0, sizeof(*session) ); - *slot = (mali_kernel_subsystem_session_slot)session; - - session->subsystem = &subsystem_mali200; - - session->notification_queue = queue; - -#if USING_MMU - session->mmu_session = mali_session_data; -#endif - - mali_core_session_begin(session); - - MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_begin\n") ) ; - - MALI_SUCCESS; -} - -static void mali200_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot) -{ - mali_core_session * session; - - MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_end\n") ) ; - if ( NULL==slot || NULL==*slot) - { - MALI_PRINT_ERROR(("Input slot==NULL")); - return; - } - session = (mali_core_session*) *slot; - mali_core_session_close(session); - - _mali_osk_free(session); - *slot = NULL; - - MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_end\n") ) ; -} - -/** - * We fill in info about all the cores we have - * @param info Pointer to system info struct to update - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali200_subsystem_core_system_info_fill(_mali_system_info* info) -{ - return mali_core_subsystem_system_info_fill(&subsystem_mali200, info); -} - - -static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource) -{ - mali_core_renderunit *core; - _mali_osk_errcode_t err; - - MALI_DEBUG_PRINT(3, ("Mali PP: mali200_renderunit_create\n") ) ; - /* Checking that the resource settings are correct */ -#if defined(USING_MALI200) - if(MALI200 != resource->type) - { - MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#elif defined(USING_MALI400) - if(MALI400PP != resource->type) - { - MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#endif - if ( 0 != resource->size ) - { - MALI_PRINT_ERROR(("Memory size set to " MALI_PP_SUBSYSTEM_NAME " core should be zero.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - if ( NULL == resource->description ) - { - MALI_PRINT_ERROR(("A " MALI_PP_SUBSYSTEM_NAME " core needs a unique description field")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Create a new core object */ - core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core)); - if ( NULL == core ) - { - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - /* Variables set to be able to open and register the core */ - core->subsystem = &subsystem_mali200 ; - core->registers_base_addr = resource->base ; - core->size = MALI200_REG_SIZEOF_REGISTER_BANK ; - core->irq_nr = resource->irq ; - core->description = resource->description; -#if USING_MMU - core->mmu_id = resource->mmu_id; - core->mmu = NULL; -#endif -#if USING_MALI_PMM - /* Set up core's PMM id */ - switch( subsystem_mali200.number_of_cores ) - { - case 0: - core->pmm_id = MALI_PMM_CORE_PP0; - break; - case 1: - core->pmm_id = MALI_PMM_CORE_PP1; - break; - case 2: - core->pmm_id = MALI_PMM_CORE_PP2; - break; - case 3: - core->pmm_id = MALI_PMM_CORE_PP3; - break; - default: - MALI_DEBUG_PRINT(1, ("Unknown supported core for PMM\n")); - err = _MALI_OSK_ERR_FAULT; - goto exit_on_error0; - } -#endif - - err = mali_core_renderunit_init( core ); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n")); - goto exit_on_error0; - } - - /* Map the new core object, setting: core->registers_mapped */ - err = mali_core_renderunit_map_registers(core); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(1, ("Failed to map register\n")); - goto exit_on_error1; - } - - /* Check that the register mapping of the core works. - Return 0 if Mali PP core is present and accessible. */ - if (mali_benchmark) { -#if defined(USING_MALI200) - core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 5 /* Fake Mali200-r0p5 */; -#elif defined(USING_MALI400) - core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 0x0101 /* Fake Mali400-r1p1 */; -#else -#error "No supported mali core defined" -#endif - } else { - core->core_version = mali_core_renderunit_register_read( - core, - MALI200_REG_ADDR_MGMT_VERSION); - } - - err = mali200_core_version_legal(core); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(1, ("Invalid core\n")); - goto exit_on_error2; - } - - /* Reset the core. Put the core into a state where it can start to render. */ - mali200_reset(core); - - /* Registering IRQ, init the work_queue_irq_handle */ - /* Adding this core as an available renderunit in the subsystem. */ - err = mali_core_subsystem_register_renderunit(&subsystem_mali200, core); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(1, ("Failed to register with core\n")); - goto exit_on_error2; - } - MALI_DEBUG_PRINT(6, ("Mali PP: mali200_renderunit_create\n") ) ; - - MALI_SUCCESS; - -exit_on_error2: - mali_core_renderunit_unmap_registers(core); -exit_on_error1: - mali_core_renderunit_term(core); -exit_on_error0: - _mali_osk_free( core ) ; - MALI_PRINT_ERROR(("Renderunit NOT created.")); - MALI_ERROR(err); -} - -#if USING_MMU -/* Used currently only for signalling when MMU has a pagefault */ -static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data) -{ - mali_core_subsystem_broadcast_notification(&subsystem_mali200, message, data); -} -#endif - -static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core ) -{ - u32 mali_type; - - mali_type = core->core_version >> 16; -#if defined(USING_MALI400) - /* Mali300 and Mali400 is compatible, accept either core. */ - if (MALI400_PP_PRODUCT_ID != mali_type && MALI300_PP_PRODUCT_ID != mali_type) -#else - if (MALI_PP_PRODUCT_ID != mali_type) -#endif - { - MALI_PRINT_ERROR(("Error: reading this from " MALI_PP_SUBSYSTEM_NAME " version register: 0x%x\n", core->core_version)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - MALI_DEBUG_PRINT(3, ("Mali PP: core_version_legal: Reads correct mali version: %d\n", mali_type) ) ; - MALI_SUCCESS; -} - -static void subsystem_mali200_renderunit_stop_bus(struct mali_core_renderunit* core) -{ - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); -} - -static void mali200_raw_reset( mali_core_renderunit *core ) -{ - int i; - const int request_loop_count = 20; - - MALI_DEBUG_PRINT(4, ("Mali PP: mali200_raw_reset: %s\n", core->description)); - if (mali_benchmark) return; - - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable IRQs */ - -#if defined(USING_MALI200) - - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) break; - _mali_osk_time_ubusydelay(10); - } - - MALI_DEBUG_PRINT_IF(1, request_loop_count == i, ("Mali PP: Bus was never stopped during core reset\n")); - - - if (request_loop_count==i) - { -#if USING_MMU - if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery)) - { - /* Could not stop bus connections from core, probably because some of the already pending - bus request has had a page fault, and therefore can not complete before the MMU does PageFault - handling. This can be treated as a heavier reset function - which unfortunately reset all - the cores on this MMU in addition to the MMU itself */ - MALI_DEBUG_PRINT(1, ("Mali PP: Forcing Bus reset\n")); - mali_kernel_mmu_force_bus_reset(core->mmu); - return; - } -#endif - MALI_PRINT(("A MMU reset did not allow PP to stop its bus, system failure, unable to recover\n")); - return; - } - - /* use the hard reset routine to do the actual reset */ - mali200_reset_hard(core); - -#elif defined(USING_MALI400) - - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED); - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET); - - for (i = 0; i < request_loop_count; i++) - { - if (mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) break; - _mali_osk_time_ubusydelay(10); - } - - if (request_loop_count==i) - { -#if USING_MMU - if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery)) - { - /* Could not stop bus connections from core, probably because some of the already pending - bus request has had a page fault, and therefore can not complete before the MMU does PageFault - handling. This can be treated as a heavier reset function - which unfortunately reset all - the cores on this MMU in addition to the MMU itself */ - MALI_DEBUG_PRINT(1, ("Mali PP: Forcing Bus reset\n")); - mali_kernel_mmu_force_bus_reset(core->mmu); - return; - } -#endif - MALI_PRINT(("A MMU reset did not allow PP to stop its bus, system failure, unable to recover\n")); - return; - } - else - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); - -#else -#error "no supported mali core defined" -#endif -} - -static void mali200_reset( mali_core_renderunit *core ) -{ - if (!mali_benchmark) { - mali200_raw_reset(core); - mali200_initialize_registers_mgmt(core); - } -} - -/* Sets the registers on mali200 according to the const default_mgmt_regs array. */ -static void mali200_initialize_registers_mgmt(mali_core_renderunit *core ) -{ - MALI_DEBUG_PRINT(6, ("Mali PP: mali200_initialize_registers_mgmt: %s\n", core->description)) ; - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); -} - -/* Start this job on this core. Return MALI_TRUE if the job was started. */ -static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core) -{ - mali200_job *job200; - - /* The local extended version of the general structs */ - job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job); - - if ( (0 == job200->user_input.frame_registers[0]) || - (0 == job200->user_input.frame_registers[1]) ) - { - MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n", - (u32)job200->user_input.user_job_ptr)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x START_RENDER Tile_list: 0x%08x\n", - (u32)job200->user_input.user_job_ptr, - job200->user_input.frame_registers[0])); - MALI_DEBUG_PRINT(6, ("Mali PP: RSW base addr: 0x%08x Vertex base addr: 0x%08x\n", - job200->user_input.frame_registers[1], job200->user_input.frame_registers[2])); - - /* Frame registers. Copy from mem to physical registers */ - mali_core_renderunit_register_write_array( - core, - MALI200_REG_ADDR_FRAME, - &(job200->user_input.frame_registers[0]), - MALI200_NUM_REGS_FRAME); - - /* Write Back unit 0. Copy from mem to physical registers only if the WB unit will be used. */ - if (job200->user_input.wb0_registers[0]) - { - mali_core_renderunit_register_write_array( - core, - MALI200_REG_ADDR_WB0, - &(job200->user_input.wb0_registers[0]), - MALI200_NUM_REGS_WBx); - } - - /* Write Back unit 1. Copy from mem to physical registers only if the WB unit will be used. */ - if (job200->user_input.wb1_registers[0]) - { - mali_core_renderunit_register_write_array( - core, - MALI200_REG_ADDR_WB1, - &(job200->user_input.wb1_registers[0]), - MALI200_NUM_REGS_WBx); - } - - /* Write Back unit 2. Copy from mem to physical registers only if the WB unit will be used. */ - if (job200->user_input.wb2_registers[0]) - { - mali_core_renderunit_register_write_array( - core, - MALI200_REG_ADDR_WB2, - &(job200->user_input.wb2_registers[0]), - MALI200_NUM_REGS_WBx); - } - -#if MALI_TRACEPOINTS_ENABLED - { - int counter = ((core->core_number)*2)+9; /* magic numbers for FP0 are 9 & 10 */ - - //printk("FP core->number = %d\n", core->core_number); - //TODO we are using magic numbers again... these are from gator_events_mali.c - job200->user_input.perf_counter_flag = 0; - - if( counter>=9 && counter<=16) { - - if( counter_table[counter] != 0xFFFFFFFF ) { - job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE; - job200->user_input.perf_counter_src0 = counter_table[counter]; - } - if( counter_table[counter+1] != 0xFFFFFFFF ) { - job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE; - job200->user_input.perf_counter_src1 = counter_table[counter+1]; - } - - } else { - MALI_DEBUG_PRINT(2, ("core->core_number out of the range (0-3) (%d)\n", core->core_number)); - } - } -#if defined(USING_MALI400_L2_CACHE) - if( counter_table[5] != 0xFFFFFFFF ) { - job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE | _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET; - job200->user_input.perf_counter_l2_src0 = counter_table[5]; - } - if( counter_table[6] != 0xFFFFFFFF ) { - job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE | _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET; - job200->user_input.perf_counter_l2_src1 = counter_table[6]; - } -#endif -#endif - - /* This selects which performance counters we are reading */ - if ( 0 != job200->user_input.perf_counter_flag ) - { - if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) - { - mali_core_renderunit_register_write_relaxed( - core, - MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, - MALI200_REG_VAL_PERF_CNT_ENABLE); - mali_core_renderunit_register_write_relaxed( - core, - MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, - job200->user_input.perf_counter_src0); - - } - - if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) - { - mali_core_renderunit_register_write_relaxed( - core, - MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, - MALI200_REG_VAL_PERF_CNT_ENABLE); - mali_core_renderunit_register_write_relaxed( - core, - MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, - job200->user_input.perf_counter_src1); - - } - -#if defined(USING_MALI400_L2_CACHE) - if ( job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) ) - { - int force_reset = ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0; - u32 src0 = 0; - u32 src1 = 0; - - if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE ) - { - src0 = job200->user_input.perf_counter_l2_src0; - } - if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE ) - { - src1 = job200->user_input.perf_counter_l2_src1; - } - - mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */ - - /* Now, retrieve the current values, so we can substract them when the job has completed */ - mali_kernel_l2_cache_get_perf_counters(&job200->perf_counter_l2_src0, - &job200->perf_counter_l2_val0, - &job200->perf_counter_l2_src1, - &job200->perf_counter_l2_val1); - } -#endif - } - - subsystem_flush_mapped_mem_cache(); - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_started); -#endif - - /* This is the command that starts the Core */ - mali_core_renderunit_register_write( - core, - MALI200_REG_ADDR_MGMT_CTRL_MGMT, - MALI200_REG_VAL_CTRL_MGMT_START_RENDERING); - _mali_osk_write_mem_barrier(); - - - pr_debug("SPI_GPU_PP%u Start\n", core->core_number); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job200->user_input.frame_builder_id, job200->user_input.flush_id, 0, 0, 0); - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid, -#if defined(USING_MALI400_L2_CACHE) - (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24), - job200->perf_counter_l2_val0, job200->perf_counter_l2_val1 -#else - 0, 0, 0 -#endif - ); -#endif - - MALI_SUCCESS; -} - -static u32 subsystem_mali200_irq_handler_upper_half(mali_core_renderunit * core) -{ - u32 irq_readout; - - if (mali_benchmark) { - return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */ - } - - MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_irq_handler_upper_half: %s\n", core->description)) ; - irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS); - - if ( MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout ) - { - /* Mask out all IRQs from this core until IRQ is handled */ - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0); -#endif - - return 1; - } - return 0; -} - -static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit* core) -{ - u32 irq_readout; - u32 current_tile_addr; - u32 core_status; - mali_core_job * job; - mali200_job * job200; - - job = core->current_job; - job200 = GET_JOB200_PTR(job); - - - if (mali_benchmark) { - irq_readout = MALI200_REG_VAL_IRQ_END_OF_FRAME; - current_tile_addr = 0; - core_status = 0; - } else { - irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED; - current_tile_addr = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR); - core_status = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_STATUS); - } - - if (NULL == job) - { - MALI_DEBUG_ASSERT(CORE_IDLE==core->state); - if ( 0 != irq_readout ) - { - MALI_PRINT_ERROR(("Interrupt from a core not running a job. IRQ: 0x%04x Status: 0x%04x", irq_readout, core_status)); - } - return JOB_STATUS_END_UNKNOWN_ERR; - } - MALI_DEBUG_ASSERT(CORE_IDLE!=core->state); - - job200->irq_status |= irq_readout; - - MALI_DEBUG_PRINT_IF( 3, ( 0 != irq_readout ), - ("Mali PP: Job: 0x%08x IRQ RECEIVED Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n", - (u32)job200->user_input.user_job_ptr, irq_readout ,current_tile_addr ,core_status)); - - if ( MALI200_REG_VAL_IRQ_END_OF_FRAME & irq_readout) - { -#if defined(USING_MALI200) - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES); -#endif - - if (0 != job200->user_input.perf_counter_flag ) - { - if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) ) - { -#if MALI_TRACEPOINTS_ENABLED - //TODO magic numbers should come from mali_linux_trace.h instead - unsigned int counter = (core->core_number * 2) + 9; -#endif - - job200->perf_counter0 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE); - job200->perf_counter1 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE); - -#if MALI_TRACEPOINTS_ENABLED - _mali_profiling_add_counter(counter, job200->perf_counter0); - _mali_profiling_add_counter(counter + 1, job200->perf_counter1); -#endif - - } - -#if defined(USING_MALI400_L2_CACHE) - if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) ) - { - u32 src0; - u32 val0; - u32 src1; - u32 val1; - mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1); - - if (job200->perf_counter_l2_src0 == src0) - { - job200->perf_counter_l2_val0_raw = val0; - job200->perf_counter_l2_val0 = val0 - job200->perf_counter_l2_val0; - } - else - { - job200->perf_counter_l2_val0_raw = 0; - job200->perf_counter_l2_val0 = 0; - } - - if (job200->perf_counter_l2_src1 == src1) - { - job200->perf_counter_l2_val1_raw = val1; - job200->perf_counter_l2_val1 = val1 - job200->perf_counter_l2_val1; - } - else - { - job200->perf_counter_l2_val1_raw = 0; - job200->perf_counter_l2_val1 = 0; - } - -#if MALI_TRACEPOINTS_ENABLED - //TODO magic numbers should come from mali_linux_trace.h instead - _mali_profiling_add_counter(5, val0); - _mali_profiling_add_counter(6, val1); -#endif - } -#endif - - } - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), - job200->perf_counter0, job200->perf_counter1, - job200->user_input.perf_counter_src0 | (job200->user_input.perf_counter_src1 << 8) -#if defined(USING_MALI400_L2_CACHE) - | (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24), - job200->perf_counter_l2_val0, job200->perf_counter_l2_val1 -#else - , 0, 0 -#endif - ); -#endif - - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - - pr_debug("SPI_GPU_PP%u Idle\n", core->core_number); - - return JOB_STATUS_END_SUCCESS; /* reschedule */ - } - /* Overall SW watchdog timeout or (time to do hang checking and progress detected)? */ - else if ( - (CORE_WATCHDOG_TIMEOUT == core->state) || - ((CORE_HANG_CHECK_TIMEOUT == core->state) && (current_tile_addr == job200->last_tile_list_addr)) - ) - { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ -#endif - /* no progress detected, killed by the watchdog */ - MALI_PRINT( ("M200: SW-Timeout Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x.\n", irq_readout ,current_tile_addr ,core_status) ); - /* In this case will the system outside cleanup and reset the core */ - - MALI_PANIC("%s Watchdog timeout (rawstat: 0x%x tile_addr: 0x%x status: 0x%x)\n", MALI_PP_SUBSYSTEM_NAME, irq_readout, current_tile_addr, core_status); - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - - return JOB_STATUS_END_HANG; - } - /* HW watchdog triggered or an existing hang check passed? */ - else if ((CORE_HANG_CHECK_TIMEOUT == core->state) || (irq_readout & job200->active_mask & MALI200_REG_VAL_IRQ_HANG)) - { - /* check interval in ms */ - u32 timeout = mali_core_hang_check_timeout_get(); - MALI_PRINT( ("M200: HW/SW Watchdog triggered, checking for progress in %d ms\n", timeout)); - job200->last_tile_list_addr = current_tile_addr; - /* hw watchdog triggered, set up a progress checker every HANGCHECK ms */ - _mali_osk_timer_add(core->timer_hang_detection, _mali_osk_time_mstoticks(timeout)); - job200->active_mask &= ~MALI200_REG_VAL_IRQ_HANG; /* ignore the hw watchdoig from now on */ - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, irq_readout & ~MALI200_REG_VAL_IRQ_HANG); - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, job200->active_mask); - return JOB_STATUS_CONTINUE_RUN; /* not finished */ - } - /* No irq pending, core still busy */ - else if ((0 == (irq_readout & MALI200_REG_VAL_IRQ_MASK_USED)) && ( 0 != (core_status & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE))) - { - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, irq_readout); - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, job200->active_mask); - return JOB_STATUS_CONTINUE_RUN; /* Not finished */ - } - else - { -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */ -#endif - - MALI_PRINT( ("Mali PP: Job: 0x%08x CRASH? Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n", - (u32)job200->user_input.user_job_ptr, irq_readout ,current_tile_addr ,core_status) ) ; - - if (irq_readout & MALI200_REG_VAL_IRQ_BUS_ERROR) - { - u32 bus_error = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS); - - MALI_PRINT(("Bus error status: 0x%08X\n", bus_error)); - MALI_DEBUG_PRINT_IF(1, (bus_error & 0x01), ("Bus write error from id 0x%02x\n", (bus_error>>2) & 0x0F)); - MALI_DEBUG_PRINT_IF(1, (bus_error & 0x02), ("Bus read error from id 0x%02x\n", (bus_error>>6) & 0x0F)); - MALI_DEBUG_PRINT_IF(1, (0 == (bus_error & 0x03)), ("Bus error but neither read or write was set as the error reason\n")); - (void)bus_error; - } - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&job->session->jobs_ended); -#endif - return JOB_STATUS_END_UNKNOWN_ERR; /* reschedule */ - } -} - - -/* This function is called from the ioctl function and should return a mali_core_job pointer -to a created mali_core_job object with the data given from userspace */ -static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument) -{ - mali200_job *job200; - mali_core_job *job = NULL; - mali_core_job *previous_replaced_job; - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_uk_pp_start_job_s * user_ptr_job_input; - - user_ptr_job_input = (_mali_uk_pp_start_job_s *)argument; - - MALI_CHECK_NON_NULL(job200 = (mali200_job *) _mali_osk_malloc(sizeof(mali200_job)), _MALI_OSK_ERR_NOMEM); - _mali_osk_memset(job200, 0 , sizeof(mali200_job) ); - - /* We read job data from Userspace pointer */ - if ( NULL == _mali_osk_memcpy((void*)&job200->user_input, user_ptr_job_input, sizeof(job200->user_input)) ) - { - MALI_PRINT_ERROR( ("Mali PP: Could not copy data from U/K interface.\n")) ; - err = _MALI_OSK_ERR_FAULT; - goto function_exit; - } - - MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_get_new_job_from_user 0x%x\n", (void*)job200->user_input.user_job_ptr)); - - MALI_DEBUG_PRINT(5, ("Mali PP: Frameregs: 0x%x 0x%x 0x%x Writeback[1] 0x%x, Pri:%d; Watchd:%d\n", - job200->user_input.frame_registers[0], job200->user_input.frame_registers[1], job200->user_input.frame_registers[2], - job200->user_input.wb0_registers[1], job200->user_input.priority, - job200->user_input.watchdog_msecs)); - - if ( job200->user_input.perf_counter_flag) - { -#if defined(USING_MALI400_L2_CACHE) - MALI_DEBUG_PRINT(5, ("Mali PP: Performance counters: flag:0x%x src0:0x%x src1:0x%x l2_src0:0x%x l2_src1:0x%x\n", - job200->user_input.perf_counter_flag, - job200->user_input.perf_counter_src0, - job200->user_input.perf_counter_src1, - job200->user_input.perf_counter_l2_src0, - job200->user_input.perf_counter_l2_src1)); -#else - MALI_DEBUG_PRINT(5, ("Mali PP: Performance counters: flag:0x%x src0:0x%x src1:0x%x\n", - job200->user_input.perf_counter_flag, - job200->user_input.perf_counter_src0, - job200->user_input.perf_counter_src1)); -#endif - } - - job = GET_JOB_EMBEDDED_PTR(job200); - - job->session = session; - job->flags = user_ptr_job_input->flags; - job_priority_set(job, job200->user_input.priority); - job_watchdog_set(job, job200->user_input.watchdog_msecs ); - -#if MALI_TIMELINE_PROFILING_ENABLED - job200->pid = _mali_osk_get_pid(); - job200->tid = _mali_osk_get_tid(); -#endif - - job->abort_id = job200->user_input.abort_id; - if (mali_job_queue_full(session)) - { - user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE; - goto function_exit; - } - - /* We now know that we has a job, and a empty session slot to put it in */ - - job200->active_mask = MALI200_REG_VAL_IRQ_MASK_USED; - - /* Allocating User Return Data */ - job200->notification_obj = _mali_osk_notification_create( - _MALI_NOTIFICATION_PP_FINISHED, - sizeof(_mali_uk_pp_job_finished_s) ); - - if ( NULL == job200->notification_obj ) - { - MALI_PRINT_ERROR( ("Mali PP: Could not get notification_obj.\n")) ; - err = _MALI_OSK_ERR_NOMEM; - goto function_exit; - } - - _MALI_OSK_INIT_LIST_HEAD( &(job->list) ) ; - - MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x INPUT from user.\n", (u32)job200->user_input.user_job_ptr)) ; - - /* This should not happen since we have the checking of priority above */ - if ( _MALI_OSK_ERR_OK != mali_core_session_add_job(session, job, &previous_replaced_job)) - { - MALI_PRINT_ERROR( ("Mali PP: Internal error\n")) ; - user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE; - _mali_osk_notification_delete( job200->notification_obj ); - goto function_exit; - } - - /* If MALI_TRUE: This session had a job with lower priority which were removed. - This replaced job is given back to userspace. */ - if ( NULL != previous_replaced_job ) - { - mali200_job *previous_replaced_job200; - - previous_replaced_job200 = GET_JOB200_PTR(previous_replaced_job); - - MALI_DEBUG_PRINT(4, ("Mali PP: Replacing job: 0x%08x\n", (u32)previous_replaced_job200->user_input.user_job_ptr)) ; - - /* Copy to the input data (which also is output data) the - pointer to the job that were replaced, so that the userspace - driver can put this job in the front of its job-queue */ - - user_ptr_job_input->returned_user_job_ptr = previous_replaced_job200->user_input.user_job_ptr; - - /** @note failure to 'copy to user' at this point must not free job200, - * and so no transaction rollback required in the U/K interface */ - - /* This does not cause job200 to free: */ - user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED; - MALI_DEBUG_PRINT(5, ("subsystem_mali200_get_new_job_from_user: Job added, prev returned\n")) ; - } - else - { - /* This does not cause job200 to free: */ - user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED; - MALI_DEBUG_PRINT(5, ("subsystem_mali200_get_new_job_from_user: Job added\n")) ; - } - -function_exit: - if (_MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE == user_ptr_job_input->status - || _MALI_OSK_ERR_OK != err ) - { - _mali_osk_free(job200); - } -#if MALI_STATE_TRACKING - if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status) - { - if(job) - { - job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received); - } - } -#endif - - MALI_ERROR(err); -} - -/* This function is called from the ioctl function and should write the necessary data -to userspace telling which job was finished and the status and debuginfo for this job. -The function must also free and cleanup the input job object. */ -static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status) -{ - mali200_job *job200; - _mali_uk_pp_job_finished_s * job_out; - _mali_uk_pp_start_job_s * job_input; - mali_core_session *session; - - if (NULL == job) - { - MALI_DEBUG_PRINT(1, ("subsystem_mali200_return_job_to_user received a NULL ptr\n")); - return; - } - - job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job); - - if (NULL == job200->notification_obj) - { - MALI_DEBUG_PRINT(1, ("Found job200 with NULL notification object, abandoning userspace sending\n")); - return; - } - - job_out = job200->notification_obj->result_buffer; - job_input= &(job200->user_input); - session = job->session; - - MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x OUTPUT to user. Runtime: %dus\n", - (u32)job200->user_input.user_job_ptr, - job->render_time_usecs)) ; - - _mali_osk_memset(job_out, 0 , sizeof(_mali_uk_pp_job_finished_s)); - - job_out->user_job_ptr = job_input->user_job_ptr; - - switch( end_status ) - { - case JOB_STATUS_CONTINUE_RUN: - case JOB_STATUS_END_SUCCESS: - case JOB_STATUS_END_OOM: - case JOB_STATUS_END_ABORT: - case JOB_STATUS_END_TIMEOUT_SW: - case JOB_STATUS_END_HANG: - case JOB_STATUS_END_SEG_FAULT: - case JOB_STATUS_END_ILLEGAL_JOB: - case JOB_STATUS_END_UNKNOWN_ERR: - case JOB_STATUS_END_SHUTDOWN: - case JOB_STATUS_END_SYSTEM_UNUSABLE: - job_out->status = (mali_subsystem_job_end_code) end_status; - break; - - default: - job_out->status = JOB_STATUS_END_UNKNOWN_ERR ; - } - job_out->irq_status = job200->irq_status; - job_out->perf_counter0 = job200->perf_counter0; - job_out->perf_counter1 = job200->perf_counter1; - job_out->render_time = job->render_time_usecs; - -#if defined(USING_MALI400_L2_CACHE) - job_out->perf_counter_l2_src0 = job200->perf_counter_l2_src0; - job_out->perf_counter_l2_src1 = job200->perf_counter_l2_src1; - job_out->perf_counter_l2_val0 = job200->perf_counter_l2_val0; - job_out->perf_counter_l2_val1 = job200->perf_counter_l2_val1; - job_out->perf_counter_l2_val0_raw = job200->perf_counter_l2_val0_raw; - job_out->perf_counter_l2_val1_raw = job200->perf_counter_l2_val1_raw; -#endif - -#if MALI_STATE_TRACKING - _mali_osk_atomic_inc(&session->jobs_returned); -#endif - _mali_osk_notification_queue_send( session->notification_queue, job200->notification_obj); - job200->notification_obj = NULL; - - _mali_osk_free(job200); -} - -static void subsystem_mali200_renderunit_delete(mali_core_renderunit * core) -{ - MALI_DEBUG_PRINT(5, ("Mali PP: mali200_renderunit_delete\n")); - _mali_osk_free(core); -} - -static void mali200_reset_hard(struct mali_core_renderunit * core) -{ - const int reset_finished_loop_count = 15; - const u32 reset_wait_target_register = MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW; - const u32 reset_invalid_value = 0xC0FFE000; - const u32 reset_check_value = 0xC01A0000; - const u32 reset_default_value = 0; - int i; - - MALI_DEBUG_PRINT(5, ("subsystem_mali200_renderunit_reset_core_hard called for core %s\n", core->description)); - - mali_core_renderunit_register_write(core, reset_wait_target_register, reset_invalid_value); - - mali_core_renderunit_register_write( - core, - MALI200_REG_ADDR_MGMT_CTRL_MGMT, - MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET); - - for (i = 0; i < reset_finished_loop_count; i++) - { - mali_core_renderunit_register_write(core, reset_wait_target_register, reset_check_value); - if (reset_check_value == mali_core_renderunit_register_read(core, reset_wait_target_register)) - { - MALI_DEBUG_PRINT(5, ("Reset loop exiting after %d iterations\n", i)); - break; - } - _mali_osk_time_ubusydelay(10); - } - - if (i == reset_finished_loop_count) - { - MALI_DEBUG_PRINT(1, ("The reset loop didn't work\n")); - } - - mali_core_renderunit_register_write(core, reset_wait_target_register, reset_default_value); /* set it back to the default */ - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL); -} - -static void subsystem_mali200_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style) -{ - MALI_DEBUG_PRINT(5, ("Mali PP: renderunit_reset_core\n")); - - switch (style) - { - case MALI_CORE_RESET_STYLE_RUNABLE: - mali200_reset(core); - break; - case MALI_CORE_RESET_STYLE_DISABLE: - mali200_raw_reset(core); /* do the raw reset */ - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* then disable the IRQs */ - break; - case MALI_CORE_RESET_STYLE_HARD: - mali200_reset_hard(core); - break; - default: - MALI_DEBUG_PRINT(1, ("Unknown reset type %d\n", style)); - } -} - -static void subsystem_mali200_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core) -{ - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED); - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG); - _mali_osk_mem_barrier(); -} - -static _mali_osk_errcode_t subsystem_mali200_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core) -{ - u32 irq_readout; - - irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS); - - if ( MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout ) - { - mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG); - _mali_osk_mem_barrier(); - MALI_SUCCESS; - } - - MALI_ERROR(_MALI_OSK_ERR_FAULT); -} - -_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_start_job(session, args); -} - -_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_number_of_cores_get(session, &args->number_of_cores); -} - -_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args ) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id); - MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT); - return mali_core_subsystem_ioctl_core_version_get(session, &args->version); -} - -void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s * args) -{ - mali_core_session * session; - MALI_DEBUG_ASSERT_POINTER(args); - if (NULL == args->ctx) return; - session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id); - if (NULL == session) return; - mali_core_subsystem_ioctl_abort_job(session, args->abort_id); - -} - -#if USING_MALI_PMM - -_mali_osk_errcode_t malipp_signal_power_up( u32 core_num, mali_bool queue_only ) -{ - MALI_DEBUG_PRINT(4, ("Mali PP: signal power up core: %d - queue_only: %d\n", core_num, queue_only )); - - return( mali_core_subsystem_signal_power_up( &subsystem_mali200, core_num, queue_only ) ); -} - -_mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_only ) -{ - MALI_DEBUG_PRINT(4, ("Mali PP: signal power down core: %d - immediate_only: %d\n", core_num, immediate_only )); - - return( mali_core_subsystem_signal_power_down( &subsystem_mali200, core_num, immediate_only ) ); -} - -#endif - -#if MALI_STATE_TRACKING -u32 mali200_subsystem_dump_state(char *buf, u32 size) -{ - return mali_core_renderunit_dump_state(&subsystem_mali200, buf, size); -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_common.h b/drivers/media/video/samsung/mali/common/mali_kernel_common.h index ab6f143..b354f92 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_common.h +++ b/drivers/media/video/samsung/mali/common/mali_kernel_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -28,7 +28,6 @@ #define MALI_PANIC(fmt, args...) #endif - /* The file include several useful macros for error checking, debugging and printing. * - MALI_PRINTF(...) Do not use this function: Will be included in Release builds. * - MALI_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=MALI_DEBUG_LEVEL. @@ -129,7 +128,9 @@ } while (0) #ifdef DEBUG +#ifndef mali_debug_level extern int mali_debug_level; +#endif #define MALI_DEBUG_CODE(code) code #define MALI_DEBUG_PRINT(level, args) do { \ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.c b/drivers/media/video/samsung/mali/common/mali_kernel_core.c index be1889d..0155dfc 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_core.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -8,344 +8,805 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "mali_kernel_subsystem.h" -#include "mali_kernel_mem.h" -#include "mali_kernel_session_manager.h" -#include "mali_kernel_pp.h" -#include "mali_kernel_gp.h" +#include "mali_kernel_common.h" +#include "mali_session.h" #include "mali_osk.h" #include "mali_osk_mali.h" #include "mali_ukk.h" #include "mali_kernel_core.h" -#include "mali_kernel_rendercore.h" -#if defined USING_MALI400_L2_CACHE -#include "mali_kernel_l2_cache.h" +#include "mali_memory.h" +#include "mali_mem_validation.h" +#include "mali_mmu.h" +#include "mali_mmu_page_directory.h" +#include "mali_dlbu.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_gp_scheduler.h" +#include "mali_pp_scheduler.h" +#include "mali_cluster.h" +#include "mali_group.h" +#include "mali_pm.h" +#include "mali_pmu.h" +#include "mali_scheduler.h" +#ifdef CONFIG_MALI400_GPU_UTILIZATION +#include "mali_kernel_utilization.h" +#endif +#include "mali_l2_cache.h" +#if MALI_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" #endif -#if USING_MALI_PMM -#include "mali_pmm.h" -#endif /* USING_MALI_PMM */ - -/* platform specific set up */ -#include "mali_platform.h" - -/* Initialized when this subsystem is initialized. This is determined by the - * position in subsystems[], and so the value used to initialize this is - * determined at compile time */ -static mali_kernel_subsystem_identifier mali_subsystem_core_id = -1; /** Pointer to table of resource definitions available to the Mali driver. * _mali_osk_resources_init() sets up the pointer to this table. */ static _mali_osk_resource_t *arch_configuration = NULL; +/** Start profiling from module load? */ +int mali_boot_profiling = 0; + /** Number of resources initialized by _mali_osk_resources_init() */ static u32 num_resources; -static _mali_osk_errcode_t register_resources( _mali_osk_resource_t **arch_configuration, u32 num_resources ); - -static _mali_osk_errcode_t initialize_subsystems(void); -static void terminate_subsystems(void); - -static _mali_osk_errcode_t mali_kernel_subsystem_core_setup(mali_kernel_subsystem_identifier id); -static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier id); -static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_system_info* info); -static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); +static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN; +static u32 global_gpu_base_address = 0; +static u32 global_gpu_major_version = 0; +static u32 global_gpu_minor_version = 0; static _mali_osk_errcode_t build_system_info(void); static void cleanup_system_info(_mali_system_info *cleanup); -/** - * @brief handler for MEM_VALIDATION resources - * - * This resource handler is common to all memory systems. It provides a default - * means for validating requests to map in external memory via - * _mali_ukk_map_external_mem. In addition, if _mali_ukk_va_to_pa is - * implemented, then _mali_ukk_va_to_pa can make use of this MEM_VALIDATION - * resource. - * - * MEM_VALIDATION also provide a CPU physical to Mali physical address - * translation, for use by _mali_ukk_map_external_mem. - * - * @note MEM_VALIDATION resources are only to handle simple cases where a - * certain physical address range is allowed to be mapped in by any process, - * e.g. a framebuffer at a fixed location. If the implementor has more complex - * mapping requirements, then they must either: - * - implement their own memory validation function - * - or, integrate with UMP. - * - * @param resource The resource to handle (type MEM_VALIDATION) - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -static _mali_osk_errcode_t mali_kernel_core_resource_mem_validation(_mali_osk_resource_t * resource); - -/* MEM_VALIDATION handler state */ -typedef struct -{ - u32 phys_base; /**< Mali physical base of the memory, page aligned */ - u32 size; /**< size in bytes of the memory, multiple of page size */ - s32 cpu_usage_adjust; /**< Offset to add to Mali Physical address to obtain CPU physical address */ -} _mali_mem_validation_t; +/* system info variables */ +static _mali_osk_lock_t *system_info_lock = NULL; +static _mali_system_info *system_info = NULL; +static u32 system_info_size = 0; +static u32 first_pp_offset = 0; -#define INVALID_MEM 0xffffffff +#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */ +#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */ -static _mali_mem_validation_t mem_validator = { INVALID_MEM, INVALID_MEM, -1 }; +/* timer related */ +int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT; +int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT; -static struct mali_kernel_subsystem mali_subsystem_core = +static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset) { - mali_kernel_subsystem_core_setup, /* startup */ - mali_kernel_subsystem_core_cleanup, /* shutdown */ - NULL, /* load_complete */ - mali_kernel_subsystem_core_system_info_fill, /* system_info_fill */ - mali_kernel_subsystem_core_session_begin, /* session_begin */ - NULL, /* session_end */ - NULL, /* broadcast_notification */ -#if MALI_STATE_TRACKING - NULL, /* dump_state */ -#endif -}; + int i; + u32 addr = global_gpu_base_address + offset; -static struct mali_kernel_subsystem * subsystems[] = -{ + for (i = 0; i < num_resources; i++) + { + if (type == arch_configuration[i].type && arch_configuration[i].base == addr) + { + return &(arch_configuration[i]); + } + } -#if USING_MALI_PMM - /* The PMM must be initialized before any cores - including L2 cache */ - &mali_subsystem_pmm, -#endif + return NULL; +} - /* always included */ - &mali_subsystem_memory, +static u32 mali_count_resources(_mali_osk_resource_type_t type) +{ + int i; + u32 retval = 0; - /* The rendercore subsystem must be initialized before any subsystem based on the - * rendercores is started e.g. mali_subsystem_mali200 and mali_subsystem_gp2 */ - &mali_subsystem_rendercore, + for (i = 0; i < num_resources; i++) + { + if (type == arch_configuration[i].type) + { + retval++; + } + } - /* add reference to the subsystem */ - &mali_subsystem_mali200, + return retval; +} - /* add reference to the subsystem */ - &mali_subsystem_gp2, -#if defined USING_MALI400_L2_CACHE - &mali_subsystem_l2_cache, -#endif +static _mali_osk_errcode_t mali_parse_gpu_base_and_first_pp_offset_address(void) +{ + int i; + _mali_osk_resource_t *first_gp_resource = NULL; + _mali_osk_resource_t *first_pp_resource = NULL; + + for (i = 0; i < num_resources; i++) + { + if (MALI_GP == arch_configuration[i].type) + { + if (NULL == first_gp_resource || first_gp_resource->base > arch_configuration[i].base) + { + first_gp_resource = &(arch_configuration[i]); + } + } + if (MALI_PP == arch_configuration[i].type) + { + if (NULL == first_pp_resource || first_pp_resource->base > arch_configuration[i].base) + { + first_pp_resource = &(arch_configuration[i]); + } + } + } - /* always included */ - /* NOTE Keep the core entry at the tail of the list */ - &mali_subsystem_core -}; + if (NULL == first_gp_resource || NULL == first_pp_resource) + { + MALI_PRINT_ERROR(("No GP+PP core specified in config file\n")); + return _MALI_OSK_ERR_FAULT; + } -#define SUBSYSTEMS_COUNT ( sizeof(subsystems) / sizeof(subsystems[0]) ) + if (first_gp_resource->base < first_pp_resource->base) + { + /* GP is first, so we are dealing with Mali-300, Mali-400 or Mali-450 */ + global_gpu_base_address = first_gp_resource->base; + first_pp_offset = 0x8000; + } + else + { + /* PP is first, so we are dealing with Mali-200 */ + global_gpu_base_address = first_pp_resource->base; + first_pp_offset = 0x0; + } + MALI_SUCCESS; +} -/* Pointers to this type available as incomplete struct in mali_kernel_session_manager.h */ -struct mali_session_data +static _mali_osk_errcode_t mali_parse_product_info(void) { - void * subsystem_data[SUBSYSTEMS_COUNT]; - _mali_osk_notification_queue_t * ioctl_queue; -}; + _mali_osk_resource_t *first_pp_resource = NULL; -static mali_kernel_resource_registrator resource_handler[RESOURCE_TYPE_COUNT] = { NULL, }; + /* Find the first PP core */ + first_pp_resource = mali_find_resource(MALI_PP, first_pp_offset); + if (NULL != first_pp_resource) + { + /* Create a dummy PP object for this core so that we can read the version register */ + struct mali_group *group = mali_group_create(NULL, NULL); + if (NULL != group) + { + /*struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group, 0);*/ + struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group); + if (NULL != pp_core) + { + u32 pp_version = mali_pp_core_get_version(pp_core); + mali_pp_delete(pp_core); + mali_group_delete(group); + + global_gpu_major_version = (pp_version >> 8) & 0xFF; + global_gpu_minor_version = pp_version & 0xFF; + + switch (pp_version >> 16) + { + case MALI200_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI200; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + case MALI300_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI300; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + case MALI400_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI400; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + case MALI450_PP_PRODUCT_ID: + global_product_id = _MALI_PRODUCT_ID_MALI450; + MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version)); + break; + default: + MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version)); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; + } + else + { + MALI_PRINT_ERROR(("Failed to create initial PP object\n")); + } + } + else + { + MALI_PRINT_ERROR(("Failed to create initial group object\n")); + } + } + else + { + MALI_PRINT_ERROR(("First PP core not specified in config file\n")); + } -/* system info variables */ -static _mali_osk_lock_t *system_info_lock = NULL; -static _mali_system_info * system_info = NULL; -static u32 system_info_size = 0; + return _MALI_OSK_ERR_FAULT; +} -/* is called from OS specific driver entry point */ -_mali_osk_errcode_t mali_kernel_constructor( void ) +static void mali_delete_clusters(void) { - _mali_osk_errcode_t err; - - err = mali_platform_init(); - if (_MALI_OSK_ERR_OK != err) goto error1; + u32 i; + u32 number_of_clusters = mali_cluster_get_glob_num_clusters(); - err = _mali_osk_init(); - if (_MALI_OSK_ERR_OK != err) goto error2; + for (i = 0; i < number_of_clusters; i++) + { + mali_cluster_delete(mali_cluster_get_global_cluster(i)); + } +} - MALI_DEBUG_PRINT(2, ("\n")); - MALI_DEBUG_PRINT(2, ("Inserting Mali v%d device driver. \n",_MALI_API_VERSION)); - MALI_DEBUG_PRINT(2, ("Compiled: %s, time: %s.\n", __DATE__, __TIME__)); - MALI_DEBUG_PRINT(2, ("Svn revision: %s\n", SVN_REV_STRING)); +static _mali_osk_errcode_t mali_create_cluster(_mali_osk_resource_t *resource) +{ + if (NULL != resource) + { + struct mali_l2_cache_core *l2_cache; - err = initialize_subsystems(); - if (_MALI_OSK_ERR_OK != err) goto error3; + if (mali_l2_cache_core_get_glob_num_l2_cores() >= mali_l2_cache_core_get_max_num_l2_cores()) + { + MALI_PRINT_ERROR(("Found too many L2 cache core objects, max %u is supported\n", mali_l2_cache_core_get_max_num_l2_cores())); + return _MALI_OSK_ERR_FAULT; + } - MALI_PRINT(("Mali device driver %s loaded\n", SVN_REV_STRING)); + MALI_DEBUG_PRINT(3, ("Found L2 cache %s, starting new cluster\n", resource->description)); - MALI_SUCCESS; + /*l2_cache = mali_l2_cache_create(resource, global_num_l2_cache_cores);*/ + l2_cache = mali_l2_cache_create(resource); + if (NULL == l2_cache) + { + MALI_PRINT_ERROR(("Failed to create L2 cache object\n")); + return _MALI_OSK_ERR_FAULT; + } -error3: - MALI_PRINT(("Mali subsystems failed\n")); - _mali_osk_term(); -error2: - MALI_PRINT(("Mali device driver init failed\n")); - if (_MALI_OSK_ERR_OK != mali_platform_deinit()) + if (NULL == mali_cluster_create(l2_cache)) + { + MALI_PRINT_ERROR(("Failed to create cluster object\n")); + mali_l2_cache_delete(l2_cache); + return _MALI_OSK_ERR_FAULT; + } + } + else { - MALI_PRINT(("Failed to deinit platform\n")); + mali_cluster_create(NULL); + if (NULL == mali_cluster_get_global_cluster(0)) + { + MALI_PRINT_ERROR(("Failed to create cluster object\n")); + return _MALI_OSK_ERR_FAULT; + } } -error1: - MALI_PRINT(("Failed to init platform\n")); - MALI_ERROR(err); + + MALI_DEBUG_PRINT(3, ("Created cluster object\n")); + return _MALI_OSK_ERR_OK; } -/* is called from OS specific driver exit point */ -void mali_kernel_destructor( void ) +static _mali_osk_errcode_t mali_parse_config_cluster(void) { - MALI_DEBUG_PRINT(2, ("\n")); - MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION)); -#if USING_MALI_PMM - malipmm_force_powerup(); -#endif - terminate_subsystems(); /* subsystems are responsible for their registered resources */ - _mali_osk_term(); - - if (_MALI_OSK_ERR_OK != mali_platform_deinit()) + if (_MALI_PRODUCT_ID_MALI200 == global_product_id) { - MALI_PRINT(("Failed to deinit platform\n")); + /* Create dummy cluster without L2 cache */ + return mali_create_cluster(NULL); } - MALI_DEBUG_PRINT(2, ("Module unloaded.\n")); -} + else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || _MALI_PRODUCT_ID_MALI400 == global_product_id) + { + _mali_osk_resource_t *l2_resource = mali_find_resource(MALI_L2, 0x1000); + if (NULL == l2_resource) + { + MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n")); + return _MALI_OSK_ERR_FAULT; + } -_mali_osk_errcode_t register_resources( _mali_osk_resource_t **arch_configuration, u32 num_resources ) -{ - _mali_osk_resource_t *arch_resource = *arch_configuration; - u32 i; -#if USING_MALI_PMM - u32 is_pmu_first_resource = 1; -#endif /* USING_MALI_PMM */ - - /* loop over arch configuration */ - for (i = 0; i < num_resources; ++i, arch_resource++) - { - if ( (arch_resource->type >= RESOURCE_TYPE_FIRST) && - (arch_resource->type < RESOURCE_TYPE_COUNT) && - (NULL != resource_handler[arch_resource->type]) - ) - { -#if USING_MALI_PMM - if((arch_resource->type != PMU) && (is_pmu_first_resource == 1)) + return mali_create_cluster(l2_resource); + } + else if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + /* + * L2 for GP at 0x10000 + * L2 for PP0-3 at 0x01000 + * L2 for PP4-7 at 0x11000 (optional) + */ + + _mali_osk_resource_t *l2_gp_resource; + _mali_osk_resource_t *l2_pp_grp0_resource; + _mali_osk_resource_t *l2_pp_grp1_resource; + + /* Make cluster for GP's L2 */ + l2_gp_resource = mali_find_resource(MALI_L2, 0x10000); + if (NULL != l2_gp_resource) + { + _mali_osk_errcode_t ret; + MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for GP\n")); + ret = mali_create_cluster(l2_gp_resource); + if (_MALI_OSK_ERR_OK != ret) { - _mali_osk_resource_t mali_pmu_virtual_resource; - mali_pmu_virtual_resource.type = PMU; - mali_pmu_virtual_resource.description = "Virtual PMU"; - mali_pmu_virtual_resource.base = 0x00000000; - mali_pmu_virtual_resource.cpu_usage_adjust = 0; - mali_pmu_virtual_resource.size = 0; - mali_pmu_virtual_resource.irq = 0; - mali_pmu_virtual_resource.flags = 0; - mali_pmu_virtual_resource.mmu_id = 0; - mali_pmu_virtual_resource.alloc_order = 0; - MALI_CHECK_NO_ERROR(resource_handler[mali_pmu_virtual_resource.type](&mali_pmu_virtual_resource)); + return ret; } - is_pmu_first_resource = 0; -#endif /* USING_MALI_PMM */ + } + else + { + MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n")); + return _MALI_OSK_ERR_FAULT; + } - MALI_CHECK_NO_ERROR(resource_handler[arch_resource->type](arch_resource)); - /* the subsystem shutdown process will release all the resources already registered */ + /* Make cluster for first PP core group */ + l2_pp_grp0_resource = mali_find_resource(MALI_L2, 0x1000); + if (NULL != l2_pp_grp0_resource) + { + _mali_osk_errcode_t ret; + MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n")); + ret = mali_create_cluster(l2_pp_grp0_resource); + if (_MALI_OSK_ERR_OK != ret) + { + return ret; + } } else { - MALI_DEBUG_PRINT(1, ("No handler installed for resource %s, type %d\n", arch_resource->description, arch_resource->type)); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Second PP core group is optional, don't fail if we don't find it */ + l2_pp_grp1_resource = mali_find_resource(MALI_L2, 0x11000); + if (NULL != l2_pp_grp1_resource) + { + _mali_osk_errcode_t ret; + MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n")); + ret = mali_create_cluster(l2_pp_grp1_resource); + if (_MALI_OSK_ERR_OK != ret) + { + return ret; + } } } - MALI_SUCCESS; + return _MALI_OSK_ERR_OK; } -static _mali_osk_errcode_t initialize_subsystems(void) +static _mali_osk_errcode_t mali_create_group(struct mali_cluster *cluster, + _mali_osk_resource_t *resource_mmu, + _mali_osk_resource_t *resource_gp, + _mali_osk_resource_t *resource_pp) { - int i, j; - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; /* default error code */ + struct mali_mmu_core *mmu; + struct mali_group *group; + struct mali_pp_core *pp; - MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT); + MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description)); - for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) + /* Create the MMU object */ + mmu = mali_mmu_create(resource_mmu); + if (NULL == mmu) { - if (NULL != subsystems[i]->startup) + MALI_PRINT_ERROR(("Failed to create MMU object\n")); + return _MALI_OSK_ERR_FAULT; + } + + /* Create the group object */ + group = mali_group_create(cluster, mmu); + if (NULL == group) + { + MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description)); + mali_mmu_delete(mmu); + return _MALI_OSK_ERR_FAULT; + } + + /* Set pointer back to group in mmu.*/ + mali_mmu_set_group(mmu, group); + + /* Add this group to current cluster */ + mali_cluster_add_group(cluster, group); + + if (NULL != resource_gp) + { + /* Create the GP core object inside this group */ + /* global_gp_core = mali_gp_create(resource_gp, group); */ + if (NULL == mali_gp_create(resource_gp, group)) { - /* the subsystem has a startup function defined */ - err = subsystems[i]->startup(i); /* the subsystem identifier is the offset in our subsystems array */ - if (_MALI_OSK_ERR_OK != err) goto cleanup; + /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */ + MALI_PRINT_ERROR(("Failed to create GP object\n")); + return _MALI_OSK_ERR_FAULT; } + + /* Add GP object to this group */ + MALI_DEBUG_PRINT(3, ("Adding GP %s to group\n", resource_gp->description)); + mali_group_add_gp_core(group, mali_gp_get_global_gp_core()); } - for (j = 0; j < (int)SUBSYSTEMS_COUNT; ++j) + if (NULL != resource_pp) { - if (NULL != subsystems[j]->load_complete) + /* Create the PP core object inside this group */ + pp = mali_pp_create(resource_pp, group); + + if (NULL == pp) { - /* the subsystem has a load_complete function defined */ - err = subsystems[j]->load_complete(j); - if (_MALI_OSK_ERR_OK != err) goto cleanup; + /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */ + MALI_PRINT_ERROR(("Failed to create PP object\n")); + return _MALI_OSK_ERR_FAULT; } + + /* Add PP object to this group */ + MALI_DEBUG_PRINT(3, ("Adding PP %s to group\n", resource_pp->description)); + mali_group_add_pp_core(group, pp); } - /* All systems loaded and resources registered */ - /* Build system info */ - if (_MALI_OSK_ERR_OK != build_system_info()) goto cleanup; + return _MALI_OSK_ERR_OK; +} + +static _mali_osk_errcode_t mali_parse_config_groups(void) +{ + if (_MALI_PRODUCT_ID_MALI200 == global_product_id) + { + _mali_osk_resource_t *resource_gp; + _mali_osk_resource_t *resource_pp; + _mali_osk_resource_t *resource_mmu; + + MALI_DEBUG_ASSERT(1 == mali_cluster_get_glob_num_clusters()); - MALI_SUCCESS; /* all ok */ + resource_gp = mali_find_resource(MALI_GP, 0x02000); + resource_pp = mali_find_resource(MALI_PP, 0x00000); + resource_mmu = mali_find_resource(MMU, 0x03000); -cleanup: - /* i is index of subsystem which failed to start, all indices before that has to be shut down */ - for (i = i - 1; i >= 0; --i) + if (NULL == resource_mmu || NULL == resource_gp || NULL == resource_pp) + { + /* Missing mandatory core(s) */ + return _MALI_OSK_ERR_FAULT; + } + + /*return mali_create_group(global_clusters[0], resource_mmu, resource_gp, resource_pp);*/ + return mali_create_group(mali_cluster_get_global_cluster(0), resource_mmu, resource_gp, resource_pp); + } + else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || + _MALI_PRODUCT_ID_MALI400 == global_product_id || + _MALI_PRODUCT_ID_MALI450 == global_product_id) { - /* the subsystem identifier is the offset in our subsystems array */ - /* Call possible shutdown notficiation functions */ - if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i); + _mali_osk_errcode_t err; + int cluster_id_gp = 0; + int cluster_id_pp_grp0 = 0; + int cluster_id_pp_grp1 = 0; + int i; + _mali_osk_resource_t *resource_gp; + _mali_osk_resource_t *resource_gp_mmu; + _mali_osk_resource_t *resource_pp[mali_pp_get_max_num_pp_cores()]; + _mali_osk_resource_t *resource_pp_mmu[mali_pp_get_max_num_pp_cores()]; + u32 max_num_pp_cores = mali_pp_get_max_num_pp_cores(); + + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + /* Mali-450 has separate L2s for GP, and PP core group(s) */ + cluster_id_pp_grp0 = 1; + cluster_id_pp_grp1 = 2; + } + + resource_gp = mali_find_resource(MALI_GP, 0x00000); + resource_gp_mmu = mali_find_resource(MMU, 0x03000); + resource_pp[0] = mali_find_resource(MALI_PP, 0x08000); + resource_pp[1] = mali_find_resource(MALI_PP, 0x0A000); + resource_pp[2] = mali_find_resource(MALI_PP, 0x0C000); + resource_pp[3] = mali_find_resource(MALI_PP, 0x0E000); + resource_pp[4] = mali_find_resource(MALI_PP, 0x28000); + resource_pp[5] = mali_find_resource(MALI_PP, 0x2A000); + resource_pp[6] = mali_find_resource(MALI_PP, 0x2C000); + resource_pp[7] = mali_find_resource(MALI_PP, 0x2E000); + resource_pp_mmu[0] = mali_find_resource(MMU, 0x04000); + resource_pp_mmu[1] = mali_find_resource(MMU, 0x05000); + resource_pp_mmu[2] = mali_find_resource(MMU, 0x06000); + resource_pp_mmu[3] = mali_find_resource(MMU, 0x07000); + resource_pp_mmu[4] = mali_find_resource(MMU, 0x1C000); + resource_pp_mmu[5] = mali_find_resource(MMU, 0x1D000); + resource_pp_mmu[6] = mali_find_resource(MMU, 0x1E000); + resource_pp_mmu[7] = mali_find_resource(MMU, 0x1F000); + + if (NULL == resource_gp || NULL == resource_gp_mmu || NULL == resource_pp[0] || NULL == resource_pp_mmu[0]) + { + /* Missing mandatory core(s) */ + MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU (0x%08X, 0x%08X, 0x%08X, 0x%08X)\n", + resource_gp, resource_gp_mmu, resource_pp[0], resource_pp_mmu[0])); + return _MALI_OSK_ERR_FAULT; + } + + MALI_DEBUG_ASSERT(1 <= mali_cluster_get_glob_num_clusters()); + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_gp), resource_gp_mmu, resource_gp, NULL); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + + /* Create group for first (and mandatory) PP core */ + MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */ + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[0], NULL, resource_pp[0]); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + + /* Create groups for rest of the cores in the first PP core group */ + for (i = 1; i < 4; i++) /* First half of the PP cores belong to first core group */ + { + if (NULL != resource_pp[i]) + { + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[i], NULL, resource_pp[i]); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + } + } + + /* Create groups for cores in the second PP core group */ + for (i = 4; i < max_num_pp_cores; i++) /* Second half of the PP cores belong to second core group */ + { + if (NULL != resource_pp[i]) + { + MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= 2); /* Only Mali-450 have more than 4 PPs, and these cores belong to second core group */ + err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp1), resource_pp_mmu[i], NULL, resource_pp[i]); + if (err != _MALI_OSK_ERR_OK) + { + return err; + } + } + } } - _mali_osk_lock_term( system_info_lock ); - MALI_ERROR(err); /* err is what the module which failed its startup returned, or the default */ + return _MALI_OSK_ERR_OK; } -static void terminate_subsystems(void) +static _mali_osk_errcode_t mali_parse_config_pmu(void) { - int i; - /* shut down subsystems in reverse order from startup */ - for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i) + _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; + _mali_osk_resource_t *resource_pmu; + u32 number_of_pp_cores; + u32 number_of_l2_caches; + + resource_pmu = mali_find_resource(PMU, 0x02000); + number_of_pp_cores = mali_count_resources(MALI_PP); + number_of_l2_caches = mali_count_resources(MALI_L2); + + if (NULL != resource_pmu) { - /* the subsystem identifier is the offset in our subsystems array */ - if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i); + if (NULL == mali_pmu_create(resource_pmu, number_of_pp_cores, number_of_l2_caches)) + { + err = _MALI_OSK_ERR_FAULT; + } } - if (system_info_lock) _mali_osk_lock_term( system_info_lock ); - - /* Free _mali_system_info struct */ - cleanup_system_info(system_info); + return err; } -void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data) +static _mali_osk_errcode_t mali_parse_config_memory(void) { int i; + _mali_osk_errcode_t ret; - for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) + for(i = 0; i < num_resources; i++) { - if (NULL != subsystems[i]->broadcast_notification) + switch(arch_configuration[i].type) { - subsystems[i]->broadcast_notification(message, data); + case OS_MEMORY: + ret = mali_memory_core_resource_os_memory(&arch_configuration[i]); + if (_MALI_OSK_ERR_OK != ret) + { + MALI_PRINT_ERROR(("Failed to register OS_MEMORY\n")); + mali_memory_terminate(); + return ret; + } + break; + case MEMORY: + ret = mali_memory_core_resource_dedicated_memory(&arch_configuration[i]); + if (_MALI_OSK_ERR_OK != ret) + { + MALI_PRINT_ERROR(("Failed to register MEMORY\n")); + mali_memory_terminate(); + return ret; + } + break; + case MEM_VALIDATION: + ret = mali_mem_validation_add_range(&arch_configuration[i]); + if (_MALI_OSK_ERR_OK != ret) + { + MALI_PRINT_ERROR(("Failed to register MEM_VALIDATION\n")); + mali_memory_terminate(); + return ret; + } + break; + default: + break; } } + return _MALI_OSK_ERR_OK; } -static _mali_osk_errcode_t mali_kernel_subsystem_core_setup(mali_kernel_subsystem_identifier id) +_mali_osk_errcode_t mali_initialize_subsystems(void) { - mali_subsystem_core_id = id; + _mali_osk_errcode_t err; + mali_bool is_pmu_enabled; - /* Register our own resources */ - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MEM_VALIDATION, mali_kernel_core_resource_mem_validation)); + MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT); - /* parse the arch resource definition and tell all the subsystems */ - /* this is why the core subsystem has to be specified last in the subsystem array */ - MALI_CHECK_NO_ERROR(_mali_osk_resources_init(&arch_configuration, &num_resources)); + err = mali_session_initialize(); + if (_MALI_OSK_ERR_OK != err) goto session_init_failed; - MALI_CHECK_NO_ERROR(register_resources(&arch_configuration, num_resources)); +#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 - /* resource parsing succeeded and the subsystem have corretly accepted their resources */ - MALI_SUCCESS; + /* Build dummy system info. Will be removed in the future. */ + err = build_system_info(); + if (_MALI_OSK_ERR_OK != err) goto build_system_info_failed; + + /* Get data from config.h */ + err = _mali_osk_resources_init(&arch_configuration, &num_resources); + if (_MALI_OSK_ERR_OK != err) goto osk_resources_init_failed; + + /* Initialize driver subsystems */ + err = mali_memory_initialize(); + if (_MALI_OSK_ERR_OK != err) goto memory_init_failed; + + /* Configure memory early. Memory allocation needed for mali_mmu_initialize. */ + err = mali_parse_config_memory(); + if (_MALI_OSK_ERR_OK != err) goto parse_memory_config_failed; + + /* Parsing the GPU base address and first pp offset */ + err = mali_parse_gpu_base_and_first_pp_offset_address(); + if (_MALI_OSK_ERR_OK != err) goto parse_gpu_base_address_failed; + + /* Initialize the MALI PMU */ + err = mali_parse_config_pmu(); + if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed; + + is_pmu_enabled = mali_pmu_get_global_pmu_core() != NULL ? MALI_TRUE : MALI_FALSE; + + /* Initialize the power management module */ + err = mali_pm_initialize(); + if (_MALI_OSK_ERR_OK != err) goto pm_init_failed; + + /* Make sure the power stays on for the rest of this function */ + mali_pm_always_on(MALI_TRUE); + + /* Detect which Mali GPU we are dealing with */ + err = mali_parse_product_info(); + if (_MALI_OSK_ERR_OK != err) goto product_info_parsing_failed; + + /* The global_product_id is now populated with the correct Mali GPU */ + + /* Initialize MMU module */ + err = mali_mmu_initialize(); + if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed; + + /* Initialize the DLBU module for Mali-450 */ + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + err = mali_dlbu_initialize(); + if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed; + } + + /* Start configuring the actual Mali hardware. */ + err = mali_parse_config_cluster(); + if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed; + err = mali_parse_config_groups(); + if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed; + + /* Initialize the schedulers */ + err = mali_scheduler_initialize(); + if (_MALI_OSK_ERR_OK != err) goto scheduler_init_failed; + err = mali_gp_scheduler_initialize(); + if (_MALI_OSK_ERR_OK != err) goto gp_scheduler_init_failed; + err = mali_pp_scheduler_initialize(); + if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed; + +#ifdef CONFIG_MALI400_GPU_UTILIZATION + /* Initialize the GPU utilization tracking */ + err = mali_utilization_init(); + if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed; +#endif + + /* We no longer need to stay */ + mali_pm_always_on(MALI_FALSE); + MALI_SUCCESS; /* all ok */ + + /* Error handling */ +#ifdef CONFIG_MALI400_GPU_UTILIZATION +utilization_init_failed: + mali_pp_scheduler_terminate(); +#endif +pp_scheduler_init_failed: + mali_gp_scheduler_terminate(); +gp_scheduler_init_failed: + mali_scheduler_terminate(); +scheduler_init_failed: +config_parsing_failed: + mali_delete_clusters(); /* Delete clusters even if config parsing failed. */ + if (_MALI_PRODUCT_ID_MALI450 == global_product_id) + { + mali_dlbu_terminate(); + } +dlbu_init_failed: + mali_mmu_terminate(); +mmu_init_failed: + /* Nothing to roll back */ +product_info_parsing_failed: + mali_pm_terminate(); +pm_init_failed: + if (is_pmu_enabled) + { + mali_pmu_delete(mali_pmu_get_global_pmu_core()); + } +parse_pmu_config_failed: +parse_gpu_base_address_failed: +parse_memory_config_failed: + mali_memory_terminate(); +memory_init_failed: + _mali_osk_resources_term(&arch_configuration, num_resources); +osk_resources_init_failed: + cleanup_system_info(system_info); +build_system_info_failed: +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_term(); +#endif + mali_session_terminate(); +session_init_failed: + return err; +} + +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); + + cleanup_system_info(system_info); + +#if MALI_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_term(); +#endif + + mali_session_terminate(); + + if (NULL != system_info_lock) + { + _mali_osk_lock_term( system_info_lock ); + } +} + +_mali_product_id_t mali_kernel_core_get_product_id(void) +{ + return global_product_id; } -static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier id) +void mali_kernel_core_wakeup(void) { - _mali_osk_resources_term(&arch_configuration, num_resources); + u32 i; + u32 glob_num_clusters = mali_cluster_get_glob_num_clusters(); + struct mali_cluster *cluster; + + for (i = 0; i < glob_num_clusters; i++) + { + cluster = mali_cluster_get_global_cluster(i); + mali_cluster_reset(cluster); + } } static void cleanup_system_info(_mali_system_info *cleanup) @@ -373,11 +834,10 @@ static void cleanup_system_info(_mali_system_info *cleanup) _mali_osk_free(cleanup); } +/* Build a dummy system info struct. User space still need this. */ static _mali_osk_errcode_t build_system_info(void) { - unsigned int i; - int err = _MALI_OSK_ERR_FAULT; - _mali_system_info * new_info, * cleanup; + _mali_system_info * new_info; _mali_core_info * current_core; _mali_mem_info * current_mem; u32 new_size = 0; @@ -387,19 +847,25 @@ static _mali_osk_errcode_t build_system_info(void) _mali_osk_memset(new_info, 0, sizeof(_mali_system_info)); - /* if an error happens during any of the system_info_fill calls cleanup the new info structs */ - cleanup = new_info; + /* fill in the info */ + new_info->has_mmu = 1; + new_info->drivermode = _MALI_DRIVER_MODE_NORMAL; - /* ask each subsystems to fill in their info */ - for (i = 0; i < SUBSYSTEMS_COUNT; ++i) + new_info->core_info = NULL; /* Not used by user space */ + + new_info->mem_info = _mali_osk_calloc(1, sizeof(_mali_mem_info)); + if(NULL == new_info->mem_info) { - if (NULL != subsystems[i]->system_info_fill) - { - err = subsystems[i]->system_info_fill(new_info); - if (_MALI_OSK_ERR_OK != err) goto error_exit; - } + _mali_osk_free(new_info); + return _MALI_OSK_ERR_NOMEM; } + new_info->mem_info->size = 1024 * 1024 * 1024; /* 1GiB */ + new_info->mem_info->flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE; + new_info->mem_info->maximum_order_supported = 30; + new_info->mem_info->identifier = 0; + new_info->mem_info->next = NULL; + /* building succeeded, calculate the size */ /* size needed of the system info struct itself */ @@ -420,8 +886,6 @@ static _mali_osk_errcode_t build_system_info(void) /* lock system info access so a user wont't get a corrupted version */ _mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW ); - /* cleanup the old one */ - cleanup = system_info; /* set new info */ system_info = new_info; system_info_size = new_size; @@ -430,25 +894,15 @@ static _mali_osk_errcode_t build_system_info(void) _mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW ); /* ok result */ - err = _MALI_OSK_ERR_OK; - - /* we share the cleanup routine with the error case */ -error_exit: - if (NULL == cleanup) MALI_ERROR((_mali_osk_errcode_t)err); /* no cleanup needed, return what err contains */ - - /* cleanup */ - cleanup_system_info(cleanup); - - /* return whatever err is, we could end up here in both the error and success cases */ - MALI_ERROR((_mali_osk_errcode_t)err); + return _MALI_OSK_ERR_OK; } _mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args ) { - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - /* check compatability */ + /* check compatability */ if ( args->version == _MALI_UK_API_VERSION ) { args->compatible = 1; @@ -461,14 +915,14 @@ _mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args args->version = _MALI_UK_API_VERSION; /* report our version */ /* success regardless of being compatible or not */ - MALI_SUCCESS; + MALI_SUCCESS; } _mali_osk_errcode_t _mali_ukk_get_system_info_size(_mali_uk_get_system_info_size_s *args) { - MALI_DEBUG_ASSERT_POINTER(args); - args->size = system_info_size; - MALI_SUCCESS; + MALI_DEBUG_ASSERT_POINTER(args); + args->size = system_info_size; + MALI_SUCCESS; } _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args ) @@ -477,12 +931,12 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args _mali_mem_info * current_mem; _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; void * current_write_pos, ** current_patch_pos; - u32 adjust_ptr_base; + u32 adjust_ptr_base; /* check input */ MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS); /* lock the system info */ _mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW ); @@ -491,20 +945,20 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args if (args->size < system_info_size) goto exit_when_locked; /* we build a copy of system_info in the user space buffer specified by the user and - * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may - * indicate a different base address for patching the pointers (normally the - * address of the provided system_info buffer would be used). This is helpful when - * the system_info buffer needs to get copied to user space and the pointers need - * to be in user space. - */ - if (0 == args->ukk_private) - { - adjust_ptr_base = (u32)args->system_info; - } - else - { - adjust_ptr_base = args->ukk_private; - } + * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may + * indicate a different base address for patching the pointers (normally the + * address of the provided system_info buffer would be used). This is helpful when + * the system_info buffer needs to get copied to user space and the pointers need + * to be in user space. + */ + if (0 == args->ukk_private) + { + adjust_ptr_base = (u32)args->system_info; + } + else + { + adjust_ptr_base = args->ukk_private; + } /* copy each struct into the buffer, and update its pointers */ current_write_pos = (void *)args->system_info; @@ -557,56 +1011,56 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args err = _MALI_OSK_ERR_OK; exit_when_locked: _mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW ); - MALI_ERROR(err); + MALI_ERROR(err); } _mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args ) { _mali_osk_errcode_t err; - _mali_osk_notification_t * notification; - _mali_osk_notification_queue_t *queue; + _mali_osk_notification_t *notification; + _mali_osk_notification_queue_t *queue; - /* check input */ + /* check input */ MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id); + queue = ((struct mali_session_data *)args->ctx)->ioctl_queue; /* if the queue does not exist we're currently shutting down */ if (NULL == queue) { MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n")); - args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS; + args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS; MALI_SUCCESS; } - /* receive a notification, might sleep */ + /* receive a notification, might sleep */ err = _mali_osk_notification_queue_receive(queue, ¬ification); if (_MALI_OSK_ERR_OK != err) { - MALI_ERROR(err); /* errcode returned, pass on to caller */ - } + MALI_ERROR(err); /* errcode returned, pass on to caller */ + } /* copy the buffer to the user */ - args->type = (_mali_uk_notification_type)notification->notification_type; - _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size); + args->type = (_mali_uk_notification_type)notification->notification_type; + _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size); /* finished with the notification */ _mali_osk_notification_delete( notification ); - MALI_SUCCESS; /* all ok */ + MALI_SUCCESS; /* all ok */ } _mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args ) { _mali_osk_notification_t * notification; - _mali_osk_notification_queue_t *queue; + _mali_osk_notification_queue_t *queue; - /* check input */ + /* check input */ MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id); + queue = ((struct mali_session_data *)args->ctx)->ioctl_queue; /* if the queue does not exist we're currently shutting down */ if (NULL == queue) @@ -618,294 +1072,115 @@ _mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *a notification = _mali_osk_notification_create(args->type, 0); if ( NULL == notification) { - MALI_PRINT_ERROR( ("Failed to create notification object\n")) ; + MALI_PRINT_ERROR( ("Failed to create notification object\n")); return _MALI_OSK_ERR_NOMEM; } _mali_osk_notification_queue_send(queue, notification); - MALI_SUCCESS; /* all ok */ -} - -static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_system_info* info) -{ - MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS); - - info->drivermode = _MALI_DRIVER_MODE_NORMAL; - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue) -{ - MALI_CHECK_NON_NULL(slot, _MALI_OSK_ERR_INVALID_ARGS); - *slot = queue; - MALI_SUCCESS; -} - -/* MEM_VALIDATION resource handler */ -static _mali_osk_errcode_t mali_kernel_core_resource_mem_validation(_mali_osk_resource_t * resource) -{ - /* Check that no other MEM_VALIDATION resources exist */ - MALI_CHECK( ((u32)-1) == mem_validator.phys_base, _MALI_OSK_ERR_FAULT ); - - /* Check restrictions on page alignment */ - MALI_CHECK( 0 == (resource->base & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT ); - MALI_CHECK( 0 == (resource->size & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT ); - MALI_CHECK( 0 == (resource->cpu_usage_adjust & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT ); - - mem_validator.phys_base = resource->base; - mem_validator.size = resource->size; - mem_validator.cpu_usage_adjust = resource->cpu_usage_adjust; - MALI_DEBUG_PRINT( 2, ("Memory Validator '%s' installed for Mali physical address base==0x%08X, size==0x%08X, cpu_adjust==0x%08X\n", - resource->description, mem_validator.phys_base, mem_validator.size, mem_validator.cpu_usage_adjust )); - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_kernel_core_translate_cpu_to_mali_phys_range( u32 *phys_base, u32 size ) -{ - u32 mali_phys_base; - - mali_phys_base = *phys_base - mem_validator.cpu_usage_adjust; - - MALI_CHECK( 0 == ( mali_phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT ); - MALI_CHECK( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT ); - - MALI_CHECK_NO_ERROR( mali_kernel_core_validate_mali_phys_range( mali_phys_base, size ) ); - - *phys_base = mali_phys_base; - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size ) -{ - MALI_CHECK_GOTO( 0 == ( phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), failure ); - MALI_CHECK_GOTO( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), failure ); - - if ( phys_base >= mem_validator.phys_base - && (phys_base + size) >= mem_validator.phys_base - && phys_base <= (mem_validator.phys_base + mem_validator.size) - && (phys_base + size) <= (mem_validator.phys_base + mem_validator.size) ) - { - MALI_SUCCESS; - } - - failure: - MALI_PRINTF( ("*******************************************************************************\n") ); - MALI_PRINTF( ("MALI PHYSICAL RANGE VALIDATION ERROR!\n") ); - MALI_PRINTF( ("\n") ); - MALI_PRINTF( ("We failed to validate a Mali-Physical range that the user-side wished to map in\n") ); - MALI_PRINTF( ("\n") ); - MALI_PRINTF( ("It is likely that the user-side wished to do Direct Rendering, but a suitable\n") ); - MALI_PRINTF( ("address range validation mechanism has not been correctly setup\n") ); - MALI_PRINTF( ("\n") ); - MALI_PRINTF( ("The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_base, size) ); - MALI_PRINTF( ("\n") ); - MALI_PRINTF( ("Please refer to the ARM Mali Software Integration Guide for more information.\n") ); - MALI_PRINTF( ("\n") ); - MALI_PRINTF( ("*******************************************************************************\n") ); - - MALI_ERROR( _MALI_OSK_ERR_FAULT ); -} - - -_mali_osk_errcode_t _mali_kernel_core_register_resource_handler(_mali_osk_resource_type_t type, mali_kernel_resource_registrator handler) -{ - MALI_CHECK(type < RESOURCE_TYPE_COUNT, _MALI_OSK_ERR_INVALID_ARGS); - MALI_DEBUG_ASSERT(NULL == resource_handler[type]); /* A handler for resource already exists */ - resource_handler[type] = handler; - MALI_SUCCESS; -} - -void * mali_kernel_session_manager_slot_get(struct mali_session_data * session_data, int id) -{ - MALI_DEBUG_ASSERT_POINTER(session_data); - if(id >= SUBSYSTEMS_COUNT) { MALI_DEBUG_PRINT(3, ("mali_kernel_session_manager_slot_get: id %d out of range\n", id)); return NULL; } - - if (NULL == session_data) { MALI_DEBUG_PRINT(3, ("mali_kernel_session_manager_slot_get: got NULL session data\n")); return NULL; } - return session_data->subsystem_data[id]; + MALI_SUCCESS; /* all ok */ } _mali_osk_errcode_t _mali_ukk_open(void **context) { - int i; - _mali_osk_errcode_t err; - struct mali_session_data * session_data; + struct mali_session_data *session_data; /* allocated struct to track this session */ - session_data = (struct mali_session_data *)_mali_osk_malloc(sizeof(struct mali_session_data)); - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); + session_data = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data)); + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); - _mali_osk_memset(session_data->subsystem_data, 0, sizeof(session_data->subsystem_data)); + MALI_DEBUG_PRINT(2, ("Session starting\n")); /* create a response queue for this session */ session_data->ioctl_queue = _mali_osk_notification_queue_init(); if (NULL == session_data->ioctl_queue) { _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); } - MALI_DEBUG_PRINT(3, ("Session starting\n")); - - /* call session_begin on all subsystems */ - for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) + session_data->page_directory = mali_mmu_pagedir_alloc(); + if (NULL == session_data->page_directory) { - if (NULL != subsystems[i]->session_begin) - { - /* subsystem has a session_begin */ - err = subsystems[i]->session_begin(session_data, &session_data->subsystem_data[i], session_data->ioctl_queue); - MALI_CHECK_GOTO(err == _MALI_OSK_ERR_OK, cleanup); - } + _mali_osk_notification_queue_term(session_data->ioctl_queue); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); } - *context = (void*)session_data; + if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session_data->page_directory, MALI_DLB_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE)) + { + MALI_PRINT_ERROR(("Failed to map DLB page into session\n")); + _mali_osk_notification_queue_term(session_data->ioctl_queue); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } - MALI_DEBUG_PRINT(3, ("Session started\n")); - MALI_SUCCESS; + if (0 != mali_dlbu_phys_addr) + { + mali_mmu_pagedir_update(session_data->page_directory, MALI_DLB_VIRT_ADDR, mali_dlbu_phys_addr, _MALI_OSK_MALI_PAGE_SIZE); + } -cleanup: - MALI_DEBUG_PRINT(2, ("Session startup failed\n")); - /* i is index of subsystem which failed session begin, all indices before that has to be ended */ - /* end subsystem sessions in the reverse order they where started in */ - for (i = i - 1; i >= 0; --i) + if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session_data)) { - if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); + mali_mmu_pagedir_free(session_data->page_directory); + _mali_osk_notification_queue_term(session_data->ioctl_queue); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); } - _mali_osk_notification_queue_term(session_data->ioctl_queue); - _mali_osk_free(session_data); + *context = (void*)session_data; - /* return what the subsystem which failed session start returned */ - MALI_ERROR(err); + /* 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) { - int i; - struct mali_session_data * session_data; + struct mali_session_data *session; + MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); + session = (struct mali_session_data *)*context; - MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS); + MALI_DEBUG_PRINT(3, ("Session ending\n")); - session_data = (struct mali_session_data *)*context; + /* Remove session from list of all sessions. */ + mali_session_remove(session); - MALI_DEBUG_PRINT(2, ("Session ending\n")); + /* Abort queued and running jobs */ + mali_gp_scheduler_abort_session(session); + mali_pp_scheduler_abort_session(session); - /* end subsystem sessions in the reverse order they where started in */ - for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i) - { - if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); - } + /* Flush pending work. + * Needed to make sure all bottom half processing related to this + * session has been completed, before we free internal data structures. + */ + _mali_osk_flush_workqueue(NULL); - _mali_osk_notification_queue_term(session_data->ioctl_queue); - _mali_osk_free(session_data); + /* Free remaining memory allocated to this session */ + mali_memory_session_end(session); - *context = NULL; + /* Free session data structures */ + mali_mmu_pagedir_free(session->page_directory); + _mali_osk_notification_queue_term(session->ioctl_queue); + _mali_osk_free(session); - MALI_DEBUG_PRINT(2, ("Session has ended\n")); - - MALI_SUCCESS; -} + *context = NULL; -#if USING_MALI_PMM - -_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only ) -{ - switch( core ) - { - case MALI_PMM_CORE_GP: - MALI_CHECK_NO_ERROR(maligp_signal_power_up(queue_only)); - break; -#if defined USING_MALI400_L2_CACHE - case MALI_PMM_CORE_L2: - if( !queue_only ) - { - /* Enable L2 cache due to power up */ - mali_kernel_l2_cache_do_enable(); + MALI_DEBUG_PRINT(2, ("Session has ended\n")); - /* Invalidate the cache on power up */ - MALI_DEBUG_PRINT(5, ("L2 Cache: Invalidate all\n")); - MALI_CHECK_NO_ERROR(mali_kernel_l2_cache_invalidate_all()); - } - break; -#endif - case MALI_PMM_CORE_PP0: - MALI_CHECK_NO_ERROR(malipp_signal_power_up(0, queue_only)); - break; - case MALI_PMM_CORE_PP1: - MALI_CHECK_NO_ERROR(malipp_signal_power_up(1, queue_only)); - break; - case MALI_PMM_CORE_PP2: - MALI_CHECK_NO_ERROR(malipp_signal_power_up(2, queue_only)); - break; - case MALI_PMM_CORE_PP3: - MALI_CHECK_NO_ERROR(malipp_signal_power_up(3, queue_only)); - break; - default: - /* Unknown core */ - MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power up: %d\n", core) ); - MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS ); - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only ) -{ - switch( core ) - { - case MALI_PMM_CORE_GP: - MALI_CHECK_NO_ERROR(maligp_signal_power_down(immediate_only)); - break; -#if defined USING_MALI400_L2_CACHE - case MALI_PMM_CORE_L2: - /* Nothing to do */ - break; -#endif - case MALI_PMM_CORE_PP0: - MALI_CHECK_NO_ERROR(malipp_signal_power_down(0, immediate_only)); - break; - case MALI_PMM_CORE_PP1: - MALI_CHECK_NO_ERROR(malipp_signal_power_down(1, immediate_only)); - break; - case MALI_PMM_CORE_PP2: - MALI_CHECK_NO_ERROR(malipp_signal_power_down(2, immediate_only)); - break; - case MALI_PMM_CORE_PP3: - MALI_CHECK_NO_ERROR(malipp_signal_power_down(3, immediate_only)); - break; - default: - /* Unknown core */ - MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power down: %d\n", core) ); - MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS ); - } - MALI_SUCCESS; } -#endif - - #if MALI_STATE_TRACKING u32 _mali_kernel_core_dump_state(char* buf, u32 size) { - int i, n; - char *original_buf = buf; - for (i = 0; i < SUBSYSTEMS_COUNT; ++i) - { - if (NULL != subsystems[i]->dump_state) - { - n = subsystems[i]->dump_state(buf, size); - size -= n; - buf += n; - } - } -#if USING_MALI_PMM - n = mali_pmm_dump_os_thread_state(buf, size); - size -= n; - buf += n; -#endif - /* Return number of bytes written to buf */ - return (u32)(buf - original_buf); + int n = 0; /* Number of bytes written to buf */ + + n += mali_gp_scheduler_dump_state(buf + n, size - n); + n += mali_pp_scheduler_dump_state(buf + n, size - n); + + return n; } #endif diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.h b/drivers/media/video/samsung/mali/common/mali_kernel_core.h index 715c1cd..d424c48 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_core.h +++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -13,122 +13,27 @@ #include "mali_osk.h" -#if USING_MALI_PMM -#include "mali_ukk.h" -#include "mali_pmm.h" -#include "mali_pmm_system.h" -#endif +extern int mali_hang_check_interval; +extern int mali_max_job_runtime; -_mali_osk_errcode_t mali_kernel_constructor( void ); -void mali_kernel_destructor( void ); +typedef enum +{ + _MALI_PRODUCT_ID_UNKNOWN, + _MALI_PRODUCT_ID_MALI200, + _MALI_PRODUCT_ID_MALI300, + _MALI_PRODUCT_ID_MALI400, + _MALI_PRODUCT_ID_MALI450, +} _mali_product_id_t; -/** - * @brief Tranlate CPU physical to Mali physical addresses. - * - * This function is used to convert CPU physical addresses to Mali Physical - * addresses, such that _mali_ukk_map_external_mem may be used to map them - * into Mali. This will be used by _mali_ukk_va_to_mali_pa. - * - * This function only supports physically contiguous regions. - * - * A default implementation is provided, which uses a registered MEM_VALIDATION - * resource to do a static translation. Only an address range which will lie - * in the range specified by MEM_VALIDATION will be successfully translated. - * - * If a more complex, or non-static translation is required, then the - * implementor has the following options: - * - Rewrite this function to provide such a translation - * - Integrate the provider of the memory with UMP. - * - * @param[in,out] phys_base pointer to the page-aligned base address of the - * physical range to be translated - * - * @param[in] size size of the address range to be translated, which must be a - * multiple of the physical page size. - * - * @return on success, _MALI_OSK_ERR_OK and *phys_base is translated. If the - * cpu physical address range is not in the valid range, then a suitable - * _mali_osk_errcode_t error. - * - */ -_mali_osk_errcode_t mali_kernel_core_translate_cpu_to_mali_phys_range( u32 *phys_base, u32 size ); - - -/** - * @brief Validate a Mali physical address range. - * - * This function is used to ensure that an address range passed to - * _mali_ukk_map_external_mem is allowed to be mapped into Mali. - * - * This function only supports physically contiguous regions. - * - * A default implementation is provided, which uses a registered MEM_VALIDATION - * resource to do a static translation. Only an address range which will lie - * in the range specified by MEM_VALIDATION will be successfully validated. - * - * If a more complex, or non-static validation is required, then the - * implementor has the following options: - * - Rewrite this function to provide such a validation - * - Integrate the provider of the memory with UMP. - * - * @param phys_base page-aligned base address of the Mali physical range to be - * validated. - * - * @param size size of the address range to be validated, which must be a - * multiple of the physical page size. - * - * @return _MALI_OSK_ERR_OK if the Mali physical range is valid. Otherwise, a - * suitable _mali_osk_errcode_t error. - * - */ -_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size ); +_mali_osk_errcode_t mali_initialize_subsystems(void); -#if USING_MALI_PMM -/** - * @brief Signal a power up on a Mali core. - * - * This function flags a core as powered up. - * For PP and GP cores it calls functions that move the core from a power off - * queue into the idle queue ready to run jobs. It also tries to schedule any - * pending jobs to run on it. - * - * This function will fail if the core is not powered off - either running or - * already idle. - * - * @param core The PMM core id to power up. - * @param queue_only When MALI_TRUE only re-queue the core - do not reset. - * - * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a - * suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only ); - -/** - * @brief Signal a power down on a Mali core. - * - * This function flags a core as powered down. - * For PP and GP cores it calls functions that move the core from an idle - * queue into the power off queue. - * - * This function will fail if the core is not idle - either running or - * already powered down. - * - * @param core The PMM core id to power up. - * @param immediate_only Do not set the core to pending power down if it can't - * power down immediately - * - * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a - * suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only ); +void mali_terminate_subsystems(void); -#endif +void mali_kernel_core_wakeup(void); -/** - * Flag to indicate whether or not mali_benchmark is turned on. - */ -extern int mali_benchmark; +_mali_product_id_t mali_kernel_core_get_product_id(void); +u32 _mali_kernel_core_dump_state(char* buf, u32 size); #endif /* __MALI_KERNEL_CORE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c index 8b2a97d..b9f05ca 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -40,11 +40,7 @@ mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int m map->table = descriptor_table_alloc(init_entries); if (NULL != map->table) { -#if !USING_MMU - map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 20); -#else - map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 116); -#endif + map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP); if (NULL != map->lock) { _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ @@ -151,15 +147,20 @@ _mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, i MALI_ERROR(result); } -void mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor) +void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor) { + void *old_value = NULL; + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) { + old_value = map->table->mappings[descriptor]; map->table->mappings[descriptor] = NULL; _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); } _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); + + return old_value; } static mali_descriptor_table * descriptor_table_alloc(int count) diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h index 745be92..82ed94d 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h +++ b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -93,7 +93,9 @@ void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void ( * For the descriptor to be reused it has to be freed * @param map The map to free the descriptor from * @param descriptor The descriptor ID to free + * + * @return old value of descriptor mapping */ -void mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor); +void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor); #endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_gp.h b/drivers/media/video/samsung/mali/common/mali_kernel_gp.h deleted file mode 100644 index efd3b43..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_gp.h +++ /dev/null @@ -1,21 +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 __MALI_KERNEL_GP2_H__ -#define __MALI_KERNEL_GP2_H__ - -extern struct mali_kernel_subsystem mali_subsystem_gp2; - -#if USING_MALI_PMM -_mali_osk_errcode_t maligp_signal_power_up( mali_bool queue_only ); -_mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only ); -#endif - -#endif /* __MALI_KERNEL_GP2_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c b/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c deleted file mode 100644 index e4d4ab1..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c +++ /dev/null @@ -1,517 +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. - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_list.h" - -#include "mali_kernel_core.h" -#include "mali_kernel_pp.h" -#include "mali_kernel_subsystem.h" -#include "regs/mali_200_regs.h" -#include "mali_kernel_rendercore.h" -#include "mali_kernel_l2_cache.h" - -/** - * Size of the Mali L2 cache registers in bytes - */ -#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30 - -/** - * Mali L2 cache register numbers - * Used in the register read/write routines. - * See the hardware documentation for more information about each register - */ -typedef enum mali_l2_cache_register { - MALI400_L2_CACHE_REGISTER_STATUS = 0x0002, - /*unused = 0x0003 */ - MALI400_L2_CACHE_REGISTER_COMMAND = 0x0004, /**< Misc cache commands, e.g. clear */ - MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0005, - MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0006, /**< Limit of outstanding read requests */ - MALI400_L2_CACHE_REGISTER_ENABLE = 0x0007, /**< Enable misc cache features */ - MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0008, - MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0009, - MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x000A, - MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x000B, -} mali_l2_cache_register; - - -/** - * Mali L2 cache commands - * These are the commands that can be sent to the Mali L2 cache unit - */ -typedef enum mali_l2_cache_command -{ - MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */ - /* Read HW TRM carefully before adding/using other commands than the clear above */ -} mali_l2_cache_command; - -/** - * Mali L2 cache commands - * These are the commands that can be sent to the Mali L2 cache unit - */ -typedef enum mali_l2_cache_enable -{ - MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */ - MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */ - MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */ -} mali_l2_cache_enable; - -/** - * Mali L2 cache status bits - */ -typedef enum mali_l2_cache_status -{ - MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */ - MALI400_L2_CACHE_STATUS_DATA_BUSY = 0x02, /**< L2 cache is busy handling data requests */ -} mali_l2_cache_status; - - -/** - * Definition of the L2 cache core struct - * Used to track a L2 cache unit in the system. - * Contains information about the mapping of the registers - */ -typedef struct mali_kernel_l2_cache_core -{ - unsigned long base; /**< Physical address of the registers */ - mali_io_address mapped_registers; /**< Virtual mapping of the registers */ - u32 mapping_size; /**< Size of registers in bytes */ - _mali_osk_list_t list; /**< Used to link multiple cache cores into a list */ - _mali_osk_lock_t *lock; /**< Serialize all L2 cache commands */ -} mali_kernel_l2_cache_core; - - -#define MALI400_L2_MAX_READS_DEFAULT 0x1C - -int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT; - - -/** - * Mali L2 cache subsystem startup function - * Called by the driver core when the driver is loaded. - * - * @param id Identifier assigned by the core to the L2 cache subsystem - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_l2_cache_initialize(mali_kernel_subsystem_identifier id); - -/** - * Mali L2 cache subsystem shutdown function - * Called by the driver core when the driver is unloaded. - * Cleans up - * @param id Identifier assigned by the core to the L2 cache subsystem - */ -static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id); - -/** - * L2 cache subsystem complete notification function. - * Called by the driver core when all drivers have loaded and all resources has been registered - * @param id Identifier assigned by the core to the L2 cache subsystem - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_l2_cache_load_complete(mali_kernel_subsystem_identifier id); - -/** - * Mali L2 cache subsystem's notification handler for a Mali L2 cache resource instances. - * Registered with the core during startup. - * Called by the core for each Mali L2 cache described in the active architecture's config.h file. - * @param resource The resource to handle (type MALI400L2) - * @return 0 if the Mali L2 cache was found and initialized, negative on error - */ -static _mali_osk_errcode_t mali_l2_cache_core_create(_mali_osk_resource_t * resource); - -/** - * Write to a L2 cache register - * Writes the given value to the specified register - * @param unit The L2 cache to write to - * @param reg The register to write to - * @param val The value to write to the register - */ -static void mali_l2_cache_register_write(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg, u32 val); - - - -/** - * Invalidate specified L2 cache - * @param cache The L2 cache to invalidate - * @return 0 if Mali L2 cache was successfully invalidated, otherwise error - */ -static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all_cache(mali_kernel_l2_cache_core *cache); - - -/* - The fixed Mali L2 cache system's mali subsystem interface implementation. - We currently handle module and session life-time management. -*/ -struct mali_kernel_subsystem mali_subsystem_l2_cache = -{ - mali_l2_cache_initialize, /**< startup */ - NULL, /*mali_l2_cache_terminate,*/ /**< shutdown */ - mali_l2_cache_load_complete, /**< load_complete */ - NULL, /**< system_info_fill */ - NULL, /**< session_begin */ - NULL, /**< session_end */ - NULL, /**< broadcast_notification */ -#if MALI_STATE_TRACKING - NULL, /**< dump_state */ -#endif -}; - - - -static _MALI_OSK_LIST_HEAD(caches_head); - - - - -/* called during module init */ -static _mali_osk_errcode_t mali_l2_cache_initialize(mali_kernel_subsystem_identifier id) -{ - _mali_osk_errcode_t err; - - MALI_IGNORE( id ); - - MALI_DEBUG_PRINT(2, ( "Mali L2 cache system initializing\n")); - - _MALI_OSK_INIT_LIST_HEAD(&caches_head); - - /* This will register the function for adding Mali L2 cache cores to the subsystem */ - err = _mali_kernel_core_register_resource_handler(MALI400L2, mali_l2_cache_core_create); - - MALI_ERROR(err); -} - - - -/* called if/when our module is unloaded */ -static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id) -{ - mali_kernel_l2_cache_core * cache, *temp_cache; - - MALI_DEBUG_PRINT(2, ( "Mali L2 cache system terminating\n")); - - /* loop over all L2 cache units and shut them down */ - _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list ) - { - /* reset to defaults */ - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT); - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT); - - /* remove from the list of cacges on the system */ - _mali_osk_list_del( &cache->list ); - - /* release resources */ - _mali_osk_mem_unmapioregion( cache->base, cache->mapping_size, cache->mapped_registers ); - _mali_osk_mem_unreqregion( cache->base, cache->mapping_size ); - _mali_osk_lock_term( cache->lock ); - _mali_osk_free( cache ); - - #if USING_MALI_PMM - /* Unregister the L2 cache with the PMM */ - malipmm_core_unregister( MALI_PMM_CORE_L2 ); - #endif - } -} - -static _mali_osk_errcode_t mali_l2_cache_core_create(_mali_osk_resource_t * resource) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT ; - mali_kernel_l2_cache_core * cache = NULL; - - MALI_DEBUG_PRINT(2, ( "Creating Mali L2 cache: %s\n", resource->description)); - -#if USING_MALI_PMM - /* Register the L2 cache with the PMM */ - err = malipmm_core_register( MALI_PMM_CORE_L2 ); - if( _MALI_OSK_ERR_OK != err ) - { - MALI_DEBUG_PRINT(1, ( "Failed to register L2 cache unit with PMM")); - return err; - } -#endif - - err = _mali_osk_mem_reqregion( resource->base, MALI400_L2_CACHE_REGISTERS_SIZE, resource->description); - - MALI_CHECK_GOTO( _MALI_OSK_ERR_OK == err, err_cleanup_requestmem_failed); - - /* Reset error that might be passed out */ - err = _MALI_OSK_ERR_FAULT; - - cache = _mali_osk_malloc(sizeof(mali_kernel_l2_cache_core)); - - MALI_CHECK_GOTO( NULL != cache, err_cleanup); - - cache->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 104 ); - - MALI_CHECK_GOTO( NULL != cache->lock, err_cleanup); - - /* basic setup */ - _MALI_OSK_INIT_LIST_HEAD(&cache->list); - - cache->base = resource->base; - cache->mapping_size = MALI400_L2_CACHE_REGISTERS_SIZE; - - /* map the registers */ - cache->mapped_registers = _mali_osk_mem_mapioregion( cache->base, cache->mapping_size, resource->description ); - - MALI_CHECK_GOTO( NULL != cache->mapped_registers, err_cleanup); - - /* Invalidate cache (just to keep it in a known state at startup) */ - err = mali_kernel_l2_cache_invalidate_all_cache(cache); - - MALI_CHECK_GOTO( _MALI_OSK_ERR_OK == err, err_cleanup); - - /* add to our list of L2 caches */ - _mali_osk_list_add( &cache->list, &caches_head ); - - MALI_SUCCESS; - -err_cleanup: - /* This cleanup used when resources have been requested successfully */ - - if ( NULL != cache ) - { - if (NULL != cache->mapped_registers) - { - _mali_osk_mem_unmapioregion( cache->base, cache->mapping_size, cache->mapped_registers); - } - else - { - MALI_DEBUG_PRINT(1, ( "Failed to map Mali L2 cache registers at 0x%08lX\n", cache->base)); - } - - if( NULL != cache->lock ) - { - _mali_osk_lock_term( cache->lock ); - } - else - { - MALI_DEBUG_PRINT(1, ( "Failed to allocate a lock for handling a L2 cache unit")); - } - - _mali_osk_free( cache ); - } - else - { - MALI_DEBUG_PRINT(1, ( "Failed to allocate memory for handling a L2 cache unit")); - } - - /* A call is to request region, so this must always be reversed */ - _mali_osk_mem_unreqregion( resource->base, MALI400_L2_CACHE_REGISTERS_SIZE); -#if USING_MALI_PMM - malipmm_core_unregister( MALI_PMM_CORE_L2 ); -#endif - return err; - -err_cleanup_requestmem_failed: - MALI_DEBUG_PRINT(1, ("Failed to request Mali L2 cache '%s' register address space at (0x%08X - 0x%08X)\n", - resource->description, resource->base, resource->base + MALI400_L2_CACHE_REGISTERS_SIZE - 1) ); -#if USING_MALI_PMM - malipmm_core_unregister( MALI_PMM_CORE_L2 ); -#endif - return err; - -} - - -static void mali_l2_cache_register_write(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg, u32 val) -{ - _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val); -} - - -static u32 mali_l2_cache_register_read(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg) -{ - return _mali_osk_mem_ioread32(unit->mapped_registers, (u32)reg * sizeof(u32)); -} - -void mali_kernel_l2_cache_do_enable(void) -{ - mali_kernel_l2_cache_core * cache, *temp_cache; - - /* loop over all L2 cache units and enable them*/ - _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list) - { - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE); - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads); - } -} - - -static _mali_osk_errcode_t mali_l2_cache_load_complete(mali_kernel_subsystem_identifier id) -{ - mali_kernel_l2_cache_do_enable(); - MALI_DEBUG_PRINT(2, ( "Mali L2 cache system load complete\n")); - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_kernel_l2_cache_send_command(mali_kernel_l2_cache_core *cache, u32 reg, u32 val) -{ - int i = 0; - const int loop_count = 100000; - - /* - * Grab lock in order to send commands to the L2 cache in a serialized fashion. - * The L2 cache will ignore commands if it is busy. - */ - _mali_osk_lock_wait(cache->lock, _MALI_OSK_LOCKMODE_RW); - - /* First, wait for L2 cache command handler to go idle */ - - for (i = 0; i < loop_count; i++) - { - if (!(_mali_osk_mem_ioread32(cache->mapped_registers , (u32)MALI400_L2_CACHE_REGISTER_STATUS * sizeof(u32)) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY)) - { - break; - } - } - - if (i == loop_count) - { - _mali_osk_lock_signal(cache->lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n")); - MALI_ERROR( _MALI_OSK_ERR_FAULT ); - } - - /* then issue the command */ - mali_l2_cache_register_write(cache, reg, val); - - _mali_osk_lock_signal(cache->lock, _MALI_OSK_LOCKMODE_RW); - MALI_SUCCESS; -} - - -static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all_cache(mali_kernel_l2_cache_core *cache) -{ - return mali_kernel_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL); -} - -_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all(void) -{ - mali_kernel_l2_cache_core * cache, *temp_cache; - - /* loop over all L2 cache units and invalidate them */ - - _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list) - { - MALI_CHECK_NO_ERROR( mali_kernel_l2_cache_invalidate_all_cache(cache) ); - } - - MALI_SUCCESS; -} - - -static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page_cache(mali_kernel_l2_cache_core *cache, u32 page) -{ - return mali_kernel_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, page); -} - -_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page(u32 page) -{ - mali_kernel_l2_cache_core * cache, *temp_cache; - - /* loop over all L2 cache units and invalidate them */ - - _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list) - { - MALI_CHECK_NO_ERROR( mali_kernel_l2_cache_invalidate_page_cache(cache, page) ); - } - - MALI_SUCCESS; -} - - -void mali_kernel_l2_cache_set_perf_counters(u32 src0, u32 src1, int force_reset) -{ - mali_kernel_l2_cache_core * cache, *temp_cache; - int reset0 = force_reset; - int reset1 = force_reset; - MALI_DEBUG_CODE( - int changed0 = 0; - int changed1 = 0; - ) - - /* loop over all L2 cache units and activate the counters on them */ - _MALI_OSK_LIST_FOREACHENTRY(cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list) - { - u32 cur_src0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0); - u32 cur_src1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1); - - if (src0 != cur_src0) - { - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, src0); - MALI_DEBUG_CODE(changed0 = 1;) - reset0 = 1; - } - - if (src1 != cur_src1) - { - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, src1); - MALI_DEBUG_CODE(changed1 = 1;) - reset1 = 1; - } - - if (reset0) - { - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0, 0); - } - - if (reset1) - { - mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1, 0); - } - - MALI_DEBUG_PRINT(5, ("L2 cache counters set: SRC0=%u, CHANGED0=%d, RESET0=%d, SRC1=%u, CHANGED1=%d, RESET1=%d\n", - src0, changed0, reset0, - src1, changed1, reset1)); - } -} - - -void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1) -{ - mali_kernel_l2_cache_core * cache, *temp_cache; - int first_time = 1; - *src0 = 0; - *src1 = 0; - *val0 = 0; - *val1 = 0; - - /* loop over all L2 cache units and read the counters */ - _MALI_OSK_LIST_FOREACHENTRY(cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list) - { - u32 cur_src0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0); - u32 cur_src1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1); - u32 cur_val0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0); - u32 cur_val1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1); - - MALI_DEBUG_PRINT(5, ("L2 cache counters get: SRC0=%u, VAL0=%u, SRC1=%u, VAL1=%u\n", cur_src0, cur_val0, cur_src1, cur_val1)); - - /* Only update the counter source once, with the value from the first L2 cache unit. */ - if (first_time) - { - *src0 = cur_src0; - *src1 = cur_src1; - first_time = 0; - } - - /* Bail out if the L2 cache units have different counters set. */ - if (*src0 == cur_src0 && *src1 == cur_src1) - { - *val0 += cur_val0; - *val1 += cur_val1; - } - else - { - MALI_DEBUG_PRINT(1, ("Warning: Mali L2 caches has different performance counters set, not retrieving data\n")); - } - } -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h b/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h deleted file mode 100644 index 8c12b50..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h +++ /dev/null @@ -1,25 +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 __MALI_KERNEL_L2_CACHE_H__ -#define __MALI_KERNEL_L2_CACHE_H__ - -#include "mali_osk.h" -#include "mali_kernel_subsystem.h" -extern struct mali_kernel_subsystem mali_subsystem_l2_cache; - -_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all(void); -_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page(u32 page); - -void mali_kernel_l2_cache_do_enable(void); -void mali_kernel_l2_cache_set_perf_counters(u32 src0, u32 src1, int force_reset); -void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1); - -#endif /* __MALI_KERNEL_L2_CACHE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem.h b/drivers/media/video/samsung/mali/common/mali_kernel_mem.h deleted file mode 100644 index 8caafe3..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem.h +++ /dev/null @@ -1,17 +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 __MALI_KERNEL_MEM_H__ -#define __MALI_KERNEL_MEM_H__ - -#include "mali_kernel_subsystem.h" -extern struct mali_kernel_subsystem mali_subsystem_memory; - -#endif /* __MALI_KERNEL_MEM_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c deleted file mode 100644 index e378f03..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c +++ /dev/null @@ -1,1427 +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. - */ - -#include "mali_kernel_core.h" -#include "mali_kernel_subsystem.h" -#include "mali_kernel_mem.h" -#include "mali_kernel_descriptor_mapping.h" -#include "mali_kernel_session_manager.h" - -/* kernel side OS functions and user-kernel interface */ -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_osk_list.h" -#include "mali_ukk.h" - -#ifdef _MALI_OSK_SPECIFIC_INDIRECT_MMAP -#include "mali_osk_indir_mmap.h" -#endif - -#error Support for non-MMU builds is no longer supported and is planned for removal. - -/** - * Minimum memory allocation size - */ -#define MIN_BLOCK_SIZE (1024*1024UL) - -/** - * Per-session memory descriptor mapping table sizes - */ -#define MALI_MEM_DESCRIPTORS_INIT 64 -#define MALI_MEM_DESCRIPTORS_MAX 4096 - -/** - * Enum uses to store multiple fields in one u32 to keep the memory block struct small - */ -enum MISC_SHIFT { MISC_SHIFT_FREE = 0, MISC_SHIFT_ORDER = 1, MISC_SHIFT_TOPLEVEL = 6 }; -enum MISC_MASK { MISC_MASK_FREE = 0x01, MISC_MASK_ORDER = 0x1F, MISC_MASK_TOPLEVEL = 0x1F }; - -/* forward declaration of the block struct */ -struct mali_memory_block; - -/** - * Definition of memory bank type. - * Represents a memory bank (separate address space) - * Each bank keeps track of its block usage. - * A buddy system used to track the usage -*/ -typedef struct mali_memory_bank -{ - _mali_osk_list_t list; /* links multiple banks together */ - _mali_osk_lock_t *lock; - u32 base_addr; /* Mali seen address of bank */ - u32 cpu_usage_adjust; /* Adjustment factor for what the CPU sees */ - u32 size; /* the effective size */ - u32 real_size; /* the real size of the bank, as given by to the subsystem */ - int min_order; - int max_order; - struct mali_memory_block * blocklist; - _mali_osk_list_t *freelist; - _mali_osk_atomic_t num_active_allocations; - u32 used_for_flags; - u32 alloc_order; /**< Order in which the bank will be used for allocations */ - const char *name; /**< Descriptive name of the bank */ -} mali_memory_bank; - -/** - * Definition of the memory block type - * Represents a memory block, which is the smallest memory unit operated on. - * A block keeps info about its mapping, if in use by a user process - */ -typedef struct mali_memory_block -{ - _mali_osk_list_t link; /* used for freelist and process usage list*/ - mali_memory_bank * bank; /* the bank it belongs to */ - void __user * mapping; /* possible user space mapping of this block */ - u32 misc; /* used while a block is free to track the number blocks it represents */ - int descriptor; - u32 mmap_cookie; /**< necessary for interaction with _mali_ukk_mem_mmap/munmap */ -} mali_memory_block; - -/** - * Defintion of the type used to represent memory used by a session. - * Containts the head of the list of memory currently in use by a session. - */ -typedef struct memory_session -{ - _mali_osk_lock_t *lock; - _mali_osk_list_t memory_head; /* List of the memory blocks used by this session. */ - mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */ -} memory_session; - -/* - Subsystem interface implementation -*/ -/** - * Buddy block memory subsystem startup function - * Called by the driver core when the driver is loaded. - * Registers the memory systems ioctl handler, resource handlers and memory map function with the core. - * - * @param id Identifier assigned by the core to the memory subsystem - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id); - -/** - * Buddy block memory subsystem shutdown function - * Called by the driver core when the driver is unloaded. - * Cleans up - * @param id Identifier assigned by the core to the memory subsystem - */ -static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id); - -/** - * Buddy block memory load complete notification function. - * Called by the driver core when all drivers have loaded and all resources has been registered - * Reports on the memory resources registered - * @param id Identifier assigned by the core to the memory subsystem - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id); - - -/** - * Buddy block memory subsystem session begin notification - * Called by the core when a new session to the driver is started. - * Creates a memory session object and sets it as the subsystem slot data for this session - * @param slot Pointer to the slot to use for storing per-session data - * @param queue The user space event sink - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); - -/** - * Buddy block memory subsystem session end notification - * Called by the core when a session to the driver has ended. - * Cleans up per session data, which includes checking and fixing memory leaks - * - * @param slot Pointer to the slot to use for storing per-session data - */ -static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot); - -/** - * Buddy block memory subsystem system info filler - * Called by the core when a system info update is needed - * We fill in info about all the memory types we have - * @param info Pointer to system info struct to update - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info); - -/* our registered resource handlers */ -/** - * Buddy block memory subsystem's notification handler for MEMORY resource instances. - * Registered with the core during startup. - * Called by the core for each memory bank described in the active architecture's config.h file. - * Requests memory region ownership and calls backend. - * @param resource The resource to handle (type MEMORY) - * @return 0 if the memory was claimed and accepted, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_resource_memory(_mali_osk_resource_t * resource); - -/** - * Buddy block memory subsystem's notification handler for MMU resource instances. - * Registered with the core during startup. - * Called by the core for each mmu described in the active architecture's config.h file. - * @param resource The resource to handle (type MMU) - * @return 0 if the MMU was found and initialized, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource); - -/** - * Buddy block memory subsystem's notification handler for FPGA_FRAMEWORK resource instances. - * Registered with the core during startup. - * Called by the core for each fpga framework described in the active architecture's config.h file. - * @param resource The resource to handle (type FPGA_FRAMEWORK) - * @return 0 if the FPGA framework was found and initialized, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource); - -/* ioctl command implementations */ -/** - * Buddy block memory subsystem's handler for MALI_IOC_MEM_GET_BIG_BLOCK ioctl - * Called by the generic ioctl handler when the MALI_IOC_MEM_GET_BIG_BLOCK command is received. - * Finds an available memory block and maps into the current process' address space. - * @param ukk_private private word for use by the User/Kernel interface - * @param session_data Pointer to the per-session object which will track the memory usage - * @param argument The argument from the user. A pointer to an struct mali_dd_get_big_block in user space - * @return Zero if successful, a standard Linux error value value on error (a negative value) - */ -_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args ); - -/** - * Buddy block memory subsystem's handler for MALI_IOC_MEM_FREE_BIG_BLOCK ioctl - * Called by the generic ioctl handler when the MALI_IOC_MEM_FREE_BIG_BLOCK command is received. - * Unmaps the memory from the process' address space and marks the block as free. - * @param session_data Pointer to the per-session object which tracks the memory usage - * @param argument The argument from the user. A pointer to an struct mali_dd_get_big_block in user space - * @return Zero if successful, a standard Linux error value value on error (a negative value) - */ - -/* this static version allows us to make use of it while holding the memory_session lock. - * This is required for the session_end code */ -static _mali_osk_errcode_t _mali_ukk_free_big_block_internal( struct mali_session_data * mali_session_data, memory_session * session_data, _mali_uk_free_big_block_s *args); - -_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args ); - -/** - * Buddy block memory subsystem's memory bank registration routine - * Called when a MEMORY resource has been found. - * The memory region has already been reserved for use by this driver. - * Create a bank object to represent this region and initialize its slots. - * @note Can only be called in an module atomic scope, i.e. during module init since no locking is performed - * @param phys_base Physical base address of this bank - * @param cpu_usage_adjust Adjustment factor for CPU seen address - * @param size Size of the bank in bytes - * @param flags Memory type bits - * @param alloc_order Order in which the bank will be used for allocations - * @param name descriptive name of the bank - * @return Zero on success, negative on error - */ -static int mali_memory_bank_register(u32 phys_base, u32 cpu_usage_adjust, u32 size, u32 flags, u32 alloc_order, const char *name); - -/** - * Get a block of mali memory of at least the given size and of the given type - * This is the backend for get_big_block. - * @param type_id The type id of memory requested. - * @param minimum_size The size requested - * @return Pointer to a block on success, NULL on failure - */ -static mali_memory_block * mali_memory_block_get(u32 type_id, u32 minimum_size); - -/** - * Get the mali seen address of the memory described by the block - * @param block The memory block to return the address of - * @return The mali seen address of the memory block - */ -MALI_STATIC_INLINE u32 block_mali_addr_get(mali_memory_block * block); - -/** - * Get the cpu seen address of the memory described by the block - * The cpu_usage_adjust will be used to change the mali seen phys address - * @param block The memory block to return the address of - * @return The mali seen address of the memory block - */ -MALI_STATIC_INLINE u32 block_cpu_addr_get(mali_memory_block * block); - -/** - * Get the size of the memory described by the given block - * @param block The memory block to return the size of - * @return The size of the memory block described by the object - */ -MALI_STATIC_INLINE u32 block_size_get(mali_memory_block * block); - -/** - * Get the user space accessible mapping the memory described by the given memory block - * Returns a pointer in user space to the memory, if one has been created. - * @param block The memory block to return the mapping of - * @return User space pointer to cpu accessible memory or NULL if not mapped - */ -MALI_STATIC_INLINE void __user * block_mapping_get(mali_memory_block * block); - -/** - * Set the user space accessible mapping the memory described by the given memory block. - * Sets the stored pointer to user space for the memory described by this block. - * @param block The memory block to set mapping info for - * @param ptr User space pointer to cpu accessible memory or NULL if not mapped - */ -MALI_STATIC_INLINE void block_mapping_set(mali_memory_block * block, void __user * ptr); - -/** - * Get the cookie for use with _mali_ukk_mem_munmap(). - * @param block The memory block to get the cookie from - * @return the cookie. A return of 0 is still a valid cookie. - */ -MALI_STATIC_INLINE u32 block_mmap_cookie_get(mali_memory_block * block); - -/** - * Set the cookie returned via _mali_ukk_mem_mmap(). - * @param block The memory block to set the cookie for - * @param cookie the cookie - */ -MALI_STATIC_INLINE void block_mmap_cookie_set(mali_memory_block * block, u32 cookie); - - -/** - * Get a memory block's free status - * @param block The block to get the state of - */ -MALI_STATIC_INLINE u32 get_block_free(mali_memory_block * block); - -/** - * Set a memory block's free status - * @param block The block to set the state for - * @param state The state to set - */ -MALI_STATIC_INLINE void set_block_free(mali_memory_block * block, int state); - -/** - * Set a memory block's order - * @param block The block to set the order for - * @param order The order to set - */ -MALI_STATIC_INLINE void set_block_order(mali_memory_block * block, u32 order); - -/** - * Get a memory block's order - * @param block The block to get the order for - * @return The order this block exists on - */ -MALI_STATIC_INLINE u32 get_block_order(mali_memory_block * block); - -/** - * Tag a block as being a toplevel block. - * A toplevel block has no buddy and no parent - * @param block The block to tag as being toplevel - */ -MALI_STATIC_INLINE void set_block_toplevel(mali_memory_block * block, u32 level); - -/** - * Check if a block is a toplevel block - * @param block The block to check - * @return 1 if toplevel, 0 else - */ -MALI_STATIC_INLINE u32 get_block_toplevel(mali_memory_block * block); - -/** - * Checks if the given block is a buddy at the given order and that it's free - * @param block The block to check - * @param order The order to check against - * @return 0 if not valid, else 1 - */ -MALI_STATIC_INLINE int block_is_valid_buddy(mali_memory_block * block, int order); - -/* - The buddy system uses the following rules to quickly find a blocks buddy - and parent (block representing this block at a higher order level): - - Given a block with index i the blocks buddy is at index i ^ ( 1 << order) - - Given a block with index i the blocks parent is at i & ~(1 << order) -*/ - -/** - * Get a blocks buddy - * @param block The block to find the buddy for - * @param order The order to operate on - * @return Pointer to the buddy block - */ -MALI_STATIC_INLINE mali_memory_block * block_get_buddy(mali_memory_block * block, u32 order); - -/** - * Get a blocks parent - * @param block The block to find the parent for - * @param order The order to operate on - * @return Pointer to the parent block - */ -MALI_STATIC_INLINE mali_memory_block * block_get_parent(mali_memory_block * block, u32 order); - -/** - * Release mali memory - * Backend for free_big_block. - * Will release the mali memory described by the given block struct. - * @param block Memory block to free - */ -static void block_release(mali_memory_block * block); - -/* end interface implementation */ - -/** - * List of all the memory banks registerd with the subsystem. - * Access to this list is NOT synchronized since it's only - * written to during module init and termination. - */ -static _MALI_OSK_LIST_HEAD(memory_banks_list); - -/* - The buddy memory system's mali subsystem interface implementation. - We currently handle module and session life-time management. -*/ -struct mali_kernel_subsystem mali_subsystem_memory = -{ - mali_memory_core_initialize, /* startup */ - NULL, /*mali_memory_core_terminate,*/ /* shutdown */ - mali_memory_core_load_complete, /* load_complete */ - mali_memory_core_system_info_fill, /* system_info_fill */ - mali_memory_core_session_begin, /* session_begin */ - mali_memory_core_session_end, /* session_end */ - NULL, /* broadcast_notification */ -#if MALI_STATE_TRACKING - NULL, /* dump_state */ -#endif -}; - -/* Initialized when this subsystem is initialized. This is determined by the - * position in subsystems[], and so the value used to initialize this is - * determined at compile time */ -static mali_kernel_subsystem_identifier mali_subsystem_memory_id = -1; - -/* called during module init */ -static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id) -{ - _MALI_OSK_INIT_LIST_HEAD(&memory_banks_list); - - mali_subsystem_memory_id = id; - - /* register our handlers */ - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MEMORY, mali_memory_core_resource_memory)); - - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MMU, mali_memory_core_resource_mmu)); - - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(FPGA_FRAMEWORK, mali_memory_core_resource_fpga)); - - MALI_SUCCESS; -} - -/* called if/when our module is unloaded */ -static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id) -{ - mali_memory_bank * bank, *temp; - - /* loop over all memory banks to free them */ - /* we use the safe version since we delete the current bank in the body */ - _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list) - { - MALI_DEBUG_CODE(int usage_count = _mali_osk_atomic_read(&bank->num_active_allocations)); - /* - Report leaked memory - If this happens we have a bug in our session cleanup code. - */ - MALI_DEBUG_PRINT_IF(1, 0 != usage_count, ("%d allocation(s) from memory bank at 0x%X still in use\n", usage_count, bank->base_addr)); - - _mali_osk_atomic_term(&bank->num_active_allocations); - - _mali_osk_lock_term(bank->lock); - - /* unlink from bank list */ - _mali_osk_list_del(&bank->list); - - /* release kernel resources used by the bank */ - _mali_osk_mem_unreqregion(bank->base_addr, bank->real_size); - - /* remove all resources used to represent this bank*/ - _mali_osk_free(bank->freelist); - _mali_osk_free(bank->blocklist); - - /* destroy the bank object itself */ - _mali_osk_free(bank); - } - - /* No need to de-initialize mali_subsystem_memory_id - it could only be - * re-initialized to the same value */ -} - -/* load_complete handler */ -static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id) -{ - mali_memory_bank * bank, *temp; - - MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest number first) :\n")); - - _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list) - { - if ( NULL != bank->name ) - { - MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", bank->alloc_order, bank->name) ); - } - else - { - MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", bank->alloc_order ) ); - } - } - MALI_SUCCESS; -} - -MALI_STATIC_INLINE u32 order_needed_for_size(u32 size, struct mali_memory_bank * bank) -{ - u32 order = 0; - - if (0 < size) - { - for ( order = sizeof(u32)*8 - 1; ((1UL<min_order)) order = bank->min_order; - /* Not capped to max order, that doesn't make sense */ - - return order; -} - -MALI_STATIC_INLINE u32 maximum_order_which_fits(u32 size) -{ - u32 order = 0; - u32 powsize = 1; - while (powsize < size) - { - powsize <<= 1; - if (powsize > size) break; - order++; - } - - return order; -} - -/* called for new MEMORY resources */ -static _mali_osk_errcode_t mali_memory_bank_register(u32 phys_base, u32 cpu_usage_adjust, u32 size, u32 flags, u32 alloc_order, const char *name) -{ - /* no locking performed due to function contract */ - int i; - u32 left, offset; - mali_memory_bank * bank; - mali_memory_bank * bank_enum, *temp; - - _mali_osk_errcode_t err; - - /* Only a multiple of MIN_BLOCK_SIZE is usable */ - u32 usable_size = size & ~(MIN_BLOCK_SIZE - 1); - - /* handle zero sized banks and bank smaller than the fixed block size */ - if (0 == usable_size) - { - MALI_PRINT(("Usable size == 0\n")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - /* warn for banks not a muliple of the block size */ - MALI_DEBUG_PRINT_IF(1, usable_size != size, ("Memory bank @ 0x%X not a multiple of minimum block size. %d bytes wasted\n", phys_base, size - usable_size)); - - /* check against previous registrations */ - MALI_DEBUG_CODE( - { - _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list) - { - /* duplicate ? */ - if (bank->base_addr == phys_base) - { - MALI_PRINT(("Duplicate registration of a memory bank at 0x%X detected\n", phys_base)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - /* overlapping ? */ - else if ( - ( (phys_base > bank->base_addr) && (phys_base < (bank->base_addr + bank->real_size)) ) || - ( (phys_base + size) > bank->base_addr && ((phys_base + size) < (bank->base_addr + bank->real_size)) ) - ) - { - MALI_PRINT(("Overlapping memory blocks found. Memory at 0x%X overlaps with memory at 0x%X size 0x%X\n", bank->base_addr, phys_base, size)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - } - } - ); - - /* create an object to represent this memory bank */ - MALI_CHECK_NON_NULL(bank = (mali_memory_bank*)_mali_osk_malloc(sizeof(mali_memory_bank)), _MALI_OSK_ERR_NOMEM); - - /* init the fields */ - _MALI_OSK_INIT_LIST_HEAD(&bank->list); - bank->base_addr = phys_base; - bank->cpu_usage_adjust = cpu_usage_adjust; - bank->size = usable_size; - bank->real_size = size; - bank->alloc_order = alloc_order; - bank->name = name; - - err = _mali_osk_atomic_init(&bank->num_active_allocations, 0); - if (err != _MALI_OSK_ERR_OK) - { - _mali_osk_free(bank); - MALI_ERROR(err); - } - - bank->used_for_flags = flags; - bank->min_order = order_needed_for_size(MIN_BLOCK_SIZE, NULL); - bank->max_order = maximum_order_which_fits(usable_size); - bank->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0); - if (NULL == bank->lock) - { - _mali_osk_atomic_term(&bank->num_active_allocations); - _mali_osk_free(bank); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - bank->blocklist = _mali_osk_calloc(1, sizeof(struct mali_memory_block) * (usable_size / MIN_BLOCK_SIZE)); - if (NULL == bank->blocklist) - { - _mali_osk_lock_term(bank->lock); - _mali_osk_atomic_term(&bank->num_active_allocations); - _mali_osk_free(bank); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - for (i = 0; i < (usable_size / MIN_BLOCK_SIZE); i++) - { - bank->blocklist[i].bank = bank; - } - - bank->freelist = _mali_osk_calloc(1, sizeof(_mali_osk_list_t) * (bank->max_order - bank->min_order + 1)); - if (NULL == bank->freelist) - { - _mali_osk_lock_term(bank->lock); - _mali_osk_free(bank->blocklist); - _mali_osk_atomic_term(&bank->num_active_allocations); - _mali_osk_free(bank); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - for (i = 0; i < (bank->max_order - bank->min_order + 1); i++) _MALI_OSK_INIT_LIST_HEAD(&bank->freelist[i]); - - /* init slot info */ - for (offset = 0, left = usable_size; offset < (usable_size / MIN_BLOCK_SIZE); /* updated inside the body */) - { - u32 block_order; - mali_memory_block * block; - - /* the maximum order which fits in the remaining area */ - block_order = maximum_order_which_fits(left); - - /* find the block pointer */ - block = &bank->blocklist[offset]; - - /* tag the block as being toplevel */ - set_block_toplevel(block, block_order); - - /* tag it as being free */ - set_block_free(block, 1); - - /* set the order */ - set_block_order(block, block_order); - - _mali_osk_list_addtail(&block->link, bank->freelist + (block_order - bank->min_order)); - - left -= (1 << block_order); - offset += ((1 << block_order) / MIN_BLOCK_SIZE); - } - - /* add bank to list of banks on the system */ - _MALI_OSK_LIST_FOREACHENTRY( bank_enum, temp, &memory_banks_list, mali_memory_bank, list ) - { - if ( bank_enum->alloc_order >= alloc_order ) - { - /* Found insertion point - our item must go before this one */ - break; - } - } - _mali_osk_list_addtail(&bank->list, &bank_enum->list); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_memory_mmu_register(u32 type, u32 phys_base) -{ - /* not supported */ - return _MALI_OSK_ERR_INVALID_FUNC; -} - -void mali_memory_mmu_unregister(u32 phys_base) -{ - /* not supported */ - return; -} - -static mali_memory_block * mali_memory_block_get(u32 type_id, u32 minimum_size) -{ - mali_memory_bank * bank; - mali_memory_block * block = NULL; - u32 requested_order, current_order; - - /* input validation */ - if (0 == minimum_size) - { - /* bad size */ - MALI_DEBUG_PRINT(2, ("Zero size block requested by mali_memory_block_get\n")); - return NULL; - } - - bank = (mali_memory_bank*)type_id; - - requested_order = order_needed_for_size(minimum_size, bank); - - MALI_DEBUG_PRINT(4, ("For size %d we need order %d (%d)\n", minimum_size, requested_order, 1 << requested_order)); - - _mali_osk_lock_wait(bank->lock, _MALI_OSK_LOCKMODE_RW); - /* ! critical section begin */ - - MALI_DEBUG_PRINT(7, ("Bank 0x%x locked\n", bank)); - - for (current_order = requested_order; current_order <= bank->max_order; ++current_order) - { - _mali_osk_list_t * list = bank->freelist + (current_order - bank->min_order); - MALI_DEBUG_PRINT(7, ("Checking freelist 0x%x for order %d\n", list, current_order)); - if (0 != _mali_osk_list_empty(list)) continue; /* empty list */ - - MALI_DEBUG_PRINT(7, ("Found an entry on the freelist for order %d\n", current_order)); - - - block = _MALI_OSK_LIST_ENTRY(list->next, mali_memory_block, link); - _mali_osk_list_delinit(&block->link); - - while (current_order > requested_order) - { - mali_memory_block * buddy_block; - MALI_DEBUG_PRINT(7, ("Splitting block 0x%x\n", block)); - current_order--; - list--; - buddy_block = block_get_buddy(block, current_order - bank->min_order); - set_block_order(buddy_block, current_order); - set_block_free(buddy_block, 1); - _mali_osk_list_add(&buddy_block->link, list); - } - - set_block_order(block, current_order); - set_block_free(block, 0); - - /* update usage count */ - _mali_osk_atomic_inc(&bank->num_active_allocations); - - break; - } - - /* ! critical section end */ - _mali_osk_lock_signal(bank->lock, _MALI_OSK_LOCKMODE_RW); - - MALI_DEBUG_PRINT(7, ("Lock released for bank 0x%x\n", bank)); - - MALI_DEBUG_PRINT_IF(7, NULL != block, ("Block 0x%x allocated\n", block)); - - return block; -} - - -static void block_release(mali_memory_block * block) -{ - mali_memory_bank * bank; - u32 current_order; - - if (NULL == block) return; - - bank = block->bank; - - /* we're manipulating the free list, so we need to lock it */ - _mali_osk_lock_wait(bank->lock, _MALI_OSK_LOCKMODE_RW); - /* ! critical section begin */ - - set_block_free(block, 1); - current_order = get_block_order(block); - - while (current_order <= bank->max_order) - { - mali_memory_block * buddy_block; - buddy_block = block_get_buddy(block, current_order - bank->min_order); - if (!block_is_valid_buddy(buddy_block, current_order)) break; - _mali_osk_list_delinit(&buddy_block->link); /* remove from free list */ - /* clear tracked data in both blocks */ - set_block_order(block, 0); - set_block_free(block, 0); - set_block_order(buddy_block, 0); - set_block_free(buddy_block, 0); - /* make the parent control the new state */ - block = block_get_parent(block, current_order - bank->min_order); - set_block_order(block, current_order + 1); /* merged has a higher order */ - set_block_free(block, 1); /* mark it as free */ - current_order++; - if (get_block_toplevel(block) == current_order) break; /* stop the merge if we've arrived at a toplevel block */ - } - - _mali_osk_list_add(&block->link, &bank->freelist[current_order - bank->min_order]); - - /* update bank usage statistics */ - _mali_osk_atomic_dec(&block->bank->num_active_allocations); - - /* !critical section end */ - _mali_osk_lock_signal(bank->lock, _MALI_OSK_LOCKMODE_RW); - - return; -} - -MALI_STATIC_INLINE u32 block_get_offset(mali_memory_block * block) -{ - return block - block->bank->blocklist; -} - -MALI_STATIC_INLINE u32 block_mali_addr_get(mali_memory_block * block) -{ - if (NULL != block) return block->bank->base_addr + MIN_BLOCK_SIZE * block_get_offset(block); - else return 0; -} - -MALI_STATIC_INLINE u32 block_cpu_addr_get(mali_memory_block * block) -{ - if (NULL != block) return (block->bank->base_addr + MIN_BLOCK_SIZE * block_get_offset(block)) + block->bank->cpu_usage_adjust; - else return 0; -} - -MALI_STATIC_INLINE u32 block_size_get(mali_memory_block * block) -{ - if (NULL != block) return 1 << get_block_order(block); - else return 0; -} - -MALI_STATIC_INLINE void __user * block_mapping_get(mali_memory_block * block) -{ - if (NULL != block) return block->mapping; - else return NULL; -} - -MALI_STATIC_INLINE void block_mapping_set(mali_memory_block * block, void __user * ptr) -{ - if (NULL != block) block->mapping = ptr; -} - -MALI_STATIC_INLINE u32 block_mmap_cookie_get(mali_memory_block * block) -{ - if (NULL != block) return block->mmap_cookie; - else return 0; -} - -/** - * Set the cookie returned via _mali_ukk_mem_mmap(). - * @param block The memory block to set the cookie for - * @param cookie the cookie - */ -MALI_STATIC_INLINE void block_mmap_cookie_set(mali_memory_block * block, u32 cookie) -{ - if (NULL != block) block->mmap_cookie = cookie; -} - - -static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue) -{ - memory_session * session_data; - - /* validate input */ - if (NULL == slot) - { - MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - if (NULL != *slot) - { - MALI_DEBUG_PRINT(1, ("The slot given to memory session begin already contains data")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - /* create the session data object */ - MALI_CHECK_NON_NULL(session_data = _mali_osk_malloc(sizeof(memory_session)), _MALI_OSK_ERR_NOMEM); - - /* create descriptor mapping table */ - session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX); - - if (NULL == session_data->descriptor_mapping) - { - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _MALI_OSK_INIT_LIST_HEAD(&session_data->memory_head); /* no memory in use */ - session_data->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0); - if (NULL == session_data->lock) - { - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - *slot = session_data; /* slot will point to our data object */ - - MALI_SUCCESS; -} - -static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot) -{ - memory_session * session_data; - - /* validate input */ - if (NULL == slot) - { - MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n")); - return; - } - - if (NULL == *slot) - { - MALI_DEBUG_PRINT(1, ("NULL memory_session found in current session object")); - return; - } - - _mali_osk_lock_wait(((memory_session*)*slot)->lock, _MALI_OSK_LOCKMODE_RW); - session_data = (memory_session *)*slot; - /* clear our slot */ - *slot = NULL; - - /* - First free all memory still being used. - This can happen if the caller has leaked memory or - the application has crashed forcing an auto-session end. - */ - if (0 == _mali_osk_list_empty(&session_data->memory_head)) - { - mali_memory_block * block, * temp; - MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n")); - - /* use the _safe version since fre_big_block removes the active block from the list we're iterating */ - _MALI_OSK_LIST_FOREACHENTRY(block, temp, &session_data->memory_head, mali_memory_block, link) - { - _mali_osk_errcode_t err; - _mali_uk_free_big_block_s uk_args; - - MALI_DEBUG_PRINT(4, ("Freeing block 0x%x with mali address 0x%x size %d mapped in user space at 0x%x\n", - block, - (void*)block_mali_addr_get(block), - block_size_get(block), - block_mapping_get(block)) - ); - - /* free the block */ - /** @note manual type safety check-point */ - uk_args.ctx = mali_session_data; - uk_args.cookie = (u32)block->descriptor; - err = _mali_ukk_free_big_block_internal( mali_session_data, session_data, &uk_args ); - - if ( _MALI_OSK_ERR_OK != err ) - { - MALI_DEBUG_PRINT_ERROR(("_mali_ukk_free_big_block_internal() failed during session termination on block with cookie==0x%X\n", - uk_args.cookie) - ); - } - } - } - - if (NULL != session_data->descriptor_mapping) - { - mali_descriptor_mapping_destroy(session_data->descriptor_mapping); - session_data->descriptor_mapping = NULL; - } - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_lock_term(session_data->lock); - - /* free the session data object */ - _mali_osk_free(session_data); - - return; -} - -static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info) -{ - mali_memory_bank * bank, *temp; - _mali_mem_info **mem_info_tail; - - /* check input */ - MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS); - - /* make sure we won't leak any memory. It could also be that it's an uninitialized variable, but that would be a bug in the caller */ - MALI_DEBUG_ASSERT(NULL == info->mem_info); - - mem_info_tail = &info->mem_info; - - _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list) - { - _mali_mem_info * mem_info; - - mem_info = (_mali_mem_info *)_mali_osk_calloc(1, sizeof(_mali_mem_info)); - if (NULL == mem_info) return _MALI_OSK_ERR_NOMEM; /* memory already allocated will be freed by the caller */ - - /* set info */ - mem_info->size = bank->size; - mem_info->flags = (_mali_bus_usage)bank->used_for_flags; - mem_info->maximum_order_supported = bank->max_order; - mem_info->identifier = (u32)bank; - - /* add to system info linked list */ - (*mem_info_tail) = mem_info; - mem_info_tail = &mem_info->next; - } - - /* all OK */ - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_resource_memory(_mali_osk_resource_t * resource) -{ - _mali_osk_errcode_t err; - - /* Request ownership of the memory */ - if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description)) - { - MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1)); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - /* call backend */ - err = mali_memory_bank_register(resource->base, resource->cpu_usage_adjust, resource->size, resource->flags, resource->alloc_order, resource->description); - if (_MALI_OSK_ERR_OK != err) - { - /* if backend refused the memory we have to release the region again */ - MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n")); - _mali_osk_mem_unreqregion(resource->base, resource->size); - MALI_ERROR(err); - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource) -{ - /* Not supported by the fixed block memory system */ - MALI_DEBUG_PRINT(1, ("MMU resource not supported by non-MMU driver!\n")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_FUNC); -} - -static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource) -{ - mali_io_address mapping; - - MALI_DEBUG_PRINT(5, ("FPGA framework '%s' @ (0x%08X - 0x%08X)\n", - resource->description, resource->base, resource->base + sizeof(u32) * 2 - 1 - )); - - mapping = _mali_osk_mem_mapioregion(resource->base + 0x1000, sizeof(u32) * 2, "fpga framework"); - if (mapping) - { - u32 data; - data = _mali_osk_mem_ioread32(mapping, 0); - MALI_DEBUG_PRINT(2, ("FPGA framwork '%s' @ 0x%08X:\n", resource->description, resource->base)); - MALI_DEBUG_PRINT(2, ("\tBitfile date: %d%02d%02d_%02d%02d\n", - (data >> 20), - (data >> 16) & 0xF, - (data >> 11) & 0x1F, - (data >> 6) & 0x1F, - (data >> 0) & 0x3F)); - data = _mali_osk_mem_ioread32(mapping, sizeof(u32)); - MALI_DEBUG_PRINT(2, ("\tBitfile SCCS rev: %d\n", data)); - - _mali_osk_mem_unmapioregion(resource->base + 0x1000, sizeof(u32) *2, mapping); - } - else MALI_DEBUG_PRINT(1, ("Failed to access FPGA framwork '%s' @ 0x%08X\n", resource->description, resource->base)); - - MALI_SUCCESS; -} - -/* static _mali_osk_errcode_t get_big_block(void * ukk_private, struct mali_session_data * mali_session_data, void __user * argument) */ -_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args ) -{ - _mali_uk_mem_mmap_s args_mmap = {0, }; - int md; - mali_memory_block * block; - _mali_osk_errcode_t err; - memory_session * session_data; - - MALI_DEBUG_ASSERT_POINTER( args ); - - MALI_DEBUG_ASSERT_POINTER( args->ctx ); - - /** @note manual type safety check-point */ - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - if (!args->type_id) - { - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* at least min block size */ - if (MIN_BLOCK_SIZE > args->minimum_size_requested) args->minimum_size_requested = MIN_BLOCK_SIZE; - - /* perform the actual allocation */ - block = mali_memory_block_get(args->type_id, args->minimum_size_requested); - if ( NULL == block ) - { - /* no memory available with requested type_id */ - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, block, &md)) - { - block_release(block); - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - block->descriptor = md; - - - /* fill in response */ - args->mali_address = block_mali_addr_get(block); - args->block_size = block_size_get(block); - args->cookie = (u32)md; - args->flags = block->bank->used_for_flags; - - /* map the block into the process' address space */ - - /** @note manual type safety check-point */ - args_mmap.ukk_private = (void *)args->ukk_private; - args_mmap.ctx = args->ctx; - args_mmap.size = args->block_size; - args_mmap.phys_addr = block_cpu_addr_get(block); - -#ifndef _MALI_OSK_SPECIFIC_INDIRECT_MMAP - err = _mali_ukk_mem_mmap( &args_mmap ); -#else - err = _mali_osk_specific_indirect_mmap( &args_mmap ); -#endif - - /* check if the mapping failed */ - if ( _MALI_OSK_ERR_OK != err ) - { - MALI_DEBUG_PRINT(1, ("Memory mapping failed 0x%x\n", args->cpuptr)); - /* mapping failed */ - - /* remove descriptor entry */ - mali_descriptor_mapping_free(session_data->descriptor_mapping, md); - - /* free the mali memory */ - block_release(block); - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - return err; - } - - args->cpuptr = args_mmap.mapping; - block_mmap_cookie_set(block, args_mmap.cookie); - block_mapping_set(block, args->cpuptr); - - MALI_DEBUG_PRINT(2, ("Mali memory 0x%x (size %d) mapped in process memory space at 0x%x\n", (void*)args->mali_address, args->block_size, args->cpuptr)); - - /* track memory in use for the session */ - _mali_osk_list_addtail(&block->link, &session_data->memory_head); - - /* memory assigned to the session, memory mapped into the process' view */ - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - MALI_SUCCESS; -} - -/* Internal code that assumes the memory session lock is held */ -static _mali_osk_errcode_t _mali_ukk_free_big_block_internal( struct mali_session_data * mali_session_data, memory_session * session_data, _mali_uk_free_big_block_s *args) -{ - mali_memory_block * block = NULL; - _mali_osk_errcode_t err; - _mali_uk_mem_munmap_s args_munmap = {0,}; - - MALI_DEBUG_ASSERT_POINTER( mali_session_data ); - MALI_DEBUG_ASSERT_POINTER( session_data ); - MALI_DEBUG_ASSERT_POINTER( args ); - - err = mali_descriptor_mapping_get(session_data->descriptor_mapping, (int)args->cookie, (void**)&block); - if (_MALI_OSK_ERR_OK != err) - { - MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release memory pages\n", (int)args->cookie)); - MALI_ERROR(err); - } - - MALI_DEBUG_ASSERT_POINTER(block); - - MALI_DEBUG_PRINT(4, ("Asked to free block 0x%x with mali address 0x%x size %d mapped in user space at 0x%x\n", - block, - (void*)block_mali_addr_get(block), - block_size_get(block), - block_mapping_get(block)) - ); - - /** @note manual type safety check-point */ - args_munmap.ctx = (void*)mali_session_data; - args_munmap.mapping = block_mapping_get( block ); - args_munmap.size = block_size_get( block ); - args_munmap.cookie = block_mmap_cookie_get( block ); - -#ifndef _MALI_OSK_SPECIFIC_INDIRECT_MMAP - _mali_ukk_mem_munmap( &args_munmap ); -#else - _mali_osk_specific_indirect_munmap( &args_munmap ); -#endif - - MALI_DEBUG_PRINT(6, ("Session data 0x%x, lock 0x%x\n", session_data, &session_data->lock)); - - /* unlink from session usage list */ - MALI_DEBUG_PRINT(5, ("unlink from session usage list\n")); - _mali_osk_list_delinit(&block->link); - - /* remove descriptor entry */ - mali_descriptor_mapping_free(session_data->descriptor_mapping, (int)args->cookie); - - /* free the mali memory */ - block_release(block); - MALI_DEBUG_PRINT(5, ("Block freed\n")); - - MALI_SUCCESS; -} - -/* static _mali_osk_errcode_t free_big_block( struct mali_session_data * mali_session_data, void __user * argument) */ -_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args ) -{ - _mali_osk_errcode_t err; - struct mali_session_data * mali_session_data; - memory_session * session_data; - - MALI_DEBUG_ASSERT_POINTER( args ); - - MALI_DEBUG_ASSERT_POINTER( args->ctx ); - - /** @note manual type safety check-point */ - mali_session_data = (struct mali_session_data *)args->ctx; - - /* Must always verify this, since these are provided by the user */ - MALI_CHECK_NON_NULL(mali_session_data, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id); - - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - /** @note this has been separated out so that the session_end handler can call this while it has the memory_session lock held */ - err = _mali_ukk_free_big_block_internal( mali_session_data, session_data, args ); - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - return err; -} - -MALI_STATIC_INLINE u32 get_block_free(mali_memory_block * block) -{ - return (block->misc >> MISC_SHIFT_FREE) & MISC_MASK_FREE; -} - -MALI_STATIC_INLINE void set_block_free(mali_memory_block * block, int state) -{ - if (state) block->misc |= (MISC_MASK_FREE << MISC_SHIFT_FREE); - else block->misc &= ~(MISC_MASK_FREE << MISC_SHIFT_FREE); -} - -MALI_STATIC_INLINE void set_block_order(mali_memory_block * block, u32 order) -{ - block->misc &= ~(MISC_MASK_ORDER << MISC_SHIFT_ORDER); - block->misc |= ((order & MISC_MASK_ORDER) << MISC_SHIFT_ORDER); -} - -MALI_STATIC_INLINE u32 get_block_order(mali_memory_block * block) -{ - return (block->misc >> MISC_SHIFT_ORDER) & MISC_MASK_ORDER; -} - -MALI_STATIC_INLINE void set_block_toplevel(mali_memory_block * block, u32 level) -{ - block->misc |= ((level & MISC_MASK_TOPLEVEL) << MISC_SHIFT_TOPLEVEL); -} - -MALI_STATIC_INLINE u32 get_block_toplevel(mali_memory_block * block) -{ - return (block->misc >> MISC_SHIFT_TOPLEVEL) & MISC_MASK_TOPLEVEL; -} - -MALI_STATIC_INLINE int block_is_valid_buddy(mali_memory_block * block, int order) -{ - if (get_block_free(block) && (get_block_order(block) == order)) return 1; - else return 0; -} - -MALI_STATIC_INLINE mali_memory_block * block_get_buddy(mali_memory_block * block, u32 order) -{ - return block + ( (block_get_offset(block) ^ (1 << order)) - block_get_offset(block)); -} - -MALI_STATIC_INLINE mali_memory_block * block_get_parent(mali_memory_block * block, u32 order) -{ - return block + ((block_get_offset(block) & ~(1 << order)) - block_get_offset(block)); -} - -/* This handler registered to mali_mmap for non-MMU builds */ -_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) -{ - _mali_osk_errcode_t ret; - struct mali_session_data * mali_session_data; - mali_memory_allocation * descriptor; - memory_session * session_data; - - /* validate input */ - if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } - - /* Unpack arguments */ - mali_session_data = (struct mali_session_data *)args->ctx; - - if (NULL == mali_session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: mali_session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } - - MALI_DEBUG_ASSERT( mali_subsystem_memory_id >= 0 ); - - session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id); - /* validate input */ - if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } - - descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) ); - if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } - - descriptor->size = args->size; - descriptor->mali_address = args->phys_addr; - descriptor->mali_addr_mapping_info = (void*)session_data; - descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */ - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE; - - ret = _mali_osk_mem_mapregion_init( descriptor ); - if ( _MALI_OSK_ERR_OK != ret ) - { - MALI_DEBUG_PRINT(3, ("_mali_osk_mem_mapregion_init() failed\n")); - _mali_osk_free(descriptor); - MALI_ERROR(ret); - } - - ret = _mali_osk_mem_mapregion_map( descriptor, 0, &descriptor->mali_address, descriptor->size ); - if ( _MALI_OSK_ERR_OK != ret ) - { - MALI_DEBUG_PRINT(3, ("_mali_osk_mem_mapregion_map() failed\n")); - _mali_osk_mem_mapregion_term( descriptor ); - _mali_osk_free(descriptor); - MALI_ERROR(ret); - } - - args->mapping = descriptor->mapping; - - /** - * @note we do not require use of mali_descriptor_mapping here: - * the cookie gets stored in the mali_memory_block struct, which itself is - * protected by mali_descriptor_mapping, and so this cookie never leaves - * kernel space (on any OS). - * - * In the MMU case, we must use a mali_descriptor_mapping, since on _some_ - * OSs, the cookie leaves kernel space. - */ - args->cookie = (u32)descriptor; - MALI_SUCCESS; -} - -/* This handler registered to mali_munmap for non-MMU builds */ -_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) -{ - mali_memory_allocation * descriptor; - - /** see note in _mali_ukk_mem_mmap() - no need to use descriptor mapping */ - descriptor = (mali_memory_allocation *)args->cookie; - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /* args->mapping and args->size are also discarded. They are only necessary for certain do_munmap implementations. However, they could be used to check the descriptor at this point. */ - _mali_osk_mem_mapregion_unmap( descriptor, 0, descriptor->size, (_mali_osk_mem_mapregion_flags_t)0 ); - - _mali_osk_mem_mapregion_term( descriptor ); - - _mali_osk_free(descriptor); - - return _MALI_OSK_ERR_OK; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c deleted file mode 100644 index c993ad5..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c +++ /dev/null @@ -1,3157 +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. - */ - -#include "mali_kernel_subsystem.h" -#include "mali_kernel_mem.h" -#include "mali_kernel_ioctl.h" -#include "mali_kernel_descriptor_mapping.h" -#include "mali_kernel_mem_mmu.h" -#include "mali_kernel_memory_engine.h" -#include "mali_block_allocator.h" -#include "mali_kernel_mem_os.h" -#include "mali_kernel_session_manager.h" -#include "mali_kernel_core.h" -#include "mali_kernel_rendercore.h" - -#if defined USING_MALI400_L2_CACHE -#include "mali_kernel_l2_cache.h" -#endif - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -#include "ump_kernel_interface.h" -#endif - -/* kernel side OS functions and user-kernel interface */ -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_ukk.h" -#include "mali_osk_bitops.h" -#include "mali_osk_list.h" - -/** - * Size of the MMU registers in bytes - */ -#define MALI_MMU_REGISTERS_SIZE 0x24 - -/** - * Size of an MMU page in bytes - */ -#define MALI_MMU_PAGE_SIZE 0x1000 - -/** - * Page directory index from address - * Calculates the page directory index from the given address - */ -#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF) - -/** - * Page table index from address - * Calculates the page table index from the given address - */ -#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF) - -/** - * Extract the memory address from an PDE/PTE entry - */ -#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00) - -/** - * Calculate memory address from PDE and PTE - */ -#define MALI_MMU_ADDRESS(pde, pte) (((pde)<<22) | ((pte)<<12)) - -/** - * Linux kernel version has marked SA_SHIRQ as deprecated, IRQF_SHARED should be used. - * This is to handle older kernels which haven't done this swap. - */ -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif /* IRQF_SHARED */ - -/** - * Per-session memory descriptor mapping table sizes - */ -#define MALI_MEM_DESCRIPTORS_INIT 64 -#define MALI_MEM_DESCRIPTORS_MAX 65536 - -/** - * Used to disallow more than one core to run a MMU at the same time - * - * @note This value is hardwired into some systems' configuration files, - * which \em might not be a header file (e.g. some external data configuration - * file). Therefore, if this value is modified, its occurance must be - * \b manually checked for in the entire driver source tree. - */ -#define MALI_MMU_DISALLOW_PARALLELL_WORK_OF_MALI_CORES 1 - -#define MALI_INVALID_PAGE ((u32)(~0)) - -/** - * - */ -typedef enum mali_mmu_entry_flags -{ - MALI_MMU_FLAGS_PRESENT = 0x01, - MALI_MMU_FLAGS_READ_PERMISSION = 0x02, - MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04, - MALI_MMU_FLAGS_MASK = 0x07 -} mali_mmu_entry_flags; - -/** - * MMU register numbers - * Used in the register read/write routines. - * See the hardware documentation for more information about each register - */ -typedef enum mali_mmu_register { - MALI_MMU_REGISTER_DTE_ADDR = 0x0000, /**< Current Page Directory Pointer */ - MALI_MMU_REGISTER_STATUS = 0x0001, /**< Status of the MMU */ - MALI_MMU_REGISTER_COMMAND = 0x0002, /**< Command register, used to control the MMU */ - MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x0003, /**< Logical address of the last page fault */ - MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x004, /**< Used to invalidate the mapping of a single page from the MMU */ - MALI_MMU_REGISTER_INT_RAWSTAT = 0x0005, /**< Raw interrupt status, all interrupts visible */ - MALI_MMU_REGISTER_INT_CLEAR = 0x0006, /**< Indicate to the MMU that the interrupt has been received */ - MALI_MMU_REGISTER_INT_MASK = 0x0007, /**< Enable/disable types of interrupts */ - MALI_MMU_REGISTER_INT_STATUS = 0x0008 /**< Interrupt status based on the mask */ -} mali_mmu_register; - -/** - * MMU interrupt register bits - * Each cause of the interrupt is reported - * through the (raw) interrupt status registers. - * Multiple interrupts can be pending, so multiple bits - * can be set at once. - */ -typedef enum mali_mmu_interrupt -{ - MALI_MMU_INTERRUPT_PAGE_FAULT = 0x01, /**< A page fault occured */ - MALI_MMU_INTERRUPT_READ_BUS_ERROR = 0x02 /**< A bus read error occured */ -} mali_mmu_interrupt; - -/** - * MMU commands - * These are the commands that can be sent - * to the MMU unit. - */ -typedef enum mali_mmu_command -{ - MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */ - MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */ - MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**< Enable stall on page fault */ - MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */ - MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */ - MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */ - MALI_MMU_COMMAND_SOFT_RESET = 0x06 /**< Reset the MMU back to power-on settings */ -} mali_mmu_command; - -typedef enum mali_mmu_status_bits -{ - MALI_MMU_STATUS_BIT_PAGING_ENABLED = 1 << 0, - MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE = 1 << 1, - MALI_MMU_STATUS_BIT_STALL_ACTIVE = 1 << 2, - MALI_MMU_STATUS_BIT_IDLE = 1 << 3, - MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY = 1 << 4, - MALI_MMU_STATUS_BIT_PAGE_FAULT_IS_WRITE = 1 << 5, -} mali_mmu_status_bits; - -/** - * Defintion of the type used to represent memory used by a session. - * Containts the pointer to the huge user space virtual memory area - * used to access the Mali memory. - */ -typedef struct memory_session -{ - _mali_osk_lock_t *lock; /**< Lock protecting the vm manipulation */ - - u32 mali_base_address; /**< Mali virtual memory area used by this session */ - mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */ - - u32 page_directory; /**< Physical address of the memory session's page directory */ - - mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */ - mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */ - u32 page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */ - - _mali_osk_list_t active_mmus; /**< The MMUs in this session, in increasing order of ID (so we can lock them in the correct order when necessary) */ - _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */ -} memory_session; - -typedef struct mali_kernel_memory_mmu_idle_callback -{ - _mali_osk_list_t link; - void (*callback)(void*); - void * callback_argument; -} mali_kernel_memory_mmu_idle_callback; - -/** - * Definition of the MMU struct - * Used to track a MMU unit in the system. - * Contains information about the mapping of the registers - */ -typedef struct mali_kernel_memory_mmu -{ - int id; /**< ID of the MMU, no duplicate IDs may exist on the system */ - const char * description; /**< Description text received from the resource manager to help identify the resource for people */ - int irq_nr; /**< IRQ number */ - u32 base; /**< Physical address of the registers */ - mali_io_address mapped_registers; /**< Virtual mapping of the registers */ - u32 mapping_size; /**< Size of registers in bytes */ - _mali_osk_list_t list; /**< Used to link multiple MMU's into a list */ - _mali_osk_irq_t *irq; - u32 flags; /**< Used to store if there is something special with this mmu. */ - - _mali_osk_lock_t *lock; /**< Lock protecting access to the usage fields */ - /* usage fields */ - memory_session * active_session; /**< Active session, NULL if no session is active */ - u32 usage_count; /**< Number of nested activations of the active session */ - _mali_osk_list_t callbacks; /**< Callback registered for MMU idle notification */ - void *core; - - int in_page_fault_handler; - - _mali_osk_list_t session_link; -} mali_kernel_memory_mmu; - -typedef struct dedicated_memory_info -{ - u32 base; - u32 size; - struct dedicated_memory_info * next; -} dedicated_memory_info; - -/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */ -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -typedef struct ump_mem_allocation -{ - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; - u32 initial_offset; - u32 size_allocated; - ump_dd_handle ump_mem; -} ump_mem_allocation ; -#endif - -typedef struct external_mem_allocation -{ - mali_allocation_engine * engine; - mali_memory_allocation * descriptor; - u32 initial_offset; - u32 size; -} external_mem_allocation; - -/* - Subsystem interface implementation -*/ -/** - * Fixed block memory subsystem startup function. - * Called by the driver core when the driver is loaded. - * Registers the memory systems ioctl handler, resource handlers and memory map function with the core. - * - * @param id Identifier assigned by the core to the memory subsystem - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id); - -/** - * Fixed block memory subsystem shutdown function. - * Called by the driver core when the driver is unloaded. - * Cleans up - * @param id Identifier assigned by the core to the memory subsystem - */ -static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id); - -/** - * MMU Memory load complete notification function. - * Called by the driver core when all drivers have loaded and all resources has been registered - * Builds the memory overall memory list - * @param id Identifier assigned by the core to the memory subsystem - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id); - -/** - * Fixed block memory subsystem session begin notification - * Called by the core when a new session to the driver is started. - * Creates a memory session object and sets it as the subsystem slot data for this session - * @param slot Pointer to the slot to use for storing per-session data - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); - -/** - * Fixed block memory subsystem session end notification - * Called by the core when a session to the driver has ended. - * Cleans up per session data, which includes checking and fixing memory leaks - * - * @param slot Pointer to the slot to use for storing per-session data - */ -static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot); - -/** - * Fixed block memory subsystem system info filler - * Called by the core when a system info update is needed - * We fill in info about all the memory types we have - * @param info Pointer to system info struct to update - * @return 0 on success, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info); - -/* our registered resource handlers */ - -/** - * Fixed block memory subsystem's notification handler for MMU resource instances. - * Registered with the core during startup. - * Called by the core for each mmu described in the active architecture's config.h file. - * @param resource The resource to handle (type MMU) - * @return 0 if the MMU was found and initialized, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource); - -/** - * Fixed block memory subsystem's notification handler for FPGA_FRAMEWORK resource instances. - * Registered with the core during startup. - * Called by the core for each fpga framework described in the active architecture's config.h file. - * @param resource The resource to handle (type FPGA_FRAMEWORK) - * @return 0 if the FPGA framework was found and initialized, negative on error - */ -static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource); - - -static _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource); -static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource); - -/** - * @brief Internal function for unmapping memory - * - * Worker function for unmapping memory from a user-process. We assume that the - * session/descriptor's lock was obtained before entry. For example, the - * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this - * function to do the actual unmapping. mali_memory_core_session_end() could - * also call this directly (depending on compilation options), having locked - * the descriptor. - * - * This function will fail if it is unable to put the MMU in stall mode (which - * might be the case if a page fault is also being processed). - * - * @param args see _mali_uk_mem_munmap_s in "mali_uk_types.h" - * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. - */ -static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ); - -/** - * The MMU interrupt handler - * Upper half of the MMU interrupt processing. - * Called by the kernel when the MMU has triggered an interrupt. - * The interrupt function supports IRQ sharing. So it'll probe the MMU in question - * @param irq The irq number (not used) - * @param dev_id Points to the MMU object being handled - * @param regs Registers of interrupted process (not used) - * @return Standard Linux interrupt result. - * Subset used by the driver is IRQ_HANDLED processed - * IRQ_NONE Not processed - */ -static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(void * data); - -/** - * The MMU reset hander - * Bottom half of the MMU interrupt processing for page faults and bus errors - * @param work The item to operate on, NULL in our case - */ -static void mali_kernel_memory_mmu_interrupt_handler_bottom_half ( void *data ); - -/** - * Read MMU register value - * Reads the contents of the specified register. - * @param unit The MMU to read from - * @param reg The register to read - * @return The contents of the register - */ -static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_register reg); - -/** - * Write to a MMU register - * Writes the given value to the specified register - * @param unit The MMU to write to - * @param reg The register to write to - * @param val The value to write to the register - */ -static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val); - -/** - * Issues the reset command to the MMU and waits for HW to be ready again - * @param mmu The MMU to reset - */ -static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu); - -/** - * Issues the enable paging command to the MMU and waits for HW to complete the request - * @param mmu The MMU to enable paging for - */ -static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu); - -/** - * Issues the enable stall command to the MMU and waits for HW to complete the request - * @param mmu The MMU to enable paging for - * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out) - */ -static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu); - -/** - * Issues the disable stall command to the MMU and waits for HW to complete the request - * @param mmu The MMU to enable paging for - */ -static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu); - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -static void ump_memory_release(void * ctx, void * handle); -static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/ - - -static void external_memory_release(void * ctx, void * handle); -static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); - - - - -/* nop functions */ - -/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */ -static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */ -static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size); -static void mali_address_manager_release(mali_memory_allocation * descriptor); - -static void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory); - -_mali_osk_errcode_t mali_mmu_page_table_cache_create(void); -void mali_mmu_page_table_cache_destroy(void); - -_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping); -void mali_mmu_release_table_page(u32 pa); - -static _mali_osk_errcode_t mali_allocate_empty_page_directory(void); - -static void mali_free_empty_page_directory(void); - -static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data); - -static _mali_osk_errcode_t mali_allocate_fault_flush_pages(void); - -static void mali_free_fault_flush_pages(void); - -static void mali_mmu_probe_irq_trigger(mali_kernel_memory_mmu * mmu); -static _mali_osk_errcode_t mali_mmu_probe_irq_acknowledge(mali_kernel_memory_mmu * mmu); - -/* MMU variables */ - -typedef struct mali_mmu_page_table_allocation -{ - _mali_osk_list_t list; - u32 * usage_map; - u32 usage_count; - u32 num_pages; - mali_page_table_block pages; -} mali_mmu_page_table_allocation; - -typedef struct mali_mmu_page_table_allocations -{ - _mali_osk_lock_t *lock; - _mali_osk_list_t partial; - _mali_osk_list_t full; - /* we never hold on to a empty allocation */ -} mali_mmu_page_table_allocations; - -/* Head of the list of MMUs */ -static _MALI_OSK_LIST_HEAD(mmu_head); - -/* the mmu page table cache */ -static struct mali_mmu_page_table_allocations page_table_cache; - -/* page fault queue flush helper pages - * note that the mapping pointers are currently unused outside of the initialization functions */ -static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE; -static mali_io_address mali_page_fault_flush_page_directory_mapping = NULL; -static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE; -static mali_io_address mali_page_fault_flush_page_table_mapping = NULL; -static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE; -static mali_io_address mali_page_fault_flush_data_page_mapping = NULL; - -/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */ -static u32 mali_empty_page_directory = MALI_INVALID_PAGE; - -/* - The fixed memory system's mali subsystem interface implementation. - We currently handle module and session life-time management. -*/ -struct mali_kernel_subsystem mali_subsystem_memory = -{ - mali_memory_core_initialize, /* startup */ - NULL, /*mali_memory_core_terminate,*/ /* shutdown */ - mali_memory_core_load_complete, /* load_complete */ - mali_memory_core_system_info_fill, /* system_info_fill */ - mali_memory_core_session_begin, /* session_begin */ - mali_memory_core_session_end, /* session_end */ - NULL, /* broadcast_notification */ -#if MALI_STATE_TRACKING - NULL, /* dump_state */ -#endif -}; - -static mali_kernel_mem_address_manager mali_address_manager = -{ - mali_address_manager_allocate, /* allocate */ - mali_address_manager_release, /* release */ - mali_address_manager_map, /* map_physical */ - NULL /* unmap_physical not present*/ -}; - -static mali_kernel_mem_address_manager process_address_manager = -{ - _mali_osk_mem_mapregion_init, /* allocate */ - _mali_osk_mem_mapregion_term, /* release */ - _mali_osk_mem_mapregion_map, /* map_physical */ - _mali_osk_mem_mapregion_unmap /* unmap_physical */ -}; - -static mali_allocation_engine memory_engine = NULL; -static mali_physical_memory_allocator * physical_memory_allocators = NULL; - -static dedicated_memory_info * mem_region_registrations = NULL; - -/* Initialized when this subsystem is initialized. This is determined by the - * position in subsystems[], and so the value used to initialize this is - * determined at compile time */ -static mali_kernel_subsystem_identifier mali_subsystem_memory_id = (mali_kernel_subsystem_identifier)-1; - -/* called during module init */ -static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id) -{ - MALI_DEBUG_PRINT(2, ("MMU memory system initializing\n")); - - /* save our subsystem id for later for use in slot lookup during session activation */ - mali_subsystem_memory_id = id; - - _MALI_OSK_INIT_LIST_HEAD(&mmu_head); - - MALI_CHECK_NO_ERROR( mali_mmu_page_table_cache_create() ); - - /* register our handlers */ - MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(MMU, mali_memory_core_resource_mmu) ); - - MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(FPGA_FRAMEWORK, mali_memory_core_resource_fpga) ); - - MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(MEMORY, mali_memory_core_resource_dedicated_memory) ); - - MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(OS_MEMORY, mali_memory_core_resource_os_memory) ); - - memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager); - MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT); - - MALI_SUCCESS; -} - -/* called if/when our module is unloaded */ -static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id) -{ - mali_kernel_memory_mmu * mmu, *temp_mmu; - - MALI_DEBUG_PRINT(2, ("MMU memory system terminating\n")); - - /* loop over all MMU units and shut them down */ - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list) - { - /* reset to defaults */ - mali_mmu_raw_reset(mmu); - - /* unregister the irq */ - _mali_osk_irq_term(mmu->irq); - - /* remove from the list of MMU's on the system */ - _mali_osk_list_del(&mmu->list); - - /* release resources */ - _mali_osk_mem_unmapioregion(mmu->base, mmu->mapping_size, mmu->mapped_registers); - _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size); - _mali_osk_lock_term(mmu->lock); - _mali_osk_free(mmu); - } - - /* free global helper pages */ - mali_free_empty_page_directory(); - mali_free_fault_flush_pages(); - - /* destroy the page table cache before shutting down backends in case we have a page table leak to report */ - mali_mmu_page_table_cache_destroy(); - - while ( NULL != mem_region_registrations) - { - dedicated_memory_info * m; - m = mem_region_registrations; - mem_region_registrations = m->next; - _mali_osk_mem_unreqregion(m->base, m->size); - _mali_osk_free(m); - } - - while ( NULL != physical_memory_allocators) - { - mali_physical_memory_allocator * m; - m = physical_memory_allocators; - physical_memory_allocators = m->next; - m->destroy(m); - } - - if (NULL != memory_engine) - { - mali_allocation_engine_destroy(memory_engine); - memory_engine = NULL; - } - -} - -static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue) -{ - memory_session * session_data; - _mali_osk_errcode_t err; - int i; - mali_io_address pd_mapped; - - /* validate input */ - if (NULL == slot) - { - MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - if (NULL != *slot) - { - MALI_DEBUG_PRINT(1, ("The slot given to memory session begin already contains data")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - MALI_DEBUG_PRINT(2, ("MMU session begin\n")); - - /* create the session data object */ - session_data = _mali_osk_calloc(1, sizeof(memory_session)); - MALI_CHECK_NON_NULL( session_data, _MALI_OSK_ERR_NOMEM ); - - /* create descriptor mapping table */ - session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX); - - if (NULL == session_data->descriptor_mapping) - { - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - err = mali_mmu_get_table_page(&session_data->page_directory, &pd_mapped); - - session_data->page_directory_mapped = pd_mapped; - if (_MALI_OSK_ERR_OK != err) - { - mali_descriptor_mapping_destroy(session_data->descriptor_mapping); - _mali_osk_free(session_data); - MALI_ERROR(err); - } - MALI_DEBUG_ASSERT_POINTER( session_data->page_directory_mapped ); - - MALI_DEBUG_PRINT(2, ("Page directory for session 0x%x placed at physical address 0x%08X\n", mali_session_data, session_data->page_directory)); - - for (i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) - { - /* mark each page table as not present */ - _mali_osk_mem_iowrite32_relaxed(session_data->page_directory_mapped, sizeof(u32) * i, 0); - } - _mali_osk_write_mem_barrier(); - - /* page_table_mapped[] is already set to NULL by _mali_osk_calloc call */ - - _MALI_OSK_INIT_LIST_HEAD(&session_data->active_mmus); - session_data->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 128); - if (NULL == session_data->lock) - { - mali_mmu_release_table_page(session_data->page_directory); - mali_descriptor_mapping_destroy(session_data->descriptor_mapping); - _mali_osk_free(session_data); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Init the session's memory allocation list */ - _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head ); - - *slot = session_data; /* slot will point to our data object */ - MALI_DEBUG_PRINT(2, ("MMU session begin: success\n")); - MALI_SUCCESS; -} - -static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target) -{ - mali_memory_allocation * descriptor; - - descriptor = (mali_memory_allocation*)map_target; - - MALI_DEBUG_PRINT(1, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target)); - MALI_DEBUG_ASSERT(descriptor); - - mali_allocation_engine_release_memory(memory_engine, descriptor); - _mali_osk_free(descriptor); -} - -static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot) -{ - memory_session * session_data; - int i; - const int num_page_table_entries = sizeof(session_data->page_entries_mapped) / sizeof(session_data->page_entries_mapped[0]); - - MALI_DEBUG_PRINT(2, ("MMU session end\n")); - - /* validate input */ - if (NULL == slot) - { - MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n")); - return; - } - - session_data = (memory_session *)*slot; - - if (NULL == session_data) - { - MALI_DEBUG_PRINT(1, ("No session data found during session end\n")); - return; - } - /* Lock the session so we can modify the memory list */ - _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW ); - /* Noninterruptable spinlock type, so must always have locked. Checking should've been done in OSK function. */ - -#ifndef MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP -#if _MALI_OSK_SPECIFIC_INDIRECT_MMAP -#error Indirect MMAP specified, but UKK does not have implicit MMAP cleanup. Current implementation does not handle this. -#else - - /* Free all memory engine allocations */ - if (0 == _mali_osk_list_empty(&session_data->memory_head)) - { - mali_memory_allocation *descriptor; - mali_memory_allocation *temp; - _mali_uk_mem_munmap_s unmap_args; - - MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n")); - - unmap_args.ctx = mali_session_data; - - /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */ - _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list) - { - MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n", - descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping) - ); - /* ASSERT that the descriptor's lock references the correct thing */ - MALI_DEBUG_ASSERT( descriptor->lock == session_data->lock ); - /* Therefore, we have already locked the descriptor */ - - unmap_args.size = descriptor->size; - unmap_args.mapping = descriptor->mapping; - unmap_args.cookie = (u32)descriptor; - - /* - * This removes the descriptor from the list, and frees the descriptor - * - * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since - * the only OS we are aware of that requires indirect MMAP also has - * implicit mmap cleanup. - */ - _mali_ukk_mem_munmap_internal( &unmap_args ); - } - } - - /* Assert that we really did free everything */ - MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) ); -#endif /* _MALI_OSK_SPECIFIC_INDIRECT_MMAP */ -#endif /* MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP */ - - if (NULL != session_data->descriptor_mapping) - { - mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback); - mali_descriptor_mapping_destroy(session_data->descriptor_mapping); - session_data->descriptor_mapping = NULL; - } - - for (i = 0; i < num_page_table_entries; i++) - { - /* free PTE memory */ - if (session_data->page_directory_mapped && (_mali_osk_mem_ioread32(session_data->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT)) - { - mali_mmu_release_table_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); - _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); - } - } - - if (MALI_INVALID_PAGE != session_data->page_directory) - { - mali_mmu_release_table_page(session_data->page_directory); - session_data->page_directory = MALI_INVALID_PAGE; - } - - _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW ); - - /** - * @note Could the VMA close handler mean that we use the session data after it was freed? - * In which case, would need to refcount the session data, and free on VMA close - */ - - /* Free the lock */ - _mali_osk_lock_term( session_data->lock ); - /* free the session data object */ - _mali_osk_free(session_data); - - /* clear our slot */ - *slot = NULL; - - return; -} - -static _mali_osk_errcode_t mali_allocate_empty_page_directory(void) -{ - _mali_osk_errcode_t err; - mali_io_address mapping; - - MALI_CHECK_NO_ERROR(mali_mmu_get_table_page(&mali_empty_page_directory, &mapping)); - - MALI_DEBUG_ASSERT_POINTER( mapping ); - - err = fill_page(mapping, 0); - if (_MALI_OSK_ERR_OK != err) - { - mali_mmu_release_table_page(mali_empty_page_directory); - mali_empty_page_directory = MALI_INVALID_PAGE; - } - return err; -} - -static void mali_free_empty_page_directory(void) -{ - if (MALI_INVALID_PAGE != mali_empty_page_directory) - { - mali_mmu_release_table_page(mali_empty_page_directory); - mali_empty_page_directory = MALI_INVALID_PAGE; - } -} - -static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data) -{ - int i; - MALI_DEBUG_ASSERT_POINTER( mapping ); - - for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) - { - _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data); - } - _mali_osk_mem_barrier(); - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_allocate_fault_flush_pages(void) -{ - _mali_osk_errcode_t err; - - err = mali_mmu_get_table_page(&mali_page_fault_flush_data_page, &mali_page_fault_flush_data_page_mapping); - if (_MALI_OSK_ERR_OK == err) - { - err = mali_mmu_get_table_page(&mali_page_fault_flush_page_table, &mali_page_fault_flush_page_table_mapping); - if (_MALI_OSK_ERR_OK == err) - { - err = mali_mmu_get_table_page(&mali_page_fault_flush_page_directory, &mali_page_fault_flush_page_directory_mapping); - if (_MALI_OSK_ERR_OK == err) - { - fill_page(mali_page_fault_flush_data_page_mapping, 0); - fill_page(mali_page_fault_flush_page_table_mapping, mali_page_fault_flush_data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); - fill_page(mali_page_fault_flush_page_directory_mapping, mali_page_fault_flush_page_table | MALI_MMU_FLAGS_PRESENT); - MALI_SUCCESS; - } - mali_mmu_release_table_page(mali_page_fault_flush_page_table); - mali_page_fault_flush_page_table = MALI_INVALID_PAGE; - mali_page_fault_flush_page_table_mapping = NULL; - } - mali_mmu_release_table_page(mali_page_fault_flush_data_page); - mali_page_fault_flush_data_page = MALI_INVALID_PAGE; - mali_page_fault_flush_data_page_mapping = NULL; - } - MALI_ERROR(err); -} - -static void mali_free_fault_flush_pages(void) -{ - if (MALI_INVALID_PAGE != mali_page_fault_flush_page_directory) - { - mali_mmu_release_table_page(mali_page_fault_flush_page_directory); - mali_page_fault_flush_page_directory = MALI_INVALID_PAGE; - } - - if (MALI_INVALID_PAGE != mali_page_fault_flush_page_table) - { - mali_mmu_release_table_page(mali_page_fault_flush_page_table); - mali_page_fault_flush_page_table = MALI_INVALID_PAGE; - } - - if (MALI_INVALID_PAGE != mali_page_fault_flush_data_page) - { - mali_mmu_release_table_page(mali_page_fault_flush_data_page); - mali_page_fault_flush_data_page = MALI_INVALID_PAGE; - } -} - -static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id) -{ - mali_kernel_memory_mmu * mmu, * temp_mmu; - - /* Report the allocators */ - mali_allocation_engine_report_allocators( physical_memory_allocators ); - - /* allocate the helper pages */ - MALI_CHECK_NO_ERROR( mali_allocate_empty_page_directory() ); - if (_MALI_OSK_ERR_OK != mali_allocate_fault_flush_pages()) - { - mali_free_empty_page_directory(); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* activate the empty page directory on all MMU's */ - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list) - { - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); - mali_mmu_enable_paging(mmu); - } - - MALI_DEBUG_PRINT(4, ("MMUs activated\n")); - /* the MMU system is now active */ - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info) -{ - _mali_mem_info * mem_info; - - /* Make sure we won't leak any memory. It could also be that it's an - * uninitialized variable, but the caller should have zeroed the - * variable. */ - MALI_DEBUG_ASSERT(NULL == info->mem_info); - - info->has_mmu = 1; - - mem_info = _mali_osk_calloc(1,sizeof(_mali_mem_info)); - MALI_CHECK_NON_NULL( mem_info, _MALI_OSK_ERR_NOMEM ); - - mem_info->size = 2048UL * 1024UL * 1024UL; - mem_info->maximum_order_supported = 30; - mem_info->flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE; - mem_info->identifier = 0; - - info->mem_info = mem_info; - - /* all OK */ - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource) -{ - mali_kernel_memory_mmu * mmu; - - MALI_DEBUG_PRINT(4, ("MMU '%s' @ (0x%08X - 0x%08X)\n", - resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1 - )); - - if (NULL != mali_memory_core_mmu_lookup(resource->mmu_id)) - { - MALI_DEBUG_PRINT(1, ("Duplicate MMU ids found. The id %d is already in use\n", resource->mmu_id)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, MALI_MMU_REGISTERS_SIZE, resource->description)) - { - /* specified addresses are already in used by another driver / the kernel */ - MALI_DEBUG_PRINT( - 1, ("Failed to request MMU '%s' register address space at (0x%08X - 0x%08X)\n", - resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1 - )); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - mmu = _mali_osk_calloc(1, sizeof(mali_kernel_memory_mmu)); - - if (NULL == mmu) - { - MALI_DEBUG_PRINT(1, ("Failed to allocate memory for handling a MMU unit")); - _mali_osk_mem_unreqregion(resource->base, MALI_MMU_REGISTERS_SIZE); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - /* basic setup */ - _MALI_OSK_INIT_LIST_HEAD(&mmu->list); - - mmu->id = resource->mmu_id; - mmu->irq_nr = resource->irq; - mmu->flags = resource->flags; - mmu->base = resource->base; - mmu->mapping_size = MALI_MMU_REGISTERS_SIZE; - mmu->description = resource->description; /* no need to copy */ - _MALI_OSK_INIT_LIST_HEAD(&mmu->callbacks); - _MALI_OSK_INIT_LIST_HEAD(&mmu->session_link); - mmu->in_page_fault_handler = 0; - - mmu->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 127-mmu->id); - if (NULL == mmu->lock) - { - MALI_DEBUG_PRINT(1, ("Failed to create mmu lock\n")); - _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size); - _mali_osk_free(mmu); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* map the registers */ - mmu->mapped_registers = _mali_osk_mem_mapioregion( mmu->base, mmu->mapping_size, mmu->description ); - if (NULL == mmu->mapped_registers) - { - /* failed to map the registers */ - MALI_DEBUG_PRINT(1, ("Failed to map MMU registers at 0x%08X\n", mmu->base)); - _mali_osk_lock_term(mmu->lock); - _mali_osk_mem_unreqregion(mmu->base, MALI_MMU_REGISTERS_SIZE); - _mali_osk_free(mmu); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - MALI_DEBUG_PRINT(4, ("MMU '%s' @ (0x%08X - 0x%08X) mapped to 0x%08X\n", - resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1, mmu->mapped_registers - )); - - /* setup MMU interrupt mask */ - /* set all values to known defaults */ - mali_mmu_raw_reset(mmu); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - /* setup MMU page directory pointer */ - /* The mali_page_directory pointer is guaranteed to be 4kb aligned because we've used get_zeroed_page to accquire it */ - /* convert the kernel virtual address into a physical address and set */ - - /* add to our list of MMU's */ - _mali_osk_list_addtail(&mmu->list, &mmu_head); - - mmu->irq = _mali_osk_irq_init( - mmu->irq_nr, - mali_kernel_memory_mmu_interrupt_handler_upper_half, - mali_kernel_memory_mmu_interrupt_handler_bottom_half, - (_mali_osk_irq_trigger_t)mali_mmu_probe_irq_trigger, - (_mali_osk_irq_ack_t)mali_mmu_probe_irq_acknowledge, - mmu, - "mali_mmu_irq_handlers" - ); - if (NULL == mmu->irq) - { - _mali_osk_list_del(&mmu->list); - _mali_osk_lock_term(mmu->lock); - _mali_osk_mem_unmapioregion( mmu->base, mmu->mapping_size, mmu->mapped_registers ); - _mali_osk_mem_unreqregion(resource->base, MALI_MMU_REGISTERS_SIZE); - _mali_osk_free(mmu); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* set to a known state */ - mali_mmu_raw_reset(mmu); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - - MALI_DEBUG_PRINT(2, ("MMU registered\n")); - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource) -{ - mali_io_address mapping; - - MALI_DEBUG_PRINT(5, ("FPGA framework '%s' @ (0x%08X - 0x%08X)\n", - resource->description, resource->base, resource->base + sizeof(u32) * 2 - 1 - )); - - mapping = _mali_osk_mem_mapioregion(resource->base + 0x1000, sizeof(u32) * 2, "fpga framework"); - if (mapping) - { - MALI_DEBUG_CODE(u32 data = ) - _mali_osk_mem_ioread32(mapping, 0); - MALI_DEBUG_PRINT(2, ("FPGA framwork '%s' @ 0x%08X:\n", resource->description, resource->base)); - MALI_DEBUG_PRINT(2, ("\tBitfile date: %d%02d%02d_%02d%02d\n", - (data >> 20), - (data >> 16) & 0xF, - (data >> 11) & 0x1F, - (data >> 6) & 0x1F, - (data >> 0) & 0x3F)); - MALI_DEBUG_CODE(data = ) - _mali_osk_mem_ioread32(mapping, sizeof(u32)); - MALI_DEBUG_PRINT(2, ("\tBitfile SCCS rev: %d\n", data)); - - _mali_osk_mem_unmapioregion(resource->base + 0x1000, sizeof(u32) *2, mapping); - } - else MALI_DEBUG_PRINT(1, ("Failed to access FPGA framwork '%s' @ 0x%08X\n", resource->description, resource->base)); - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource) -{ - mali_physical_memory_allocator * allocator; - mali_physical_memory_allocator ** next_allocator_list; - - u32 alloc_order = resource->alloc_order; - - allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description); - if (NULL == allocator) - { - MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - allocator->alloc_order = alloc_order; - - /* link in the allocator: insertion into ordered list - * resources of the same alloc_order will be Last-in-first */ - next_allocator_list = &physical_memory_allocators; - - while ( NULL != *next_allocator_list && - (*next_allocator_list)->alloc_order < alloc_order ) - { - next_allocator_list = &((*next_allocator_list)->next); - } - - allocator->next = (*next_allocator_list); - (*next_allocator_list) = allocator; - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource) -{ - mali_physical_memory_allocator * allocator; - mali_physical_memory_allocator ** next_allocator_list; - dedicated_memory_info * cleanup_data; - - u32 alloc_order = resource->alloc_order; - - /* do the lowlevel linux operation first */ - - /* Request ownership of the memory */ - if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description)) - { - MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* create generic block allocator object to handle it */ - allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description ); - - if (NULL == allocator) - { - MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n")); - _mali_osk_mem_unreqregion(resource->base, resource->size); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* save lowlevel cleanup info */ - allocator->alloc_order = alloc_order; - - cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info)); - - if (NULL == cleanup_data) - { - _mali_osk_mem_unreqregion(resource->base, resource->size); - allocator->destroy(allocator); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - cleanup_data->base = resource->base; - cleanup_data->size = resource->size; - - cleanup_data->next = mem_region_registrations; - mem_region_registrations = cleanup_data; - - /* link in the allocator: insertion into ordered list - * resources of the same alloc_order will be Last-in-first */ - next_allocator_list = &physical_memory_allocators; - - while ( NULL != *next_allocator_list && - (*next_allocator_list)->alloc_order < alloc_order ) - { - next_allocator_list = &((*next_allocator_list)->next); - } - - allocator->next = (*next_allocator_list); - (*next_allocator_list) = allocator; - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(void * data) -{ - mali_kernel_memory_mmu * mmu; - u32 int_stat; - mali_core_renderunit *core; - - if (mali_benchmark) MALI_SUCCESS; - - mmu = (mali_kernel_memory_mmu *)data; - - MALI_DEBUG_ASSERT_POINTER(mmu); - - /* Pointer to core holding this MMU */ - core = (mali_core_renderunit *)mmu->core; - if(core && (CORE_OFF == core->state)) - { - MALI_SUCCESS; - } - - - /* check if it was our device which caused the interrupt (we could be sharing the IRQ line) */ - int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS); - if (0 == int_stat) - { - MALI_ERROR(_MALI_OSK_ERR_FAULT); /* no bits set, we are sharing the IRQ line and someone else caused the interrupt */ - } - - - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0); - - mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS); - - if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) - { - _mali_osk_irq_schedulework(mmu->irq); - } - if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) - { - /* clear interrupt flag */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); - /* reenable it */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - } - - MALI_SUCCESS; -} - - -static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu) -{ - -#if defined(USING_MALI200) - int i; - const int replay_buffer_check_interval = 10; /* must be below 1000 */ - const int replay_buffer_max_number_of_checks = 100; -#endif - - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - /* add an extra reference while handling the page fault */ - mmu->usage_count++; - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - MALI_DEBUG_PRINT(4, ("Sending stop bus request to cores\n")); - /* request to stop the bus, but don't wait for it to actually stop */ - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES, (u32)mmu); - -#if defined(USING_MALI200) - /* no new request will come from any of the connected cores from now - * we must now flush the playback buffer for any requests queued already - */ - - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - MALI_DEBUG_PRINT(4, ("Switching to the special page fault flush page directory\n")); - /* don't use the mali_mmu_activate_address_space function here as we can't stall the MMU */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_page_fault_flush_page_directory); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - /* resume the MMU */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE); - /* the MMU will now play back all the requests, all going to our special page fault flush data page */ - - /* just to be safe, check that the playback buffer is empty before continuing */ - if (!mali_benchmark) { - for (i = 0; i < replay_buffer_max_number_of_checks; i++) - { - if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY) break; - _mali_osk_time_ubusydelay(replay_buffer_check_interval); - } - - MALI_DEBUG_PRINT_IF(1, i == replay_buffer_max_number_of_checks, ("MMU: %s: Failed to flush replay buffer on page fault\n", mmu->description)); - MALI_DEBUG_PRINT(1, ("Replay playback took %ld usec\n", i * replay_buffer_check_interval)); - } - - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - -#endif - /* notify all subsystems that the core should be reset once the bus is actually stopped */ - MALI_DEBUG_PRINT(4,("Sending job abort command to subsystems\n")); - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, (u32)mmu); - - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - /* reprogram the MMU */ - mali_mmu_raw_reset(mmu); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */ - mali_mmu_enable_paging(mmu); - - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - /* release the extra address space reference, will schedule */ - mali_memory_core_mmu_release_address_space_reference(mmu); - - /* resume normal operation */ - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP3_CONTINUE_JOB_HANDLING, (u32)mmu); - MALI_DEBUG_PRINT(4, ("Page fault handling complete\n")); -} - -static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 1; - - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET); - - if (!mali_benchmark) - { - int i; - for (i = 0; i < max_loop_count; ++i) - { - if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_DTE_ADDR) == 0) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Reset request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); - } -} - -static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 1; - - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING); - - if (!mali_benchmark) - { - int i; - for (i = 0; i < max_loop_count; ++i) - { - if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable paging request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); - } -} - -static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 999; - int i; - - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL); - - if (!mali_benchmark) - { - for (i = 0; i < max_loop_count; ++i) - { - if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); - if (max_loop_count == i) - { - return MALI_FALSE; - } - } - - return MALI_TRUE; -} - -static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu) -{ - const int max_loop_count = 100; - const int delay_in_usecs = 1; - int i; - - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL); - - if (!mali_benchmark) - { - for (i = 0; i < max_loop_count; ++i) - { - if ((mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0) - { - break; - } - _mali_osk_time_ubusydelay(delay_in_usecs); - } - MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Disable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS))); - } -} - -void mali_kernel_mmu_reset(void * input_mmu) -{ - mali_kernel_memory_mmu * mmu; - MALI_DEBUG_ASSERT_POINTER(input_mmu); - mmu = (mali_kernel_memory_mmu *)input_mmu; - - MALI_DEBUG_PRINT(4, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->description)); - - if ( 0 != mmu->in_page_fault_handler) - { - /* This is possible if the bus can never be stopped for some reason */ - MALI_PRINT_ERROR(("Stopping the Memory bus not possible. Mali reset could not be performed.")); - return; - } - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - mali_mmu_raw_reset(mmu); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */ - mali_mmu_enable_paging(mmu); - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - -} - -void mali_kernel_mmu_force_bus_reset(void * input_mmu) -{ - mali_kernel_memory_mmu * mmu; - MALI_DEBUG_ASSERT_POINTER(input_mmu); - mmu = (mali_kernel_memory_mmu *)input_mmu; - if ( 0 != mmu->in_page_fault_handler) - { - /* This is possible if the bus can never be stopped for some reason */ - MALI_PRINT_ERROR(("Stopping the Memory bus not possible. Mali reset could not be performed.")); - return; - } - MALI_DEBUG_PRINT(1, ("Mali MMU: Force_bus_reset.\n")); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0); - mali_kernel_mmu_bus_reset(mmu); -} - - -static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data) -{ - mali_kernel_memory_mmu * mmu; - u32 raw, fault_address, status; - mali_core_renderunit *core; - - MALI_DEBUG_PRINT(1, ("mali_kernel_memory_mmu_interrupt_handler_bottom_half\n")); - if (NULL == data) - { - MALI_PRINT_ERROR(("MMU IRQ work queue: NULL argument")); - return; /* Error */ - } - mmu = (mali_kernel_memory_mmu*)data; - - MALI_DEBUG_PRINT(4, ("Locking subsystems\n")); - /* lock all subsystems */ - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP0_LOCK_SUBSYSTEM, (u32)mmu); - - /* Pointer to core holding this MMU */ - core = (mali_core_renderunit *)mmu->core; - - if(CORE_OFF == core->state) - { - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu); - return; - } - - raw = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_RAWSTAT); - status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS); - - if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) ) - { - MALI_DEBUG_PRINT(1, ("MMU: Page fault bottom half: No Irq found.\n")); - MALI_DEBUG_PRINT(4, ("Unlocking subsystems")); - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu); - return; - } - - mmu->in_page_fault_handler = 1; - - fault_address = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_PAGE_FAULT_ADDR); - MALI_PRINT(("Page fault detected at 0x%x from bus id %d of type %s on %s\n", - (void*)fault_address, - (status >> 6) & 0x1F, - (status & 32) ? "write" : "read", - mmu->description) - ); - - if (NULL == mmu->active_session) - { - MALI_PRINT(("Spurious memory access detected from MMU %s\n", mmu->description)); - } - else - { - MALI_PRINT(("Active page directory at 0x%08X\n", mmu->active_session->page_directory)); - MALI_PRINT(("Info from page table for VA 0x%x:\n", (void*)fault_address)); - MALI_PRINT(("DTE entry: PTE at 0x%x marked as %s\n", - (void*)(_mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped, - MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK), - _mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped, - MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT ? "present" : "not present" - )); - - if (_mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped, MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT) - { - mali_io_address pte; - u32 data; - pte = mmu->active_session->page_entries_mapped[MALI_MMU_PDE_ENTRY(fault_address)]; - data = _mali_osk_mem_ioread32(pte, MALI_MMU_PTE_ENTRY(fault_address) * sizeof(u32)); - MALI_PRINT(("PTE entry: Page at 0x%x, %s %s %s\n", - (void*)(data & ~MALI_MMU_FLAGS_MASK), - data & MALI_MMU_FLAGS_PRESENT ? "present" : "not present", - data & MALI_MMU_FLAGS_READ_PERMISSION ? "readable" : "", - data & MALI_MMU_FLAGS_WRITE_PERMISSION ? "writable" : "" - )); - } - else - { - MALI_PRINT(("PTE entry: Not present\n")); - } - } - - - mali_kernel_mmu_bus_reset(mmu); - - mmu->in_page_fault_handler = 0; - - /* unlock all subsystems */ - MALI_DEBUG_PRINT(4, ("Unlocking subsystems")); - _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu); - -} - - -static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_register reg) -{ - u32 val; - - if (mali_benchmark) return 0; - - val = _mali_osk_mem_ioread32(unit->mapped_registers, (u32)reg * sizeof(u32)); - - MALI_DEBUG_PRINT(6, ("mali_mmu_register_read addr:0x%04X val:0x%08x\n", (u32)reg * sizeof(u32),val)); - - return val; -} - -static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val) -{ - if (mali_benchmark) return; - - MALI_DEBUG_PRINT(6, ("mali_mmu_register_write addr:0x%04X val:0x%08x\n", (u32)reg * sizeof(u32), val)); - - _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val); -} - -#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 -static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - ump_dd_handle ump_mem; - u32 nr_blocks; - u32 i; - ump_dd_physical_block * ump_blocks; - ump_mem_allocation *ret_allocation; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) ); - if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE; - - ump_mem = (ump_dd_handle)ctx; - - MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n")); - - nr_blocks = ump_dd_phys_block_count_get(ump_mem); - - MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks)); - - if (nr_blocks == 0) - { - MALI_DEBUG_PRINT(1, ("No block count\n")); - _mali_osk_free( ret_allocation ); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks ); - if ( NULL==ump_blocks ) - { - _mali_osk_free( ret_allocation ); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) - { - _mali_osk_free(ump_blocks); - _mali_osk_free( ret_allocation ); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - /* Store away the initial offset for unmapping purposes */ - ret_allocation->initial_offset = *offset; - - for(i=0; iinitial_offset; - MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); - - /* unmap all previous blocks (if any) */ - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); - - _mali_osk_free(ump_blocks); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += ump_blocks[i].size; - } - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - /* Map in an extra virtual guard page at the end of the VMA */ - MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE )) - { - u32 size_allocated = *offset - ret_allocation->initial_offset; - MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); - - /* unmap all previous blocks (if any) */ - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); - - _mali_osk_free(ump_blocks); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += _MALI_OSK_MALI_PAGE_SIZE; - } - - _mali_osk_free( ump_blocks ); - - ret_allocation->engine = engine; - ret_allocation->descriptor = descriptor; - ret_allocation->ump_mem = ump_mem; - ret_allocation->size_allocated = *offset - ret_allocation->initial_offset; - - alloc_info->ctx = NULL; - alloc_info->handle = ret_allocation; - alloc_info->next = NULL; - alloc_info->release = ump_memory_release; - - return MALI_MEM_ALLOC_FINISHED; -} - -static void ump_memory_release(void * ctx, void * handle) -{ - ump_dd_handle ump_mem; - ump_mem_allocation *allocation; - - allocation = (ump_mem_allocation *)handle; - - MALI_DEBUG_ASSERT_POINTER( allocation ); - - ump_mem = allocation->ump_mem; - - MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem); - - /* At present, this is a no-op. But, it allows the mali_address_manager to - * do unmapping of a subrange in future. */ - mali_allocation_engine_unmap_physical( allocation->engine, - allocation->descriptor, - allocation->initial_offset, - allocation->size_allocated, - (_mali_osk_mem_mapregion_flags_t)0 - ); - _mali_osk_free( allocation ); - - - ump_dd_reference_release(ump_mem) ; - return; -} - -_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ) -{ - ump_dd_handle ump_mem; - mali_physical_memory_allocator external_memory_allocator; - memory_session * session_data; - mali_memory_allocation * descriptor; - int md; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - /* check arguments */ - /* NULL might be a valid Mali address */ - if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - /* size must be a multiple of the system page size */ - if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - MALI_DEBUG_PRINT(3, - ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n", - args->secure_id, args->mali_address, args->size)); - - ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ; - - if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT); - - descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); - if (NULL == descriptor) - { - ump_dd_reference_release(ump_mem); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - descriptor->size = args->size; - descriptor->mapping = NULL; - descriptor->mali_address = args->mali_address; - descriptor->mali_addr_mapping_info = (void*)session_data; - descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ - descriptor->lock = session_data->lock; - if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) - { - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; - } - _mali_osk_list_init( &descriptor->list ); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) - { - ump_dd_reference_release(ump_mem); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - external_memory_allocator.allocate = ump_memory_commit; - external_memory_allocator.allocate_page_table_block = NULL; - external_memory_allocator.ctx = ump_mem; - external_memory_allocator.name = "UMP Memory"; - external_memory_allocator.next = NULL; - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) - { - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - mali_descriptor_mapping_free(session_data->descriptor_mapping, md); - ump_dd_reference_release(ump_mem); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - args->cookie = md; - - MALI_DEBUG_PRINT(5,("Returning from UMP attach\n")); - - /* All OK */ - MALI_SUCCESS; -} - - -_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ) -{ - mali_memory_allocation * descriptor; - memory_session * session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) - { - MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); - - _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW ); - - mali_allocation_engine_release_memory(memory_engine, descriptor); - - _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW ); - - _mali_osk_free(descriptor); - - MALI_SUCCESS; - -} -#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */ - - -static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) -{ - u32 * data; - external_mem_allocation * ret_allocation; - - MALI_DEBUG_ASSERT_POINTER(ctx); - MALI_DEBUG_ASSERT_POINTER(engine); - MALI_DEBUG_ASSERT_POINTER(descriptor); - MALI_DEBUG_ASSERT_POINTER(alloc_info); - - ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) ); - - if ( NULL == ret_allocation ) - { - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - - data = (u32*)ctx; - - ret_allocation->engine = engine; - ret_allocation->descriptor = descriptor; - ret_allocation->initial_offset = *offset; - - alloc_info->ctx = NULL; - alloc_info->handle = ret_allocation; - alloc_info->next = NULL; - alloc_info->release = external_memory_release; - - MALI_DEBUG_PRINT(3, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1])); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1])) - { - MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += data[1]; - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - /* Map in an extra virtual guard page at the end of the VMA */ - MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); - if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE)) - { - u32 size_allocated = *offset - ret_allocation->initial_offset; - MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); - - /* unmap what we previously mapped */ - mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); - _mali_osk_free(ret_allocation); - return MALI_MEM_ALLOC_INTERNAL_FAILURE; - } - *offset += _MALI_OSK_MALI_PAGE_SIZE; - } - - ret_allocation->size = *offset - ret_allocation->initial_offset; - - return MALI_MEM_ALLOC_FINISHED; -} - -static void external_memory_release(void * ctx, void * handle) -{ - external_mem_allocation * allocation; - - allocation = (external_mem_allocation *) handle; - MALI_DEBUG_ASSERT_POINTER( allocation ); - - /* At present, this is a no-op. But, it allows the mali_address_manager to - * do unmapping of a subrange in future. */ - - mali_allocation_engine_unmap_physical( allocation->engine, - allocation->descriptor, - allocation->initial_offset, - allocation->size, - (_mali_osk_mem_mapregion_flags_t)0 - ); - - _mali_osk_free( allocation ); - - return; -} - -_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ) -{ - mali_physical_memory_allocator external_memory_allocator; - memory_session * session_data; - u32 info[2]; - mali_memory_allocation * descriptor; - int md; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - external_memory_allocator.allocate = external_memory_commit; - external_memory_allocator.allocate_page_table_block = NULL; - external_memory_allocator.ctx = &info[0]; - external_memory_allocator.name = "External Memory"; - external_memory_allocator.next = NULL; - - /* check arguments */ - /* NULL might be a valid Mali address */ - if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - /* size must be a multiple of the system page size */ - if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - - MALI_DEBUG_PRINT(3, - ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n", - (void*)args->phys_addr, - (void*)(args->phys_addr + args->size -1), - (void*)args->mali_address) - ); - - /* Validate the mali physical range */ - MALI_CHECK_NO_ERROR( mali_kernel_core_validate_mali_phys_range( args->phys_addr, args->size ) ); - - info[0] = args->phys_addr; - info[1] = args->size; - - descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); - if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM); - - descriptor->size = args->size; - descriptor->mapping = NULL; - descriptor->mali_address = args->mali_address; - descriptor->mali_addr_mapping_info = (void*)session_data; - descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ - descriptor->lock = session_data->lock; - if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) - { - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE; - } - _mali_osk_list_init( &descriptor->list ); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) - { - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) - { - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - mali_descriptor_mapping_free(session_data->descriptor_mapping, md); - _mali_osk_free(descriptor); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - args->cookie = md; - - MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n")); - - /* All OK */ - MALI_SUCCESS; -} - - -_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ) -{ - mali_memory_allocation * descriptor; - memory_session * session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); - - if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) - { - MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); - - _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW ); - - mali_allocation_engine_release_memory(memory_engine, descriptor); - - _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW ); - - _mali_osk_free(descriptor); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */ - args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */ - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ) -{ - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_mmu_page_table_cache_create(void) -{ - page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 110); - MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT ); - _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial); - _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full); - MALI_SUCCESS; -} - -void mali_mmu_page_table_cache_destroy(void) -{ - mali_mmu_page_table_allocation * alloc, *temp; - - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list) - { - MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count)); - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - - MALI_DEBUG_PRINT_IF(1, 0 == _mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n")); - - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list) - { - MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count)); - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - - _mali_osk_lock_term(page_table_cache.lock); -} - -_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping) -{ - _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - - if (0 == _mali_osk_list_empty(&page_table_cache.partial)) - { - mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list); - int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages); - MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number)); - _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map); - alloc->usage_count++; - if (alloc->num_pages == alloc->usage_count) - { - /* full, move alloc to full list*/ - _mali_osk_list_move(&alloc->list, &page_table_cache.full); - } - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - - *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base; - *mapping = (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping); - MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); - MALI_SUCCESS; - } - else - { - mali_mmu_page_table_allocation * alloc; - /* no free pages, allocate a new one */ - - alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation)); - if (NULL == alloc) - { - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = MALI_INVALID_PAGE; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - _MALI_OSK_INIT_LIST_HEAD(&alloc->list); - - if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators)) - { - MALI_DEBUG_PRINT(1, ("No more memory for page tables\n")); - _mali_osk_free(alloc); - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = MALI_INVALID_PAGE; - *mapping = NULL; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - /* create the usage map */ - alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE; - alloc->usage_count = 1; - MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages)); - alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long)); - if (NULL == alloc->usage_map) - { - MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n")); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc); - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = MALI_INVALID_PAGE; - *mapping = NULL; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - - /* clear memory allocation */ - fill_page(alloc->pages.mapping, 0); - - _mali_osk_set_nonatomic_bit(0, alloc->usage_map); - - if (alloc->num_pages > 1) - { - _mali_osk_list_add(&alloc->list, &page_table_cache.partial); - } - else - { - _mali_osk_list_add(&alloc->list, &page_table_cache.full); - } - - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - *table_page = alloc->pages.phys_base; /* return the first page */ - *mapping = alloc->pages.mapping; /* Mapping for first page */ - MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); - MALI_SUCCESS; - } -} - -void mali_mmu_release_table_page(u32 pa) -{ - mali_mmu_page_table_allocation * alloc, * temp_alloc; - - MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa)); - - MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa)); - - _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - - /* find the entry this address belongs to */ - /* first check the partial list */ - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list) - { - u32 start = alloc->pages.phys_base; - u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; - if (pa >= start && pa <= last) - { - MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map)); - _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); - alloc->usage_count--; - - _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); - - if (0 == alloc->usage_count) - { - /* empty, release whole page alloc */ - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa)); - return; - } - } - - /* the check the full list */ - _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list) - { - u32 start = alloc->pages.phys_base; - u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; - if (pa >= start && pa <= last) - { - _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); - alloc->usage_count--; - - _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); - - - if (0 == alloc->usage_count) - { - /* empty, release whole page alloc */ - _mali_osk_list_del(&alloc->list); - alloc->pages.release(&alloc->pages); - _mali_osk_free(alloc->usage_map); - _mali_osk_free(alloc); - } - else - { - /* transfer to partial list */ - _mali_osk_list_move(&alloc->list, &page_table_cache.partial); - } - - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa)); - return; - } - } - - MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa)); - - _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); -} - -void* mali_memory_core_mmu_lookup(u32 id) -{ - mali_kernel_memory_mmu * mmu, * temp_mmu; - - /* find an MMU with a matching id */ - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list) - { - if (id == mmu->id) return mmu; - } - - /* not found */ - return NULL; -} - -void mali_memory_core_mmu_owner(void *core, void *mmu_ptr) -{ - mali_kernel_memory_mmu *mmu; - - MALI_DEBUG_ASSERT_POINTER(mmu_ptr); - MALI_DEBUG_ASSERT_POINTER(core); - - mmu = (mali_kernel_memory_mmu *)mmu_ptr; - mmu->core = core; -} - -void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory) -{ - mali_mmu_enable_stall(mmu); /* this might fail, but changing the DTE address and ZAP should work anyway... */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, page_directory); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - mali_mmu_disable_stall(mmu); -} - -_mali_osk_errcode_t mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument) -{ - memory_session * requested_memory_session; - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - mali_kernel_memory_mmu * mmu; - - MALI_DEBUG_ASSERT_POINTER(mmu_ptr); - MALI_DEBUG_ASSERT_POINTER(mali_session_data); - - mmu = (mali_kernel_memory_mmu *)mmu_ptr; - - MALI_DEBUG_PRINT(4, ("Asked to activate page table for session 0x%x on MMU %s\n", mali_session_data, mmu->description)); - requested_memory_session = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id); - MALI_DEBUG_PRINT(5, ("Session 0x%x looked up as using memory session 0x%x\n", mali_session_data, requested_memory_session)); - - MALI_DEBUG_ASSERT_POINTER(requested_memory_session); - - MALI_DEBUG_PRINT(7, ("Taking locks\n")); - - _mali_osk_lock_wait(requested_memory_session->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - if (0 == mmu->usage_count) - { - /* no session currently active, activate the requested session */ - MALI_DEBUG_ASSERT(NULL == mmu->active_session); - mmu->active_session = requested_memory_session; - mmu->usage_count = 1; - MALI_DEBUG_PRINT(4, ("MMU idle, activating page directory 0x%08X on MMU %s\n", requested_memory_session->page_directory, mmu->description)); - mali_mmu_activate_address_space(mmu, requested_memory_session->page_directory); - { - /* Insert mmu into the right place in the active_mmus list so that - * it is still sorted. The list must be sorted by ID so we can get - * the mutexes in the right order in - * _mali_ukk_mem_munmap_internal(). - */ - _mali_osk_list_t *entry; - for (entry = requested_memory_session->active_mmus.next; - entry != &requested_memory_session->active_mmus; - entry = entry->next) - { - mali_kernel_memory_mmu *temp = _MALI_OSK_LIST_ENTRY(entry, mali_kernel_memory_mmu, session_link); - if (mmu->id < temp->id) - break; - } - /* If we broke out, then 'entry' points to the list node of the - * first mmu with a greater ID; otherwise, it points to - * active_mmus. We want to add *before* this node. - */ - _mali_osk_list_addtail(&mmu->session_link, entry); - } - err = _MALI_OSK_ERR_OK; - } - - /* Allow two cores to run in parallel if they come from the same session */ - else if ( - (mmu->in_page_fault_handler == 0) && - (requested_memory_session == mmu->active_session ) && - (0==(MALI_MMU_DISALLOW_PARALLELL_WORK_OF_MALI_CORES & mmu->flags)) - ) - { - /* nested activation detected, just update the reference count */ - MALI_DEBUG_PRINT(4, ("Nested activation detected, %d previous activations found\n", mmu->usage_count)); - mmu->usage_count++; - err = _MALI_OSK_ERR_OK; - } - - else if (NULL != callback) - { - /* can't activate right now, notify caller on idle via callback */ - mali_kernel_memory_mmu_idle_callback * callback_object, * temp_callback_object; - int found = 0; - - MALI_DEBUG_PRINT(3, ("The MMU is busy and is using a different address space, callback given\n")); - /* check for existing registration */ - _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp_callback_object, &mmu->callbacks, mali_kernel_memory_mmu_idle_callback, link) - { - if (callback_object->callback == callback) - { - found = 1; - break; - } - } - - if (found) - { - MALI_DEBUG_PRINT(5, ("Duplicate callback registration found, ignoring\n")); - /* callback already registered */ - err = _MALI_OSK_ERR_BUSY; - } - else - { - MALI_DEBUG_PRINT(5,("New callback, registering\n")); - /* register the new callback */ - callback_object = _mali_osk_malloc(sizeof(mali_kernel_memory_mmu_idle_callback)); - if (NULL != callback_object) - { - MALI_DEBUG_PRINT(7,("Callback struct setup\n")); - callback_object->callback = callback; - callback_object->callback_argument = callback_argument; - _mali_osk_list_addtail(&callback_object->link, &mmu->callbacks); - err = _MALI_OSK_ERR_BUSY; - } - } - } - - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - _mali_osk_lock_signal(requested_memory_session->lock, _MALI_OSK_LOCKMODE_RW); - - MALI_ERROR(err); -} - -void mali_memory_core_mmu_release_address_space_reference(void* mmu_ptr) -{ - mali_kernel_memory_mmu_idle_callback * callback_object, * temp; - mali_kernel_memory_mmu * mmu; - memory_session * session; - - _MALI_OSK_LIST_HEAD(callbacks); - - MALI_DEBUG_ASSERT_POINTER(mmu_ptr); - mmu = (mali_kernel_memory_mmu *)mmu_ptr; - - session = mmu->active_session; - - /* support that we handle spurious page faults */ - if (NULL != session) - { - _mali_osk_lock_wait(session->lock, _MALI_OSK_LOCKMODE_RW); - } - - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - MALI_DEBUG_PRINT(4, ("Deactivation of address space on MMU %s, %d references exists\n", mmu->description, mmu->usage_count)); - MALI_DEBUG_ASSERT(0 != mmu->usage_count); - mmu->usage_count--; - if (0 != mmu->usage_count) - { - MALI_DEBUG_PRINT(4, ("MMU still in use by this address space, %d references still exists\n", mmu->usage_count)); - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - /* support that we handle spurious page faults */ - if (NULL != session) - { - _mali_osk_lock_signal(session->lock, _MALI_OSK_LOCKMODE_RW); - } - return; - } - - MALI_DEBUG_PRINT(4, ("Activating the empty page directory on %s\n", mmu->description)); - - /* last reference gone, deactivate current address space */ - mali_mmu_activate_address_space(mmu, mali_empty_page_directory); - - /* unlink from session */ - _mali_osk_list_delinit(&mmu->session_link); - /* remove the active session pointer */ - mmu->active_session = NULL; - - /* Notify all registered callbacks. - * We have to be clever here: - * We must call the callbacks with the spinlock unlocked and - * the callback list emptied to allow them to re-register. - * So we make a copy of the list, clears the list and then later call the callbacks on the local copy - */ - /* copy list */ - _MALI_OSK_INIT_LIST_HEAD(&callbacks); - _mali_osk_list_splice(&mmu->callbacks, &callbacks); - /* clear the original, allowing new registrations during the callback */ - _MALI_OSK_INIT_LIST_HEAD(&mmu->callbacks); - - /* end of mmu manipulation, so safe to unlock */ - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - /* then finally remove the (possible) session lock, supporting that no session was active (spurious page fault handling) */ - if (NULL != session) - { - _mali_osk_lock_signal(session->lock, _MALI_OSK_LOCKMODE_RW); - } - - _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp, &callbacks, mali_kernel_memory_mmu_idle_callback, link) - { - MALI_DEBUG_ASSERT_POINTER(callback_object->callback); - (callback_object->callback)(callback_object->callback_argument); - _mali_osk_list_del(&callback_object->link); - _mali_osk_free(callback_object); - } -} - -void mali_memory_core_mmu_unregister_callback(void* mmu_ptr, void(*callback)(void*)) -{ - mali_kernel_memory_mmu_idle_callback * callback_object, * temp_callback_object; - mali_kernel_memory_mmu * mmu; - MALI_DEBUG_ASSERT_POINTER(mmu_ptr); - - MALI_DEBUG_ASSERT_POINTER(callback); - MALI_DEBUG_ASSERT_POINTER(mmu_ptr); - - mmu = (mali_kernel_memory_mmu *)mmu_ptr; - - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp_callback_object, &mmu->callbacks, mali_kernel_memory_mmu_idle_callback, link) - { - MALI_DEBUG_ASSERT_POINTER(callback_object->callback); - if (callback_object->callback == callback) - { - _mali_osk_list_del(&callback_object->link); - _mali_osk_free(callback_object); - break; - } - } - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); -} - -static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor) -{ - /* allocate page tables, if needed */ - int i; - const int first_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address); - int last_pde_idx; - memory_session * session_data; -#if defined USING_MALI400_L2_CACHE - int has_active_mmus = 0; - int page_dir_updated = 0; -#endif - - - if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) - { - last_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address + _MALI_OSK_MALI_PAGE_SIZE + descriptor->size - 1); - } - else - { - last_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address + descriptor->size - 1); - } - - session_data = (memory_session*)descriptor->mali_addr_mapping_info; - MALI_DEBUG_ASSERT_POINTER(session_data); - - MALI_DEBUG_PRINT(4, ("allocating page tables for Mali virtual address space 0x%08X to 0x%08X\n", descriptor->mali_address, descriptor->mali_address + descriptor->size - 1)); - -#if defined USING_MALI400_L2_CACHE - if (0 == _mali_osk_list_empty(&session_data->active_mmus)) - { - /* - * We have active MMUs, so we are probably in the process of alocating more memory for a suspended GP job (PLBU heap) - * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page directory - * from the L2 cache if we add new page directory entries (PDEs) to the page directory. - * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start - */ - has_active_mmus = 1; - } -#endif - - for (i = first_pde_idx; i <= last_pde_idx; i++) - { - if ( 0 == (_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT) ) - { - u32 pte_phys; - mali_io_address pte_mapped; - _mali_osk_errcode_t err; - - /* allocate a new page table */ - MALI_DEBUG_ASSERT(0 == session_data->page_entries_usage_count[i]); - MALI_DEBUG_ASSERT(NULL == session_data->page_entries_mapped[i]); - - err = mali_mmu_get_table_page(&pte_phys, &pte_mapped); - if (_MALI_OSK_ERR_OK == err) - { - session_data->page_entries_mapped[i] = pte_mapped; - MALI_DEBUG_ASSERT_POINTER( session_data->page_entries_mapped[i] ); - - _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), pte_phys | MALI_MMU_FLAGS_PRESENT); /* mark page table as present */ - - /* update usage count */ - session_data->page_entries_usage_count[i]++; -#if defined USING_MALI400_L2_CACHE - page_dir_updated = 1; -#endif - continue; /* continue loop */ - } - - MALI_DEBUG_PRINT(1, ("Page table alloc failed\n")); - break; /* abort loop, failed to allocate one or more page tables */ - } - else - { - session_data->page_entries_usage_count[i]++; - } - } - - if (i <= last_pde_idx) - { - /* one or more pages could not be allocated, release reference count for the ones we added one for */ - /* adjust for the one which caused the for loop to be aborted */ - i--; - - while (i >= first_pde_idx) - { - MALI_DEBUG_ASSERT(0 != session_data->page_entries_usage_count[i]); - session_data->page_entries_usage_count[i]--; - if (0 == session_data->page_entries_usage_count[i]) - { - /* last reference removed */ - mali_mmu_release_table_page(MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)))); - session_data->page_entries_mapped[i] = NULL; - _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); /* mark as not present in the page directory */ - } - i--; - } - - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - -#if defined USING_MALI400_L2_CACHE - if (1 == has_active_mmus && 1 == page_dir_updated) - { - /* - * We have updated the page directory and have an active MMU using it, so invalidate it in the Mali L2 cache. - */ - mali_kernel_l2_cache_invalidate_page(session_data->page_directory); - } -#endif - - /* all OK */ - MALI_SUCCESS; -} - -static void mali_address_manager_release(mali_memory_allocation * descriptor) -{ - int first_pde_idx; - int last_pde_idx; - memory_session * session_data; - u32 mali_address; - u32 mali_address_end; - u32 left; - int i; -#if defined USING_MALI400_L2_CACHE - int has_active_mmus = 0; - int page_dir_updated = 0; -#endif - - MALI_DEBUG_ASSERT_POINTER(descriptor); - session_data = (memory_session*)descriptor->mali_addr_mapping_info; - MALI_DEBUG_ASSERT_POINTER(session_data); - MALI_DEBUG_ASSERT_POINTER(session_data->page_directory_mapped); - - mali_address = descriptor->mali_address; - mali_address_end = descriptor->mali_address + descriptor->size; - left = descriptor->size; - - first_pde_idx = MALI_MMU_PDE_ENTRY(mali_address); - last_pde_idx = MALI_MMU_PDE_ENTRY(mali_address_end - 1); - - MALI_DEBUG_PRINT(3, ("Zapping Mali MMU table for address 0x%08X size 0x%08X\n", mali_address, left)); - MALI_DEBUG_PRINT(4, ("Zapping PDE %d through %d\n", first_pde_idx, last_pde_idx)); - -#if defined USING_MALI400_L2_CACHE - if (0 == _mali_osk_list_empty(&session_data->active_mmus)) - { - /* - * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page tables - * from the L2 cache to ensure that the memory is unmapped. - * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start - */ - has_active_mmus = 1; - } -#endif - - - for (i = first_pde_idx; i <= last_pde_idx; i++) - { - int size_inside_pte = left < 0x400000 ? left : 0x400000; - const int first_pte_idx = MALI_MMU_PTE_ENTRY(mali_address); - int last_pte_idx = MALI_MMU_PTE_ENTRY(mali_address + size_inside_pte - 1); - - if (last_pte_idx < first_pte_idx) - { - /* The last_pte_idx is into the next PTE, crop it to fit into this */ - last_pte_idx = 1023; /* 1024 PTE entries, so 1023 is the last one */ - size_inside_pte = MALI_MMU_ADDRESS(i + 1, 0) - mali_address; - } - - MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[i]); - MALI_DEBUG_ASSERT(0 != session_data->page_entries_usage_count[i]); - MALI_DEBUG_PRINT(4, ("PDE %d: zapping entries %d through %d, address 0x%08X, size 0x%08X, left 0x%08X (page table at 0x%08X)\n", - i, first_pte_idx, last_pte_idx, mali_address, size_inside_pte, left, - MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32))))); - - session_data->page_entries_usage_count[i]--; - - if (0 == session_data->page_entries_usage_count[i]) - { - MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n")); - /* last reference removed, no need to zero out each PTE */ - mali_mmu_release_table_page(MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)))); - session_data->page_entries_mapped[i] = NULL; - _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); /* mark as not present in the page directory */ -#if defined USING_MALI400_L2_CACHE - page_dir_updated = 1; -#endif - } - else - { - int j; - - for (j = first_pte_idx; j <= last_pte_idx; j++) - { - _mali_osk_mem_iowrite32(session_data->page_entries_mapped[i], j * sizeof(u32), 0); - } - -#if defined USING_MALI400_L2_CACHE - if (1 == has_active_mmus) - { - /* Invalidate the page we've just modified */ - mali_kernel_l2_cache_invalidate_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); - } -#endif - } - left -= size_inside_pte; - mali_address += size_inside_pte; - } - -#if defined USING_MALI400_L2_CACHE - if ((1 == page_dir_updated) && (1== has_active_mmus)) - { - /* The page directory was also updated */ - mali_kernel_l2_cache_invalidate_page(session_data->page_directory); - } -#endif -} - -static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size) -{ - memory_session * session_data; - u32 mali_address; - u32 mali_address_end; - u32 current_phys_addr; -#if defined USING_MALI400_L2_CACHE - int has_active_mmus = 0; -#endif - - MALI_DEBUG_ASSERT_POINTER(descriptor); - - MALI_DEBUG_ASSERT_POINTER( phys_addr ); - - current_phys_addr = *phys_addr; - - session_data = (memory_session*)descriptor->mali_addr_mapping_info; - MALI_DEBUG_ASSERT_POINTER(session_data); - - mali_address = descriptor->mali_address + offset; - mali_address_end = descriptor->mali_address + offset + size; - -#if defined USING_MALI400_L2_CACHE - if (0 == _mali_osk_list_empty(&session_data->active_mmus)) - { - /* - * We have active MMUs, so we are probably in the process of alocating more memory for a suspended GP job (PLBU heap) - * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page tables - * from the L2 cache when we have allocated more heap memory. - * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start - */ - has_active_mmus = 1; - } -#endif - - MALI_DEBUG_PRINT(6, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", current_phys_addr, mali_address, size)); - - MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped); - - for ( ; mali_address < mali_address_end; mali_address += MALI_MMU_PAGE_SIZE, current_phys_addr += MALI_MMU_PAGE_SIZE) - { - MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]); - _mali_osk_mem_iowrite32_relaxed(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); - } - _mali_osk_write_mem_barrier(); - -#if defined USING_MALI400_L2_CACHE - if (1 == has_active_mmus) - { - int i; - const int first_pde_idx = MALI_MMU_PDE_ENTRY(mali_address); - const int last_pde_idx = MALI_MMU_PDE_ENTRY(mali_address_end - 1); - - /* - * Invalidate the updated page table(s), incase they have been used for something - * else since last job start (invalidation of entire Mali L2 cache) - */ - for (i = first_pde_idx; i <= last_pde_idx; i++) - { - mali_kernel_l2_cache_invalidate_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); - } - } -#endif - - MALI_SUCCESS; -} - -/* This handler registered to mali_mmap for MMU builds */ -_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) -{ - struct mali_session_data * mali_session_data; - mali_memory_allocation * descriptor; - memory_session * session_data; - - /* validate input */ - if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } - - /* Unpack arguments */ - mali_session_data = (struct mali_session_data *)args->ctx; - - if (NULL == mali_session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: mali_session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } - - MALI_DEBUG_ASSERT( mali_subsystem_memory_id >= 0 ); - - session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id); - /* validate input */ - if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } - - descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) ); - if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } - - descriptor->size = args->size; - descriptor->mali_address = args->phys_addr; - descriptor->mali_addr_mapping_info = (void*)session_data; - - descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */ - descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE; - descriptor->lock = session_data->lock; - _mali_osk_list_init( &descriptor->list ); - - _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head)) - { - mali_kernel_memory_mmu * mmu, * temp_mmu; - - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) - { - /* no need to lock the MMU as we own it already */ - MALI_DEBUG_PRINT(5, ("Zapping the cache of mmu %s as it's using the page table we have updated\n", mmu->description)); - - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - mali_mmu_enable_stall(mmu); /* this might fail, but ZAP should work anyway... */ - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - mali_mmu_disable_stall(mmu); - - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - } - - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - - /* All ok, write out any information generated from this call */ - args->mapping = descriptor->mapping; - args->cookie = (u32)descriptor; - - MALI_DEBUG_PRINT(7, ("MMAP OK\n")); - /* All done */ - MALI_SUCCESS; - } - else - { - _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - /* OOM, but not a fatal error */ - MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n")); - _mali_osk_free(descriptor); - /* Linux will free the CPU address allocation, userspace client the Mali address allocation */ - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -} - -static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) -{ - memory_session * session_data; - mali_kernel_memory_mmu * mmu, * temp_mmu; - mali_memory_allocation * descriptor; - - descriptor = (mali_memory_allocation *)args->cookie; - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /** @note args->context unused; we use the memory_session from the cookie */ - /* args->mapping and args->size are also discarded. They are only necessary - for certain do_munmap implementations. However, they could be used to check the - descriptor at this point. */ - - session_data = (memory_session*)descriptor->mali_addr_mapping_info; - MALI_DEBUG_ASSERT_POINTER(session_data); - - /* Stall the MMU(s) which is using the address space we're operating on. - * Note that active_mmus must be sorted in order of ID to avoid a mutex - * ordering violation. - */ - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) - { - u32 status; - status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS); - if ( MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE == (status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) { - MALI_DEBUG_PRINT(2, ("Stopped stall attempt for mmu with id %d since it is in page fault mode.\n", mmu->id)); - continue; - } - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - - /* - * If we're unable to stall, then make sure we tell our caller that, - * the caller should then release the session lock for a while, - * then this function again. - * This function will fail if we're in page fault mode, and to get - * out of page fault mode, the page fault handler must be able to - * take the session lock. - */ - if (!mali_mmu_enable_stall(mmu)) - { - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_BUSY; - } - - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - } - - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) - { - _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW); - } - - /* This function also removes the memory from the session's memory list */ - mali_allocation_engine_release_memory(memory_engine, descriptor); - _mali_osk_free(descriptor); - - /* any L2 maintenance was done during mali_allocation_engine_release_memory */ - /* the session is locked, so the active mmu list should be the same */ - /* zap the TLB and resume operation */ - _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link) - { - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); - mali_mmu_disable_stall(mmu); - - _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW); - } - - return _MALI_OSK_ERR_OK; -} - -/* Handler for unmapping memory for MMU builds */ -_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) -{ - mali_memory_allocation * descriptor; - _mali_osk_lock_t *descriptor_lock; - _mali_osk_errcode_t err; - - descriptor = (mali_memory_allocation *)args->cookie; - MALI_DEBUG_ASSERT_POINTER(descriptor); - - /** @note args->context unused; we use the memory_session from the cookie */ - /* args->mapping and args->size are also discarded. They are only necessary - for certain do_munmap implementations. However, they could be used to check the - descriptor at this point. */ - - MALI_DEBUG_ASSERT_POINTER((memory_session*)descriptor->mali_addr_mapping_info); - - descriptor_lock = descriptor->lock; /* should point to the session data lock... */ - - err = _MALI_OSK_ERR_BUSY; - while (err == _MALI_OSK_ERR_BUSY) - { - if (descriptor_lock) - { - _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); - } - - err = _mali_ukk_mem_munmap_internal( args ); - - if (descriptor_lock) - { - _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); - } - - if (err == _MALI_OSK_ERR_BUSY) - { - /* - * Reason for this; - * We where unable to stall the MMU, probably because we are in page fault handling. - * Sleep for a while with the session lock released, then try again. - * Abnormal termination of programs with running Mali jobs is a normal reason for this. - */ - _mali_osk_time_ubusydelay(10); - } - } - - return err; -} - -/* Is called when the rendercore wants the mmu to give an interrupt */ -static void mali_mmu_probe_irq_trigger(mali_kernel_memory_mmu * mmu) -{ - MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_trigger\n")); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR); -} - -/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */ -static _mali_osk_errcode_t mali_mmu_probe_irq_acknowledge(mali_kernel_memory_mmu * mmu) -{ - u32 int_stat; - - int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS); - - MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat)); - if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) - { - MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n")); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT); - } - else MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n")); - - if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) - { - MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n")); - mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); - } - else MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n")); - - if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) == - (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) - { - MALI_SUCCESS; - } - - MALI_ERROR(_MALI_OSK_ERR_FAULT); -} - -struct dump_info -{ - u32 buffer_left; - u32 register_writes_size; - u32 page_table_dump_size; - u32 *buffer; -}; - -static _mali_osk_errcode_t writereg(u32 where, u32 what, const char * comment, struct dump_info * info, int dump_to_serial) -{ - if (dump_to_serial) MALI_DEBUG_PRINT(1, ("writereg %08X %08X # %s\n", where, what, comment)); - - if (NULL != info) - { - info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */ - - if (NULL != info->buffer) - { - /* check that we have enough space */ - if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM); - - *info->buffer = where; - info->buffer++; - - *info->buffer = what; - info->buffer++; - - info->buffer_left -= sizeof(u32)*2; - } - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info, int dump_to_serial) -{ - if (dump_to_serial) - { - int i; - for (i = 0; i < 256; i++) - { - MALI_DEBUG_PRINT(1, ("%08X: %08X %08X %08X %08X\n", phys_addr + 16*i, _mali_osk_mem_ioread32(page, (i*4 + 0) * sizeof(u32)), - _mali_osk_mem_ioread32(page, (i*4 + 1) * sizeof(u32)), - _mali_osk_mem_ioread32(page, (i*4 + 2) * sizeof(u32)), - _mali_osk_mem_ioread32(page, (i*4 + 3) * sizeof(u32)))); - - } - } - - if (NULL != info) - { - /* 4096 for the page and 4 bytes for the address */ - const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4; - const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE; - const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4; - - info->page_table_dump_size += dump_size_in_bytes; - - if (NULL != info->buffer) - { - if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM); - - *info->buffer = phys_addr; - info->buffer++; - - _mali_osk_memcpy(info->buffer, page, page_size_in_bytes); - info->buffer += page_size_in_elements; - - info->buffer_left -= dump_size_in_bytes; - } - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t dump_mmu_page_table(memory_session * session_data, struct dump_info * info) -{ - MALI_DEBUG_ASSERT_POINTER(session_data); - MALI_DEBUG_ASSERT_POINTER(info); - - if (NULL != session_data->page_directory_mapped) - { - int i; - - MALI_CHECK_NO_ERROR( - dump_page(session_data->page_directory_mapped, session_data->page_directory, info, 0) - ); - - for (i = 0; i < 1024; i++) - { - if (NULL != session_data->page_entries_mapped[i]) - { - MALI_CHECK_NO_ERROR( - dump_page(session_data->page_entries_mapped[i], _mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info, 0) - ); - } - } - } - - MALI_SUCCESS; -} - -static _mali_osk_errcode_t dump_mmu_registers(memory_session * session_data, struct dump_info * info) -{ - MALI_CHECK_NO_ERROR(writereg(0x00000000, session_data->page_directory, "set the page directory address", info, 0)); - MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info, 0)); - MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info, 0)); - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ) -{ - struct dump_info info = { 0, 0, 0, NULL }; - memory_session * session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - - MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data, &info)); - MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data, &info)); - args->size = info.register_writes_size + info.page_table_dump_size; - MALI_SUCCESS; -} - -_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ) -{ - struct dump_info info = { 0, 0, 0, NULL }; - memory_session * session_data; - - MALI_DEBUG_ASSERT_POINTER(args); - MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); - MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS); - - session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id); - - info.buffer_left = args->size; - info.buffer = args->buffer; - - args->register_writes = info.buffer; - MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data, &info)); - - args->page_table_dump = info.buffer; - MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data, &info)); - - args->register_writes_size = info.register_writes_size; - args->page_table_dump_size = info.page_table_dump_size; - - MALI_SUCCESS; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -/** - * Stub function to satisfy UDD interface exclusion requirement. - * This is because the Base code compiles in \b both MMU and non-MMU calls, - * so both sets must be declared (but the 'unused' set may be stub) - */ -_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args ) -{ - MALI_IGNORE( args ); - return _MALI_OSK_ERR_FAULT; -} - -u32 _mali_ukk_report_memory_usage(void) -{ - return mali_allocation_engine_memory_usage(physical_memory_allocators); -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h b/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h deleted file mode 100644 index 6a110d0..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h +++ /dev/null @@ -1,75 +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 __MALI_KERNEL_MEM_MMU_H__ -#define __MALI_KERNEL_MEM_MMU_H__ - -#include "mali_kernel_session_manager.h" - -/** - * Lookup a MMU core by ID. - * @param id ID of the MMU to find - * @return NULL if ID not found or valid, non-NULL if a core was found. - */ -void* mali_memory_core_mmu_lookup(u32 id); - -/** - * Set the core pointer of MMU to core owner of MMU - * - * @param core Core holding this MMU - * @param mmu_ptr The MMU whose core pointer needs set to core holding the MMU - * - */ -void mali_memory_core_mmu_owner(void *core, void *mmu_ptr); - -/** - * Activate a user session with its address space on the given MMU. - * If the session can't be activated due to that the MMU is busy and - * a callback pointer is given, the callback will be called once the MMU becomes idle. - * If the same callback pointer is registered multiple time it will only be called once. - * Nested activations are supported. - * Each call must be matched by a call to @see mali_memory_core_mmu_release_address_space_reference - * - * @param mmu The MMU to activate the address space on - * @param mali_session_data The user session object which address space to activate - * @param callback Pointer to the function to call when the MMU becomes idle - * @param callback_arg Argument given to the callback - * @return 0 if the address space was activated, -EBUSY if the MMU was busy, -EFAULT in all other cases. - */ -int mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument); - -/** - * Release a reference to the current active address space. - * Once the last reference is released any callback(s) registered will be called before the function returns - * - * @note Caution must be shown calling this function with locks held due to that callback can be called - * @param mmu The mmu to release a reference to the active address space of - */ -void mali_memory_core_mmu_release_address_space_reference(void* mmu); - -/** - * Soft reset of MMU - needed after power up - * - * @param mmu_ptr The MMU pointer registered with the relevant core - */ -void mali_kernel_mmu_reset(void * mmu_ptr); - -void mali_kernel_mmu_force_bus_reset(void * mmu_ptr); - -/** - * Unregister a previously registered callback. - * @param mmu The MMU to unregister the callback on - * @param callback The function to unregister - */ -void mali_memory_core_mmu_unregister_callback(void* mmu, void(*callback)(void*)); - - - -#endif /* __MALI_KERNEL_MEM_MMU_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c index 324fcab..7462a6d 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -65,19 +65,19 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3 info->num_pages_allocated = 0; info->cpu_usage_adjust = cpu_usage_adjust; - info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, 106); - if (NULL != info->mutex) - { - allocator->allocate = os_allocator_allocate; - allocator->allocate_page_table_block = os_allocator_allocate_page_table_block; - allocator->destroy = os_allocator_destroy; + info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); + if (NULL != info->mutex) + { + allocator->allocate = os_allocator_allocate; + allocator->allocate_page_table_block = os_allocator_allocate_page_table_block; + allocator->destroy = os_allocator_destroy; allocator->stat = os_allocator_stat; - allocator->ctx = info; + allocator->ctx = info; allocator->name = name; - return allocator; - } - _mali_osk_free(info); + return allocator; + } + _mali_osk_free(info); } _mali_osk_free(allocator); } @@ -132,7 +132,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER; MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*))); - while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max) && _mali_osk_mem_check_allocated(os_mem_max_usage)) + while (left > 0) { err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE); if ( _MALI_OSK_ERR_OK != err) @@ -243,7 +243,7 @@ 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) { - int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */ + int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 11 */ 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_memory_engine.c b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c index ff105a4..1377560 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -161,13 +161,28 @@ _mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engin void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) { + mali_allocation_engine_release_pt1_mali_pagetables_unmap(mem_engine, descriptor); + mali_allocation_engine_release_pt2_physical_memory_free(mem_engine, descriptor); +} + +void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) +{ memory_engine * engine = (memory_engine*)mem_engine; - mali_physical_memory_allocation * active_allocation_tracker; MALI_DEBUG_ASSERT_POINTER(engine); MALI_DEBUG_ASSERT_POINTER(descriptor); - /* Determine whether we need to remove this from a tracking list */ + /* Calling: mali_address_manager_release() */ + /* This function is allowed to be called several times, and it only does the release on the first call. */ + engine->mali_address->release(descriptor); +} + +void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor) +{ + memory_engine * engine = (memory_engine*)mem_engine; + mali_physical_memory_allocation * active_allocation_tracker; + + /* Remove this from a tracking list in session_data->memory_head */ if ( ! _mali_osk_list_empty( &descriptor->list ) ) { _mali_osk_list_del( &descriptor->list ); @@ -175,8 +190,6 @@ void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, ma MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; ) } - engine->mali_address->release(descriptor); - active_allocation_tracker = &descriptor->physical_allocation; while (NULL != active_allocation_tracker) { @@ -199,7 +212,6 @@ void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, ma } } - _mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size) { _mali_osk_errcode_t err; @@ -244,7 +256,7 @@ _mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine m } } - MALI_DEBUG_PRINT(4, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset)); + MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset)); /* Mali address manager must use the physical address - no point in asking * it to allocate another one for us */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h index 0173c78..cda74c3 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h +++ b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -136,6 +136,9 @@ void mali_allocation_engine_destroy(mali_allocation_engine engine); int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list ); void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor); +void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor); +void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor); + int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size); void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags); diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_pp.h b/drivers/media/video/samsung/mali/common/mali_kernel_pp.h deleted file mode 100644 index 8cf7bf7..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_pp.h +++ /dev/null @@ -1,21 +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 __MALI_KERNEL_PP_H__ -#define __MALI_KERNEL_PP_H__ - -extern struct mali_kernel_subsystem mali_subsystem_mali200; - -#if USING_MALI_PMM -_mali_osk_errcode_t malipp_signal_power_up( u32 core_num, mali_bool queue_only ); -_mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_only ); -#endif - -#endif /* __MALI_KERNEL_PP_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.c b/drivers/media/video/samsung/mali/common/mali_kernel_profiling.c deleted file mode 100644 index ca04b5f..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.c +++ /dev/null @@ -1,364 +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. - */ - -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_osk_mali.h" -#include "mali_ukk.h" -#include "mali_timestamp.h" -#include "mali_kernel_profiling.h" -#include "mali_linux_trace.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; -static mali_bool mali_profiling_default_enable = MALI_FALSE; - -_mali_osk_errcode_t _mali_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_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 ); - 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_profiling_default_enable = MALI_TRUE; /* save this so user space can query this on their startup */ - if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) - { - return _MALI_OSK_ERR_FAULT; - } - } - - return _MALI_OSK_ERR_OK; -} - -void _mali_profiling_term(void) -{ - prof_state = MALI_PROFILING_STATE_UNINITIALIZED; - - /* wait for all elements to be completely inserted into array */ - while (_mali_osk_atomic_read(&profile_insert_index) != _mali_osk_atomic_read(&profile_entries_written)) - { - /* do nothing */; - } - - if (NULL != profile_entries) - { - _mali_osk_vfree(profile_entries); - profile_entries = NULL; - } - - if (NULL != lock) - { - _mali_osk_lock_term(lock); - lock = NULL; - } -} - -inline _mali_osk_errcode_t _mali_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_profiling_add_counter(u32 event_id, u32 data0) -{ -#if MALI_TRACEPOINTS_ENABLED - _mali_osk_profiling_add_counter(event_id, data0); -#endif -} - -inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4) -{ - u32 cur_index = _mali_osk_atomic_inc_return(&profile_insert_index) - 1; - -#if MALI_TRACEPOINTS_ENABLED - _mali_osk_profiling_add_event(event_id, data0); -#endif - - if (prof_state != MALI_PROFILING_STATE_RUNNING || cur_index >= profile_entry_count) - { - /* - * Not in recording mode, or buffer is full - * Decrement index again, and early out - */ - _mali_osk_atomic_dec(&profile_insert_index); - return _MALI_OSK_ERR_FAULT; - } - - profile_entries[cur_index].timestamp = _mali_timestamp_get(); - profile_entries[cur_index].event_id = event_id; - profile_entries[cur_index].data[0] = data0; - profile_entries[cur_index].data[1] = data1; - profile_entries[cur_index].data[2] = data2; - profile_entries[cur_index].data[3] = data3; - profile_entries[cur_index].data[4] = data4; - - _mali_osk_atomic_inc(&profile_entries_written); - - return _MALI_OSK_ERR_OK; -} - -#if MALI_TRACEPOINTS_ENABLED -/* - * The following code uses a bunch of magic numbers taken from the userspace - * side of the DDK; they are re-used here verbatim. They are taken from the - * file mali_instrumented_counter_types.h. - */ -#define MALI_GLES_COUNTER_OFFSET 1000 -#define MALI_VG_COUNTER_OFFSET 2000 -#define MALI_EGL_COUNTER_OFFSET 3000 -#define MALI_SHARED_COUNTER_OFFSET 4000 - -/* These offsets are derived from the gator driver; see gator_events_mali.c. */ -#define GATOR_EGL_COUNTER_OFFSET 17 -#define GATOR_GLES_COUNTER_OFFSET 18 - -_mali_osk_errcode_t _mali_ukk_transfer_sw_counters(_mali_uk_sw_counters_s *args) -{ - /* Convert the DDK counter ID to what gator expects */ - unsigned int gator_counter_value = 0; - - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (args->id >= MALI_EGL_COUNTER_OFFSET && args->id <= MALI_SHARED_COUNTER_OFFSET) - { - gator_counter_value = (args->id - MALI_EGL_COUNTER_OFFSET) + GATOR_EGL_COUNTER_OFFSET; - } - else if (args->id >= MALI_GLES_COUNTER_OFFSET && args->id <= MALI_VG_COUNTER_OFFSET) - { - gator_counter_value = (args->id - MALI_GLES_COUNTER_OFFSET) + GATOR_GLES_COUNTER_OFFSET; - } - else - { - /* Pass it straight through; gator will ignore it anyway. */ - gator_counter_value = args->id; - } - - trace_mali_sw_counter(gator_counter_value, args->value); - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - - return _MALI_OSK_ERR_OK; -} -#endif - -inline _mali_osk_errcode_t _mali_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); - - return _MALI_OSK_ERR_OK; -} - -inline u32 _mali_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); - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - - return retval; -} - -inline _mali_osk_errcode_t _mali_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) -{ - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - - if (prof_state != MALI_PROFILING_STATE_RETURN) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ - } - - if (index >= _mali_osk_atomic_read(&profile_entries_written)) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_FAULT; - } - - *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]; - - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return _MALI_OSK_ERR_OK; -} - -inline _mali_osk_errcode_t _mali_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_profiling_is_recording(void) -{ - return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; -} - -mali_bool _mali_profiling_have_recording(void) -{ - return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; -} - -void _mali_profiling_set_default_enable_state(mali_bool enable) -{ - mali_profiling_default_enable = enable; -} - -mali_bool _mali_profiling_get_default_enable_state(void) -{ - return mali_profiling_default_enable; -} - -_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) -{ - return _mali_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 */ - return _mali_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); -} - -_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) -{ - return _mali_profiling_stop(&args->count); -} - -_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) -{ - return _mali_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_profiling_clear(); -} - -_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args) -{ - args->enable_events = mali_profiling_default_enable; - return _MALI_OSK_ERR_OK; -} diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.h b/drivers/media/video/samsung/mali/common/mali_kernel_profiling.h deleted file mode 100644 index eb1e6c2..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.h +++ /dev/null @@ -1,127 +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 __MALI_KERNEL_PROFILING_H__ -#define __MALI_KERNEL_PROFILING_H__ - -#if MALI_TIMELINE_PROFILING_ENABLED - -#include "cinstr/mali_cinstr_profiling_events_m200.h" - -#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 - -/** - * Initialize the profiling module. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start); - -/* - * Terminate the profiling module. - */ -void _mali_profiling_term(void); - -/** Add a counter event - * @param event_id - Magic counter id - * @param data0 - Value of counter - */ -void _mali_profiling_add_counter(u32 event_id, u32 data0); - -/** - * Start recording profiling data - * - * The specified limit will determine how large the capture buffer is. - * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver. - * - * @param limit The desired maximum number of events to record on input, the actual maximum on output. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_start(u32 * limit); - -/** - * Add an profiling event - * - * @param event_id The event identificator. - * @param data0 First data parameter, depending on event_id specified. - * @param data1 Second data parameter, depending on event_id specified. - * @param data2 Third data parameter, depending on event_id specified. - * @param data3 Fourth data parameter, depending on event_id specified. - * @param data4 Fifth data parameter, depending on event_id specified. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4); - -/** - * Stop recording profiling data - * - * @param count Returns the number of recorded events. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_stop(u32 * count); - -/** - * Retrieves the number of events that can be retrieved - * - * @return The number of recorded events that can be retrieved. - */ -u32 _mali_profiling_get_count(void); - -/** - * Retrieve an event - * - * @param index Event index (start with 0 and continue until this function fails to retrieve all events) - * @param timestamp The timestamp for the retrieved event will be stored here. - * @param event_id The event ID for the retrieved event will be stored here. - * @param data The 5 data values for the retrieved event will be stored here. - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */_mali_osk_errcode_t _mali_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]); - -/** - * Clear the recorded buffer. - * - * This is needed in order to start another recording. - * - * @return _MALI_OSK_ERR_OK on success, otherwise failure. - */ -_mali_osk_errcode_t _mali_profiling_clear(void); - -/** - * Checks if a recording of profiling data is in progress - * - * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not - */ -mali_bool _mali_profiling_is_recording(void); - -/** - * Checks if profiling data is available for retrival - * - * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not - */ -mali_bool _mali_profiling_have_recording(void); - -/** - * Enable or disable profiling events as default for new sessions (applications) - * - * @param enable MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE - */ -void _mali_profiling_set_default_enable_state(mali_bool enable); - -/** - * Get current default enable state for new sessions (applications) - * - * @return MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE - */ -mali_bool _mali_profiling_get_default_enable_state(void); - -#endif /* MALI_TIMELINE_PROFILING_ENABLED */ - -#endif /* __MALI_KERNEL_PROFILING_H__ */ - - diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c b/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c deleted file mode 100644 index cfc5ec1..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c +++ /dev/null @@ -1,2031 +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. - */ - -#include "mali_kernel_common.h" -#include "mali_kernel_core.h" -#include "mali_osk.h" -#include "mali_kernel_subsystem.h" -#include "mali_kernel_rendercore.h" -#include "mali_osk_list.h" -#if MALI_GPU_UTILIZATION -#include "mali_kernel_utilization.h" -#endif -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" -#endif -#if USING_MMU -#include "mali_kernel_mem_mmu.h" -#endif /* USING_MMU */ -#if defined USING_MALI400_L2_CACHE -#include "mali_kernel_l2_cache.h" -#endif /* USING_MALI400_L2_CACHE */ - -#define HANG_CHECK_MSECS_MIN 100 -#define HANG_CHECK_MSECS_MAX 2000 /* 2 secs */ -#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */ - -#define WATCHDOG_MSECS_MIN (10*HANG_CHECK_MSECS_MIN) -#define WATCHDOG_MSECS_MAX 3600000 /* 1 hour */ -#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 secs */ - -/* max value that will be converted from jiffies to micro seconds and written to job->render_time_usecs */ -#define JOB_MAX_JIFFIES 100000 - -int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT; -int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT; - -#if MALI_TIMELINE_PROFILING_ENABLED -int mali_boot_profiling = 0; -#endif - -#ifdef MALI_REBOOTNOTIFIER -extern _mali_osk_atomic_t mali_shutdown_state; -#endif - -/* Subsystem entrypoints: */ -static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id); -static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id); -#if USING_MMU -static void rendercore_subsystem_broadcast_notification(mali_core_notification_message message, u32 data); -#endif - - -static void mali_core_subsystem_cleanup_all_renderunits(struct mali_core_subsystem* subsys); -static void mali_core_subsystem_move_core_set_idle(struct mali_core_renderunit *core); - -static mali_core_session * mali_core_subsystem_get_waiting_session(mali_core_subsystem *subsystem); -static mali_core_job * mali_core_subsystem_release_session_get_job(mali_core_subsystem *subsystem, mali_core_session * session); - -static void find_and_abort(mali_core_session* session, u32 abort_id); - -static void mali_core_job_start_on_core(mali_core_job *job, mali_core_renderunit *core); -#if USING_MMU -static void mali_core_subsystem_callback_schedule_wrapper(void* sub); -#endif -static void mali_core_subsystem_schedule(mali_core_subsystem*subsystem); -static void mali_core_renderunit_detach_job_from_core(mali_core_renderunit* core, mali_subsystem_reschedule_option reschedule, mali_subsystem_job_end_code end_status); - -static void mali_core_renderunit_irq_handler_remove(struct mali_core_renderunit *core); - -static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data); -static void mali_core_irq_handler_bottom_half ( void *data ); - -#if USING_MMU -static void lock_subsystem(struct mali_core_subsystem * subsys); -static void unlock_subsystem(struct mali_core_subsystem * subsys); -#endif - - -/** - * This will be one of the subsystems in the array of subsystems: - * static struct mali_kernel_subsystem * subsystems[]; - * found in file: mali_kernel_core.c - * - * This subsystem is necessary for operations common to all rendercore - * subsystems. For example, mali_subsystem_mali200 and mali_subsystem_gp2 may - * share a mutex when RENDERCORES_USE_GLOBAL_MUTEX is non-zero. - */ -struct mali_kernel_subsystem mali_subsystem_rendercore= -{ - rendercore_subsystem_startup, /* startup */ - NULL, /*rendercore_subsystem_terminate,*/ /* shutdown */ - NULL, /* load_complete */ - NULL, /* system_info_fill */ - NULL, /* session_begin */ - NULL, /* session_end */ -#if USING_MMU - rendercore_subsystem_broadcast_notification, /* broadcast_notification */ -#else - NULL, -#endif -#if MALI_STATE_TRACKING - NULL, /* dump_state */ -#endif -} ; - -static _mali_osk_lock_t *rendercores_global_mutex = NULL; -static u32 rendercores_global_mutex_is_held = 0; -static u32 rendercores_global_mutex_owner = 0; - -/** The 'dummy' rendercore subsystem to allow global subsystem mutex to be - * locked for all subsystems that extend the ''rendercore'' */ -static mali_core_subsystem rendercore_dummy_subsystem = {0,}; - -/* - * Rendercore Subsystem functions. - * - * These are exposed by mali_subsystem_rendercore - */ - -/** - * @brief Initialize the Rendercore subsystem. - * - * This must be called before any other subsystem that extends the - * ''rendercore'' may be initialized. For example, this must be called before - * the following functions: - * - mali200_subsystem_startup(), from mali_subsystem_mali200 - * - maligp_subsystem_startup(), from mali_subsystem_gp2 - * - * @note This function is separate from mali_core_subsystem_init(). They - * are related, in that mali_core_subsystem_init() may use the structures - * initialized by rendercore_subsystem_startup() - */ -static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id) -{ - rendercores_global_mutex_is_held = 0; - rendercores_global_mutex = _mali_osk_lock_init( - (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED), - 0, 129); - - if (NULL == rendercores_global_mutex) - { - MALI_PRINT_ERROR(("Failed: _mali_osk_lock_init\n")) ; - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - rendercore_dummy_subsystem.name = "Rendercore Global Subsystem"; /* On the constant pool, do not free */ - rendercore_dummy_subsystem.magic_nr = SUBSYSTEM_MAGIC_NR; /* To please the Subsystem Mutex code */ - -#if MALI_GPU_UTILIZATION - if (mali_utilization_init() != _MALI_OSK_ERR_OK) - { - _mali_osk_lock_term(rendercores_global_mutex); - rendercores_global_mutex = NULL; - MALI_PRINT_ERROR(("Failed: mali_utilization_init\n")) ; - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#endif - -#if MALI_TIMELINE_PROFILING_ENABLED - if (_mali_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE) != _MALI_OSK_ERR_OK) - { - /* No biggie if we wheren't able to initialize the profiling */ - MALI_PRINT_ERROR(("Rendercore: Failed to initialize profiling, feature will be unavailable\n")) ; - } -#endif - - MALI_DEBUG_PRINT(2, ("Rendercore: subsystem global mutex initialized\n")) ; - MALI_SUCCESS; -} - -/** - * @brief Terminate the Rendercore subsystem. - * - * This must only be called \b after any other subsystem that extends the - * ''rendercore'' has been terminated. For example, this must be called \b after - * the following functions: - * - mali200_subsystem_terminate(), from mali_subsystem_mali200 - * - maligp_subsystem_terminate(), from mali_subsystem_gp2 - * - * @note This function is separate from mali_core_subsystem_cleanup(), though, - * the subsystems that extend ''rendercore'' must still call - * mali_core_subsystem_cleanup() when they terminate. - */ -static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id) -{ - /* Catch double-terminate */ - MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex ); - -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_term(); -#endif - -#if MALI_GPU_UTILIZATION - mali_utilization_term(); -#endif - - rendercore_dummy_subsystem.name = NULL; /* The original string was on the constant pool, do not free */ - rendercore_dummy_subsystem.magic_nr = 0; - - /* ASSERT that no-one's holding this */ - MALI_DEBUG_PRINT_ASSERT( 0 == rendercores_global_mutex_is_held, - ("Rendercores' Global Mutex was held at termination time. Have the subsystems that extend ''rendercore'' been terminated?\n") ); - - _mali_osk_lock_term( rendercores_global_mutex ); - rendercores_global_mutex = NULL; - - MALI_DEBUG_PRINT(2, ("Rendercore: subsystem global mutex terminated\n")) ; -} - - -#if USING_MMU -/** - * @brief Handle certain Rendercore subsystem broadcast notifications - * - * When RENDERCORES_USE_GLOBAL_MUTEX is non-zero, this handles the following messages: - * - MMU_KILL_STEP0_LOCK_SUBSYSTEM - * - MMU_KILL_STEP4_UNLOCK_SUBSYSTEM - * - * The purpose is to manage the Rendercode Global Mutex, which cannot be - * managed by any system that extends the ''rendercore''. - * - * All other messages must be handled by mali_core_subsystem_broadcast_notification() - * - * - * When RENDERCORES_USE_GLOBAL_MUTEX is 0, this function does nothing. - * Instead, the subsystem that extends the ''rendercore' \b must handle its - * own mutexes - refer to mali_core_subsystem_broadcast_notification(). - * - * Used currently only for signalling when MMU has a pagefault - */ -static void rendercore_subsystem_broadcast_notification(mali_core_notification_message message, u32 data) -{ - switch(message) - { - case MMU_KILL_STEP0_LOCK_SUBSYSTEM: - lock_subsystem( &rendercore_dummy_subsystem ); - break; - case MMU_KILL_STEP4_UNLOCK_SUBSYSTEM: - unlock_subsystem( &rendercore_dummy_subsystem ); - break; - - case MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES: - /** FALLTHROUGH */ - case MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS: - /** FALLTHROUGH */ - case MMU_KILL_STEP3_CONTINUE_JOB_HANDLING: - break; - - default: - MALI_PRINT_ERROR(("Illegal message: 0x%x, data: 0x%x\n", (u32)message, data)); - break; - } - -} -#endif - -/* - * Functions inherited by the subsystems that extend the ''rendercore''. - */ - -void mali_core_renderunit_timeout_function_hang_detection(void *arg) -{ - mali_bool action = MALI_FALSE; - mali_core_renderunit * core; - - core = (mali_core_renderunit *) arg; - if( !core ) return; - - /* if NOT idle OR NOT powered off OR has TIMED_OUT */ - if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state) || (CORE_OFF == core->state)) ) - { - core->state = CORE_HANG_CHECK_TIMEOUT; - action = MALI_TRUE; - } - - if(action) _mali_osk_irq_schedulework(core->irq); -} - - -void mali_core_renderunit_timeout_function(void *arg) -{ - mali_core_renderunit * core; - mali_bool is_watchdog; - - core = (mali_core_renderunit *)arg; - if( !core ) return; - - is_watchdog = MALI_TRUE; - if (mali_benchmark) - { - /* poll based core */ - mali_core_job *job; - job = core->current_job; - if ( (NULL != job) && - (0 != _mali_osk_time_after(job->watchdog_jiffies,_mali_osk_time_tickcount())) - ) - { - core->state = CORE_POLL; - is_watchdog = MALI_FALSE; - } - } - - if (is_watchdog) - { - MALI_DEBUG_PRINT(3, ("SW-Watchdog timeout: Core:%s\n", core->description)); - core->state = CORE_WATCHDOG_TIMEOUT; - } - - _mali_osk_irq_schedulework(core->irq); -} - -/* Used by external renderunit_create<> function */ -_mali_osk_errcode_t mali_core_renderunit_init(mali_core_renderunit * core) -{ - MALI_DEBUG_PRINT(5, ("Core: renderunit_init: Core:%s\n", core->description)); - - _MALI_OSK_INIT_LIST_HEAD(&core->list) ; - core->timer = _mali_osk_timer_init(); - if (NULL == core->timer) - { - MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot init timer\n", core->description)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - _mali_osk_timer_setcallback(core->timer, mali_core_renderunit_timeout_function, (void *)core); - - core->timer_hang_detection = _mali_osk_timer_init(); - if (NULL == core->timer_hang_detection) - { - _mali_osk_timer_term(core->timer); - MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot init hang detection timer\n", core->description)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - _mali_osk_timer_setcallback(core->timer_hang_detection, mali_core_renderunit_timeout_function_hang_detection, (void *)core); - -#if USING_MALI_PMM - /* Init no pending power downs */ - core->pend_power_down = MALI_FALSE; - - /* Register the core with the PMM - which powers it up */ - if (_MALI_OSK_ERR_OK != malipmm_core_register( core->pmm_id )) - { - _mali_osk_timer_term(core->timer); - _mali_osk_timer_term(core->timer_hang_detection); - MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot register with PMM\n", core->description)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#endif /* USING_MALI_PMM */ - - core->error_recovery = MALI_FALSE; - core->in_detach_function = MALI_FALSE; - core->state = CORE_IDLE; - core->current_job = NULL; - core->magic_nr = CORE_MAGIC_NR; -#if USING_MMU - core->mmu = NULL; -#endif /* USING_MMU */ - - MALI_SUCCESS; -} - -void mali_core_renderunit_term(mali_core_renderunit * core) -{ - MALI_DEBUG_PRINT(5, ("Core: renderunit_term: Core:%s\n", core->description)); - - if (NULL != core->timer) - { - _mali_osk_timer_term(core->timer); - core->timer = NULL; - } - if (NULL != core->timer_hang_detection) - { - _mali_osk_timer_term(core->timer_hang_detection); - core->timer_hang_detection = NULL; - } - -#if USING_MALI_PMM - /* Unregister the core with the PMM */ - malipmm_core_unregister( core->pmm_id ); -#endif -} - -/* Used by external renderunit_create<> function */ -_mali_osk_errcode_t mali_core_renderunit_map_registers(mali_core_renderunit *core) -{ - MALI_DEBUG_PRINT(3, ("Core: renderunit_map_registers: Core:%s\n", core->description)) ; - if( (0 == core->registers_base_addr) || - (0 == core->size) || - (NULL == core->description) - ) - { - MALI_PRINT_ERROR(("Missing fields in the core structure %u %u 0x%x;\n", core->registers_base_addr, core->size, core->description)); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(core->registers_base_addr, core->size, core->description)) - { - MALI_PRINT_ERROR(("Could not request register region (0x%08X - 0x%08X) to core: %s\n", - core->registers_base_addr, core->registers_base_addr + core->size - 1, core->description)); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - else - { - MALI_DEBUG_PRINT(6, ("Success: request_mem_region: (0x%08X - 0x%08X) Core:%s\n", - core->registers_base_addr, core->registers_base_addr + core->size - 1, core->description)); - } - - core->registers_mapped = _mali_osk_mem_mapioregion( core->registers_base_addr, core->size, core->description ); - - if ( 0 == core->registers_mapped ) - { - MALI_PRINT_ERROR(("Could not ioremap registers for %s .\n", core->description)); - _mali_osk_mem_unreqregion(core->registers_base_addr, core->size); - MALI_ERROR(_MALI_OSK_ERR_NOMEM); - } - else - { - MALI_DEBUG_PRINT(6, ("Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) Core:%s\n", - (u32) core->registers_mapped, - ((u32)core->registers_mapped)+ core->size - 1, - core->description)); - } - - MALI_DEBUG_PRINT(4, ("Success: Mapping registers to core: %s\n",core->description)); - - MALI_SUCCESS; -} - -/* Used by external renderunit_create<> function + other places */ -void mali_core_renderunit_unmap_registers(mali_core_renderunit *core) -{ - MALI_DEBUG_PRINT(3, ("Core: renderunit_unmap_registers: Core:%s\n", core->description)); - if (0 == core->registers_mapped) - { - MALI_PRINT_ERROR(("Trying to unmap register-mapping with NULL from core: %s\n", core->description)); - return; - } - _mali_osk_mem_unmapioregion(core->registers_base_addr, core->size, core->registers_mapped); - core->registers_mapped = 0; - _mali_osk_mem_unreqregion(core->registers_base_addr, core->size); -} - -static void mali_core_renderunit_irq_handler_remove(mali_core_renderunit *core) -{ - MALI_DEBUG_PRINT(3, ("Core: renderunit_irq_handler_remove: Core:%s\n", core->description)); - _mali_osk_irq_term(core->irq); -} - -mali_core_renderunit * mali_core_renderunit_get_mali_core_nr(mali_core_subsystem *subsys, u32 mali_core_nr) -{ - mali_core_renderunit * core; - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); - if (subsys->number_of_cores <= mali_core_nr) - { - MALI_PRINT_ERROR(("Trying to get illegal mali_core_nr: 0x%x for %s", mali_core_nr, subsys->name)); - return NULL; - } - core = (subsys->mali_core_array)[mali_core_nr]; - MALI_DEBUG_PRINT(6, ("Core: renderunit_get_mali_core_nr: Core:%s\n", core->description)); - MALI_CHECK_CORE(core); - return core; -} - -/* Is used by external function: - subsystem_startup<> */ -_mali_osk_errcode_t mali_core_subsystem_init(mali_core_subsystem* new_subsys) -{ - int i; - - /* These function pointers must have been set on before calling this function */ - if ( - ( NULL == new_subsys->name ) || - ( NULL == new_subsys->start_job ) || - ( NULL == new_subsys->irq_handler_upper_half ) || - ( NULL == new_subsys->irq_handler_bottom_half ) || - ( NULL == new_subsys->get_new_job_from_user ) || - ( NULL == new_subsys->return_job_to_user ) - ) - { - MALI_PRINT_ERROR(("Missing functions in subsystem.")); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - MALI_DEBUG_PRINT(2, ("Core: subsystem_init: %s\n", new_subsys->name)) ; - - /* Catch use-before-initialize/use-after-terminate */ - MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex ); - - new_subsys->magic_nr = SUBSYSTEM_MAGIC_NR; - - _MALI_OSK_INIT_LIST_HEAD(&new_subsys->renderunit_idle_head); /* Idle cores of this type */ - _MALI_OSK_INIT_LIST_HEAD(&new_subsys->renderunit_off_head); /* Powered off cores of this type */ - - /* Linked list for each priority of sessions with a job ready for scheduleing */ - for(i=0; iawaiting_sessions_head[i]); - } - - /* Linked list of all sessions connected to this coretype */ - _MALI_OSK_INIT_LIST_HEAD(&new_subsys->all_sessions_head); - - MALI_SUCCESS; -} - -#if USING_MMU -void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys) -{ - u32 i; - mali_core_renderunit * core; - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - - for(i=0 ; i < subsys->number_of_cores ; ++i) - { - core = mali_core_renderunit_get_mali_core_nr(subsys,i); - if ( NULL==core ) break; - core->mmu = mali_memory_core_mmu_lookup(core->mmu_id); - mali_memory_core_mmu_owner(core,core->mmu); - MALI_DEBUG_PRINT(2, ("Attach mmu: 0x%x to core: %s in subsystem: %s\n", core->mmu, core->description, subsys->name)); - } - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); -} -#endif - -/* This will register an IRQ handler, and add the core to the list of available cores for this subsystem. */ -_mali_osk_errcode_t mali_core_subsystem_register_renderunit(mali_core_subsystem* subsys, mali_core_renderunit * core) -{ - mali_core_renderunit ** mali_core_array; - u32 previous_nr; - u32 previous_size; - u32 new_nr; - u32 new_size; - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - - /* If any of these are 0 there is an error */ - if(0 == core->subsystem || - 0 == core->registers_base_addr || - 0 == core->size || - 0 == core->description) - { - MALI_PRINT_ERROR(("Missing fields in the core structure 0x%x 0x%x 0x%x;\n", - core->registers_base_addr, core->size, core->description)); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - MALI_DEBUG_PRINT(3, ("Core: subsystem_register_renderunit: %s\n", core->description)); - - MALI_CHECK_NON_NULL( - core->irq = _mali_osk_irq_init( - core->irq_nr, - mali_core_irq_handler_upper_half, - mali_core_irq_handler_bottom_half, - (_mali_osk_irq_trigger_t)subsys->probe_core_irq_trigger, - (_mali_osk_irq_ack_t)subsys->probe_core_irq_acknowledge, - core, - "mali_core_irq_handlers" - ), - _MALI_OSK_ERR_FAULT - ); - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - - /* Update which core number this is */ - core->core_number = subsys->number_of_cores; - - /* Update the array of cores in the subsystem. */ - previous_nr = subsys->number_of_cores; - previous_size = sizeof(mali_core_renderunit*)*previous_nr; - new_nr = previous_nr + 1; - new_size = sizeof(mali_core_renderunit*)*new_nr; - - if (0 != previous_nr) - { - if (NULL == subsys->mali_core_array) - { - MALI_PRINT_ERROR(("Internal error")); - goto exit_function; - } - - mali_core_array = (mali_core_renderunit **) _mali_osk_malloc( new_size ); - if (NULL == mali_core_array ) - { - MALI_PRINT_ERROR(("Out of mem")); - err = _MALI_OSK_ERR_NOMEM; - goto exit_function; - } - _mali_osk_memcpy(mali_core_array, subsys->mali_core_array, previous_size); - _mali_osk_free( subsys->mali_core_array); - MALI_DEBUG_PRINT(5, ("Success: adding a new core to subsystem array %s\n", core->description) ) ; - } - else - { - mali_core_array = (mali_core_renderunit **) _mali_osk_malloc( new_size ); - if (NULL == mali_core_array ) - { - MALI_PRINT_ERROR(("Out of mem")); - err = _MALI_OSK_ERR_NOMEM; - goto exit_function; - } - MALI_DEBUG_PRINT(6, ("Success: adding first core to subsystem array %s\n", core->description) ) ; - } - subsys->mali_core_array = mali_core_array; - mali_core_array[previous_nr] = core; - - /* Add the core to the list of available cores on the system */ - _mali_osk_list_add(&(core->list), &(subsys->renderunit_idle_head)); - - /* Update total number of cores */ - subsys->number_of_cores = new_nr; - MALI_DEBUG_PRINT(6, ("Success: mali_core_subsystem_register_renderunit %s\n", core->description)); - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_SUCCESS; - -exit_function: - mali_core_renderunit_irq_handler_remove(core); - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_ERROR(err); -} - - -/** - * Called by the core when a system info update is needed - * We fill in info about all the core types available - * @param subsys Pointer to the core's @a mali_core_subsystem data structure - * @param info Pointer to system info struct to update - * @return _MALI_OSK_ERR_OK on success, or another _mali_osk_errcode_t error code on failure - */ -_mali_osk_errcode_t mali_core_subsystem_system_info_fill(mali_core_subsystem* subsys, _mali_system_info* info) -{ - u32 i; - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; /* OK if no cores to update info for */ - mali_core_renderunit * core; - _mali_core_info **core_info_nextp; - _mali_core_info * cinfo; - - MALI_DEBUG_PRINT(4, ("mali_core_subsystem_system_info_fill: %s\n", subsys->name) ) ; - - /* check input */ - MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS); - - core_info_nextp = &(info->core_info); - cinfo = info->core_info; - - while(NULL!=cinfo) - { - core_info_nextp = &(cinfo->next); - cinfo = cinfo->next; - } - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - for(i=0 ; i < subsys->number_of_cores ; ++i) - { - core = mali_core_renderunit_get_mali_core_nr(subsys,i); - if ( NULL==core ) - { - err = _MALI_OSK_ERR_FAULT; - goto early_exit; - } - cinfo = (_mali_core_info *)_mali_osk_calloc(1, sizeof(_mali_core_info)); - if ( NULL==cinfo ) - { - err = _MALI_OSK_ERR_NOMEM; - goto early_exit; - } - cinfo->version = core->core_version; - cinfo->type =subsys->core_type; - cinfo->reg_address = core->registers_base_addr; - cinfo->core_nr = i; - cinfo->next = NULL; - /* Writing this address to the previous' *(&next) ptr */ - *core_info_nextp = cinfo; - /* Setting the next_ptr to point to &this->next_ptr */ - core_info_nextp = &(cinfo->next); - } -early_exit: - if ( _MALI_OSK_ERR_OK != err) MALI_PRINT_ERROR(("Error: In mali_core_subsystem_system_info_fill %d\n", err)); - MALI_DEBUG_CODE( - cinfo = info->core_info; - - MALI_DEBUG_PRINT(3, ("Current list of cores\n")); - while( NULL != cinfo ) - { - MALI_DEBUG_PRINT(3, ("Type: 0x%x\n", cinfo->type)); - MALI_DEBUG_PRINT(3, ("Version: 0x%x\n", cinfo->version)); - MALI_DEBUG_PRINT(3, ("Reg_addr: 0x%x\n", cinfo->reg_address)); - MALI_DEBUG_PRINT(3, ("Core_nr: 0x%x\n", cinfo->core_nr)); - MALI_DEBUG_PRINT(3, ("Flags: 0x%x\n", cinfo->flags)); - MALI_DEBUG_PRINT(3, ("*****\n")); - cinfo = cinfo->next; - } - ); - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_ERROR(err); -} - - -/* Is used by external function: - subsystem_terminate<> */ -void mali_core_subsystem_cleanup(mali_core_subsystem* subsys) -{ - u32 i; - mali_core_renderunit * core; - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - MALI_DEBUG_PRINT(2, ("Core: subsystem_cleanup: %s\n", subsys->name )) ; - - for(i=0 ; i < subsys->number_of_cores ; ++i) - { - core = mali_core_renderunit_get_mali_core_nr(subsys,i); - -#if USING_MMU - if (NULL != core->mmu) - { - /* the MMU is attached in the load_complete callback, which will never be called if the module fails to load, handle that case */ - mali_memory_core_mmu_unregister_callback(core->mmu, mali_core_subsystem_callback_schedule_wrapper); - } -#endif - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - - mali_core_renderunit_irq_handler_remove(core); - - /* When a process terminates, all cores running jobs from that process is reset and put to idle. - That means that when the module is unloading (this code) we are guaranteed that all cores are idle. - However: if something (we can't think of) is really wrong, a core may give an interrupt during this - unloading, and we may now in the code have a bottom-half-processing pending from the interrupts - we deregistered above. To be sure that the bottom halves do not access the structures after they - are deallocated we flush the bottom-halves processing here, before the deallocation. */ - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - -#if USING_MALI_PMM - /* Only reset when we are using PMM and the core is not off */ -#if MALI_PMM_NO_PMU - /* We need to reset when there is no PMU - but this will - * cause the register read/write functions to report an - * error (hence the if to check for CORE_OFF below) we - * change state to allow the reset to happen. - */ - core->state = CORE_IDLE; -#endif - if( core->state != CORE_OFF ) - { - subsys->reset_core( core, MALI_CORE_RESET_STYLE_DISABLE ); - } -#else - /* Always reset the core */ - subsys->reset_core( core, MALI_CORE_RESET_STYLE_DISABLE ); -#endif - - mali_core_renderunit_unmap_registers(core); - - _mali_osk_list_delinit(&core->list); - - mali_core_renderunit_term(core); - - subsys->renderunit_delete(core); - } - - mali_core_subsystem_cleanup_all_renderunits(subsys); - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT(6, ("SUCCESS: mali_core_subsystem_cleanup: %s\n", subsys->name )) ; -} - -_mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_session * session, u32 *number_of_cores) -{ - mali_core_subsystem * subsystem; - - subsystem = session->subsystem; - if ( NULL != number_of_cores ) - { - *number_of_cores = subsystem->number_of_cores; - - MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ; - } - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data) -{ - mali_core_subsystem * subsystem; - _mali_osk_errcode_t err; - - /* need the subsystem to run callback function */ - subsystem = session->subsystem; - MALI_CHECK_NON_NULL(subsystem, _MALI_OSK_ERR_FAULT); - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem); - err = subsystem->get_new_job_from_user(session, job_data); - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); - - MALI_ERROR(err); -} - - -/* We return the version number to the first core in this subsystem */ -_mali_osk_errcode_t mali_core_subsystem_ioctl_core_version_get(mali_core_session * session, _mali_core_version *version) -{ - mali_core_subsystem * subsystem; - mali_core_renderunit * core0; - u32 nr_return; - - subsystem = session->subsystem; - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem); - - core0 = mali_core_renderunit_get_mali_core_nr(subsystem, 0); - - if( NULL == core0 ) - { - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - nr_return = core0->core_version; - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); - - MALI_DEBUG_PRINT(4, ("Core: ioctl_core_version_get: %s: %u\n", subsystem->name, nr_return )) ; - - *version = nr_return; - - MALI_SUCCESS; -} - -void mali_core_subsystem_ioctl_abort_job(mali_core_session * session, u32 id) -{ - find_and_abort(session, id); -} - -static mali_bool job_should_be_aborted(mali_core_job *job, u32 abort_id) -{ - if ( job->abort_id == abort_id ) return MALI_TRUE; - else return MALI_FALSE; -} - -static void find_and_abort(mali_core_session* session, u32 abort_id) -{ - mali_core_subsystem * subsystem; - mali_core_renderunit *core; - mali_core_renderunit *tmp; - mali_core_job *job; - - subsystem = session->subsystem; - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem ); - - job = mali_job_queue_abort_job(session, abort_id); - if (NULL != job) - { - MALI_DEBUG_PRINT(3, ("Core: Aborting %s job, with id nr: %u, from the waiting_to_run slot.\n", subsystem->name, abort_id )); - if (mali_job_queue_empty(session)) - { - _mali_osk_list_delinit(&(session->awaiting_sessions_list)); - } - subsystem->awaiting_sessions_sum_all_priorities--; - subsystem->return_job_to_user(job , JOB_STATUS_END_ABORT); - } - - _MALI_OSK_LIST_FOREACHENTRY( core, tmp, &session->renderunits_working_head, mali_core_renderunit, list ) - { - job = core->current_job; - if ( (job!=NULL) && (job_should_be_aborted (job, abort_id) ) ) - { - MALI_DEBUG_PRINT(3, ("Core: Aborting %s job, with id nr: %u, which is currently running on mali.\n", subsystem->name, abort_id )); - if ( core->state==CORE_IDLE ) - { - MALI_PRINT_ERROR(("Aborting core with running job which is idle. Must be something very wrong.")); - goto end_bug; - } - mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_ABORT); - } - } -end_bug: - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem ); -} - - -_mali_osk_errcode_t mali_core_subsystem_ioctl_suspend_response(mali_core_session * session, void *argument) -{ - mali_core_subsystem * subsystem; - _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; - - /* need the subsystem to run callback function */ - subsystem = session->subsystem; - MALI_CHECK_NON_NULL(subsystem, _MALI_OSK_ERR_FAULT); - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem); - if ( NULL != subsystem->suspend_response) - { - MALI_DEBUG_PRINT(4, ("MALI_IOC_CORE_CMD_SUSPEND_RESPONSE start\n")); - err = subsystem->suspend_response(session, argument); - MALI_DEBUG_PRINT(4, ("MALI_IOC_CORE_CMD_SUSPEND_RESPONSE end\n")); - } - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); - - return err; -} - - -/* Is used by internal function: - mali_core_subsystem_cleanup<>s */ -/* All cores should be removed before calling this function -Must hold subsystem_mutex before entering this function */ -static void mali_core_subsystem_cleanup_all_renderunits(mali_core_subsystem* subsys) -{ - int i; - _mali_osk_free(subsys->mali_core_array); - subsys->number_of_cores = 0; - - MALI_DEBUG_PRINT(5, ("Core: subsystem_cleanup_all_renderunits: %s\n", subsys->name) ) ; - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); - - if ( ! _mali_osk_list_empty(&(subsys->renderunit_idle_head))) - { - MALI_PRINT_ERROR(("List renderunit_list_idle should be empty.")); - _MALI_OSK_INIT_LIST_HEAD(&(subsys->renderunit_idle_head)) ; - } - - if ( ! _mali_osk_list_empty(&(subsys->renderunit_off_head))) - { - MALI_PRINT_ERROR(("List renderunit_list_off should be empty.")); - _MALI_OSK_INIT_LIST_HEAD(&(subsys->renderunit_off_head)) ; - } - - for(i=0; iawaiting_sessions_head[i]))) - { - MALI_PRINT_ERROR(("List awaiting_sessions_linkedlist should be empty.")); - _MALI_OSK_INIT_LIST_HEAD(&(subsys->awaiting_sessions_head[i])) ; - subsys->awaiting_sessions_sum_all_priorities = 0; - } - } - - if ( ! _mali_osk_list_empty(&(subsys->all_sessions_head))) - { - MALI_PRINT_ERROR(("List all_sessions_linkedlist should be empty.")); - _MALI_OSK_INIT_LIST_HEAD(&(subsys->all_sessions_head)) ; - } -} - -/* Is used by internal functions: - mali_core_irq_handler_bottom_half<>; - mali_core_subsystem_schedule<>; */ -/* Will release the core.*/ -/* Must hold subsystem_mutex before entering this function */ -static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core) -{ - mali_core_subsystem *subsystem; -#if USING_MALI_PMM - mali_core_status oldstatus; -#endif - subsystem = core->subsystem; - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - MALI_CHECK_CORE(core); - MALI_CHECK_SUBSYSTEM(subsystem); - - _mali_osk_timer_del(core->timer); - _mali_osk_timer_del(core->timer_hang_detection); - - MALI_DEBUG_PRINT(5, ("Core: subsystem_move_core_set_idle: %s\n", core->description) ) ; - - core->current_job = NULL ; - -#if USING_MALI_PMM - - oldstatus = core->state; - - if ( !core->pend_power_down ) - { - core->state = CORE_IDLE ; - _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head ); - } - - if( CORE_OFF != oldstatus ) - { - /* Message that this core is now idle or in fact off */ - _mali_uk_pmm_message_s event = { - NULL, - MALI_PMM_EVENT_JOB_FINISHED, - 0 }; - event.data = core->pmm_id; - _mali_ukk_pmm_event_message( &event ); -#if USING_MMU - /* Only free the reference when entering idle state from - * anything other than power off - */ - mali_memory_core_mmu_release_address_space_reference(core->mmu); -#endif /* USING_MMU */ - } - - if( core->pend_power_down ) - { - core->state = CORE_OFF ; - _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head ); - - /* Done the move from the active queues, so the pending power down can be done */ - core->pend_power_down = MALI_FALSE; - malipmm_core_power_down_okay( core->pmm_id ); - } - -#else /* !USING_MALI_PMM */ - - core->state = CORE_IDLE ; - _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head ); - -#if USING_MMU - mali_memory_core_mmu_release_address_space_reference(core->mmu); -#endif - -#endif /* USING_MALI_PMM */ -} - -/* Must hold subsystem_mutex before entering this function */ -static void mali_core_subsystem_move_set_working(mali_core_renderunit *core, mali_core_job *job) -{ - mali_core_subsystem *subsystem; - mali_core_session *session; - u64 time_now; - - session = job->session; - subsystem = core->subsystem; - - MALI_CHECK_CORE(core); - MALI_CHECK_JOB(job); - MALI_CHECK_SUBSYSTEM(subsystem); - - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - - MALI_DEBUG_PRINT(5, ("Core: subsystem_move_set_working: %s\n", core->description) ) ; - - time_now = _mali_osk_time_get_ns(); - job->start_time = time_now; -#if MALI_GPU_UTILIZATION - mali_utilization_core_start(time_now); -#endif - - core->current_job = job ; - core->state = CORE_WORKING ; - _mali_osk_list_move( &core->list, &session->renderunits_working_head ); - -} - -#if USING_MALI_PMM - -/* Must hold subsystem_mutex before entering this function */ -static void mali_core_subsystem_move_core_set_off(mali_core_renderunit *core) -{ - mali_core_subsystem *subsystem; - subsystem = core->subsystem; - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - MALI_CHECK_CORE(core); - MALI_CHECK_SUBSYSTEM(subsystem); - - /* Cores must be idle before powering off */ - MALI_DEBUG_ASSERT(core->state == CORE_IDLE); - - MALI_DEBUG_PRINT(5, ("Core: subsystem_move_core_set_off: %s\n", core->description) ) ; - - core->current_job = NULL ; - core->state = CORE_OFF ; - _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head ); -} - -#endif /* USING_MALI_PMM */ - -/* Is used by internal function: - mali_core_subsystem_schedule<>; */ -/* Returns the job with the highest priority for the subsystem. NULL if none*/ -/* Must hold subsystem_mutex before entering this function */ -static mali_core_session * mali_core_subsystem_get_waiting_session(mali_core_subsystem *subsystem) -{ - int i; - - MALI_CHECK_SUBSYSTEM(subsystem); - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - - if ( 0 == subsystem->awaiting_sessions_sum_all_priorities ) - { - MALI_DEBUG_PRINT(5, ("Core: subsystem_get_waiting_job: No awaiting session found\n")); - return NULL; - } - - for( i=0; iawaiting_sessions_head[i])) - { - return _MALI_OSK_LIST_ENTRY(subsystem->awaiting_sessions_head[i].next, mali_core_session, awaiting_sessions_list); - } - } - - return NULL; -} - -static mali_core_job * mali_core_subsystem_release_session_get_job(mali_core_subsystem *subsystem, mali_core_session * session) -{ - mali_core_job *job; - MALI_CHECK_SUBSYSTEM(subsystem); - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - - job = mali_job_queue_get_job(session); - subsystem->awaiting_sessions_sum_all_priorities--; - - if(mali_job_queue_empty(session)) - { - /* This is the last job, so remove it from the list */ - _mali_osk_list_delinit(&session->awaiting_sessions_list); - } - else - { - if (0 == (job->flags & MALI_UK_START_JOB_FLAG_MORE_JOBS_FOLLOW)) - { - /* There are more jobs, but the follow flag is not set, so let other sessions run their jobs first */ - _mali_osk_list_del(&(session->awaiting_sessions_list)); - _mali_osk_list_addtail(&(session->awaiting_sessions_list), &(subsystem->awaiting_sessions_head[ - session->queue[session->queue_head]->priority])); - } - /* else; keep on list, follow flag is set and there are more jobs in queue for this session */ - } - - MALI_CHECK_JOB(job); - return job; -} - -/* Is used by internal functions: - mali_core_subsystem_schedule<> */ -/* This will start the job on the core. It will also release the core if it did not start.*/ -/* Must hold subsystem_mutex before entering this function */ -static void mali_core_job_start_on_core(mali_core_job *job, mali_core_renderunit *core) -{ - mali_core_session *session; - mali_core_subsystem *subsystem; - _mali_osk_errcode_t err; - session = job->session; - subsystem = core->subsystem; - - MALI_CHECK_CORE(core); - MALI_CHECK_JOB(job); - MALI_CHECK_SUBSYSTEM(subsystem); - MALI_CHECK_SESSION(session); - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - - MALI_DEBUG_PRINT(4, ("Core: job_start_on_core: job=0x%x, session=0x%x, core=%s\n", job, session, core->description)); - - MALI_DEBUG_ASSERT(NULL == core->current_job) ; - MALI_DEBUG_ASSERT(CORE_IDLE == core->state ); - - mali_core_subsystem_move_set_working(core, job); - -#if defined USING_MALI400_L2_CACHE - if (0 == (job->flags & MALI_UK_START_JOB_FLAG_NO_FLUSH)) - { - /* Invalidate the L2 cache */ - if (_MALI_OSK_ERR_OK != mali_kernel_l2_cache_invalidate_all() ) - { - MALI_DEBUG_PRINT(4, ("Core: Clear of L2 failed, return job. System may not be usable for some reason.\n")); - mali_core_subsystem_move_core_set_idle(core); - subsystem->return_job_to_user(job,JOB_STATUS_END_SYSTEM_UNUSABLE ); - return; - } - } -#endif - - /* Tries to start job on the core. Returns MALI_FALSE if the job could not be started */ - err = subsystem->start_job(job, core); - - if ( _MALI_OSK_ERR_OK != err ) - { - /* This will happen only if there is something in the job object - which make it inpossible to start. Like if it require illegal memory.*/ - MALI_DEBUG_PRINT(4, ("Core: start_job failed, return job and putting core back into idle list\n")); - mali_core_subsystem_move_core_set_idle(core); - subsystem->return_job_to_user(job,JOB_STATUS_END_ILLEGAL_JOB ); - } - else - { - u32 delay = _mali_osk_time_mstoticks(job->watchdog_msecs)+1; - job->watchdog_jiffies = _mali_osk_time_tickcount() + delay; - if (mali_benchmark) - { - _mali_osk_timer_add(core->timer, 1); - } - else - { - _mali_osk_timer_add(core->timer, delay); - } - } -} - -#if USING_MMU -static void mali_core_subsystem_callback_schedule_wrapper(void* sub) -{ - mali_core_subsystem * subsystem; - subsystem = (mali_core_subsystem *)sub; - MALI_DEBUG_PRINT(3, ("MMU: Is schedulling subsystem: %s\n", subsystem->name)); - mali_core_subsystem_schedule(subsystem); -} -#endif - -/* Is used by internal function: - mali_core_irq_handler_bottom_half - mali_core_session_add_job -*/ -/* Must hold subsystem_mutex before entering this function */ -static void mali_core_subsystem_schedule(mali_core_subsystem * subsystem) -{ - mali_core_renderunit *core, *tmp; - mali_core_session *session; - mali_core_job *job; -#ifdef MALI_REBOOTNOTIFIER - if (_mali_osk_atomic_read(&mali_shutdown_state) > 0) { - MALI_DEBUG_PRINT(3, ("Core: mali already under shutdown process!!")) ; - return; - } -#endif - - MALI_DEBUG_PRINT(5, ("Core: subsystem_schedule: %s\n", subsystem->name )) ; - - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - - /* First check that there are sessions with jobs waiting to run */ - if ( 0 == subsystem->awaiting_sessions_sum_all_priorities) - { - MALI_DEBUG_PRINT(6, ("Core: No jobs available for %s\n", subsystem->name) ) ; - return; - } - - /* Returns the session with the highest priority job for the subsystem. NULL if none*/ - session = mali_core_subsystem_get_waiting_session(subsystem); - - if (NULL == session) - { - MALI_DEBUG_PRINT(6, ("Core: Schedule: No runnable job found\n")); - return; - } - - _MALI_OSK_LIST_FOREACHENTRY(core, tmp, &subsystem->renderunit_idle_head, mali_core_renderunit, list) - { -#if USING_MMU - int err = mali_memory_core_mmu_activate_page_table(core->mmu, session->mmu_session, mali_core_subsystem_callback_schedule_wrapper, subsystem); - if (0 == err) - { - /* core points to a core where the MMU page table activation succeeded */ -#endif - /* This will remove the job from queue system */ - job = mali_core_subsystem_release_session_get_job(subsystem, session); - MALI_DEBUG_ASSERT_POINTER(job); - - MALI_DEBUG_PRINT(6, ("Core: Schedule: Got a job 0x%x\n", job)); - -#if USING_MALI_PMM - { - /* Message that there is a job scheduled to run - * NOTE: mali_core_job_start_on_core() can fail to start - * the job for several reasons, but it will move the core - * back to idle which will create the FINISHED message - * so we can still say that the job is SCHEDULED - */ - _mali_uk_pmm_message_s event = { - NULL, - MALI_PMM_EVENT_JOB_SCHEDULED, - 0 }; - event.data = core->pmm_id; - _mali_ukk_pmm_event_message( &event ); - } -#endif - /* This will {remove core from freelist AND start the job on the core}*/ - mali_core_job_start_on_core(job, core); - - MALI_DEBUG_PRINT(6, ("Core: Schedule: Job started, done\n")); - return; -#if USING_MMU - } -#endif - } - MALI_DEBUG_PRINT(6, ("Core: Schedule: Could not activate MMU. Scheduelling postponed to MMU, checking next.\n")); - -#if USING_MALI_PMM - { - /* Message that there are jobs to run */ - _mali_uk_pmm_message_s event = { - NULL, - MALI_PMM_EVENT_JOB_QUEUED, - 0 }; - if( subsystem->core_type == _MALI_GP2 || subsystem->core_type == _MALI_400_GP ) - { - event.data = MALI_PMM_CORE_GP; - } - else - { - /* Check the PP is supported by the PMM */ - MALI_DEBUG_ASSERT( subsystem->core_type == _MALI_200 || subsystem->core_type == _MALI_400_PP ); - /* We state that all PP cores are scheduled to inform the PMM - * that it may need to power something up! - */ - event.data = MALI_PMM_CORE_PP_ALL; - } - _mali_ukk_pmm_event_message( &event ); - } -#endif /* USING_MALI_PMM */ - -} - -/* Is used by external function: - session_begin<> */ -void mali_core_session_begin(mali_core_session * session) -{ - mali_core_subsystem * subsystem; - int i; - - subsystem = session->subsystem; - if ( NULL == subsystem ) - { - MALI_PRINT_ERROR(("Missing data in struct\n")); - return; - } - MALI_DEBUG_PRINT(2, ("Core: session_begin: for %s\n", session->subsystem->name )) ; - - session->magic_nr = SESSION_MAGIC_NR; - - _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head); - - for (i = 0; i < MALI_JOB_QUEUE_SIZE; i++) - { - session->queue[i] = NULL; - } - session->queue_head = 0; - session->queue_tail = 0; - _MALI_OSK_INIT_LIST_HEAD(&session->awaiting_sessions_list); - _MALI_OSK_INIT_LIST_HEAD(&session->all_sessions_list); - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem); - _mali_osk_list_add(&session->all_sessions_list, &session->subsystem->all_sessions_head); - -#if MALI_STATE_TRACKING - _mali_osk_atomic_init(&session->jobs_received, 0); - _mali_osk_atomic_init(&session->jobs_returned, 0); - session->pid = _mali_osk_get_pid(); -#endif - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); - - MALI_DEBUG_PRINT(5, ("Core: session_begin: for %s DONE\n", session->subsystem->name) ) ; -} - -#if USING_MMU -static void mali_core_renderunit_stop_bus(mali_core_renderunit* core) -{ - core->subsystem->stop_bus(core); -} -#endif - -void mali_core_session_close(mali_core_session * session) -{ - mali_core_subsystem * subsystem; - mali_core_renderunit *core; - - subsystem = session->subsystem; - MALI_DEBUG_ASSERT_POINTER(subsystem); - - MALI_DEBUG_PRINT(2, ("Core: session_close: for %s\n", session->subsystem->name) ) ; - - /* We must grab subsystem mutex since the list this session belongs to - is owned by the subsystem */ - MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem ); - - /* Remove this session from the global sessionlist */ - _mali_osk_list_delinit(&session->all_sessions_list); - - _mali_osk_list_delinit(&(session->awaiting_sessions_list)); - - /* Return the potensial waiting job to user */ - while ( !mali_job_queue_empty(session) ) - { - /* Queue not empty */ - mali_core_job *job = mali_job_queue_get_job(session); - subsystem->return_job_to_user( job, JOB_STATUS_END_SHUTDOWN ); - subsystem->awaiting_sessions_sum_all_priorities--; - } - - /* Kill active cores working for this session - freeing their jobs - Since the handling of one core also could stop jobs from another core, there is a while loop */ - while ( ! _mali_osk_list_empty(&session->renderunits_working_head) ) - { - core = _MALI_OSK_LIST_ENTRY(session->renderunits_working_head.next, mali_core_renderunit, list); - MALI_DEBUG_PRINT(3, ("Core: session_close: Core was working: %s\n", core->description )) ; - mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_SHUTDOWN ); - } - _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head); /* Not necessary - we will _mali_osk_free session*/ - - MALI_DEBUG_PRINT(5, ("Core: session_close: for %s FINISHED\n", session->subsystem->name )) ; - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem ); -} - -/* Must hold subsystem_mutex before entering this function */ -_mali_osk_errcode_t mali_core_session_add_job(mali_core_session * session, mali_core_job *job, mali_core_job **job_return) -{ - mali_core_subsystem * subsystem; - - job->magic_nr = JOB_MAGIC_NR; - MALI_CHECK_SESSION(session); - - subsystem = session->subsystem; - MALI_CHECK_SUBSYSTEM(subsystem); - MALI_ASSERT_MUTEX_IS_GRABBED(subsystem); - - MALI_DEBUG_PRINT(5, ("Core: session_add_job: for %s\n", subsystem->name )) ; - - /* Setting the default value; No job to return */ - MALI_DEBUG_ASSERT_POINTER(job_return); - *job_return = NULL; - - if (mali_job_queue_empty(session)) - { - /* Add session to the wait list only if it didn't already have a job waiting. */ - _mali_osk_list_addtail( &(session->awaiting_sessions_list), &(subsystem->awaiting_sessions_head[job->priority])); - } - - - if (_MALI_OSK_ERR_OK != mali_job_queue_add_job(session, job)) - { - if (mali_job_queue_empty(session)) - { - _mali_osk_list_delinit(&(session->awaiting_sessions_list)); - } - MALI_DEBUG_PRINT(4, ("Core: session_add_job: %s queue is full\n", subsystem->name)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Continue to add the new job as the next job from this session */ - MALI_DEBUG_PRINT(6, ("Core: session_add_job job=0x%x\n", job)); - - subsystem->awaiting_sessions_sum_all_priorities++; - - mali_core_subsystem_schedule(subsystem); - - MALI_DEBUG_PRINT(6, ("Core: session_add_job: for %s FINISHED\n", session->subsystem->name )) ; - - MALI_SUCCESS; -} - -static void mali_core_job_set_run_time(mali_core_job * job, u64 end_time) -{ - u32 time_used_nano_seconds; - - time_used_nano_seconds = end_time - job->start_time; - job->render_time_usecs = time_used_nano_seconds / 1000; -} - -static void mali_core_renderunit_detach_job_from_core(mali_core_renderunit* core, mali_subsystem_reschedule_option reschedule, mali_subsystem_job_end_code end_status) -{ - mali_core_job * job; - mali_core_subsystem * subsystem; - mali_bool already_in_detach_function; - u64 time_now; - - MALI_DEBUG_ASSERT(CORE_IDLE != core->state); - time_now = _mali_osk_time_get_ns(); - job = core->current_job; - subsystem = core->subsystem; - - /* The reset_core() called some lines below might call this detach - * funtion again. To protect the core object from being modified by - * recursive calls, the in_detach_function would track if it is an recursive call - */ - already_in_detach_function = core->in_detach_function; - - - if ( MALI_FALSE == already_in_detach_function ) - { - core->in_detach_function = MALI_TRUE; - if ( NULL != job ) - { - mali_core_job_set_run_time(job, time_now); - core->current_job = NULL; - } - } - - if (JOB_STATUS_END_SEG_FAULT == end_status) - { - subsystem->reset_core( core, MALI_CORE_RESET_STYLE_HARD ); - } - else - { - subsystem->reset_core( core, MALI_CORE_RESET_STYLE_RUNABLE ); - } - - if ( MALI_FALSE == already_in_detach_function ) - { - if ( CORE_IDLE != core->state ) - { - #if MALI_GPU_UTILIZATION - mali_utilization_core_end(time_now); - #endif - mali_core_subsystem_move_core_set_idle(core); - } - - core->in_detach_function = MALI_FALSE; - - if ( SUBSYSTEM_RESCHEDULE == reschedule ) - { - mali_core_subsystem_schedule(subsystem); - } - if ( NULL != job ) - { - core->subsystem->return_job_to_user(job, end_status); - } - } -} - -#if USING_MMU -/* This function intentionally does not release the semaphore. You must run - stop_bus_for_all_cores(), reset_all_cores_on_mmu() and continue_job_handling() - after calling this function, and then call unlock_subsystem() to release the - semaphore. */ - -static void lock_subsystem(struct mali_core_subsystem * subsys) -{ - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); -} - -/* You must run lock_subsystem() before entering this function, to ensure that - the subsystem mutex is held. - Later, unlock_subsystem() can be called to release the mutex. - - This function only stops cores behind the given MMU, unless "mmu" is NULL, in - which case all cores are stopped. -*/ -static void stop_bus_for_all_cores_on_mmu(struct mali_core_subsystem * subsys, void* mmu) -{ - u32 i; - - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); - MALI_DEBUG_PRINT(2,("Handling: bus stop %s\n", subsys->name )); - for(i=0 ; i < subsys->number_of_cores ; ++i) - { - mali_core_renderunit * core; - core = mali_core_renderunit_get_mali_core_nr(subsys,i); - - /* We stop only cores behind the given MMU, unless MMU is NULL */ - if ( (NULL!=mmu) && (core->mmu != mmu) ) continue; - - if ( CORE_IDLE != core->state ) - { - MALI_DEBUG_PRINT(4, ("Stopping bus on core %s\n", core->description)); - mali_core_renderunit_stop_bus(core); - core->error_recovery = MALI_TRUE; - } - else - { - MALI_DEBUG_PRINT(4,("Core: not active %s\n", core->description )); - } - } - /* Mutex is still being held, to prevent things to happen while we do cleanup */ - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); -} - -/* You must run lock_subsystem() before entering this function, to ensure that - the subsystem mutex is held. - Later, unlock_subsystem() can be called to release the mutex. - - This function only resets cores behind the given MMU, unless "mmu" is NULL, in - which case all cores are reset. -*/ -static void reset_all_cores_on_mmu(struct mali_core_subsystem * subsys, void* mmu) -{ - u32 i; - - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); - MALI_DEBUG_PRINT(3, ("Handling: reset cores from mmu: 0x%x on %s\n", mmu, subsys->name )); - for(i=0 ; i < subsys->number_of_cores ; ++i) - { - mali_core_renderunit * core; - core = mali_core_renderunit_get_mali_core_nr(subsys,i); - - /* We reset only cores behind the given MMU, unless MMU is NULL */ - if ( (NULL!=mmu) && (core->mmu != mmu) ) continue; - - if ( CORE_IDLE != core->state ) - { - MALI_DEBUG_PRINT(4, ("Abort and reset core: %s\n", core->description )); - mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_WAIT, JOB_STATUS_END_SEG_FAULT); - } - else - { - MALI_DEBUG_PRINT(4, ("Core: not active %s\n", core->description )); - } - } - MALI_DEBUG_PRINT(4, ("Handling: done %s\n", subsys->name )); - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); -} - -/* You must run lock_subsystem() before entering this function, to ensure that - the subsystem mutex is held. - Later, unlock_subsystem() can be called to release the mutex. */ -static void continue_job_handling(struct mali_core_subsystem * subsys) -{ - u32 i, j; - - MALI_DEBUG_PRINT(3, ("Handling: Continue: %s\n", subsys->name )); - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); - - - for(i=0 ; i < subsys->number_of_cores ; ++i) - { - mali_core_renderunit * core; - core = mali_core_renderunit_get_mali_core_nr(subsys,i); - core->error_recovery = MALI_FALSE; - } - - i = subsys->number_of_cores; - j = subsys->awaiting_sessions_sum_all_priorities; - - /* Schedule MIN(nr_waiting_jobs , number of cores) times */ - while( i-- && j--) - { - mali_core_subsystem_schedule(subsys); - } - MALI_DEBUG_PRINT(4, ("Handling: done %s\n", subsys->name )); - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); -} - -/* Unlock the subsystem. */ -static void unlock_subsystem(struct mali_core_subsystem * subsys) -{ - MALI_ASSERT_MUTEX_IS_GRABBED(subsys); - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); -} - -void mali_core_subsystem_broadcast_notification(struct mali_core_subsystem * subsys, mali_core_notification_message message, u32 data) -{ - void * mmu; - mmu = (void*) data; - - switch(message) - { - case MMU_KILL_STEP0_LOCK_SUBSYSTEM: - break; - case MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES: - stop_bus_for_all_cores_on_mmu(subsys, mmu); - break; - case MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS: - reset_all_cores_on_mmu(subsys, mmu ); - break; - case MMU_KILL_STEP3_CONTINUE_JOB_HANDLING: - continue_job_handling(subsys); - break; - case MMU_KILL_STEP4_UNLOCK_SUBSYSTEM: - break; - - default: - MALI_PRINT_ERROR(("Illegal message: 0x%x, data: 0x%x\n", (u32)message, data)); - break; - } -} -#endif /* USING_MMU */ - -void job_watchdog_set(mali_core_job * job, u32 watchdog_msecs) -{ - if (watchdog_msecs == 0) job->watchdog_msecs = mali_max_job_runtime; /* use the default */ - else if (watchdog_msecs > WATCHDOG_MSECS_MAX) job->watchdog_msecs = WATCHDOG_MSECS_MAX; /* no larger than max */ - else if (watchdog_msecs < WATCHDOG_MSECS_MIN) job->watchdog_msecs = WATCHDOG_MSECS_MIN; /* not below min */ - else job->watchdog_msecs = watchdog_msecs; -} - -u32 mali_core_hang_check_timeout_get(void) -{ - /* check the value. The user might have set the value outside the allowed range */ - if (mali_hang_check_interval > HANG_CHECK_MSECS_MAX) mali_hang_check_interval = HANG_CHECK_MSECS_MAX; /* cap to max */ - else if (mali_hang_check_interval < HANG_CHECK_MSECS_MIN) mali_hang_check_interval = HANG_CHECK_MSECS_MIN; /* cap to min */ - - /* return the active value */ - return mali_hang_check_interval; -} - -static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data) -{ - mali_core_renderunit *core; - u32 has_pending_irq; - - core = (mali_core_renderunit * )data; - - if(core && (CORE_OFF == core->state)) - { - MALI_SUCCESS; - } - - if ( (NULL == core) || - (NULL == core->subsystem) || - (NULL == core->subsystem->irq_handler_upper_half) ) - { - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - MALI_CHECK_CORE(core); - MALI_CHECK_SUBSYSTEM(core->subsystem); - - has_pending_irq = core->subsystem->irq_handler_upper_half(core); - - if ( has_pending_irq ) - { - _mali_osk_irq_schedulework( core->irq ) ; - MALI_SUCCESS; - } - - if (mali_benchmark) MALI_SUCCESS; - - MALI_ERROR(_MALI_OSK_ERR_FAULT); -} - -static void mali_core_irq_handler_bottom_half ( void *data ) -{ - mali_core_renderunit *core; - mali_core_subsystem* subsystem; - - mali_subsystem_job_end_code job_status; - - core = (mali_core_renderunit * )data; - - MALI_CHECK_CORE(core); - subsystem = core->subsystem; - MALI_CHECK_SUBSYSTEM(subsystem); - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem ); - if ( CORE_IDLE == core->state || CORE_OFF == core->state ) goto end_function; - - MALI_DEBUG_PRINT(5, ("IRQ: handling irq from core %s\n", core->description )) ; - - _mali_osk_cache_flushall(); - - /* This function must also update the job status flag */ - job_status = subsystem->irq_handler_bottom_half( core ); - - /* Retval is nonzero if the job is finished. */ - if ( JOB_STATUS_CONTINUE_RUN != job_status ) - { - mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, job_status); - } - else - { - switch ( core->state ) - { - case CORE_WATCHDOG_TIMEOUT: - MALI_DEBUG_PRINT(2, ("Watchdog SW Timeout of job from core: %s\n", core->description )); - mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_TIMEOUT_SW ); - break; - - case CORE_POLL: - MALI_DEBUG_PRINT(5, ("Poll core: %s\n", core->description )) ; - core->state = CORE_WORKING; - _mali_osk_timer_add( core->timer, 1); - break; - - default: - MALI_DEBUG_PRINT(4, ("IRQ: The job on the core continue to run: %s\n", core->description )) ; - break; - } - } -end_function: - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem); -} - -void subsystem_flush_mapped_mem_cache(void) -{ - _mali_osk_cache_flushall(); - _mali_osk_mem_barrier(); -} - -#if USING_MALI_PMM - -_mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool immediate_only) -{ - mali_core_renderunit * core = NULL; - - MALI_CHECK_SUBSYSTEM(subsys); - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - - /* It is possible that this signal funciton can be called during a driver exit, - * and so the requested core may now be destroyed. (This is due to us not having - * the subsys lock before signalling power down). - * mali_core_renderunit_get_mali_core_nr() will report a Mali ERR because - * the core number is out of range (which is a valid error in other cases). - * So instead we check here (now that we have the subsys lock) and let the - * caller cope with the core get failure and check that the core has - * been unregistered in the PMM as part of its destruction. - */ - if ( subsys->number_of_cores > mali_core_nr ) - { - core = mali_core_renderunit_get_mali_core_nr(subsys, mali_core_nr); - } - - if ( NULL == core ) - { - /* Couldn't find the core */ - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power down\n") ); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - else if ( core->state != CORE_IDLE ) - { - /* When powering down we either set a pending power down flag here so we - * can power down cleanly after the job completes or we don't set the - * flag if we have been asked to only do a power down right now - * In either case, return that the core is busy - */ - if ( !immediate_only ) core->pend_power_down = MALI_TRUE; - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 5, ("Core: No idle core to power down\n") ); - MALI_ERROR(_MALI_OSK_ERR_BUSY); - } - - /* Shouldn't have a pending power down flag set */ - MALI_DEBUG_ASSERT( !core->pend_power_down ); - - /* Move core to off queue */ - mali_core_subsystem_move_core_set_off(core); - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool queue_only) -{ - mali_core_renderunit * core; - - MALI_CHECK_SUBSYSTEM(subsys); - MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys); - - core = mali_core_renderunit_get_mali_core_nr(subsys, mali_core_nr); - - if( core == NULL ) - { - /* Couldn't find the core */ - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power up\n") ); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - else if( core->state != CORE_OFF ) - { - /* This will usually happen because we are trying to cancel a pending power down */ - core->pend_power_down = MALI_FALSE; - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - MALI_DEBUG_PRINT( 1, ("Core: No powered off core to power up (cancelled power down?)\n") ); - MALI_ERROR(_MALI_OSK_ERR_BUSY); - } - - /* Shouldn't have a pending power down set */ - MALI_DEBUG_ASSERT( !core->pend_power_down ); - - /* Move core to idle queue */ - mali_core_subsystem_move_core_set_idle(core); - - if( !queue_only ) - { - /* Reset MMU & core - core must be idle to allow this */ -#if USING_MMU - if ( NULL!=core->mmu ) - { -#if defined(USING_MALI200) - if (core->pmm_id != MALI_PMM_CORE_PP0) - { -#endif - mali_kernel_mmu_reset(core->mmu); -#if defined(USING_MALI200) - } -#endif - - } -#endif /* USING_MMU */ - subsys->reset_core( core, MALI_CORE_RESET_STYLE_RUNABLE ); - } - - /* Need to schedule work to start on this core */ - mali_core_subsystem_schedule(subsys); - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys); - - MALI_SUCCESS; -} - -#endif /* USING_MALI_PMM */ - -#if MALI_STATE_TRACKING -u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size) -{ - u32 i, len = 0; - mali_core_renderunit *core; - mali_core_renderunit *tmp_core; - - mali_core_session* session; - mali_core_session* tmp_session; - - if (0 >= size) - { - return 0; - } - - MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem ); - - len += _mali_osk_snprintf(buf + len, size - len, "Subsystem:\n"); - len += _mali_osk_snprintf(buf + len, size - len, " Name: %s\n", subsystem->name); - - for (i = 0; i < subsystem->number_of_cores; i++) - { - len += _mali_osk_snprintf(buf + len, size - len, " Core: #%u\n", - subsystem->mali_core_array[i]->core_number); - len += _mali_osk_snprintf(buf + len, size - len, " Description: %s\n", - subsystem->mali_core_array[i]->description); - switch(subsystem->mali_core_array[i]->state) - { - case CORE_IDLE: - len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_IDLE\n"); - break; - case CORE_WORKING: - len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WORKING\n"); - break; - case CORE_WATCHDOG_TIMEOUT: - len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WATCHDOG_TIMEOUT\n"); - break; - case CORE_POLL: - len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_POLL\n"); - break; - case CORE_HANG_CHECK_TIMEOUT: - len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_HANG_CHECK_TIMEOUT\n"); - break; - case CORE_OFF: - len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_OFF\n"); - break; - default: - len += _mali_osk_snprintf(buf + len, size - len, " State: Unknown (0x%X)\n", - subsystem->mali_core_array[i]->state); - break; - } - len += _mali_osk_snprintf(buf + len, size - len, " Current job: 0x%X\n", - (u32)(subsystem->mali_core_array[i]->current_job)); - if (subsystem->mali_core_array[i]->current_job) - { - u64 time_used_nano_seconds; - u32 time_used_micro_seconds; - u64 time_now = _mali_osk_time_get_ns(); - - time_used_nano_seconds = time_now - subsystem->mali_core_array[i]->current_job->start_time; - time_used_micro_seconds = ((u32)(time_used_nano_seconds)) / 1000; - - len += _mali_osk_snprintf(buf + len, size - len, " Current job session: 0x%X\n", - subsystem->mali_core_array[i]->current_job->session); - len += _mali_osk_snprintf(buf + len, size - len, " Current job number: %d\n", - subsystem->mali_core_array[i]->current_job->job_nr); - len += _mali_osk_snprintf(buf + len, size - len, " Current job render_time micro seconds: %d\n", - time_used_micro_seconds ); - len += _mali_osk_snprintf(buf + len, size - len, " Current job start time micro seconds: %d\n", - (u32) (subsystem->mali_core_array[i]->current_job->start_time >>10) ); - } - len += _mali_osk_snprintf(buf + len, size - len, " Core version: 0x%X\n", - subsystem->mali_core_array[i]->core_version); -#if USING_MALI_PMM - len += _mali_osk_snprintf(buf + len, size - len, " PMM id: 0x%X\n", - subsystem->mali_core_array[i]->pmm_id); - len += _mali_osk_snprintf(buf + len, size - len, " Power down requested: %s\n", - subsystem->mali_core_array[i]->pend_power_down ? "TRUE" : "FALSE"); -#endif - } - - len += _mali_osk_snprintf(buf + len, size - len, " Cores on idle list:\n"); - _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_idle_head, mali_core_renderunit, list) - { - len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number); - } - - len += _mali_osk_snprintf(buf + len, size - len, " Cores on off list:\n"); - _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_off_head, mali_core_renderunit, list) - { - len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number); - } - - len += _mali_osk_snprintf(buf + len, size - len, " Connected sessions:\n"); - _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->all_sessions_head, mali_core_session, all_sessions_list) - { - len += _mali_osk_snprintf(buf + len, size - len, - " Session 0x%X:\n", (u32)session); - len += _mali_osk_snprintf(buf + len, size - len, - " Queue depth: %u\n", mali_job_queue_size(session)); - len += _mali_osk_snprintf(buf + len, size - len, - " First waiting job: 0x%p\n", session->queue[session->queue_head]); - len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n", - _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY"); - len += _mali_osk_snprintf(buf + len, size - len, - " Jobs received:%4d\n", _mali_osk_atomic_read(&session->jobs_received)); - len += _mali_osk_snprintf(buf + len, size - len, - " Jobs started :%4d\n", _mali_osk_atomic_read(&session->jobs_started)); - len += _mali_osk_snprintf(buf + len, size - len, - " Jobs ended :%4d\n", _mali_osk_atomic_read(&session->jobs_ended)); - len += _mali_osk_snprintf(buf + len, size - len, - " Jobs returned:%4d\n", _mali_osk_atomic_read(&session->jobs_returned)); - len += _mali_osk_snprintf(buf + len, size - len, " PID: %d\n", session->pid); - } - - len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions sum all priorities: %u\n", - subsystem->awaiting_sessions_sum_all_priorities); - for (i = 0; i < PRIORITY_LEVELS; i++) - { - len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions with priority %u:\n", i); - _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->awaiting_sessions_head[i], - mali_core_session, awaiting_sessions_list) - { - len += _mali_osk_snprintf(buf + len, size - len, " Session 0x%X:\n", (u32)session); - len += _mali_osk_snprintf(buf + len, size - len, " Waiting job: 0x%X\n", - (u32)session->queue[session->queue_head]); - len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n", - _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY"); - } - } - - MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem ); - return len; -} -#endif diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h b/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h deleted file mode 100644 index 5fbe686..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h +++ /dev/null @@ -1,565 +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 __MALI_RENDERCORE_H__ -#define __MALI_RENDERCORE_H__ - -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_kernel_subsystem.h" - -#define PRIORITY_LEVELS 3 -#define PRIORITY_MAX 0 -#define PRIORITY_MIN (PRIORITY_MAX+PRIORITY_LEVELS-1) - -/* This file contains what we need in kernel for all core types. */ - -typedef enum -{ - CORE_IDLE, /**< Core is ready for a new job */ - CORE_WORKING, /**< Core is working on a job */ - CORE_WATCHDOG_TIMEOUT, /**< Core is working but it has timed out */ - CORE_POLL, /**< Poll timer triggered, pending handling */ - CORE_HANG_CHECK_TIMEOUT,/**< Timeout for hang detection */ - CORE_OFF /**< Core is powered off */ -} mali_core_status; - -typedef enum -{ - SUBSYSTEM_RESCHEDULE, - SUBSYSTEM_WAIT -} mali_subsystem_reschedule_option; - -typedef enum -{ - MALI_CORE_RESET_STYLE_RUNABLE, - MALI_CORE_RESET_STYLE_DISABLE, - MALI_CORE_RESET_STYLE_HARD -} mali_core_reset_style; - -typedef enum -{ - JOB_STATUS_CONTINUE_RUN = 0x01, - JOB_STATUS_END_SUCCESS = 1<<(16+0), - JOB_STATUS_END_OOM = 1<<(16+1), - JOB_STATUS_END_ABORT = 1<<(16+2), - JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3), - JOB_STATUS_END_HANG = 1<<(16+4), - JOB_STATUS_END_SEG_FAULT = 1<<(16+5), - JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6), - JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7), - JOB_STATUS_END_SHUTDOWN = 1<<(16+8), - JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9) -} mali_subsystem_job_end_code; - - -struct mali_core_job; -struct mali_core_subsystem; -struct mali_core_renderunit; -struct mali_core_session; - -/* We have one of these subsystems for each core type */ -typedef struct mali_core_subsystem -{ - struct mali_core_renderunit ** mali_core_array; /* An array of all cores of this type */ - u32 number_of_cores; /* Number of cores in this list */ - - _mali_core_type core_type; - - u32 magic_nr; - - _mali_osk_list_t renderunit_idle_head; /* Idle cores of this type */ - _mali_osk_list_t renderunit_off_head; /* Powered off cores of this type */ - - /* Linked list for each priority of sessions with a job ready for scheduelling */ - _mali_osk_list_t awaiting_sessions_head[PRIORITY_LEVELS]; - u32 awaiting_sessions_sum_all_priorities; - - /* Linked list of all sessions connected to this coretype */ - _mali_osk_list_t all_sessions_head; - - /* Linked list of all sessions connected to this coretype */ - struct _mali_osk_notification_queue_t * notification_queue; - - const char * name; - mali_kernel_subsystem_identifier id; - - /**** Functions registered for this core type. Set during mali_core_init ******/ - /* Start this job on this core. Return MALI_TRUE if the job was started. */ - _mali_osk_errcode_t (*start_job)(struct mali_core_job * job, struct mali_core_renderunit * core); - - /* Check if given core has an interrupt pending. Return MALI_TRUE and set mask to 0 if pending */ - u32 (*irq_handler_upper_half)(struct mali_core_renderunit * core); - - /* This function should check if the interrupt indicates that job was finished. - If so it should update the job-struct, reset the core registers, and return MALI_TRUE, . - If the job is still working after this function it should return MALI_FALSE. - The function must also enable the bits in the interrupt mask for the core. - Called by the bottom half interrupt function. */ - int (*irq_handler_bottom_half)(struct mali_core_renderunit* core); - - /* This function is called from the ioctl function and should return a mali_core_job pointer - to a created mali_core_job object with the data given from userspace */ - _mali_osk_errcode_t (*get_new_job_from_user)(struct mali_core_session * session, void * argument); - - _mali_osk_errcode_t (*suspend_response)(struct mali_core_session * session, void * argument); - - /* This function is called from the ioctl function and should write the necessary data - to userspace telling which job was finished and the status and debuginfo for this job. - The function must also free and cleanup the input job object. */ - void (*return_job_to_user)(struct mali_core_job * job, mali_subsystem_job_end_code end_status); - - /* Is called when a subsystem shuts down. This function needs to - release internal pointers in the core struct, and free the - core struct before returning. - It is not allowed to write to any registers, since this - unmapping is already done. */ - void (*renderunit_delete)(struct mali_core_renderunit * core); - - /* Is called when we want to abort a job that is running on the core. - This is done if program exits while core is running */ - void (*reset_core)(struct mali_core_renderunit * core, mali_core_reset_style style); - - /* Is called when the rendercore wants the core to give an interrupt */ - void (*probe_core_irq_trigger)(struct mali_core_renderunit* core); - - /* Is called when the irq probe wants the core to acknowledge an interrupt from the hw */ - _mali_osk_errcode_t (*probe_core_irq_acknowledge)(struct mali_core_renderunit* core); - - /* Called when the rendercore want to issue a bus stop request to a core */ - void (*stop_bus)(struct mali_core_renderunit* core); -} mali_core_subsystem; - - -/* Per core data. This must be embedded into each core type internal core info. */ -typedef struct mali_core_renderunit -{ - struct mali_core_subsystem * subsystem; /* The core belongs to this subsystem */ - _mali_osk_list_t list; /* Is always in subsystem->idle_list OR session->renderunits_working */ - mali_core_status state; - mali_bool error_recovery; /* Indicates if the core is waiting for external help to recover (typically the MMU) */ - mali_bool in_detach_function; - struct mali_core_job * current_job; /* Current job being processed on this core ||NULL */ - u32 magic_nr; - _mali_osk_timer_t * timer; - _mali_osk_timer_t * timer_hang_detection; - - mali_io_address registers_mapped; /* IO-mapped pointer to registers */ - u32 registers_base_addr; /* Base addres of the registers */ - u32 size; /* The size of registers_mapped */ - const char * description; /* Description of this core. */ - u32 irq_nr; /* The IRQ nr for this core */ - u32 core_version; -#if USING_MMU - u32 mmu_id; - void * mmu; /* The MMU this rendercore is behind.*/ -#endif -#if USING_MALI_PMM - mali_pmm_core_id pmm_id; /* The PMM core id */ - mali_bool pend_power_down; /* Power down is requested */ -#endif - - u32 core_number; /* 0 for first detected core of this type, 1 for second and so on */ - - _mali_osk_irq_t *irq; -} mali_core_renderunit; - - -#define MALI_JOB_QUEUE_SIZE 8 -/* Per open FILE data. */ -/* You must held subsystem->mutex before any transactions to this datatype. */ -typedef struct mali_core_session -{ - struct mali_core_subsystem * subsystem; /* The session belongs to this subsystem */ - _mali_osk_list_t renderunits_working_head; /* List of renderunits working for this session */ - struct mali_core_job *queue[MALI_JOB_QUEUE_SIZE]; /* The next job from this session to run */ - int queue_head; - int queue_tail; - int queue_size; - - _mali_osk_list_t awaiting_sessions_list; /* Linked list of sessions with jobs, for each priority */ - _mali_osk_list_t all_sessions_list; /* Linked list of all sessions on the system. */ - - _mali_osk_notification_queue_t * notification_queue; /* Messages back to Base in userspace*/ -#if USING_MMU - struct mali_session_data * mmu_session; /* The session associated with the MMU page tables for this core */ -#endif - u32 magic_nr; -#if MALI_STATE_TRACKING - _mali_osk_atomic_t jobs_received; - _mali_osk_atomic_t jobs_started; - _mali_osk_atomic_t jobs_ended; - _mali_osk_atomic_t jobs_returned; - u32 pid; -#endif -} mali_core_session; - -/* This must be embedded into a specific mali_core_job struct */ -/* use this macro to get spesific mali_core_job: container_of(ptr, type, member)*/ -typedef struct mali_core_job -{ - _mali_osk_list_t list; /* Linked list of jobs. Used by struct mali_core_session */ - struct mali_core_session *session; - u32 magic_nr; - u32 priority; - u32 watchdog_msecs; - u32 render_time_usecs ; - u64 start_time; - unsigned long watchdog_jiffies; - u32 abort_id; - u32 job_nr; - _mali_uk_start_job_flags flags; -} mali_core_job; - -MALI_STATIC_INLINE mali_bool mali_job_queue_empty(mali_core_session *session) -{ - if (0 == session->queue_size) - { - return MALI_TRUE; - } - return MALI_FALSE; -} - -MALI_STATIC_INLINE mali_bool mali_job_queue_full(mali_core_session *session) -{ - if (MALI_JOB_QUEUE_SIZE == session->queue_size) - { - return MALI_TRUE; - } - return MALI_FALSE; -} - - -MALI_STATIC_INLINE _mali_osk_errcode_t mali_job_queue_add_job(mali_core_session *session, struct mali_core_job *job) -{ - if (mali_job_queue_full(session)) - { - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - session->queue[session->queue_tail] = job; - session->queue_tail = (session->queue_tail + 1) % MALI_JOB_QUEUE_SIZE; - session->queue_size++; - - MALI_SUCCESS; -} - -MALI_STATIC_INLINE struct mali_core_job *mali_job_queue_get_job(mali_core_session *session) -{ - struct mali_core_job *job; - MALI_DEBUG_ASSERT(!mali_job_queue_empty(session)); - - job = session->queue[session->queue_head]; - - MALI_DEBUG_ASSERT_POINTER(job); - - session->queue[session->queue_head] = NULL; - session->queue_head = (session->queue_head + 1) % MALI_JOB_QUEUE_SIZE; - session->queue_size--; - - return job; -} - -MALI_STATIC_INLINE u32 mali_job_queue_size(mali_core_session *session) -{ - return (u32)(session->queue_size); -} - -MALI_STATIC_INLINE struct mali_core_job *mali_job_queue_abort_job(mali_core_session *session, u32 abort_id) -{ - int i; - int n; - struct mali_core_job *job = NULL; - - for (i = session->queue_head, n = session->queue_size; n > 0; n--, i = (i+1)%MALI_JOB_QUEUE_SIZE) - { - if (session->queue[i]->abort_id == abort_id) - { - /* Remove job from queue */ - job = session->queue[i]; - session->queue[i] = NULL; - - session->queue_size -= 1; - n--; - break; - } - } - if (NULL == job) - { - return NULL; - } - - /* Rearrange queue */ - while (n > 0) - { - int next = (i + 1) % MALI_JOB_QUEUE_SIZE; - session->queue[i] = session->queue[next]; - i = next; - n--; - } - session->queue_tail = i; - - return job; -} - - -/* - * The rendercode subsystem is included in the subsystems[] array. - */ -extern struct mali_kernel_subsystem mali_subsystem_rendercore; - -void subsystem_flush_mapped_mem_cache(void); - - -#define SUBSYSTEM_MAGIC_NR 0xdeadbeef -#define CORE_MAGIC_NR 0xcafebabe -#define SESSION_MAGIC_NR 0xbabe1234 -#define JOB_MAGIC_NR 0x0123abcd - - -#define MALI_CHECK_SUBSYSTEM(subsystem)\ - do { \ - if ( SUBSYSTEM_MAGIC_NR != subsystem->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\ - } while (0) - -#define MALI_CHECK_CORE(CORE)\ - do { \ - if ( CORE_MAGIC_NR != CORE->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\ -} while (0) - -#define MALI_CHECK_SESSION(SESSION)\ - do { \ - if ( SESSION_MAGIC_NR != SESSION->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\ -} while (0) - -#define MALI_CHECK_JOB(JOB)\ - do { \ - if ( JOB_MAGIC_NR != JOB->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\ -} while (0) - - -/* Check if job_a has higher priority than job_b */ -MALI_STATIC_INLINE int job_has_higher_priority(mali_core_job * job_a, mali_core_job * job_b) -{ - /* The lowest number has the highest priority */ - return (int) (job_a->priority < job_b->priority); -} - -MALI_STATIC_INLINE void job_priority_set(mali_core_job * job, u32 priority) -{ - if (priority > PRIORITY_MIN) job->priority = PRIORITY_MIN; - else job->priority = priority; -} - -void job_watchdog_set(mali_core_job * job, u32 watchdog_msecs); - -/* For use by const default register settings (e.g. set these after reset) */ -typedef struct register_address_and_value -{ - u32 address; - u32 value; -} register_address_and_value ; - - -/* For use by dynamic default register settings (e.g. set these after reset) */ -typedef struct register_address_and_value_list -{ - _mali_osk_list_t list; - register_address_and_value item; -} register_address_and_value_list ; - -/* Used if the user wants to set a continious block of registers */ -typedef struct register_array_user -{ - u32 entries_in_array; - u32 start_address; - void __user * reg_array; -}register_array_user; - - -#define MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys) \ - do { \ - MALI_DEBUG_PRINT(5, ("MUTEX: GRAB %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \ - _mali_osk_lock_wait( rendercores_global_mutex, _MALI_OSK_LOCKMODE_RW); \ - MALI_DEBUG_PRINT(5, ("MUTEX: GRABBED %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \ - if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\ - rendercores_global_mutex_is_held = 1; \ - rendercores_global_mutex_owner = _mali_osk_get_tid(); \ - } while (0) ; - -#define MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys) \ - do { \ - MALI_DEBUG_PRINT(5, ("MUTEX: RELEASE %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \ - rendercores_global_mutex_is_held = 0; \ - rendercores_global_mutex_owner = 0; \ - if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\ - _mali_osk_lock_signal( rendercores_global_mutex, _MALI_OSK_LOCKMODE_RW); \ - MALI_DEBUG_PRINT(5, ("MUTEX: RELEASED %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \ - if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\ - } while (0) ; - - -#define MALI_ASSERT_MUTEX_IS_GRABBED(input_pointer)\ - do { \ - if ( 0 == rendercores_global_mutex_is_held ) MALI_PRINT_ERROR(("ASSERT MUTEX SHOULD BE GRABBED"));\ - if ( SUBSYSTEM_MAGIC_NR != input_pointer->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\ - if ( rendercores_global_mutex_owner != _mali_osk_get_tid() ) MALI_PRINT_ERROR(("Owner mismatch"));\ - } while (0) - -MALI_STATIC_INLINE _mali_osk_errcode_t mali_core_renderunit_register_rw_check(mali_core_renderunit *core, - u32 relative_address) -{ -#if USING_MALI_PMM - if( core->state == CORE_OFF ) - { - MALI_PRINT_ERROR(("Core is OFF during access: Core: %s Addr: 0x%04X\n", - core->description,relative_address)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } -#endif - - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - - if (mali_benchmark) MALI_ERROR(_MALI_OSK_ERR_FAULT); - - MALI_DEBUG_CODE(if (relative_address >= core->size) - { - MALI_PRINT_ERROR(("Trying to access illegal register: 0x%04x in core: %s", - relative_address, core->description)); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - }) - - MALI_SUCCESS; -} - - -MALI_STATIC_INLINE u32 mali_core_renderunit_register_read(struct mali_core_renderunit *core, u32 relative_address) -{ - u32 read_val; - - if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address)) - return 0xDEADBEEF; - - read_val = _mali_osk_mem_ioread32(core->registers_mapped, relative_address); - - MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read: Core:%s Addr:0x%04X Val:0x%08x\n", - core->description,relative_address, read_val)); - - return read_val; -} - -MALI_STATIC_INLINE void mali_core_renderunit_register_read_array(struct mali_core_renderunit *core, - u32 relative_address, - u32 * result_array, - u32 nr_of_regs) -{ - /* NOTE Do not use burst reads against the registers */ - u32 i; - - MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read_array: Core:%s Addr:0x%04X Nr_regs: %u\n", - core->description,relative_address, nr_of_regs)); - - for(i=0; idescription,relative_address, new_val)); - - _mali_osk_mem_iowrite32_relaxed(core->registers_mapped, relative_address, new_val); -} - -MALI_STATIC_INLINE void mali_core_renderunit_register_write(struct mali_core_renderunit *core, - u32 relative_address, - u32 new_val) -{ - MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write: Core:%s Addr:0x%04X Val:0x%08x\n", - core->description,relative_address, new_val)); - - if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address)) - return; - - _mali_osk_mem_iowrite32(core->registers_mapped, relative_address, new_val); -} - -MALI_STATIC_INLINE void mali_core_renderunit_register_write_array(struct mali_core_renderunit *core, - u32 relative_address, - u32 * write_array, - u32 nr_of_regs) -{ - u32 i; - MALI_DEBUG_PRINT(6, ("Core: renderunit_register_write_array: Core:%s Addr:0x%04X Nr_regs: %u\n", - core->description,relative_address, nr_of_regs)); - - /* Do not use burst writes against the registers */ - for( i = 0; i< nr_of_regs; i++) - { - mali_core_renderunit_register_write_relaxed(core, relative_address + i*4, write_array[i]); - } -} - -_mali_osk_errcode_t mali_core_renderunit_init(struct mali_core_renderunit * core); -void mali_core_renderunit_term(struct mali_core_renderunit * core); -int mali_core_renderunit_map_registers(struct mali_core_renderunit *core); -void mali_core_renderunit_unmap_registers(struct mali_core_renderunit *core); -int mali_core_renderunit_irq_handler_add(struct mali_core_renderunit *core); -mali_core_renderunit * mali_core_renderunit_get_mali_core_nr(mali_core_subsystem *subsys, u32 mali_core_nr); - -int mali_core_subsystem_init(struct mali_core_subsystem * new_subsys); -#if USING_MMU -void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys); -#endif -int mali_core_subsystem_register_renderunit(struct mali_core_subsystem * subsys, struct mali_core_renderunit * core); -int mali_core_subsystem_system_info_fill(mali_core_subsystem* subsys, _mali_system_info* info); -void mali_core_subsystem_cleanup(struct mali_core_subsystem * subsys); -#if USING_MMU -void mali_core_subsystem_broadcast_notification(struct mali_core_subsystem * subsys, mali_core_notification_message message, u32 data); -#endif -void mali_core_session_begin(mali_core_session *session); -void mali_core_session_close(mali_core_session * session); -int mali_core_session_add_job(mali_core_session * session, mali_core_job *job, mali_core_job **job_return); -u32 mali_core_hang_check_timeout_get(void); - -_mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data); -_mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_session * session, u32 *number_of_cores); -_mali_osk_errcode_t mali_core_subsystem_ioctl_core_version_get(mali_core_session * session, _mali_core_version *version); -_mali_osk_errcode_t mali_core_subsystem_ioctl_suspend_response(mali_core_session * session, void* argument); -void mali_core_subsystem_ioctl_abort_job(mali_core_session * session, u32 id); - -#if USING_MALI_PMM -_mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool immediate_only); -_mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool queue_only); -#endif - -#if MALI_STATE_TRACKING -u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size); -#endif - -#endif /* __MALI_RENDERCORE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_session_manager.h b/drivers/media/video/samsung/mali/common/mali_kernel_session_manager.h deleted file mode 100644 index 8cc41d7..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_session_manager.h +++ /dev/null @@ -1,19 +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 __MALI_KERNEL_SESSION_MANAGER_H__ -#define __MALI_KERNEL_SESSION_MANAGER_H__ - -/* Incomplete struct to pass around pointers to it */ -struct mali_session_data; - -void * mali_kernel_session_manager_slot_get(struct mali_session_data * session, int id); - -#endif /* __MALI_KERNEL_SESSION_MANAGER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h b/drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h deleted file mode 100644 index 8f05216..0000000 --- a/drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h +++ /dev/null @@ -1,107 +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. - */ - -/** - * @file mali_kernel_subsystem.h - */ - -#ifndef __MALI_KERNEL_SUBSYSTEM_H__ -#define __MALI_KERNEL_SUBSYSTEM_H__ - -#include "mali_osk.h" -#include "mali_uk_types.h" -#include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" - -/* typedefs of the datatypes used in the hook functions */ -typedef void * mali_kernel_subsystem_session_slot; -typedef int mali_kernel_subsystem_identifier; -typedef _mali_osk_errcode_t (*mali_kernel_resource_registrator)(_mali_osk_resource_t *); - -/** - * Broadcast notification messages - */ -typedef enum mali_core_notification_message -{ - MMU_KILL_STEP0_LOCK_SUBSYSTEM, /**< Request to lock subsystem */ - MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES, /**< Request to stop all buses */ - MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, /**< Request kill all jobs, and not start more jobs */ - MMU_KILL_STEP3_CONTINUE_JOB_HANDLING, /**< Request to continue with new jobs on all cores */ - MMU_KILL_STEP4_UNLOCK_SUBSYSTEM /**< Request to unlock subsystem */ -} mali_core_notification_message; - -/** - * A function pointer can be NULL if the subsystem isn't interested in the event. - */ -typedef struct mali_kernel_subsystem -{ - /* subsystem control */ - _mali_osk_errcode_t (*startup)(mali_kernel_subsystem_identifier id); /**< Called during module load or system startup*/ - void (*shutdown)(mali_kernel_subsystem_identifier id); /**< Called during module unload or system shutdown */ - - /** - * Called during module load or system startup. - * Called when all subsystems have reported startup OK and all resources where successfully initialized - */ - _mali_osk_errcode_t (*load_complete)(mali_kernel_subsystem_identifier id); - - /* per subsystem handlers */ - _mali_osk_errcode_t (*system_info_fill)(_mali_system_info* info); /**< Fill info into info struct. MUST allocate memory with kmalloc, since it's kfree'd */ - - /* per session handlers */ - /** - * Informs about a new session. - * slot can be used to track per-session per-subsystem data. - * queue can be used to send events to user space. - * _mali_osk_errcode_t error return value. - */ - _mali_osk_errcode_t (*session_begin)(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue); - /** - * Informs that a session is ending - * slot was the same as given during session_begin - */ - void (*session_end)(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot); - - /* Used by subsystems to send messages to each other. This is the receiving end */ - void (*broadcast_notification)(mali_core_notification_message message, u32 data); - -#if MALI_STATE_TRACKING - /** Dump the current state of the subsystem */ - u32 (*dump_state)(char *buf, u32 size); -#endif -} mali_kernel_subsystem; - -/* functions used by the subsystems to interact with the core */ -/** - * Register a resouce handler - * @param type The resoruce type to register a handler for - * @param handler Pointer to the function handling this resource - * @return _MALI_OSK_ERR_OK on success. Otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t _mali_kernel_core_register_resource_handler(_mali_osk_resource_type_t type, mali_kernel_resource_registrator handler); - -/* function used to interact with other subsystems */ -/** - * Broadcast a message - * Sends a message to all subsystems which have registered a broadcast notification handler - * @param message The message to send - * @param data Message specific extra data - */ -void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data); - -#if MALI_STATE_TRACKING -/** - * Tell all subsystems to dump their current state - */ -u32 _mali_kernel_core_dump_state(char *buf, u32 size); -#endif - - -#endif /* __MALI_KERNEL_SUBSYSTEM_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c index b43b872..a374dbf 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -27,7 +27,7 @@ static _mali_osk_timer_t *utilization_timer = NULL; static mali_bool timer_running = MALI_FALSE; -static void calculate_gpu_utilization(void *arg) +static void calculate_gpu_utilization(void* arg) { u64 time_now; u64 time_period; @@ -39,7 +39,8 @@ static void calculate_gpu_utilization(void *arg) _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); - if (accumulated_work_time == 0 && work_start_time == 0) { + 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; @@ -55,7 +56,8 @@ static void calculate_gpu_utilization(void *arg) time_period = time_now - period_start_time; /* If we are currently busy, update working period up to now */ - if (work_start_time != 0) { + if (work_start_time != 0) + { accumulated_work_time += (time_now - work_start_time); work_start_time = time_now; } @@ -79,10 +81,13 @@ static void calculate_gpu_utilization(void *arg) * (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) { + if (period_normalized > 0x00FFFFFF) + { /* The divisor is so big that it is safe to shift it down */ period_normalized >>= 8; - } else { + } + else + { /* * The divisor is so small that we can shift up the dividend, without loosing any data. * (dividend is always smaller than the divisor) @@ -99,22 +104,25 @@ static void calculate_gpu_utilization(void *arg) _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_SPINLOCK_IRQ|_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 ); + 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) { + if (NULL == utilization_timer) + { _mali_osk_lock_term(time_data_lock); return _MALI_OSK_ERR_FAULT; } @@ -125,7 +133,8 @@ _mali_osk_errcode_t mali_utilization_init(void) void mali_utilization_suspend(void) { - if (NULL != utilization_timer) { + if (NULL != utilization_timer) + { _mali_osk_timer_del(utilization_timer); timer_running = MALI_FALSE; } @@ -133,7 +142,8 @@ void mali_utilization_suspend(void) void mali_utilization_term(void) { - if (NULL != utilization_timer) { + if (NULL != utilization_timer) + { _mali_osk_timer_del(utilization_timer); timer_running = MALI_FALSE; _mali_osk_timer_term(utilization_timer); @@ -145,11 +155,10 @@ void mali_utilization_term(void) _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) { + 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 @@ -167,27 +176,26 @@ void mali_utilization_core_start(u64 time_now) } work_start_time = time_now; - - if (timer_running != MALI_TRUE) { + 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_del(utilization_timer); - _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT)); - } else { + } + 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) { + if (_mali_osk_atomic_dec_return(&num_running_cores) == 0) + { /* * No more cores are working, so accumulate the time we was busy. */ diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h index c779978..1f60517 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h +++ b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c index dc39e01..63c9f5b 100644 --- a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c +++ b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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. @@ -10,39 +10,41 @@ #include "mali_kernel_common.h" #include "mali_osk.h" -#include "mali_osk_mali.h" #include "mali_ukk.h" -/*#include "mali_timestamp.h"*/ #if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" +#include "mali_osk_profiling.h" #endif _mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args) { _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 */ -/* u64 ts = _mali_timestamp_get(); - */ #if MALI_TIMELINE_PROFILING_ENABLED + /* + * Manually generate user space events in kernel space. + * This saves user space from calling kernel space twice in this case. + * We just need to remember to add pid and tid manually. + */ if ( event==_MALI_UK_VSYNC_EVENT_BEGIN_WAIT) { - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SUSPEND | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, - 0, 0, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, + _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); } - if ( event==_MALI_UK_VSYNC_EVENT_END_WAIT) + if (event==_MALI_UK_VSYNC_EVENT_END_WAIT) { - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_RESUME | - MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | - MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, - 0, 0, 0, 0, 0); + _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME | + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC, + _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0); } #endif + MALI_DEBUG_PRINT(4, ("Received VSYNC event: %d\n", event)); MALI_SUCCESS; } diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.c b/drivers/media/video/samsung/mali/common/mali_l2_cache.c new file mode 100644 index 0000000..aa5cc54 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_l2_cache.c @@ -0,0 +1,398 @@ +/* + * 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_l2_cache.h" +#include "mali_hw_core.h" +#include "mali_pm.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. + * See the hardware documentation for more information about each register + */ +typedef enum mali_l2_cache_register { + MALI400_L2_CACHE_REGISTER_STATUS = 0x0008, + /*unused = 0x000C */ + MALI400_L2_CACHE_REGISTER_COMMAND = 0x0010, /**< Misc cache commands, e.g. clear */ + MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0014, + MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0018, /**< Limit of outstanding read requests */ + MALI400_L2_CACHE_REGISTER_ENABLE = 0x001C, /**< Enable misc cache features */ + MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0020, + MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0024, + MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x0028, + MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x002C, +} mali_l2_cache_register; + +/** + * Mali L2 cache commands + * These are the commands that can be sent to the Mali L2 cache unit + */ +typedef enum mali_l2_cache_command +{ + MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */ + /* Read HW TRM carefully before adding/using other commands than the clear above */ +} mali_l2_cache_command; + +/** + * Mali L2 cache commands + * These are the commands that can be sent to the Mali L2 cache unit + */ +typedef enum mali_l2_cache_enable +{ + MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */ + MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */ + MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */ +} mali_l2_cache_enable; + +/** + * Mali L2 cache status bits + */ +typedef enum mali_l2_cache_status +{ + MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */ + MALI400_L2_CACHE_STATUS_DATA_BUSY = 0x02, /**< L2 cache is busy handling data requests */ +} mali_l2_cache_status; + +/** + * Definition of the L2 cache core struct + * Used to track a L2 cache unit in the system. + * Contains information about the mapping of the registers + */ +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 u32 mali_global_num_l2_cache_cores = 0; + +int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT; + +/* Local helper functions */ +static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val); + + +struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource) +{ + struct mali_l2_cache_core *cache = NULL; + + MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description)); + + if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES) + { + MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n")); + return NULL; + } + + cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core)); + if (NULL != cache) + { + 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; + 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); + 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); + 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); + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description)); + } + + _mali_osk_lock_term(cache->command_lock); + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description)); + } + + mali_hw_core_delete(&cache->hw_core); + } + + _mali_osk_free(cache); + } + else + { + MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n")); + } + + return NULL; +} + +void mali_l2_cache_delete(struct mali_l2_cache_core *cache) +{ + u32 i; + + /* reset to defaults */ + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT); + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT); + + _mali_osk_lock_term(cache->counter_lock); + _mali_osk_lock_term(cache->command_lock); + mali_hw_core_delete(&cache->hw_core); + + for (i = 0; i < mali_global_num_l2_cache_cores; i++) + { + if (mali_global_l2_cache_cores[i] == cache) + { + mali_global_l2_cache_cores[i] = NULL; + mali_global_num_l2_cache_cores--; + } + } + + _mali_osk_free(cache); +} + +u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache) +{ + return cache->core_id; +} + +mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter) +{ + u32 value = 0; /* disabled src */ + + MALI_DEBUG_ASSERT_POINTER(cache); + MALI_DEBUG_ASSERT(counter < (1 << 7)); /* the possible values are 0-127 */ + + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + cache->counter_src0 = counter; + + if (counter != MALI_HW_CORE_NO_COUNTER) + { + value = counter; + } + + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, value); + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + return MALI_TRUE; +} + +mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter) +{ + u32 value = 0; /* disabled src */ + + MALI_DEBUG_ASSERT_POINTER(cache); + MALI_DEBUG_ASSERT(counter < (1 << 7)); /* the possible values are 0-127 */ + + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + cache->counter_src1 = counter; + + if (counter != MALI_HW_CORE_NO_COUNTER) + { + value = counter; + } + + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, value); + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + return MALI_TRUE; +} + +u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache) +{ + return cache->counter_src0; +} + +u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache) +{ + return cache->counter_src1; +} + +void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1) +{ + MALI_DEBUG_ASSERT(NULL != src0); + MALI_DEBUG_ASSERT(NULL != value0); + MALI_DEBUG_ASSERT(NULL != src1); + MALI_DEBUG_ASSERT(NULL != value1); + + /* Caller must hold the PM lock and know that we are powered on */ + + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + *src0 = cache->counter_src0; + *src1 = cache->counter_src1; + + if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) + { + *value0 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0); + } + + if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) + { + *value1 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1); + } + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); +} + +struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index) +{ + if (MALI_MAX_NUMBER_OF_L2_CACHE_CORES > index) + { + return mali_global_l2_cache_cores[index]; + } + + return NULL; +} + +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) +{ + /* Invalidate cache (just to keep it in a known state at startup) */ + mali_l2_cache_invalidate_all(cache); + + /* 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); + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads); + + /* Restart any performance counters (if enabled) */ + _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER) + { + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, cache->counter_src0); + } + + if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER) + { + mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, cache->counter_src1); + } + + _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_l2_cache_invalidate_all(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_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages) +{ + u32 i; + _mali_osk_errcode_t ret1, ret = _MALI_OSK_ERR_OK; + + for (i = 0; i < num_pages; i++) + { + ret1 = mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[i]); + if (_MALI_OSK_ERR_OK != ret1) + { + ret = ret1; + } + } + + return ret; +} + +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(); +} + +void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache) +{ + /* Release PM lock */ + mali_pm_unlock(); +} + +/* -------- local helper functions below -------- */ + + +static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val) +{ + int i = 0; + const int loop_count = 100000; + + /* + * Grab lock in order to send commands to the L2 cache in a serialized fashion. + * The L2 cache will ignore commands if it is busy. + */ + _mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW); + + /* First, wait for L2 cache command handler to go idle */ + + for (i = 0; i < loop_count; i++) + { + if (!(mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_STATUS) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY)) + { + break; + } + } + + if (i == loop_count) + { + _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n")); + MALI_ERROR( _MALI_OSK_ERR_FAULT ); + } + + /* then issue the command */ + mali_hw_core_register_write(&cache->hw_core, reg, val); + + _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW); + + MALI_SUCCESS; +} diff --git a/drivers/media/video/samsung/mali/common/mali_l2_cache.h b/drivers/media/video/samsung/mali/common/mali_l2_cache.h new file mode 100644 index 0000000..5a8e4da --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_l2_cache.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_KERNEL_L2_CACHE_H__ +#define __MALI_KERNEL_L2_CACHE_H__ + +#include "mali_osk.h" + +struct mali_l2_cache_core; + +_mali_osk_errcode_t mali_l2_cache_initialize(void); +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); + +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); +mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter); +u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache); +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); + +_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); + +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); + +#endif /* __MALI_KERNEL_L2_CACHE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.c b/drivers/media/video/samsung/mali/common/mali_mem_validation.c new file mode 100644 index 0000000..ea9c428 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mem_validation.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_mem_validation.h" +#include "mali_osk.h" +#include "mali_kernel_common.h" + +#define MALI_INVALID_MEM_ADDR 0xFFFFFFFF + +typedef struct +{ + u32 phys_base; /**< Mali physical base of the memory, page aligned */ + u32 size; /**< size in bytes of the memory, multiple of page size */ +} _mali_mem_validation_t; + +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) +{ + /* 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)); + return _MALI_OSK_ERR_FAULT; + } + + /* Check restrictions on page alignment */ + if ((0 != (resource->base & (~_MALI_OSK_CPU_PAGE_MASK))) || + (0 != (resource->size & (~_MALI_OSK_CPU_PAGE_MASK)))) + { + MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; incorrect alignment\n", resource->description)); + 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)); + + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size) +{ + if (phys_addr < (phys_addr + size)) /* Don't allow overflow (or zero size) */ + { + if ((0 == ( phys_addr & (~_MALI_OSK_CPU_PAGE_MASK))) && + (0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)))) + { + if ((phys_addr >= mali_mem_validator.phys_base) && + ((phys_addr + (size - 1)) >= mali_mem_validator.phys_base) && + (phys_addr <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) && + ((phys_addr + (size - 1)) <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) ) + { + MALI_DEBUG_PRINT(3, ("Accepted range 0x%08X + size 0x%08X (= 0x%08X)\n", phys_addr, size, (phys_addr + size - 1))); + return _MALI_OSK_ERR_OK; + } + } + } + + MALI_PRINT_ERROR(("MALI PHYSICAL RANGE VALIDATION ERROR: The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_addr, size)); + + return _MALI_OSK_ERR_FAULT; +} diff --git a/drivers/media/video/samsung/mali/common/mali_mem_validation.h b/drivers/media/video/samsung/mali/common/mali_mem_validation.h new file mode 100644 index 0000000..2043b44 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mem_validation.h @@ -0,0 +1,19 @@ +/* + * 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_MEM_VALIDATION_H__ +#define __MALI_MEM_VALIDATION_H__ + +#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_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/media/video/samsung/mali/common/mali_memory.c new file mode 100644 index 0000000..7a11d1a --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_memory.c @@ -0,0 +1,1321 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mali_kernel_common.h" +#include "mali_kernel_descriptor_mapping.h" +#include "mali_mem_validation.h" +#include "mali_memory.h" +#include "mali_mmu_page_directory.h" +#include "mali_kernel_memory_engine.h" +#include "mali_block_allocator.h" +#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 "ump_kernel_interface.h" +#endif + +/* kernel side OS functions and user-kernel interface */ +#include "mali_osk.h" +#include "mali_osk_mali.h" +#include "mali_ukk.h" +#include "mali_osk_list.h" +#include "mali_osk_bitops.h" + +/** + * Per-session memory descriptor mapping table sizes + */ +#define MALI_MEM_DESCRIPTORS_INIT 64 +#define MALI_MEM_DESCRIPTORS_MAX 65536 + +typedef struct dedicated_memory_info +{ + u32 base; + u32 size; + struct dedicated_memory_info * next; +} dedicated_memory_info; + +/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */ +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +typedef struct ump_mem_allocation +{ + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; + u32 initial_offset; + u32 size_allocated; + ump_dd_handle ump_mem; +} ump_mem_allocation ; +#endif + +typedef struct external_mem_allocation +{ + mali_allocation_engine * engine; + mali_memory_allocation * descriptor; + u32 initial_offset; + u32 size; +} external_mem_allocation; + +/** + * @brief Internal function for unmapping memory + * + * Worker function for unmapping memory from a user-process. We assume that the + * session/descriptor's lock was obtained before entry. For example, the + * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this + * function to do the actual unmapping. mali_memory_core_session_end() could + * also call this directly (depending on compilation options), having locked + * the descriptor. + * + * This function will fail if it is unable to put the MMU in stall mode (which + * might be the case if a page fault is also being processed). + * + * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h" + * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. + */ +static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ); + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +static void ump_memory_release(void * ctx, void * handle); +static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/ + + +static void external_memory_release(void * ctx, void * handle); +static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info); + + +/* nop functions */ + +/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */ +static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */ +static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size); +static void mali_address_manager_release(mali_memory_allocation * descriptor); + +/* MMU variables */ + +typedef struct mali_mmu_page_table_allocation +{ + _mali_osk_list_t list; + u32 * usage_map; + u32 usage_count; + u32 num_pages; + mali_page_table_block pages; +} mali_mmu_page_table_allocation; + +typedef struct mali_mmu_page_table_allocations +{ + _mali_osk_lock_t *lock; + _mali_osk_list_t partial; + _mali_osk_list_t full; + /* we never hold on to a empty allocation */ +} mali_mmu_page_table_allocations; + +static mali_kernel_mem_address_manager mali_address_manager = +{ + mali_address_manager_allocate, /* allocate */ + mali_address_manager_release, /* release */ + mali_address_manager_map, /* map_physical */ + NULL /* unmap_physical not present*/ +}; + +/* the mmu page table cache */ +static struct mali_mmu_page_table_allocations page_table_cache; + + +static mali_kernel_mem_address_manager process_address_manager = +{ + _mali_osk_mem_mapregion_init, /* allocate */ + _mali_osk_mem_mapregion_term, /* release */ + _mali_osk_mem_mapregion_map, /* map_physical */ + _mali_osk_mem_mapregion_unmap /* unmap_physical */ +}; + +static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void); +static void mali_mmu_page_table_cache_destroy(void); + +static mali_allocation_engine memory_engine = NULL; +static mali_physical_memory_allocator * physical_memory_allocators = NULL; + +static dedicated_memory_info * mem_region_registrations = NULL; + +/* called during module init */ +_mali_osk_errcode_t mali_memory_initialize(void) +{ + _mali_osk_errcode_t err; + + MALI_DEBUG_PRINT(2, ("Memory system initializing\n")); + + err = mali_mmu_page_table_cache_create(); + if(_MALI_OSK_ERR_OK != err) + { + MALI_ERROR(err); + } + + memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager); + MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT); + + MALI_SUCCESS; +} + +/* called if/when our module is unloaded */ +void mali_memory_terminate(void) +{ + MALI_DEBUG_PRINT(2, ("Memory system terminating\n")); + + mali_mmu_page_table_cache_destroy(); + + while ( NULL != mem_region_registrations) + { + dedicated_memory_info * m; + m = mem_region_registrations; + mem_region_registrations = m->next; + _mali_osk_mem_unreqregion(m->base, m->size); + _mali_osk_free(m); + } + + while ( NULL != physical_memory_allocators) + { + mali_physical_memory_allocator * m; + m = physical_memory_allocators; + physical_memory_allocators = m->next; + m->destroy(m); + } + + if (NULL != memory_engine) + { + mali_allocation_engine_destroy(memory_engine); + memory_engine = NULL; + } +} + +_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data * session_data) +{ + MALI_DEBUG_PRINT(5, ("Memory session begin\n")); + + /* create descriptor mapping table */ + session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX); + + if (NULL == session_data->descriptor_mapping) + { + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + session_data->memory_lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_SESSION); + if (NULL == session_data->memory_lock) + { + mali_descriptor_mapping_destroy(session_data->descriptor_mapping); + _mali_osk_free(session_data); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + /* Init the session's memory allocation list */ + _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head ); + + MALI_DEBUG_PRINT(5, ("MMU session begin: success\n")); + MALI_SUCCESS; +} + +static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target) +{ + mali_memory_allocation * descriptor; + + descriptor = (mali_memory_allocation*)map_target; + + MALI_DEBUG_PRINT(3, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target)); + MALI_DEBUG_ASSERT(descriptor); + + mali_allocation_engine_release_memory(memory_engine, descriptor); + _mali_osk_free(descriptor); +} + +void mali_memory_session_end(struct mali_session_data *session_data) +{ + MALI_DEBUG_PRINT(3, ("MMU session end\n")); + + if (NULL == session_data) + { + MALI_DEBUG_PRINT(1, ("No session data found during session end\n")); + return; + } + +#ifndef MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP +#if _MALI_OSK_SPECIFIC_INDIRECT_MMAP +#error Indirect MMAP specified, but UKK does not have implicit MMAP cleanup. Current implementation does not handle this. +#else + { + _mali_osk_errcode_t err; + err = _MALI_OSK_ERR_BUSY; + while (err == _MALI_OSK_ERR_BUSY) + { + /* Lock the session so we can modify the memory list */ + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + err = _MALI_OSK_ERR_OK; + + /* Free all memory engine allocations */ + if (0 == _mali_osk_list_empty(&session_data->memory_head)) + { + mali_memory_allocation *descriptor; + mali_memory_allocation *temp; + _mali_uk_mem_munmap_s unmap_args; + + MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n")); + + unmap_args.ctx = session_data; + + /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */ + _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list) + { + MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n", + descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping) + ); + /* ASSERT that the descriptor's lock references the correct thing */ + MALI_DEBUG_ASSERT( descriptor->lock == session_data->memory_lock ); + /* Therefore, we have already locked the descriptor */ + + unmap_args.size = descriptor->size; + unmap_args.mapping = descriptor->mapping; + unmap_args.cookie = (u32)descriptor; + + /* + * This removes the descriptor from the list, and frees the descriptor + * + * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since + * the only OS we are aware of that requires indirect MMAP also has + * implicit mmap cleanup. + */ + err = _mali_ukk_mem_munmap_internal( &unmap_args ); + + if (err == _MALI_OSK_ERR_BUSY) + { + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + /* + * Reason for this; + * We where unable to stall the MMU, probably because we are in page fault handling. + * Sleep for a while with the session lock released, then try again. + * Abnormal termination of programs with running Mali jobs is a normal reason for this. + */ + _mali_osk_time_ubusydelay(10); + break; /* Will jump back into: "while (err == _MALI_OSK_ERR_BUSY)" */ + } + } + } + } + /* Assert that we really did free everything */ + MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) ); + } +#endif /* _MALI_OSK_SPECIFIC_INDIRECT_MMAP */ +#else + /* Lock the session so we can modify the memory list */ + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); +#endif /* MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP */ + + if (NULL != session_data->descriptor_mapping) + { + mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback); + mali_descriptor_mapping_destroy(session_data->descriptor_mapping); + session_data->descriptor_mapping = NULL; + } + + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + /** + * @note Could the VMA close handler mean that we use the session data after it was freed? + * In which case, would need to refcount the session data, and free on VMA close + */ + + /* Free the lock */ + _mali_osk_lock_term( session_data->memory_lock ); + + return; +} + +_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource) +{ + mali_physical_memory_allocator * allocator; + mali_physical_memory_allocator ** next_allocator_list; + + u32 alloc_order = resource->alloc_order; + + allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description); + if (NULL == allocator) + { + MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n")); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + allocator->alloc_order = alloc_order; + + /* link in the allocator: insertion into ordered list + * resources of the same alloc_order will be Last-in-first */ + next_allocator_list = &physical_memory_allocators; + + while (NULL != *next_allocator_list && + (*next_allocator_list)->alloc_order < alloc_order ) + { + next_allocator_list = &((*next_allocator_list)->next); + } + + allocator->next = (*next_allocator_list); + (*next_allocator_list) = allocator; + + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource) +{ + mali_physical_memory_allocator * allocator; + mali_physical_memory_allocator ** next_allocator_list; + dedicated_memory_info * cleanup_data; + + u32 alloc_order = resource->alloc_order; + + /* do the 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)) + { + MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + /* create generic block allocator object to handle it */ + allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description ); + + if (NULL == allocator) + { + MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n")); + _mali_osk_mem_unreqregion(resource->base, resource->size); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + /* save low level cleanup info */ + allocator->alloc_order = alloc_order; + + cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info)); + + if (NULL == cleanup_data) + { + _mali_osk_mem_unreqregion(resource->base, resource->size); + allocator->destroy(allocator); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + cleanup_data->base = resource->base; + cleanup_data->size = resource->size; + + cleanup_data->next = mem_region_registrations; + mem_region_registrations = cleanup_data; + + /* link in the allocator: insertion into ordered list + * resources of the same alloc_order will be Last-in-first */ + next_allocator_list = &physical_memory_allocators; + + while ( NULL != *next_allocator_list && + (*next_allocator_list)->alloc_order < alloc_order ) + { + next_allocator_list = &((*next_allocator_list)->next); + } + + allocator->next = (*next_allocator_list); + (*next_allocator_list) = allocator; + + MALI_SUCCESS; +} + +#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 +static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + ump_dd_handle ump_mem; + u32 nr_blocks; + u32 i; + ump_dd_physical_block * ump_blocks; + ump_mem_allocation *ret_allocation; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) ); + if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE; + + ump_mem = (ump_dd_handle)ctx; + + MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n")); + + nr_blocks = ump_dd_phys_block_count_get(ump_mem); + + MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks)); + + if (nr_blocks == 0) + { + MALI_DEBUG_PRINT(1, ("No block count\n")); + _mali_osk_free( ret_allocation ); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks ); + if ( NULL==ump_blocks ) + { + _mali_osk_free( ret_allocation ); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) + { + _mali_osk_free(ump_blocks); + _mali_osk_free( ret_allocation ); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + /* Store away the initial offset for unmapping purposes */ + ret_allocation->initial_offset = *offset; + + for(i=0; iinitial_offset; + MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); + + /* unmap all previous blocks (if any) */ + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); + + _mali_osk_free(ump_blocks); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += ump_blocks[i].size; + } + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + /* Map in an extra virtual guard page at the end of the VMA */ + MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE )) + { + u32 size_allocated = *offset - ret_allocation->initial_offset; + MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); + + /* unmap all previous blocks (if any) */ + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); + + _mali_osk_free(ump_blocks); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += _MALI_OSK_MALI_PAGE_SIZE; + } + + _mali_osk_free( ump_blocks ); + + ret_allocation->engine = engine; + ret_allocation->descriptor = descriptor; + ret_allocation->ump_mem = ump_mem; + ret_allocation->size_allocated = *offset - ret_allocation->initial_offset; + + alloc_info->ctx = NULL; + alloc_info->handle = ret_allocation; + alloc_info->next = NULL; + alloc_info->release = ump_memory_release; + + return MALI_MEM_ALLOC_FINISHED; +} + +static void ump_memory_release(void * ctx, void * handle) +{ + ump_dd_handle ump_mem; + ump_mem_allocation *allocation; + + allocation = (ump_mem_allocation *)handle; + + MALI_DEBUG_ASSERT_POINTER( allocation ); + + ump_mem = allocation->ump_mem; + + MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem); + + /* At present, this is a no-op. But, it allows the mali_address_manager to + * do unmapping of a subrange in future. */ + mali_allocation_engine_unmap_physical( allocation->engine, + allocation->descriptor, + allocation->initial_offset, + allocation->size_allocated, + (_mali_osk_mem_mapregion_flags_t)0 + ); + _mali_osk_free( allocation ); + + + ump_dd_reference_release(ump_mem) ; + return; +} + +_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ) +{ + ump_dd_handle ump_mem; + mali_physical_memory_allocator external_memory_allocator; + struct mali_session_data *session_data; + mali_memory_allocation * descriptor; + int md; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + /* check arguments */ + /* NULL might be a valid Mali address */ + if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + /* size must be a multiple of the system page size */ + if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + MALI_DEBUG_PRINT(3, + ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n", + args->secure_id, args->mali_address, args->size)); + + ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ; + + if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT); + + descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); + if (NULL == descriptor) + { + ump_dd_reference_release(ump_mem); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + descriptor->size = args->size; + descriptor->mapping = NULL; + descriptor->mali_address = args->mali_address; + descriptor->mali_addr_mapping_info = (void*)session_data; + descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ + descriptor->lock = session_data->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 ); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) + { + ump_dd_reference_release(ump_mem); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + external_memory_allocator.allocate = ump_memory_commit; + external_memory_allocator.allocate_page_table_block = NULL; + external_memory_allocator.ctx = ump_mem; + external_memory_allocator.name = "UMP Memory"; + external_memory_allocator.next = NULL; + + _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) + { + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + mali_descriptor_mapping_free(session_data->descriptor_mapping, md); + ump_dd_reference_release(ump_mem); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + args->cookie = md; + + MALI_DEBUG_PRINT(5,("Returning from UMP attach\n")); + + /* All OK */ + MALI_SUCCESS; +} + + +_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ) +{ + mali_memory_allocation * descriptor; + struct mali_session_data *session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) + { + MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + descriptor = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); + + if (NULL != descriptor) + { + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + mali_allocation_engine_release_memory(memory_engine, descriptor); + + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + _mali_osk_free(descriptor); + } + + MALI_SUCCESS; + +} +#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */ + + +static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) +{ + u32 * data; + external_mem_allocation * ret_allocation; + + MALI_DEBUG_ASSERT_POINTER(ctx); + MALI_DEBUG_ASSERT_POINTER(engine); + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(alloc_info); + + ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) ); + + if ( NULL == ret_allocation ) + { + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + + data = (u32*)ctx; + + ret_allocation->engine = engine; + ret_allocation->descriptor = descriptor; + ret_allocation->initial_offset = *offset; + + alloc_info->ctx = NULL; + alloc_info->handle = ret_allocation; + alloc_info->next = NULL; + alloc_info->release = external_memory_release; + + MALI_DEBUG_PRINT(5, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1])); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1])) + { + MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n")); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += data[1]; + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + /* Map in an extra virtual guard page at the end of the VMA */ + MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n")); + if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE)) + { + u32 size_allocated = *offset - ret_allocation->initial_offset; + MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n")); + + /* unmap what we previously mapped */ + mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 ); + _mali_osk_free(ret_allocation); + return MALI_MEM_ALLOC_INTERNAL_FAILURE; + } + *offset += _MALI_OSK_MALI_PAGE_SIZE; + } + + ret_allocation->size = *offset - ret_allocation->initial_offset; + + return MALI_MEM_ALLOC_FINISHED; +} + +static void external_memory_release(void * ctx, void * handle) +{ + external_mem_allocation * allocation; + + allocation = (external_mem_allocation *) handle; + MALI_DEBUG_ASSERT_POINTER( allocation ); + + /* At present, this is a no-op. But, it allows the mali_address_manager to + * do unmapping of a subrange in future. */ + + mali_allocation_engine_unmap_physical( allocation->engine, + allocation->descriptor, + allocation->initial_offset, + allocation->size, + (_mali_osk_mem_mapregion_flags_t)0 + ); + + _mali_osk_free( allocation ); + + return; +} + +_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ) +{ + mali_physical_memory_allocator external_memory_allocator; + struct mali_session_data *session_data; + u32 info[2]; + mali_memory_allocation * descriptor; + int md; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + external_memory_allocator.allocate = external_memory_commit; + external_memory_allocator.allocate_page_table_block = NULL; + external_memory_allocator.ctx = &info[0]; + external_memory_allocator.name = "External Memory"; + external_memory_allocator.next = NULL; + + /* check arguments */ + /* NULL might be a valid Mali address */ + if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + /* size must be a multiple of the system page size */ + if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); + + MALI_DEBUG_PRINT(3, + ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n", + (void*)args->phys_addr, + (void*)(args->phys_addr + args->size -1), + (void*)args->mali_address) + ); + + /* Validate the mali physical range */ + if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size)) + { + return _MALI_OSK_ERR_FAULT; + } + + info[0] = args->phys_addr; + info[1] = args->size; + + descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation)); + if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + descriptor->size = args->size; + descriptor->mapping = NULL; + descriptor->mali_address = args->mali_address; + descriptor->mali_addr_mapping_info = (void*)session_data; + descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */ + descriptor->lock = session_data->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 ); + + _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL)) + { + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md)) + { + mali_allocation_engine_release_memory(memory_engine, descriptor); + _mali_osk_free(descriptor); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + args->cookie = md; + + MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n")); + + /* All OK */ + MALI_SUCCESS; +} + + +_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ) +{ + mali_memory_allocation * descriptor; + void* old_value; + struct mali_session_data *session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)args->ctx; + MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS); + + if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor)) + { + MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie)); + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } + + old_value = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie); + + if (NULL != old_value) + { + _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + mali_allocation_engine_release_memory(memory_engine, descriptor); + + _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW ); + + _mali_osk_free(descriptor); + } + + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */ + args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */ + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args ) +{ + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_SUCCESS; +} + +static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor) +{ + struct mali_session_data *session_data; + u32 actual_size; + + MALI_DEBUG_ASSERT_POINTER(descriptor); + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + + actual_size = descriptor->size; + + if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE) + { + actual_size += _MALI_OSK_MALI_PAGE_SIZE; + } + + return mali_mmu_pagedir_map(session_data->page_directory, descriptor->mali_address, actual_size); +} + +static void mali_address_manager_release(mali_memory_allocation * descriptor) +{ + const u32 illegal_mali_address = 0xffffffff; + struct mali_session_data *session_data; + MALI_DEBUG_ASSERT_POINTER(descriptor); + + /* It is allowed to call this function several times on the same descriptor. + When memory is released we set the illegal_mali_address so we can early out here. */ + if ( illegal_mali_address == descriptor->mali_address) return; + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + mali_mmu_pagedir_unmap(session_data->page_directory, descriptor->mali_address, descriptor->size); + + descriptor->mali_address = illegal_mali_address ; +} + +static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size) +{ + struct mali_session_data *session_data; + u32 mali_address; + + MALI_DEBUG_ASSERT_POINTER(descriptor); + MALI_DEBUG_ASSERT_POINTER(phys_addr); + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + MALI_DEBUG_ASSERT_POINTER(session_data); + + mali_address = descriptor->mali_address + offset; + + MALI_DEBUG_PRINT(7, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", *phys_addr, mali_address, size)); + + mali_mmu_pagedir_update(session_data->page_directory, mali_address, *phys_addr, size); + + MALI_SUCCESS; +} + +/* This handler registered to mali_mmap for MMU builds */ +_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ) +{ + struct mali_session_data *session_data; + mali_memory_allocation * descriptor; + + /* validate input */ + if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } + + /* Unpack arguments */ + session_data = (struct mali_session_data *)args->ctx; + + /* validate input */ + if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } + + descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) ); + if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } + + descriptor->size = args->size; + descriptor->mali_address = args->phys_addr; + descriptor->mali_addr_mapping_info = (void*)session_data; + + descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */ + descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE; + descriptor->lock = session_data->memory_lock; + _mali_osk_list_init( &descriptor->list ); + + _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head)) + { + /* We do not FLUSH nor TLB_ZAP on MMAP, since we do both of those on job start*/ + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + + args->mapping = descriptor->mapping; + args->cookie = (u32)descriptor; + + MALI_DEBUG_PRINT(7, ("MMAP OK\n")); + MALI_SUCCESS; + } + else + { + _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW); + /* OOM, but not a fatal error */ + MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n")); + _mali_osk_free(descriptor); + /* Linux will free the CPU address allocation, userspace client the Mali address allocation */ + MALI_ERROR(_MALI_OSK_ERR_FAULT); + } +} + +static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args ) +{ + 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); + + /** @note args->context unused; we use the memory_session from the cookie */ + /* args->mapping and args->size are also discarded. They are only necessary + for certain do_munmap implementations. However, they could be used to check the + descriptor at this point. */ + + session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info; + MALI_DEBUG_ASSERT_POINTER(session_data); + + /* Unmapping the memory from the mali virtual address space. + 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); + } + + /* 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); + + _mali_osk_free(descriptor); + + return _MALI_OSK_ERR_OK; +} + +/* Handler for unmapping memory for MMU builds */ +_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args ) +{ + mali_memory_allocation * descriptor; + _mali_osk_lock_t *descriptor_lock; + _mali_osk_errcode_t err; + + descriptor = (mali_memory_allocation *)args->cookie; + MALI_DEBUG_ASSERT_POINTER(descriptor); + + /** @note args->context unused; we use the memory_session from the cookie */ + /* args->mapping and args->size are also discarded. They are only necessary + for certain do_munmap implementations. However, they could be used to check the + descriptor at this point. */ + + MALI_DEBUG_ASSERT_POINTER((struct mali_session_data *)descriptor->mali_addr_mapping_info); + + descriptor_lock = descriptor->lock; /* should point to the session data lock... */ + + err = _MALI_OSK_ERR_BUSY; + while (err == _MALI_OSK_ERR_BUSY) + { + if (descriptor_lock) + { + _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + } + + err = _mali_ukk_mem_munmap_internal( args ); + + if (descriptor_lock) + { + _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW ); + } + + if (err == _MALI_OSK_ERR_BUSY) + { + /* + * Reason for this; + * We where unable to stall the MMU, probably because we are in page fault handling. + * Sleep for a while with the session lock released, then try again. + * Abnormal termination of programs with running Mali jobs is a normal reason for this. + */ + _mali_osk_time_ubusydelay(10); + } + } + + return err; +} + +u32 _mali_ukk_report_memory_usage(void) +{ + return mali_allocation_engine_memory_usage(physical_memory_allocators); +} + +_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping) +{ + _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + + if (0 == _mali_osk_list_empty(&page_table_cache.partial)) + { + mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list); + int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages); + MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number)); + _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map); + alloc->usage_count++; + if (alloc->num_pages == alloc->usage_count) + { + /* full, move alloc to full list*/ + _mali_osk_list_move(&alloc->list, &page_table_cache.full); + } + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + + *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base; + *mapping = (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping); + MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); + MALI_SUCCESS; + } + else + { + mali_mmu_page_table_allocation * alloc; + /* no free pages, allocate a new one */ + + alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation)); + if (NULL == alloc) + { + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = MALI_INVALID_PAGE; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _MALI_OSK_INIT_LIST_HEAD(&alloc->list); + + if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators)) + { + MALI_DEBUG_PRINT(1, ("No more memory for page tables\n")); + _mali_osk_free(alloc); + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = MALI_INVALID_PAGE; + *mapping = NULL; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + /* create the usage map */ + alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE; + alloc->usage_count = 1; + MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages)); + alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long)); + if (NULL == alloc->usage_map) + { + MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n")); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc); + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = MALI_INVALID_PAGE; + *mapping = NULL; + MALI_ERROR(_MALI_OSK_ERR_NOMEM); + } + + _mali_osk_set_nonatomic_bit(0, alloc->usage_map); + + if (alloc->num_pages > 1) + { + _mali_osk_list_add(&alloc->list, &page_table_cache.partial); + } + else + { + _mali_osk_list_add(&alloc->list, &page_table_cache.full); + } + + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + *table_page = alloc->pages.phys_base; /* return the first page */ + *mapping = alloc->pages.mapping; /* Mapping for first page */ + MALI_DEBUG_PRINT(4, ("Page table allocated: VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page )); + MALI_SUCCESS; + } +} + +void mali_mmu_release_table_page(u32 pa) +{ + mali_mmu_page_table_allocation * alloc, * temp_alloc; + + MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa)); + + MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa)); + + _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + + /* find the entry this address belongs to */ + /* first check the partial list */ + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list) + { + u32 start = alloc->pages.phys_base; + u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; + if (pa >= start && pa <= last) + { + MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map)); + _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); + alloc->usage_count--; + + _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); + + if (0 == alloc->usage_count) + { + /* empty, release whole page alloc */ + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa)); + return; + } + } + + /* the check the full list */ + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list) + { + u32 start = alloc->pages.phys_base; + u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE; + if (pa >= start && pa <= last) + { + _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map); + alloc->usage_count--; + + _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE); + + + if (0 == alloc->usage_count) + { + /* empty, release whole page alloc */ + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + else + { + /* transfer to partial list */ + _mali_osk_list_move(&alloc->list, &page_table_cache.partial); + } + + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); + MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa)); + return; + } + } + + MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa)); + + _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW); +} + +static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void) +{ + page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE); + MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT ); + _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial); + _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full); + MALI_SUCCESS; +} + +static void mali_mmu_page_table_cache_destroy(void) +{ + mali_mmu_page_table_allocation * alloc, *temp; + + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list) + { + MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count)); + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + + MALI_DEBUG_PRINT_IF(1, 0 == _mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n")); + + _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list) + { + MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count)); + _mali_osk_list_del(&alloc->list); + alloc->pages.release(&alloc->pages); + _mali_osk_free(alloc->usage_map); + _mali_osk_free(alloc); + } + + _mali_osk_lock_term(page_table_cache.lock); +} diff --git a/drivers/media/video/samsung/mali/common/mali_memory.h b/drivers/media/video/samsung/mali/common/mali_memory.h new file mode 100644 index 0000000..53a994c --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_memory.h @@ -0,0 +1,80 @@ +/* + * 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_MEMORY_H__ +#define __MALI_MEMORY_H__ + +#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 + * allocating Mali memory. + * + * @return On success _MALI_OSK_ERR_OK, othervise some error code describing the error. + */ +_mali_osk_errcode_t mali_memory_initialize(void); + +/** @brief Terminate Mali memory system + * + * Clean up and release internal data structures. + */ +void mali_memory_terminate(void); + +/** @brief Start new Mali memory session + * + * Allocate and prepare session specific memory allocation data data. The + * session page directory, lock, and descriptor map is set up. + * + * @param mali_session_data pointer to the session data structure + */ +_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data *mali_session_data); + +/** @brief Close a Mali memory session + * + * Release session specific memory allocation related data. + * + * @param mali_session_data pointer to the session data structure + */ +void mali_memory_session_end(struct mali_session_data *mali_session_data); + +/** @brief Allocate a page table page + * + * Allocate a page for use as a page directory or page table. The page is + * mapped into kernel space. + * + * @return _MALI_OSK_ERR_OK on success, othervise an error code + * @param table_page GPU pointer to the allocated page + * @param mapping CPU pointer to the mapping of the allocated page + */ +_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping); + +/** @brief Release a page table page + * + * Release a page table page allocated through \a mali_mmu_get_table_page + * + * @param pa the GPU address of the page to release + */ +void mali_mmu_release_table_page(u32 pa); + + +/** @brief Parse resource and prepare the OS memory allocator + */ +_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource); + +/** @brief Parse resource and prepare the dedicated memory allocator + */ +_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource); + +#endif /* __MALI_MEMORY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.c b/drivers/media/video/samsung/mali/common/mali_mmu.c new file mode 100644 index 0000000..2f2fa4d --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu.c @@ -0,0 +1,619 @@ +/* + * 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_bitops.h" +#include "mali_osk_list.h" +#include "mali_ukk.h" + +#include "mali_mmu.h" +#include "mali_hw_core.h" +#include "mali_group.h" +#include "mali_mmu_page_directory.h" + +/** + * Size of the MMU registers in bytes + */ +#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. + */ +typedef enum mali_mmu_command +{ + MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */ + MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */ + MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**< Enable stall on page fault */ + MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */ + MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */ + MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */ + MALI_MMU_COMMAND_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); + +MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu); + +/* page fault queue flush helper pages + * note that the mapping pointers are currently unused outside of the initialization functions */ +static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE; +static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE; +static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE; + +/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */ +static u32 mali_empty_page_directory = MALI_INVALID_PAGE; + +_mali_osk_errcode_t mali_mmu_initialize(void) +{ + /* allocate the helper pages */ + mali_empty_page_directory = mali_allocate_empty_page(); + if(0 == mali_empty_page_directory) + { + mali_empty_page_directory = MALI_INVALID_PAGE; + return _MALI_OSK_ERR_NOMEM; + } + + if (_MALI_OSK_ERR_OK != mali_create_fault_flush_pages(&mali_page_fault_flush_page_directory, + &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page)) + { + mali_free_empty_page(mali_empty_page_directory); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; +} + +void mali_mmu_terminate(void) +{ + MALI_DEBUG_PRINT(3, ("Mali MMU: terminating\n")); + + /* Free global helper pages */ + mali_free_empty_page(mali_empty_page_directory); + + /* Free the page fault flush pages */ + mali_destroy_fault_flush_pages(&mali_page_fault_flush_page_directory, + &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* mmu = NULL; + + MALI_DEBUG_ASSERT_POINTER(resource); + + MALI_DEBUG_PRINT(2, ("Mali MMU: Creating Mali MMU: %s\n", resource->description)); + + mmu = _mali_osk_calloc(1,sizeof(struct mali_mmu_core)); + if (NULL != mmu) + { + 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)) + { + /* 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) + { + return mmu; + } + else + { + MALI_PRINT_ERROR(("Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description)); + } + } + mali_hw_core_delete(&mmu->hw_core); + } + + _mali_osk_free(mmu); + } + else + { + MALI_PRINT_ERROR(("Failed to allocate memory for MMU\n")); + } + + return NULL; +} + +void mali_mmu_delete(struct mali_mmu_core *mmu) +{ + _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) + { + 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) + { + 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))); + } +} + +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); + + if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) ) + { + MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enebled.\n")); + return MALI_TRUE; + } + + if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE ) + { + MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it is in pagefault state.\n")); + return MALI_FALSE; + } + + 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) + { + 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)) + { + break; + } + if ( 0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED ))) + { + break; + } + _mali_osk_time_ubusydelay(delay_in_usecs); + } + if (max_loop_count == 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))); + 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")); + return MALI_FALSE; + } + + return MALI_TRUE; +} + +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); + + if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED )) + { + MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n")); + return; + } + if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) + { + MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n")); + return; + } + + 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) + { + u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS); + if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) ) + { + break; + } + if ( status & MALI_MMU_STATUS_BIT_PAGE_FAULT_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) 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_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET); + + for (i = 0; i < max_loop_count; ++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) + { + 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; + } + + return _MALI_OSK_ERR_OK; +} + +_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); + + MALI_DEBUG_PRINT(3, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->hw_core.description)); + + if (_MALI_OSK_ERR_OK == mali_mmu_raw_reset(mmu)) + { + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR); + /* no session is active, so just activate the empty page directory */ + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); + mali_mmu_enable_paging(mmu); + err = _MALI_OSK_ERR_OK; + } + mali_mmu_disable_stall(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_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE); + + if (MALI_FALSE == stall_success) + { + /* False means that it is in Pagefault state. Not possible to disable_stall then */ + return MALI_FALSE; + } + + mali_mmu_disable_stall(mmu); + return MALI_TRUE; +} + +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_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); + +} + +mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mali_page_directory *pagedir) +{ + 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); + + if ( MALI_FALSE==stall_success ) return MALI_FALSE; + mali_mmu_activate_address_space(mmu, pagedir->page_directory); + mali_mmu_disable_stall(mmu); + return MALI_TRUE; +} + +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_mmu_activate_address_space(mmu, mali_empty_page_directory); + mali_mmu_disable_stall(mmu); +} + +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); + /* This function is expect to fail the stalling, since it might be in PageFault mode when it is called */ + mali_mmu_activate_address_space(mmu, mali_page_fault_flush_page_directory); + if ( MALI_TRUE==stall_success ) mali_mmu_disable_stall(mmu); +} + +/* Is called when we want the mmu to give an interrupt */ +static void mali_mmu_probe_trigger(void *data) +{ + struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR); +} + +/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */ +static _mali_osk_errcode_t mali_mmu_probe_ack(void *data) +{ + struct mali_mmu_core *mmu = (struct mali_mmu_core *)data; + u32 int_stat; + + int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS); + + MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat)); + if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT) + { + MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n")); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT); + } + else + { + MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n")); + } + + if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR) + { + MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n")); + mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR); + } + else + { + MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n")); + } + + if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) == + (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) + { + return _MALI_OSK_ERR_OK; + } + + return _MALI_OSK_ERR_FAULT; +} + +#if 0 +void mali_mmu_print_state(struct mali_mmu_core *mmu) +{ + MALI_DEBUG_PRINT(2, ("MMU: State of %s is 0x%08x\n", mmu->hw_core.description, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); +} +#endif diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.h b/drivers/media/video/samsung/mali/common/mali_mmu.h new file mode 100644 index 0000000..c7274b8 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu.h @@ -0,0 +1,55 @@ +/* + * 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_mmu_page_directory.c b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c new file mode 100644 index 0000000..43a4cf4 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c @@ -0,0 +1,459 @@ +/* + * 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_kernel_core.h" +#include "mali_osk.h" +#include "mali_uk_types.h" +#include "mali_mmu_page_directory.h" +#include "mali_memory.h" + +#include "mali_cluster.h" +#include "mali_group.h" + +static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data); + +u32 mali_allocate_empty_page(void) +{ + _mali_osk_errcode_t err; + mali_io_address mapping; + u32 address; + + if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping)) + { + /* Allocation failed */ + return 0; + } + + MALI_DEBUG_ASSERT_POINTER( mapping ); + + err = fill_page(mapping, 0); + if (_MALI_OSK_ERR_OK != err) + { + mali_mmu_release_table_page(address); + } + return address; +} + +void mali_free_empty_page(u32 address) +{ + if (MALI_INVALID_PAGE != address) + { + mali_mmu_release_table_page(address); + } +} + +_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page) +{ + _mali_osk_errcode_t err; + mali_io_address page_directory_mapping; + mali_io_address page_table_mapping; + mali_io_address data_page_mapping; + + err = mali_mmu_get_table_page(data_page, &data_page_mapping); + if (_MALI_OSK_ERR_OK == err) + { + err = mali_mmu_get_table_page(page_table, &page_table_mapping); + if (_MALI_OSK_ERR_OK == err) + { + err = mali_mmu_get_table_page(page_directory, &page_directory_mapping); + if (_MALI_OSK_ERR_OK == err) + { + fill_page(data_page_mapping, 0); + fill_page(page_table_mapping, *data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); + fill_page(page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT); + MALI_SUCCESS; + } + mali_mmu_release_table_page(*page_table); + *page_table = MALI_INVALID_PAGE; + } + mali_mmu_release_table_page(*data_page); + *data_page = MALI_INVALID_PAGE; + } + return err; +} + +void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page) +{ + if (MALI_INVALID_PAGE != *page_directory) + { + mali_mmu_release_table_page(*page_directory); + *page_directory = MALI_INVALID_PAGE; + } + + if (MALI_INVALID_PAGE != *page_table) + { + mali_mmu_release_table_page(*page_table); + *page_table = MALI_INVALID_PAGE; + } + + if (MALI_INVALID_PAGE != *data_page) + { + mali_mmu_release_table_page(*data_page); + *data_page = MALI_INVALID_PAGE; + } +} + +static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data) +{ + int i; + MALI_DEBUG_ASSERT_POINTER( mapping ); + + for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++) + { + _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data); + } + _mali_osk_mem_barrier(); + MALI_SUCCESS; +} + +_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size) +{ + const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); + const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); + _mali_osk_errcode_t err; + mali_io_address pde_mapping; + u32 pde_phys; + int i; + + for(i = first_pde; i <= last_pde; i++) + { + if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)) + { + /* Page table not present */ + MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); + MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]); + + err = mali_mmu_get_table_page(&pde_phys, &pde_mapping); + if(_MALI_OSK_ERR_OK != err) + { + MALI_PRINT_ERROR(("Failed to allocate page table page.\n")); + return err; + } + pagedir->page_entries_mapped[i] = pde_mapping; + + /* Update PDE, mark as present */ + _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), + pde_phys | MALI_MMU_FLAGS_PRESENT); + + MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); + pagedir->page_entries_usage_count[i] = 1; + } + else + { + pagedir->page_entries_usage_count[i]++; + } + } + _mali_osk_write_mem_barrier(); + + MALI_SUCCESS; +} + +MALI_STATIC_INLINE void mali_mmu_zero_pte(mali_io_address page_table, u32 mali_address, u32 size) +{ + int i; + const int first_pte = MALI_MMU_PTE_ENTRY(mali_address); + const int last_pte = MALI_MMU_PTE_ENTRY(mali_address + size - 1); + + for (i = first_pte; i <= last_pte; i++) + { + _mali_osk_mem_iowrite32_relaxed(page_table, i * sizeof(u32), 0); + } +} + +_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size) +{ + const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); + 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 + + /* For all page directory entries in range. */ + for (i = first_pde; i <= last_pde; i++) + { + u32 size_in_pde, offset; + + MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]); + MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]); + + /* Offset into page table, 0 if mali_address is 4MiB aligned */ + offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1)); + if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset) + { + size_in_pde = left; + } + else + { + size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset; + } + + pagedir->page_entries_usage_count[i]--; + + /* If entire page table is unused, free it */ + if (0 == pagedir->page_entries_usage_count[i]) + { + u32 page_address; + MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n")); + /* last reference removed, no need to zero out each PTE */ + + page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32))); + pagedir->page_entries_mapped[i] = NULL; + _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 + + /* 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); + } + + left -= size_in_pde; + mali_address += size_in_pde; + } + _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); + } + + if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id()) + { + mali_cluster_invalidate_pages(pages_to_invalidate, num_pages_inv); + } +#endif + + MALI_SUCCESS; +} + +struct mali_page_directory *mali_mmu_pagedir_alloc(void) +{ + struct mali_page_directory *pagedir; + + pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory)); + if(NULL == pagedir) + { + return NULL; + } + + if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&pagedir->page_directory, &pagedir->page_directory_mapped)) + { + _mali_osk_free(pagedir); + return NULL; + } + + /* Zero page directory */ + fill_page(pagedir->page_directory_mapped, 0); + + return pagedir; +} + +void mali_mmu_pagedir_free(struct mali_page_directory *pagedir) +{ + const int num_page_table_entries = sizeof(pagedir->page_entries_mapped) / sizeof(pagedir->page_entries_mapped[0]); + int i; + + /* Free referenced page tables and zero PDEs. */ + for (i = 0; i < num_page_table_entries; i++) + { + if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT)) + { + mali_mmu_release_table_page( _mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); + _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0); + } + } + _mali_osk_write_mem_barrier(); + + /* Free the page directory page. */ + mali_mmu_release_table_page(pagedir->page_directory); + + _mali_osk_free(pagedir); +} + + +void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size) +{ + u32 end_address = mali_address + size; + + /* Map physical pages into MMU page tables */ + for ( ; mali_address < end_address; mali_address += MALI_MMU_PAGE_SIZE, phys_address += MALI_MMU_PAGE_SIZE) + { + MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]); + _mali_osk_mem_iowrite32_relaxed(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], + MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), + phys_address | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT); + } + _mali_osk_write_mem_barrier(); +} + +u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index) +{ + return (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, index*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK); +} + +/* For instrumented */ +struct dump_info +{ + u32 buffer_left; + u32 register_writes_size; + u32 page_table_dump_size; + u32 *buffer; +}; + +static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info) +{ + if (NULL != info) + { + info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */ + + if (NULL != info->buffer) + { + /* check that we have enough space */ + if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + *info->buffer = where; + info->buffer++; + + *info->buffer = what; + info->buffer++; + + info->buffer_left -= sizeof(u32)*2; + } + } + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info) +{ + if (NULL != info) + { + /* 4096 for the page and 4 bytes for the address */ + const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4; + const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE; + const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4; + + info->page_table_dump_size += dump_size_in_bytes; + + if (NULL != info->buffer) + { + if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM); + + *info->buffer = phys_addr; + info->buffer++; + + _mali_osk_memcpy(info->buffer, page, page_size_in_bytes); + info->buffer += page_size_in_elements; + + info->buffer_left -= dump_size_in_bytes; + } + } + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t dump_mmu_page_table(struct mali_page_directory *pagedir, struct dump_info * info) +{ + MALI_DEBUG_ASSERT_POINTER(pagedir); + MALI_DEBUG_ASSERT_POINTER(info); + + if (NULL != pagedir->page_directory_mapped) + { + int i; + + MALI_CHECK_NO_ERROR( + dump_page(pagedir->page_directory_mapped, pagedir->page_directory, info) + ); + + for (i = 0; i < 1024; i++) + { + if (NULL != pagedir->page_entries_mapped[i]) + { + MALI_CHECK_NO_ERROR( + dump_page(pagedir->page_entries_mapped[i], + _mali_osk_mem_ioread32(pagedir->page_directory_mapped, + i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info) + ); + } + } + } + + MALI_SUCCESS; +} + +static _mali_osk_errcode_t dump_mmu_registers(struct mali_page_directory *pagedir, struct dump_info * info) +{ + MALI_CHECK_NO_ERROR(writereg(0x00000000, pagedir->page_directory, + "set the page directory address", info)); + MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info)); + MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info)); + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ) +{ + struct dump_info info = { 0, 0, 0, NULL }; + struct mali_session_data * session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)(args->ctx); + + MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); + MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); + args->size = info.register_writes_size + info.page_table_dump_size; + MALI_SUCCESS; +} + +_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ) +{ + struct dump_info info = { 0, 0, 0, NULL }; + struct mali_session_data * session_data; + + MALI_DEBUG_ASSERT_POINTER(args); + MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); + MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS); + + session_data = (struct mali_session_data *)(args->ctx); + + info.buffer_left = args->size; + info.buffer = args->buffer; + + args->register_writes = info.buffer; + MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info)); + + args->page_table_dump = info.buffer; + MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info)); + + args->register_writes_size = info.register_writes_size; + args->page_table_dump_size = info.page_table_dump_size; + + MALI_SUCCESS; +} diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h new file mode 100644 index 0000000..8aababe --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h @@ -0,0 +1,83 @@ +/* + * 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_MMU_PAGE_DIRECTORY_H__ +#define __MALI_MMU_PAGE_DIRECTORY_H__ + +#include "mali_osk.h" + +/** + * Size of an MMU page in bytes + */ +#define MALI_MMU_PAGE_SIZE 0x1000 + +/* + * Size of the address space referenced by a page table page + */ +#define MALI_MMU_VIRTUAL_PAGE_SIZE 0x400000 /* 4 MiB */ + +/** + * Page directory index from address + * Calculates the page directory index from the given address + */ +#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF) + +/** + * Page table index from address + * Calculates the page table index from the given address + */ +#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF) + +/** + * Extract the memory address from an PDE/PTE entry + */ +#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00) + +#define MALI_INVALID_PAGE ((u32)(~0)) + +/** + * + */ +typedef enum mali_mmu_entry_flags +{ + MALI_MMU_FLAGS_PRESENT = 0x01, + MALI_MMU_FLAGS_READ_PERMISSION = 0x02, + MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04, + MALI_MMU_FLAGS_MASK = 0x07 +} mali_mmu_entry_flags; + + +struct mali_page_directory +{ + u32 page_directory; /**< Physical address of the memory session's page directory */ + mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */ + + mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */ + u32 page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */ +}; + +/* Map Mali virtual address space (i.e. ensure page tables exist for the virtual range) */ +_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size); +_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size); + +/* Back virtual address space with actual pages. Assumes input is contiguous and 4k aligned. */ +void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size); + +u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index); + +u32 mali_allocate_empty_page(void); +void mali_free_empty_page(u32 address); +_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page); +void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page); + +struct mali_page_directory *mali_mmu_pagedir_alloc(void); +void mali_mmu_pagedir_free(struct mali_page_directory *pagedir); + +#endif /* __MALI_MMU_PAGE_DIRECTORY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk.h b/drivers/media/video/samsung/mali/common/mali_osk.h index 72d851d..e32d15d 100644 --- a/drivers/media/video/samsung/mali/common/mali_osk.h +++ b/drivers/media/video/samsung/mali/common/mali_osk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -165,9 +165,6 @@ typedef void (*_mali_osk_irq_bhandler_t)( void * arg ); * This is public for allocation on stack. On systems that support it, this is just a single 32-bit value. * On others, it could be encapsulating an object stored elsewhere. * - * Even though the structure has space for a u32, the counters will only - * represent signed 24-bit integers. - * * Regardless of implementation, the \ref _mali_osk_atomic functions \b must be used * for all accesses to the variable's value, even if atomicity is not required. * Do not access u.val or u.obj directly. @@ -186,6 +183,40 @@ typedef struct /** @defgroup _mali_osk_lock OSK Mutual Exclusion Locks * @{ */ + +/** @brief OSK Mutual Exclusion Lock ordered list + * + * This lists the various types of locks in the system and is used to check + * that locks are taken in the correct order. + * + * Holding more than one lock of the same order at the same time is not + * allowed. + * + */ +typedef enum +{ + _MALI_OSK_LOCK_ORDER_LAST = 0, + + _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, + + _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_FIRST +} _mali_osk_lock_order_t; + + /** @brief OSK Mutual Exclusion Lock flags type * * Flags are supplied at the point where the Lock is initialized. Each flag can @@ -271,6 +302,17 @@ typedef enum /** @brief Private type for Mutual Exclusion lock objects */ typedef struct _mali_osk_lock_t_struct _mali_osk_lock_t; + +#ifdef DEBUG +/** @brief Macro for asserting that the current thread holds a given lock + */ +#define MALI_DEBUG_ASSERT_LOCK_HELD(l) MALI_DEBUG_ASSERT(_mali_osk_lock_get_owner(l) == _mali_osk_get_tid()); + +/** @brief returns a lock's owner (thread id) if debugging is enabled + */ +u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock ); +#endif + /** @} */ /* end group _mali_osk_lock */ /** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations @@ -368,7 +410,6 @@ typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queu /** @brief Public notification data object type */ typedef struct _mali_osk_notification_t_struct { - u32 magic_code; u32 notification_type; /**< The notification type */ u32 result_buffer_size; /**< Size of the result buffer to copy to user space */ void * result_buffer; /**< Buffer containing any type specific data */ @@ -527,20 +568,35 @@ typedef struct _mali_osk_list_s 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 */ - MALI200 =3, /**< Mali200 Programmable Fragment Shader */ - MALIGP2 =4, /**< MaliGP2 Programmable Vertex Shader */ - MMU =5, /**< Mali MMU (Memory Management Unit) */ - FPGA_FRAMEWORK =6, /**< Mali registers specific to FPGA implementations */ - MALI400L2 =7, /**< Mali400 L2 Cache */ - MALI300L2 =7, /**< Mali300 L2 Cache */ - MALI400GP =8, /**< Mali400 Programmable Vertex Shader Core */ - MALI300GP =8, /**< Mali300 Programmable Vertex Shader Core */ - MALI400PP =9, /**< Mali400 Programmable Fragment Shader Core */ - MALI300PP =9, /**< Mali300 Programmable Fragment Shader Core */ - MEM_VALIDATION =10, /**< External Memory Validator */ - PMU =11, /**< Power Manangement Unit */ + + 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; @@ -726,11 +782,6 @@ void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom ); /** @brief Decrement an atomic counter, return new value * - * Although the value returned is a u32, only numbers with signed 24-bit - * precision (sign extended to u32) are returned. - * - * @note It is an error to decrement the counter beyond -(1<<23) - * * @param atom pointer to an atomic counter * @return The new value, after decrement */ u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom ); @@ -744,19 +795,11 @@ void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom ); /** @brief Increment an atomic counter, return new value * - * Although the value returned is a u32, only numbers with signed 24-bit - * precision (sign extended to u32) are returned. - * - * @note It is an error to increment the counter beyond (1<<23)-1 - * * @param atom pointer to an atomic counter */ u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom ); /** @brief Initialize an atomic counter * - * The counters have storage for signed 24-bit integers. Initializing to signed - * values requiring more than 24-bits storage will fail. - * * @note the parameter required is a u32, and so signed integers should be * cast to u32. * @@ -769,9 +812,6 @@ _mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val ); /** @brief Read a value from an atomic counter * - * Although the value returned is a u32, only numbers with signed 24-bit - * precision (sign extended to u32) are returned. - * * This can only be safely used to determine the value of the counter when it * is guaranteed that other threads will not be modifying the counter. This * makes its usefulness limited. @@ -1624,6 +1664,41 @@ u64 _mali_osk_time_get_ns( void ); u32 _mali_osk_clz( u32 val ); /** @} */ /* end group _mali_osk_math */ +/** @defgroup _mali_osk_wait_queue OSK Wait Queue functionality + * @{ */ +/** @brief Private type for wait queue objects */ +typedef struct _mali_osk_wait_queue_t_struct _mali_osk_wait_queue_t; + +/** @brief Initialize an empty Wait Queue */ +_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void ); + +/** @brief Sleep if condition is false + * + * @param queue the queue to use + * @param condition function pointer to a boolean function + * + * Put thread to sleep if the given \a codition function returns false. When + * being asked to wake up again, the condition will be re-checked and the + * thread only woken up if the condition is now true. + */ +void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ); + +/** @brief Wake up all threads in wait queue if their respective conditions are + * true + * + * @param queue the queue whose threads should be woken up + * + * Wake up all threads in wait queue \a queue whose condition is now true. + */ +void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue ); + +/** @brief terminate a wait queue + * + * @param queue the queue to terminate. + */ +void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue ); +/** @} */ /* end group _mali_osk_wait_queue */ + /** @addtogroup _mali_osk_miscellaneous * @{ */ @@ -1647,6 +1722,7 @@ void _mali_osk_dbgmsg( const char *fmt, ... ); * @param size the total number of bytes allowed to write to \a buf * @param fmt a _mali_osu_vsnprintf() style format string * @param ... a variable-number of parameters suitable for \a fmt + * @return The number of bytes written to \a buf */ u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ); @@ -1685,13 +1761,19 @@ u32 _mali_osk_get_pid(void); */ u32 _mali_osk_get_tid(void); -void _mali_osk_profiling_add_event(u32 event_id, u32 data0); -void _mali_osk_profiling_add_counter(u32 event_id, u32 data0); -int _mali_osk_counter_event(u32 counter, u32 event); -extern u32 counter_table[]; +/** @brief Enable OS controlled runtime power management + */ +void _mali_osk_pm_dev_enable(void); -/** @} */ /* end group _mali_osk_miscellaneous */ +/** @brief Tells the OS that device is now idle + */ +_mali_osk_errcode_t _mali_osk_pm_dev_idle(void); +/** @brief Tells the OS that the device is about to become active + */ +_mali_osk_errcode_t _mali_osk_pm_dev_activate(void); + +/** @} */ /* end group _mali_osk_miscellaneous */ /** @} */ /* end group osuapi */ diff --git a/drivers/media/video/samsung/mali/common/mali_osk_list.h b/drivers/media/video/samsung/mali/common/mali_osk_list.h index 3a562bb..a8d15f2 100644 --- a/drivers/media/video/samsung/mali/common/mali_osk_list.h +++ b/drivers/media/video/samsung/mali/common/mali_osk_list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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/common/mali_osk_mali.h b/drivers/media/video/samsung/mali/common/mali_osk_mali.h index 0b1d13a..427fcc8 100644 --- a/drivers/media/video/samsung/mali/common/mali_osk_mali.h +++ b/drivers/media/video/samsung/mali/common/mali_osk_mali.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -26,36 +26,6 @@ extern "C" /** @addtogroup _mali_osk_miscellaneous * @{ */ -/** @brief Initialize the OSK layer - * - * This function is used to setup any initialization of OSK functionality, if - * required. - * - * This must be the first function called from the common code, specifically, - * from the common code entry-point, mali_kernel_constructor. - * - * The OS-integration into the OS's kernel must handle calling of - * mali_kernel_constructor when the device driver is loaded. - * - * @return _MALI_OSK_ERR_OK on success, or a suitable _mali_osk_errcode_t on - * failure. - */ -_mali_osk_errcode_t _mali_osk_init( void ); - -/** @brief Terminate the OSK layer - * - * This function is used to terminate any resources initialized by - * _mali_osk_init. - * - * This must be the last function called from the common code, specifically, - * from the common code closedown function, mali_kernel_destructor, and the - * error path in mali_kernel_constructor. - * - * The OS-integration into the OS's kernel must handle calling of - * mali_kernel_destructor when the device driver is terminated. - */ -void _mali_osk_term( void ); - /** @brief Read the Mali Resource configuration * * Populates a _mali_arch_resource_t array from configuration settings, which diff --git a/drivers/media/video/samsung/mali/common/mali_osk_profiling.h b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h new file mode 100644 index 0000000..fd9a8fb --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MALI_OSK_PROFILING_H__ +#define __MALI_OSK_PROFILING_H__ + +#if MALI_TIMELINE_PROFILING_ENABLED + +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include "mali_linux_trace.h" +#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */ + +#include "mali_profiling_events.h" + +#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576 + +#define MALI_PROFILING_NO_HW_COUNTER = ((u32)-1) + +/** @defgroup _mali_osk_profiling External profiling connectivity + * @{ */ + +/** + * Initialize the profiling module. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start); + +/* + * Terminate the profiling module. + */ +void _mali_osk_profiling_term(void); + +/** + * Start recording profiling data + * + * The specified limit will determine how large the capture buffer is. + * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver. + * + * @param limit The desired maximum number of events to record on input, the actual maximum on output. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit); + +/** + * Add an profiling event + * + * @param event_id The event identificator. + * @param data0 First data parameter, depending on event_id specified. + * @param data1 Second data parameter, depending on event_id specified. + * @param data2 Third data parameter, depending on event_id specified. + * @param data3 Fourth data parameter, depending on event_id specified. + * @param data4 Fifth data parameter, depending on event_id specified. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +/* 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. + * + * @param counter_id The ID of the counter. + * @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 + * + * @param counters array of counter values + */ +void _mali_osk_profiling_report_sw_counters(u32 *counters); + +/** + * Stop recording profiling data + * + * @param count Returns the number of recorded events. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count); + +/** + * Retrieves the number of events that can be retrieved + * + * @return The number of recorded events that can be retrieved. + */ +u32 _mali_osk_profiling_get_count(void); + +/** + * Retrieve an event + * + * @param index Event index (start with 0 and continue until this function fails to retrieve all events) + * @param timestamp The timestamp for the retrieved event will be stored here. + * @param event_id The event ID for the retrieved event will be stored here. + * @param data The 5 data values for the retrieved event will be stored here. + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]); + +/** + * Clear the recorded buffer. + * + * This is needed in order to start another recording. + * + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_mali_osk_errcode_t _mali_osk_profiling_clear(void); + +/** + * Checks if a recording of profiling data is in progress + * + * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not + */ +mali_bool _mali_osk_profiling_is_recording(void); + +/** + * Checks if profiling data is available for retrival + * + * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not + */ +mali_bool _mali_osk_profiling_have_recording(void); + +/** @} */ /* end group _mali_osk_profiling */ + +#endif /* MALI_TIMELINE_PROFILING_ENABLED */ + +#endif /* __MALI_OSK_PROFILING_H__ */ + + diff --git a/drivers/media/video/samsung/mali/common/mali_pm.c b/drivers/media/video/samsung/mali/common/mali_pm.c new file mode 100644 index 0000000..1ef3807 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pm.c @@ -0,0 +1,547 @@ +/* + * 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) +{ + 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); + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + + /* Aquire our reference */ + MALI_DEBUG_PRINT(4, ("Mali PM: Getting device PM reference (=> requesting MALI_POWER_MODE_ON)\n")); + _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(); + } + mali_platform_power_mode_change(power_mode); + +#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + _mali_osk_pm_dev_idle(); +#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")); +} + +void mali_pm_runtime_resume(void) +{ + MALI_DEBUG_PRINT(3, ("Mali PM: OS runtime resumed\n")); +} diff --git a/drivers/media/video/samsung/mali/common/mali_pm.h b/drivers/media/video/samsung/mali/common/mali_pm.h new file mode 100644 index 0000000..d4ccfde --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pm.h @@ -0,0 +1,56 @@ +/* + * 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_PM_H__ +#define __MALI_PM_H__ + +#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); + +void mali_pm_os_suspend(void); +void mali_pm_os_resume(void); +void mali_pm_runtime_suspend(void); +void mali_pm_runtime_resume(void); + + +#endif /* __MALI_PM_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.c b/drivers/media/video/samsung/mali/common/mali_pmu.c new file mode 100644 index 0000000..348b5dc --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pmu.c @@ -0,0 +1,199 @@ +/* + * 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_pmu.h b/drivers/media/video/samsung/mali/common/mali_pmu.h new file mode 100644 index 0000000..fd10c08 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pmu.h @@ -0,0 +1,70 @@ +/* + * 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 + */ + +#include "mali_osk.h" + +struct mali_pmu_core; + +/** @brief Initialisation of MALI PMU + * + * This is called from entry point of the driver in order to create and intialize the PMU resource + * + * @param resource it will be a pointer to a PMU resource + * @param number_of_pp_cores Number of found PP resources in configuration + * @param number_of_l2_caches Number of found L2 cache resources in configuration + * @return The created PMU object, or NULL in case of failure. + */ +struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches); + +/** @brief It deallocates the PMU resource + * + * This is called on the exit of the driver to terminate the PMU resource + * + * @param pmu Pointer to PMU core object to delete + */ +void mali_pmu_delete(struct mali_pmu_core *pmu); + +/** @brief Reset PMU core + * + * @param pmu Pointer to PMU core object to reset + * @return _MALI_OSK_ERR_OK on success, otherwise failure. + */ +_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 + * + * @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_powerdown_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); + + +/** @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); diff --git a/drivers/media/video/samsung/mali/common/mali_pp.c b/drivers/media/video/samsung/mali/common/mali_pp.c new file mode 100644 index 0000000..5549f82 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp.c @@ -0,0 +1,710 @@ +/* + * 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 new file mode 100644 index 0000000..9b425a0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp.h @@ -0,0 +1,47 @@ +/* + * 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 new file mode 100644 index 0000000..1efcfda --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_job.c @@ -0,0 +1,92 @@ +/* + * 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; + _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_job.h b/drivers/media/video/samsung/mali/common/mali_pp_job.h new file mode 100644 index 0000000..7fe87f8 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_job.h @@ -0,0 +1,255 @@ +/* + * 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_JOB_H__ +#define __MALI_PP_JOB_H__ + +#include "mali_osk.h" +#include "mali_osk_list.h" +#include "mali_uk_types.h" +#include "mali_session.h" +#include "mali_kernel_common.h" +#include "regs/mali_200_regs.h" + +/** + * The structure represends a PP job, including all sub-jobs + * (This struct unfortunatly 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) */ + 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 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 */ +}; + +struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id); +void mali_pp_job_delete(struct mali_pp_job *job); + +_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job); + +/****************************************************** + * simple utility functions for dealing with pp jobs: + *****************************************************/ + +MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job) +{ + return (NULL == job) ? 0 : job->id; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job) +{ + return job->user_id; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job) +{ + return job->frame_builder_id; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job) +{ + return job->flush_id; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job) +{ + return job->frame_registers; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job) +{ + if (sub_job == 0) + { + return job->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 0; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job) +{ + if (sub_job == 0) + { + return job->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 0; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job) +{ + return job->wb0_registers; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job) +{ + return job->wb1_registers; +} + +MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job) +{ + return job->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; +} + +MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job) +{ + job->wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0; +} + +MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job) +{ + job->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) +{ + return job->session; +} + +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; +} + +/* 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) +{ + /* 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; +} + +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; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job) +{ + return job->sub_jobs_started; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job) +{ + return job->sub_job_count; +} + +MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job) +{ + /* Assert that we are marking the "first unstarted sub job" as started */ + MALI_DEBUG_ASSERT(job->sub_jobs_started == sub_job); + job->sub_jobs_started++; +} + +MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success) +{ + job->sub_jobs_completed++; + if ( MALI_FALSE == success ) + { + job->sub_job_errors++; + } +} + +MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job) +{ + if ( 0 == job->sub_job_errors ) + { + return MALI_TRUE; + } + return MALI_FALSE; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job) +{ + return job->perf_counter_flag; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job) +{ + return job->perf_counter_src0; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job) +{ + return job->perf_counter_src1; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job) +{ + return job->perf_counter_value0[sub_job]; +} + +MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *job, u32 sub_job) +{ + return job->perf_counter_value1[sub_job]; +} + +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; +} + +MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *job, u32 sub_job, u32 value) +{ + job->perf_counter_value1[sub_job] = value; +} + +#endif /* __MALI_PP_JOB_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c new file mode 100644 index 0000000..ce07a76 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c @@ -0,0 +1,542 @@ +/* + * 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; +}; + +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; + 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 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_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; + 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) +{ + _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; + 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 */ + } + + 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 new file mode 100644 index 0000000..48eb3bd --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h @@ -0,0 +1,38 @@ +/* + * 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/common/mali_scheduler.c b/drivers/media/video/samsung/mali/common/mali_scheduler.c new file mode 100644 index 0000000..52159a0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_scheduler.c @@ -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. + */ + +#include "mali_kernel_common.h" +#include "mali_osk.h" + +static _mali_osk_atomic_t mali_job_autonumber; + +_mali_osk_errcode_t mali_scheduler_initialize(void) +{ + if ( _MALI_OSK_ERR_OK != _mali_osk_atomic_init(&mali_job_autonumber, 0)) + { + MALI_DEBUG_PRINT(1, ("Initialization of atomic job id counter failed.\n")); + return _MALI_OSK_ERR_FAULT; + } + + return _MALI_OSK_ERR_OK; +} + +void mali_scheduler_terminate(void) +{ + _mali_osk_atomic_term(&mali_job_autonumber); +} + +u32 mali_scheduler_get_new_id(void) +{ + u32 job_id = _mali_osk_atomic_inc_return(&mali_job_autonumber); + return job_id; +} diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.h b/drivers/media/video/samsung/mali/common/mali_scheduler.h new file mode 100644 index 0000000..74f0947 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_scheduler.h @@ -0,0 +1,21 @@ +/* + * 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_SCHEDULER_H__ +#define __MALI_SCHEDULER_H__ + +#include "mali_osk.h" + +_mali_osk_errcode_t mali_scheduler_initialize(void); +void mali_scheduler_terminate(void); + +u32 mali_scheduler_get_new_id(void); + +#endif /* __MALI_SCHEDULER_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_session.c b/drivers/media/video/samsung/mali/common/mali_session.c new file mode 100644 index 0000000..2394bb9 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_session.c @@ -0,0 +1,47 @@ +/* + * 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_osk.h" +#include "mali_osk_list.h" +#include "mali_session.h" + +_MALI_OSK_LIST_HEAD(mali_sessions); + +_mali_osk_lock_t *mali_sessions_lock; + +_mali_osk_errcode_t mali_session_initialize(void) +{ + _MALI_OSK_INIT_LIST_HEAD(&mali_sessions); + + mali_sessions_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_SESSIONS); + + if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM; + + return _MALI_OSK_ERR_OK; +} + +void mali_session_terminate(void) +{ + _mali_osk_lock_term(mali_sessions_lock); +} + +void mali_session_add(struct mali_session_data *session) +{ + mali_session_lock(); + _mali_osk_list_add(&session->link, &mali_sessions); + mali_session_unlock(); +} + +void mali_session_remove(struct mali_session_data *session) +{ + mali_session_lock(); + _mali_osk_list_delinit(&session->link); + mali_session_unlock(); +} diff --git a/drivers/media/video/samsung/mali/common/mali_session.h b/drivers/media/video/samsung/mali/common/mali_session.h new file mode 100644 index 0000000..b47c340 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_session.h @@ -0,0 +1,65 @@ +/* + * 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_SESSION_H__ +#define __MALI_SESSION_H__ + +#include "mali_mmu_page_directory.h" +#include "mali_kernel_descriptor_mapping.h" +#include "mali_osk.h" +#include "mali_osk_list.h" + +struct mali_session_data +{ + _mali_osk_notification_queue_t * ioctl_queue; + + _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 */ + + 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_errcode_t mali_session_initialize(void); +void mali_session_terminate(void); + +/* List of all sessions. Actual list head in mali_kernel_core.c */ +extern _mali_osk_list_t mali_sessions; +/* Lock to protect modification and access to the mali_sessions list */ +extern _mali_osk_lock_t *mali_sessions_lock; + +MALI_STATIC_INLINE void mali_session_lock(void) +{ + _mali_osk_lock_wait(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW); +} + +MALI_STATIC_INLINE void mali_session_unlock(void) +{ + _mali_osk_lock_signal(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW); +} + +void mali_session_add(struct mali_session_data *session); +void mali_session_remove(struct mali_session_data *session); +#define MALI_SESSION_FOREACH(session, tmp, link) \ + _MALI_OSK_LIST_FOREACHENTRY(session, tmp, &mali_sessions, struct mali_session_data, link) + +MALI_STATIC_INLINE struct mali_page_directory *mali_session_get_page_directory(struct mali_session_data *session) +{ + return session->page_directory; +} + +MALI_STATIC_INLINE void mali_session_send_notification(struct mali_session_data *session, _mali_osk_notification_t *object) +{ + _mali_osk_notification_queue_send(session->ioctl_queue, object); +} + +#endif /* __MALI_SESSION_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_uk_types.h b/drivers/media/video/samsung/mali/common/mali_uk_types.h deleted file mode 100644 index e114fa8..0000000 --- a/drivers/media/video/samsung/mali/common/mali_uk_types.h +++ /dev/null @@ -1,1176 +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. - */ - -/** - * @file mali_uk_types.h - * Defines the types and constants used in the user-kernel interface - */ - -#ifndef __MALI_UK_TYPES_H__ -#define __MALI_UK_TYPES_H__ - -/* - * NOTE: Because this file can be included from user-side and kernel-side, - * it is up to the includee to ensure certain typedefs (e.g. u32) are already - * defined when #including this. - */ -#include "regs/mali_200_regs.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup uddapi Unified Device Driver (UDD) APIs - * - * @{ - */ - -/** - * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs - * - * @{ - */ - -/** @defgroup _mali_uk_core U/K Core - * @{ */ - -/** Definition of subsystem numbers, to assist in creating a unique identifier - * for each U/K call. - * - * @see _mali_uk_functions */ -typedef enum -{ - _MALI_UK_CORE_SUBSYSTEM, /**< Core Group of U/K calls */ - _MALI_UK_MEMORY_SUBSYSTEM, /**< Memory Group of U/K calls */ - _MALI_UK_PP_SUBSYSTEM, /**< Fragment Processor Group of U/K calls */ - _MALI_UK_GP_SUBSYSTEM, /**< Vertex Processor Group of U/K calls */ - _MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */ - _MALI_UK_PMM_SUBSYSTEM, /**< Power Management Module Group of U/K calls */ - _MALI_UK_VSYNC_SUBSYSTEM, /**< VSYNC Group of U/K calls */ -} _mali_uk_subsystem_t; - -/** Within a function group each function has its unique sequence number - * to assist in creating a unique identifier for each U/K call. - * - * An ordered pair of numbers selected from - * ( \ref _mali_uk_subsystem_t,\ref _mali_uk_functions) will uniquely identify the - * U/K call across all groups of functions, and all functions. */ -typedef enum -{ - /** Core functions */ - - _MALI_UK_OPEN = 0, /**< _mali_ukk_open() */ - _MALI_UK_CLOSE, /**< _mali_ukk_close() */ - _MALI_UK_GET_SYSTEM_INFO_SIZE, /**< _mali_ukk_get_system_info_size() */ - _MALI_UK_GET_SYSTEM_INFO, /**< _mali_ukk_get_system_info() */ - _MALI_UK_WAIT_FOR_NOTIFICATION, /**< _mali_ukk_wait_for_notification() */ - _MALI_UK_GET_API_VERSION, /**< _mali_ukk_get_api_version() */ - _MALI_UK_POST_NOTIFICATION, /**< _mali_ukk_post_notification() */ - - /** Memory functions */ - - _MALI_UK_INIT_MEM = 0, /**< _mali_ukk_init_mem() */ - _MALI_UK_TERM_MEM, /**< _mali_ukk_term_mem() */ - _MALI_UK_GET_BIG_BLOCK, /**< _mali_ukk_get_big_block() */ - _MALI_UK_FREE_BIG_BLOCK, /**< _mali_ukk_free_big_block() */ - _MALI_UK_MAP_MEM, /**< _mali_ukk_mem_mmap() */ - _MALI_UK_UNMAP_MEM, /**< _mali_ukk_mem_munmap() */ - _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */ - _MALI_UK_DUMP_MMU_PAGE_TABLE, /**< _mali_ukk_mem_dump_mmu_page_table() */ - _MALI_UK_ATTACH_UMP_MEM, /**< _mali_ukk_attach_ump_mem() */ - _MALI_UK_RELEASE_UMP_MEM, /**< _mali_ukk_release_ump_mem() */ - _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() */ - - /** Common functions for each core */ - - _MALI_UK_START_JOB = 0, /**< Start a Fragment/Vertex Processor Job on a core */ - _MALI_UK_ABORT_JOB, /**< Abort a job */ - _MALI_UK_GET_NUMBER_OF_CORES, /**< Get the number of Fragment/Vertex Processor cores */ - _MALI_UK_GET_CORE_VERSION, /**< Get the Fragment/Vertex Processor version compatible with all cores */ - - /** Fragment Processor Functions */ - - _MALI_UK_PP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_pp_start_job() */ - _MALI_UK_PP_ABORT_JOB = _MALI_UK_ABORT_JOB, /**< _mali_ukk_pp_abort_job() */ - _MALI_UK_GET_PP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_pp_number_of_cores() */ - _MALI_UK_GET_PP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_pp_core_version() */ - - /** Vertex Processor Functions */ - - _MALI_UK_GP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_gp_start_job() */ - _MALI_UK_GP_ABORT_JOB = _MALI_UK_ABORT_JOB, /**< _mali_ukk_gp_abort_job() */ - _MALI_UK_GET_GP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_gp_number_of_cores() */ - _MALI_UK_GET_GP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_gp_core_version() */ - _MALI_UK_GP_SUSPEND_RESPONSE, /**< _mali_ukk_gp_suspend_response() */ - - /** Profiling functions */ - - _MALI_UK_PROFILING_START = 0, /**< __mali_uku_profiling_start() */ - _MALI_UK_PROFILING_ADD_EVENT, /**< __mali_uku_profiling_add_event() */ - _MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */ - _MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */ - _MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */ - _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */ - _MALI_UK_TRANSFER_SW_COUNTERS, - -#if USING_MALI_PMM - /** Power Management Module Functions */ - _MALI_UK_PMM_EVENT_MESSAGE = 0, /**< Raise an event message */ -#endif - - /** VSYNC reporting fuctions */ - _MALI_UK_VSYNC_EVENT_REPORT = 0, /**< _mali_ukk_vsync_event_report() */ - -} _mali_uk_functions; - -/** @brief Get the size necessary for system info - * - * @see _mali_ukk_get_system_info_size() - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [out] size of buffer necessary to hold system information data, in bytes */ -} _mali_uk_get_system_info_size_s; - - -/** @defgroup _mali_uk_getsysteminfo U/K Get System Info - * @{ */ - -/** - * Type definition for the core version number. - * Used when returning the version number read from a core - * - * Its format is that of the 32-bit Version register for a particular core. - * Refer to the "Mali200 and MaliGP2 3D Graphics Processor Technical Reference - * Manual", ARM DDI 0415C, for more information. - */ -typedef u32 _mali_core_version; - -/** - * Enum values for the different modes the driver can be put in. - * Normal is the default mode. The driver then uses a job queue and takes job objects from the clients. - * Job completion is reported using the _mali_ukk_wait_for_notification call. - * The driver blocks this io command until a job has completed or failed or a timeout occurs. - * - * The 'raw' mode is reserved for future expansion. - */ -typedef enum _mali_driver_mode -{ - _MALI_DRIVER_MODE_RAW = 1, /**< Reserved for future expansion */ - _MALI_DRIVER_MODE_NORMAL = 2 /**< Normal mode of operation */ -} _mali_driver_mode; - -/** @brief List of possible cores - * - * add new entries to the end of this enum */ -typedef enum _mali_core_type -{ - _MALI_GP2 = 2, /**< MaliGP2 Programmable Vertex Processor */ - _MALI_200 = 5, /**< Mali200 Programmable Fragment Processor */ - _MALI_400_GP = 6, /**< Mali400 Programmable Vertex Processor */ - _MALI_400_PP = 7, /**< Mali400 Programmable Fragment Processor */ - /* insert new core here, do NOT alter the existing values */ -} _mali_core_type; - -/** @brief Information about each Mali Core - * - * Information is stored in a linked list, which is stored entirely in the - * buffer pointed to by the system_info member of the - * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info() - * - * Both Fragment Processor (PP) and Vertex Processor (GP) cores are represented - * by this struct. - * - * The type is reported by the type field, _mali_core_info::_mali_core_type. - * - * Each core is given a unique Sequence number identifying it, the core_nr - * member. - * - * Flags are taken directly from the resource's flags, and are currently unused. - * - * Multiple mali_core_info structs are linked in a single linked list using the next field - */ -typedef struct _mali_core_info -{ - _mali_core_type type; /**< Type of core */ - _mali_core_version version; /**< Core Version, as reported by the Core's Version Register */ - u32 reg_address; /**< Address of Registers */ - u32 core_nr; /**< Sequence number */ - u32 flags; /**< Flags. Currently Unused. */ - struct _mali_core_info * next; /**< Next core in Linked List */ -} _mali_core_info; - -/** @brief Capabilities of Memory Banks - * - * These may be used to restrict memory banks for certain uses. They may be - * used when access is not possible (e.g. Bus does not support access to it) - * or when access is possible but not desired (e.g. Access is slow). - * - * In the case of 'possible but not desired', there is no way of specifying - * the flags as an optimization hint, so that the memory could be used as a - * last resort. - * - * @see _mali_mem_info - */ -typedef enum _mali_bus_usage -{ - - _MALI_PP_READABLE = (1<<0), /** Readable by the Fragment Processor */ - _MALI_PP_WRITEABLE = (1<<1), /** Writeable by the Fragment Processor */ - _MALI_GP_READABLE = (1<<2), /** Readable by the Vertex Processor */ - _MALI_GP_WRITEABLE = (1<<3), /** Writeable by the Vertex Processor */ - _MALI_CPU_READABLE = (1<<4), /** Readable by the CPU */ - _MALI_CPU_WRITEABLE = (1<<5), /** Writeable by the CPU */ - _MALI_MMU_READABLE = _MALI_PP_READABLE | _MALI_GP_READABLE, /** Readable by the MMU (including all cores behind it) */ - _MALI_MMU_WRITEABLE = _MALI_PP_WRITEABLE | _MALI_GP_WRITEABLE, /** Writeable by the MMU (including all cores behind it) */ -} _mali_bus_usage; - -/** @brief Information about the Mali Memory system - * - * Information is stored in a linked list, which is stored entirely in the - * buffer pointed to by the system_info member of the - * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info() - * - * Each element of the linked list describes a single Mali Memory bank. - * Each allocation can only come from one bank, and will not cross multiple - * banks. - * - * Each bank is uniquely identified by its identifier member. On Mali-nonMMU - * systems, to allocate from this bank, the value of identifier must be passed - * as the type_id member of the _mali_uk_get_big_block_s arguments to - * _mali_ukk_get_big_block. - * - * On Mali-MMU systems, there is only one bank, which describes the maximum - * possible address range that could be allocated (which may be much less than - * the available physical memory) - * - * The flags member describes the capabilities of the memory. It is an error - * to attempt to build a job for a particular core (PP or GP) when the memory - * regions used do not have the capabilities for supporting that core. This - * would result in a job abort from the Device Driver. - * - * For example, it is correct to build a PP job where read-only data structures - * are taken from a memory with _MALI_PP_READABLE set and - * _MALI_PP_WRITEABLE clear, and a framebuffer with _MALI_PP_WRITEABLE set and - * _MALI_PP_READABLE clear. However, it would be incorrect to use a framebuffer - * where _MALI_PP_WRITEABLE is clear. - */ -typedef struct _mali_mem_info -{ - u32 size; /**< Size of the memory bank in bytes */ - _mali_bus_usage flags; /**< Capabilitiy flags of the memory */ - u32 maximum_order_supported; /**< log2 supported size */ - u32 identifier; /**< Unique identifier, to be used in allocate calls */ - struct _mali_mem_info * next; /**< Next List Link */ -} _mali_mem_info; - -/** @brief Info about the whole Mali system. - * - * This Contains a linked list of the cores and memory banks available. Each - * list pointer will remain inside the system_info buffer supplied in the - * _mali_uk_get_system_info_s arguments to a _mali_ukk_get_system_info call. - * - * The has_mmu member must be inspected to ensure the correct group of - * Memory function calls is obtained - that is, those for either Mali-MMU - * or Mali-nonMMU. @see _mali_uk_memory - */ -typedef struct _mali_system_info -{ - _mali_core_info * core_info; /**< List of _mali_core_info structures */ - _mali_mem_info * mem_info; /**< List of _mali_mem_info structures */ - u32 has_mmu; /**< Non-zero if Mali-MMU present. Zero otherwise. */ - _mali_driver_mode drivermode; /**< Reserved. Must always be _MALI_DRIVER_MODE_NORMAL */ -} _mali_system_info; - -/** @brief Arguments to _mali_ukk_get_system_info() - * - * A buffer of the size returned by _mali_ukk_get_system_info_size() must be - * allocated, and the pointer to this buffer must be written into the - * system_info member. The buffer must be suitably aligned for storage of - * the _mali_system_info structure - for example, one returned by - * _mali_osk_malloc(), which will be suitably aligned for any structure. - * - * The ukk_private member must be set to zero by the user-side. Under an OS - * implementation, the U/K interface must write in the user-side base address - * into the ukk_private member, so that the common code in - * _mali_ukk_get_system_info() can determine how to adjust the pointers such - * that they are sensible from user space. Leaving ukk_private as NULL implies - * that no pointer adjustment is necessary - which will be the case on a - * bare-metal/RTOS system. - * - * @see _mali_system_info - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [in] size of buffer provided to store system information data */ - _mali_system_info * system_info; /**< [in,out] pointer to buffer to store system information data. No initialisation of buffer required on input. */ - u32 ukk_private; /**< [in] Kernel-side private word inserted by certain U/K interface implementations. Caller must set to Zero. */ -} _mali_uk_get_system_info_s; -/** @} */ /* end group _mali_uk_getsysteminfo */ - -/** @} */ /* end group _mali_uk_core */ - - -/** @defgroup _mali_uk_gp U/K Vertex Processor - * @{ */ - -/** @defgroup _mali_uk_gp_suspend_response_s Vertex Processor Suspend Response - * @{ */ - -/** @brief Arguments for _mali_ukk_gp_suspend_response() - * - * When _mali_wait_for_notification() receives notification that a - * Vertex Processor job was suspended, you need to send a response to indicate - * what needs to happen with this job. You can either abort or resume the job. - * - * - set @c code to indicate response code. This is either @c _MALIGP_JOB_ABORT or - * @c _MALIGP_JOB_RESUME_WITH_NEW_HEAP to indicate you will provide a new heap - * for the job that will resolve the out of memory condition for the job. - * - copy the @c cookie value from the @c _mali_uk_gp_job_suspended_s notification; - * this is an identifier for the suspended job - * - set @c arguments[0] and @c arguments[1] to zero if you abort the job. If - * you resume it, @c argument[0] should specify the Mali start address for the new - * heap and @c argument[1] the Mali end address of the heap. - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - */ -typedef enum _maligp_job_suspended_response_code -{ - _MALIGP_JOB_ABORT, /**< Abort the Vertex Processor job */ - _MALIGP_JOB_RESUME_WITH_NEW_HEAP /**< Resume the Vertex Processor job with a new heap */ -} _maligp_job_suspended_response_code; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [in] cookie from the _mali_uk_gp_job_suspended_s notification */ - _maligp_job_suspended_response_code code; /**< [in] abort or resume response code, see \ref _maligp_job_suspended_response_code */ - u32 arguments[2]; /**< [in] 0 when aborting a job. When resuming a job, the Mali start and end address for a new heap to resume the job with */ -} _mali_uk_gp_suspend_response_s; - -/** @} */ /* end group _mali_uk_gp_suspend_response_s */ - -/** @defgroup _mali_uk_gpstartjob_s Vertex Processor Start Job - * @{ */ - -/** @brief Status indicating the result of starting a Vertex or Fragment processor job */ -typedef enum -{ - _MALI_UK_START_JOB_STARTED, /**< Job started */ - _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED, /**< Job started and bumped a lower priority job that was pending execution */ - _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE /**< Job could not be started at this time. Try starting the job again */ -} _mali_uk_start_job_status; - -/** @brief Status indicating the result of starting a Vertex or Fragment processor job */ -typedef enum -{ - MALI_UK_START_JOB_FLAG_DEFAULT = 0, /**< Default behaviour; Flush L2 caches before start, no following jobs */ - MALI_UK_START_JOB_FLAG_NO_FLUSH = 1, /**< No need to flush L2 caches before start */ - MALI_UK_START_JOB_FLAG_MORE_JOBS_FOLLOW = 2, /**< More related jobs follows, try to schedule them as soon as possible after this job */ -} _mali_uk_start_job_flags; - -/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job */ - -typedef enum -{ - _MALI_UK_JOB_STATUS_END_SUCCESS = 1<<(16+0), - _MALI_UK_JOB_STATUS_END_OOM = 1<<(16+1), - _MALI_UK_JOB_STATUS_END_ABORT = 1<<(16+2), - _MALI_UK_JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3), - _MALI_UK_JOB_STATUS_END_HANG = 1<<(16+4), - _MALI_UK_JOB_STATUS_END_SEG_FAULT = 1<<(16+5), - _MALI_UK_JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6), - _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7), - _MALI_UK_JOB_STATUS_END_SHUTDOWN = 1<<(16+8), - _MALI_UK_JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9) -} _mali_uk_job_status; - -#define MALIGP2_NUM_REGS_FRAME (6) - -/** @brief Arguments for _mali_ukk_gp_start_job() - * - * To start a Vertex Processor job - * - associate the request with a reference to a @c mali_gp_job_info by setting - * user_job_ptr to the address of the @c mali_gp_job_info of the job. - * - set @c priority to the priority of the @c mali_gp_job_info - * - specify a timeout for the job by setting @c watchdog_msecs to the number of - * milliseconds the job is allowed to run. Specifying a value of 0 selects the - * default timeout in use by the device driver. - * - copy the frame registers from the @c mali_gp_job_info into @c frame_registers. - * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero - * for a non-instrumented build. For an instrumented build you can use up - * to two performance counters. Set the corresponding bit in @c perf_counter_flag - * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify - * the source of what needs to get counted (e.g. number of vertex loader - * cache hits). For source id values, see ARM DDI0415A, Table 3-60. - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - * When @c _mali_ukk_gp_start_job() returns @c _MALI_OSK_ERR_OK, status contains the - * result of the request (see \ref _mali_uk_start_job_status). If the job could - * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be - * tried again. If the job had a higher priority than the one currently pending - * execution (@c _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED), it will bump - * the lower priority job and returns the address of the @c mali_gp_job_info - * for that job in @c returned_user_job_ptr. That job should get requeued. - * - * After the job has started, @c _mali_wait_for_notification() will be notified - * that the job finished or got suspended. It may get suspended due to - * resource shortage. If it finished (see _mali_ukk_wait_for_notification()) - * the notification will contain a @c _mali_uk_gp_job_finished_s result. If - * it got suspended the notification will contain a @c _mali_uk_gp_job_suspended_s - * result. - * - * The @c _mali_uk_gp_job_finished_s contains the job status (see \ref _mali_uk_job_status), - * the number of milliseconds the job took to render, and values of core registers - * when the job finished (irq status, performance counters, renderer list - * address). A job has finished succesfully when its status is - * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering - * the job, or software detected the job is taking more than watchdog_msecs to - * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. - * If the hardware detected a bus error while accessing memory associated with the - * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. - * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to - * stop the job but the job didn't start on the hardware yet, e.g. when the - * driver shutdown. - * - * In case the job got suspended, @c _mali_uk_gp_job_suspended_s contains - * the @c user_job_ptr identifier used to start the job with, the @c reason - * why the job stalled (see \ref _maligp_job_suspended_reason) and a @c cookie - * to identify the core on which the job stalled. This @c cookie will be needed - * when responding to this nofication by means of _mali_ukk_gp_suspend_response(). - * (see _mali_ukk_gp_suspend_response()). The response is either to abort or - * resume the job. If the job got suspended due to an out of memory condition - * you may be able to resolve this by providing more memory and resuming the job. - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 user_job_ptr; /**< [in] identifier for the job in user space, a @c mali_gp_job_info* */ - u32 priority; /**< [in] job priority. A lower number means higher priority */ - u32 watchdog_msecs; /**< [in] maximum allowed runtime in milliseconds. The job gets killed if it runs longer than this. A value of 0 selects the default used by the device driver. */ - u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job */ - 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) */ - u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 returned_user_job_ptr; /**< [out] identifier for the returned job in user space, a @c mali_gp_job_info* */ - _mali_uk_start_job_status status; /**< [out] indicates job start status (success, previous job returned, requeue) */ - u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */ - u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */ - u32 frame_builder_id; /**< [in] id of the originating frame builder */ - u32 flush_id; /**< [in] flush id within the originating frame builder */ -} _mali_uk_gp_start_job_s; - -#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */ -#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE (1<<1) /**< Enable performance counter SRC1 for a job */ -#define _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE (1<<2) /**< Enable performance counter L2_SRC0 for a job */ -#define _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE (1<<3) /**< Enable performance counter L2_SRC1 for a job */ -#define _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET (1<<4) /**< Enable performance counter L2_RESET for a job */ - -/** @} */ /* end group _mali_uk_gpstartjob_s */ - -typedef struct -{ - u32 user_job_ptr; /**< [out] identifier for the job in user space */ - _mali_uk_job_status status; /**< [out] status of finished job */ - u32 irq_status; /**< [out] value of the GP interrupt rawstat register (see ARM DDI0415A) */ - u32 status_reg_on_stop; /**< [out] value of the GP control register */ - u32 vscl_stop_addr; /**< [out] value of the GP VLSCL start register */ - u32 plbcl_stop_addr; /**< [out] value of the GP PLBCL start register */ - u32 heap_current_addr; /**< [out] value of the GP PLB PL heap start address register */ - u32 perf_counter_src0; /**< [out] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_src1; /**< [out] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */ - u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */ - u32 render_time; /**< [out] number of microseconds it took for the job to render */ - u32 perf_counter_l2_src0; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_src1; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 1 */ - u32 perf_counter_l2_val0; /**< [out] Value of the Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_val1; /**< [out] Value of the Mali-400 MP L2 cache performance counter 1 */ -} _mali_uk_gp_job_finished_s; - -typedef enum _maligp_job_suspended_reason -{ - _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY /**< Polygon list builder unit (PLBU) has run out of memory */ -} _maligp_job_suspended_reason; - -typedef struct -{ - u32 user_job_ptr; /**< [out] identifier for the job in user space */ - _maligp_job_suspended_reason reason; /**< [out] reason why the job stalled */ - u32 cookie; /**< [out] identifier for the core in kernel space on which the job stalled */ -} _mali_uk_gp_job_suspended_s; - -/** @} */ /* end group _mali_uk_gp */ - - -/** @defgroup _mali_uk_pp U/K Fragment Processor - * @{ */ - -/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job - * @{ */ - -/** @brief Arguments for _mali_ukk_pp_start_job() - * - * To start a Fragment Processor job - * - associate the request with a reference to a mali_pp_job by setting - * @c user_job_ptr to the address of the @c mali_pp_job of the job. - * - set @c priority to the priority of the mali_pp_job - * - specify a timeout for the job by setting @c watchdog_msecs to the number of - * milliseconds the job is allowed to run. Specifying a value of 0 selects the - * default timeout in use by the device driver. - * - copy the frame registers from the @c mali_pp_job into @c frame_registers. - * For MALI200 you also need to copy the write back 0,1 and 2 registers. - * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero - * for a non-instrumented build. For an instrumented build you can use up - * to two performance counters. Set the corresponding bit in @c perf_counter_flag - * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify - * the source of what needs to get counted (e.g. number of vertex loader - * cache hits). For source id values, see ARM DDI0415A, Table 3-60. - * - pass in the user-kernel context in @c ctx that was returned from _mali_ukk_open() - * - * When _mali_ukk_pp_start_job() returns @c _MALI_OSK_ERR_OK, @c status contains the - * result of the request (see \ref _mali_uk_start_job_status). If the job could - * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be - * tried again. If the job had a higher priority than the one currently pending - * execution (@c _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED), it will bump - * the lower priority job and returns the address of the @c mali_pp_job - * for that job in @c returned_user_job_ptr. That job should get requeued. - * - * After the job has started, _mali_wait_for_notification() will be notified - * when the job finished. The notification will contain a - * @c _mali_uk_pp_job_finished_s result. It contains the @c user_job_ptr - * identifier used to start the job with, the job @c status (see \ref _mali_uk_job_status), - * the number of milliseconds the job took to render, and values of core registers - * when the job finished (irq status, performance counters, renderer list - * address). A job has finished succesfully when its status is - * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering - * the job, or software detected the job is taking more than @c watchdog_msecs to - * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. - * If the hardware detected a bus error while accessing memory associated with the - * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. - * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to - * stop the job but the job didn't start on the hardware yet, e.g. when the - * driver shutdown. - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 user_job_ptr; /**< [in] identifier for the job in user space */ - u32 priority; /**< [in] job priority. A lower number means higher priority */ - u32 watchdog_msecs; /**< [in] maximum allowed runtime in milliseconds. The job gets killed if it runs longer than this. A value of 0 selects the default used by the device driver. */ - u32 frame_registers[MALI200_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job, see ARM DDI0415A */ - u32 wb0_registers[MALI200_NUM_REGS_WBx]; - u32 wb1_registers[MALI200_NUM_REGS_WBx]; - u32 wb2_registers[MALI200_NUM_REGS_WBx]; - 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) */ - u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 returned_user_job_ptr; /**< [out] identifier for the returned job in user space */ - _mali_uk_start_job_status status; /**< [out] indicates job start status (success, previous job returned, requeue) */ - u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */ - u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */ - u32 frame_builder_id; /**< [in] id of the originating frame builder */ - u32 flush_id; /**< [in] flush id within the originating frame builder */ - _mali_uk_start_job_flags flags; /**< [in] Flags for job, see _mali_uk_start_job_flags for more information */ -} _mali_uk_pp_start_job_s; -/** @} */ /* end group _mali_uk_ppstartjob_s */ - -typedef struct -{ - u32 user_job_ptr; /**< [out] identifier for the job in user space */ - _mali_uk_job_status status; /**< [out] status of finished job */ - u32 irq_status; /**< [out] value of interrupt rawstat register (see ARM DDI0415A) */ - u32 last_tile_list_addr; /**< [out] value of renderer list register (see ARM DDI0415A); necessary to restart a stopped job */ - u32 perf_counter_src0; /**< [out] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter_src1; /**< [out] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ - u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */ - u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */ - u32 render_time; /**< [out] number of microseconds it took for the job to render */ - u32 perf_counter_l2_src0; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_src1; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 1 */ - u32 perf_counter_l2_val0; /**< [out] Value of the Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_val1; /**< [out] Value of the Mali-400 MP L2 cache performance counter 1 */ - u32 perf_counter_l2_val0_raw; /**< [out] Raw value of the Mali-400 MP L2 cache performance counter 0 */ - u32 perf_counter_l2_val1_raw; /**< [out] Raw value of the Mali-400 MP L2 cache performance counter 1 */ -} _mali_uk_pp_job_finished_s; -/** @} */ /* end group _mali_uk_pp */ - - -/** @addtogroup _mali_uk_core U/K Core - * @{ */ - -/** @defgroup _mali_uk_waitfornotification_s Wait For Notification - * @{ */ - -/** @brief Notification type encodings - * - * Each Notification type is an ordered pair of (subsystem,id), and is unique. - * - * The encoding of subsystem,id into a 32-bit word is: - * encoding = (( subsystem << _MALI_NOTIFICATION_SUBSYSTEM_SHIFT ) & _MALI_NOTIFICATION_SUBSYSTEM_MASK) - * | (( id << _MALI_NOTIFICATION_ID_SHIFT ) & _MALI_NOTIFICATION_ID_MASK) - * - * @see _mali_uk_wait_for_notification_s - */ -typedef enum -{ - /** core notifications */ - - _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20, - _MALI_NOTIFICATION_APPLICATION_QUIT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40, - - /** Fragment Processor notifications */ - - _MALI_NOTIFICATION_PP_FINISHED = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10, - - /** Vertex Processor notifications */ - - _MALI_NOTIFICATION_GP_FINISHED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x10, - _MALI_NOTIFICATION_GP_STALLED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x20, -} _mali_uk_notification_type; - -/** to assist in splitting up 32-bit notification value in subsystem and id value */ -#define _MALI_NOTIFICATION_SUBSYSTEM_MASK 0xFFFF0000 -#define _MALI_NOTIFICATION_SUBSYSTEM_SHIFT 16 -#define _MALI_NOTIFICATION_ID_MASK 0x0000FFFF -#define _MALI_NOTIFICATION_ID_SHIFT 0 - - -/** @brief Arguments for _mali_ukk_wait_for_notification() - * - * On successful return from _mali_ukk_wait_for_notification(), the members of - * this structure will indicate the reason for notification. - * - * Specifically, the source of the notification can be identified by the - * subsystem and id fields of the mali_uk_notification_type in the code.type - * member. The type member is encoded in a way to divide up the types into a - * subsystem field, and a per-subsystem ID field. See - * _mali_uk_notification_type for more information. - * - * Interpreting the data union member depends on the notification type: - * - * - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS - * - The kernel side is shutting down. No further - * _mali_uk_wait_for_notification() calls should be made. - * - In this case, the value of the data union member is undefined. - * - This is used to indicate to the user space client that it should close - * the connection to the Mali Device Driver. - * - type == _MALI_NOTIFICATION_PP_FINISHED - * - The notification data is of type _mali_uk_pp_job_finished_s. It contains the user_job_ptr - * identifier used to start the job with, the job status, the number of milliseconds the job took to render, - * and values of core registers when the job finished (irq status, performance counters, renderer list - * address). - * - A job has finished succesfully when its status member is _MALI_UK_JOB_STATUS_FINISHED. - * - If the hardware detected a timeout while rendering the job, or software detected the job is - * taking more than watchdog_msecs (see _mali_ukk_pp_start_job()) to complete, the status member will - * indicate _MALI_UK_JOB_STATUS_HANG. - * - If the hardware detected a bus error while accessing memory associated with the job, status will - * indicate _MALI_UK_JOB_STATUS_SEG_FAULT. - * - Status will indicate MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to stop the job but the job - * didn't start the hardware yet, e.g. when the driver closes. - * - type == _MALI_NOTIFICATION_GP_FINISHED - * - The notification data is of type _mali_uk_gp_job_finished_s. The notification is similar to that of - * type == _MALI_NOTIFICATION_PP_FINISHED, except that several other GP core register values are returned. - * The status values have the same meaning for type == _MALI_NOTIFICATION_PP_FINISHED. - * - type == _MALI_NOTIFICATION_GP_STALLED - * - The nofication data is of type _mali_uk_gp_job_suspended_s. It contains the user_job_ptr - * identifier used to start the job with, the reason why the job stalled and a cookie to identify the core on - * which the job stalled. - * - The reason member of gp_job_suspended is set to _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY - * when the polygon list builder unit has run out of memory. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_notification_type type; /**< [out] Type of notification available */ - union - { - _mali_uk_gp_job_suspended_s gp_job_suspended;/**< [out] Notification data for _MALI_NOTIFICATION_GP_STALLED notification type */ - _mali_uk_gp_job_finished_s gp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_GP_FINISHED notification type */ - _mali_uk_pp_job_finished_s pp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_PP_FINISHED notification type */ - } data; -} _mali_uk_wait_for_notification_s; - -/** @brief Arguments for _mali_ukk_post_notification() - * - * Posts the specified notification to the notification queue for this application. - * This is used to send a quit message to the callback thread. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_notification_type type; /**< [in] Type of notification to post */ -} _mali_uk_post_notification_s; -/** @} */ /* end group _mali_uk_waitfornotification_s */ - -/** @defgroup _mali_uk_getapiversion_s Get API Version - * @{ */ - -/** helpers for Device Driver API version handling */ - -/** @brief Encode a version ID from a 16-bit input - * - * @note the input is assumed to be 16 bits. It must not exceed 16 bits. */ -#define _MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) - -/** @brief Check whether a 32-bit value is likely to be Device Driver API - * version ID. */ -#define _IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) - -/** @brief Decode a 16-bit version number from a 32-bit Device Driver API version - * ID */ -#define _GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) - -/** @brief Determine whether two 32-bit encoded version IDs match */ -#define _IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) - -/** - * API version define. - * Indicates the version of the kernel API - * The version is a 16bit integer incremented on each API change. - * The 16bit integer is stored twice in a 32bit integer - * For example, for version 1 the value would be 0x00010001 - */ -#define _MALI_API_VERSION 10 -#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION) - -/** - * The API version is a 16-bit integer stored in both the lower and upper 16-bits - * of a 32-bit value. The 16-bit API version value is incremented on each API - * change. Version 1 would be 0x00010001. Used in _mali_uk_get_api_version_s. - */ -typedef u32 _mali_uk_api_version; - -/** @brief Arguments for _mali_uk_get_api_version() - * - * The user-side interface version must be written into the version member, - * encoded using _MAKE_VERSION_ID(). It will be compared to the API version of - * the kernel-side interface. - * - * On successful return, the version member will be the API version of the - * kernel-side interface. _MALI_UK_API_VERSION macro defines the current version - * of the API. - * - * The compatible member must be checked to see if the version of the user-side - * interface is compatible with the kernel-side interface, since future versions - * of the interface may be backwards compatible. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_api_version version; /**< [in,out] API version of user-side interface. */ - int compatible; /**< [out] @c 1 when @version is compatible, @c 0 otherwise */ -} _mali_uk_get_api_version_s; -/** @} */ /* end group _mali_uk_getapiversion_s */ - -/** @} */ /* end group _mali_uk_core */ - - -/** @defgroup _mali_uk_memory U/K Memory - * @{ */ - -/** @brief Arguments for _mali_ukk_init_mem(). */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 mali_address_base; /**< [out] start of MALI address space */ - u32 memory_size; /**< [out] total MALI address space available */ -} _mali_uk_init_mem_s; - -/** @brief Arguments for _mali_ukk_term_mem(). */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ -} _mali_uk_term_mem_s; - -/** @brief Arguments for _mali_ukk_get_big_block() - * - * - type_id should be set to the value of the identifier member of one of the - * _mali_mem_info structures returned through _mali_ukk_get_system_info() - * - ukk_private must be zero when calling from user-side. On Kernel-side, the - * OS implementation of the U/K interface can use it to communicate data to the - * OS implementation of the OSK layer. Specifically, ukk_private will be placed - * into the ukk_private member of the _mali_uk_mem_mmap_s structure. See - * _mali_ukk_mem_mmap() for more details. - * - minimum_size_requested will be updated if it is too small - * - block_size will always be >= minimum_size_requested, because the underlying - * allocation mechanism may only be able to divide up memory regions in certain - * ways. To avoid wasting memory, block_size should always be taken into account - * rather than assuming minimum_size_requested was really allocated. - * - to free the memory, the returned cookie member must be stored, and used to - * refer to it. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 type_id; /**< [in] the type id of the memory bank to allocate memory from */ - u32 minimum_size_requested; /**< [in,out] minimum size of the allocation */ - u32 ukk_private; /**< [in] Kernel-side private word inserted by certain U/K interface implementations. Caller must set to Zero. */ - u32 mali_address; /**< [out] address of the allocation in mali address space */ - void *cpuptr; /**< [out] address of the allocation in the current process address space */ - u32 block_size; /**< [out] size of the block that got allocated */ - u32 flags; /**< [out] flags associated with the allocated block, of type _mali_bus_usage */ - u32 cookie; /**< [out] identifier for the allocated block in kernel space */ -} _mali_uk_get_big_block_s; - -/** @brief Arguments for _mali_ukk_free_big_block() - * - * All that is required is that the cookie member must be set to the value of - * the cookie member returned through _mali_ukk_get_big_block() - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ -} _mali_uk_free_big_block_s; - -/** @note Mali-MMU only */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 phys_addr; /**< [in] physical address */ - u32 size; /**< [in] size */ - u32 mali_address; /**< [in] mali address to map the physical memory to */ - u32 rights; /**< [in] rights necessary for accessing memory */ - u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_map_external_mem_s; - -/** Flag for _mali_uk_map_external_mem_s and _mali_uk_attach_ump_mem_s */ -#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0) - -/** @note Mali-MMU only */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_unmap_external_mem_s; - -/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 secure_id; /**< [in] secure id */ - u32 size; /**< [in] size */ - u32 mali_address; /**< [in] mali address to map the physical memory to */ - u32 rights; /**< [in] rights necessary for accessing memory */ - u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ - u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ -} _mali_uk_attach_ump_mem_s; - -/** @note Mali-MMU only; will be supported in future version */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ -} _mali_uk_release_ump_mem_s; - -/** @brief Arguments for _mali_ukk_va_to_mali_pa() - * - * if size is zero or not a multiple of the system's page size, it will be - * rounded up to the next multiple of the page size. This will occur before - * any other use of the size parameter. - * - * if va is not PAGE_SIZE aligned, it will be rounded down to the next page - * boundary. - * - * The range (va) to ((u32)va)+(size-1) inclusive will be checked for physical - * contiguity. - * - * The implementor will check that the entire physical range is allowed to be mapped - * into user-space. - * - * Failure will occur if either of the above are not satisfied. - * - * Otherwise, the physical base address of the range is returned through pa, - * va is updated to be page aligned, and size is updated to be a non-zero - * multiple of the system's pagesize. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *va; /**< [in,out] Virtual address of the start of the range */ - u32 pa; /**< [out] Physical base address of the range */ - u32 size; /**< [in,out] Size of the range, in bytes. */ -} _mali_uk_va_to_mali_pa_s; - - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [out] size of MMU page table information (registers + page tables) */ -} _mali_uk_query_mmu_page_table_dump_size_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 size; /**< [in] size of buffer to receive mmu page table information */ - void *buffer; /**< [in,out] buffer to receive mmu page table information */ - u32 register_writes_size; /**< [out] size of MMU register dump */ - u32 *register_writes; /**< [out] pointer within buffer where MMU register dump is stored */ - u32 page_table_dump_size; /**< [out] size of MMU page table dump */ - u32 *page_table_dump; /**< [out] pointer within buffer where MMU page table dump is stored */ -} _mali_uk_dump_mmu_page_table_s; - -/** @} */ /* end group _mali_uk_memory */ - - -/** @addtogroup _mali_uk_pp U/K Fragment Processor - * @{ */ - -/** @brief Arguments for _mali_ukk_get_pp_number_of_cores() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_pp_number_of_cores(), @c number_of_cores - * will contain the number of Fragment Processor cores in the system. - */ -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 */ -} _mali_uk_get_pp_number_of_cores_s; - -/** @brief Arguments for _mali_ukk_get_pp_core_version() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_pp_core_version(), @c version contains - * the version that all Fragment Processor cores are compatible with. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ -} _mali_uk_get_pp_core_version_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 abort_id; /**< [in] ID of job(s) to abort */ -} _mali_uk_pp_abort_job_s; - -/** @} */ /* end group _mali_uk_pp */ - - -/** @addtogroup _mali_uk_gp U/K Vertex Processor - * @{ */ - -/** @brief Arguments for _mali_ukk_get_gp_number_of_cores() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_gp_number_of_cores(), @c number_of_cores - * will contain the number of Vertex Processor cores in the system. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 number_of_cores; /**< [out] number of Vertex Processor cores in the system */ -} _mali_uk_get_gp_number_of_cores_s; - -/** @brief Arguments for _mali_ukk_get_gp_core_version() - * - * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() - * - Upon successful return from _mali_ukk_get_gp_core_version(), @c version contains - * the version that all Vertex Processor cores are compatible with. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ -} _mali_uk_get_gp_core_version_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 abort_id; /**< [in] ID of job(s) to abort */ -} _mali_uk_gp_abort_job_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 limit; /**< [in,out] The desired limit for number of events to record on input, actual limit on output */ -} _mali_uk_profiling_start_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 event_id; /**< [in] event id to register (see enum mali_profiling_events for values) */ - u32 data[5]; /**< [in] event specific data */ -} _mali_uk_profiling_add_event_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 count; /**< [out] The number of events sampled */ -} _mali_uk_profiling_stop_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 index; /**< [in] which index to get (starting at zero) */ - u64 timestamp; /**< [out] timestamp of event */ - u32 event_id; /**< [out] event id of event (see enum mali_profiling_events for values) */ - u32 data[5]; /**< [out] event specific data */ -} _mali_uk_profiling_get_event_s; - -typedef struct -{ - void *ctx; - - u32 id; - s64 value; -} _mali_uk_sw_counters_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ -} _mali_uk_profiling_clear_s; - -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 enable_events; /**< [out] 1 if user space process should generate events, 0 if not */ -} _mali_uk_profiling_get_config_s; - - -/** @} */ /* end group _mali_uk_gp */ - - -/** @addtogroup _mali_uk_memory U/K Memory - * @{ */ - -/** @brief Arguments to _mali_ukk_mem_mmap() - * - * Use of the phys_addr member depends on whether the driver is compiled for - * Mali-MMU or nonMMU: - * - in the nonMMU case, this is the physical address of the memory as seen by - * the CPU (which may be a constant offset from that used by Mali) - * - in the MMU case, this is the Mali Virtual base address of the memory to - * allocate, and the particular physical pages used to back the memory are - * entirely determined by _mali_ukk_mem_mmap(). The details of the physical pages - * are not reported to user-space for security reasons. - * - * The cookie member must be stored for use later when freeing the memory by - * calling _mali_ukk_mem_munmap(). In the Mali-MMU case, the cookie is secure. - * - * The ukk_private word must be set to zero when calling from user-space. On - * Kernel-side, the OS implementation of the U/K interface can use it to - * communicate data to the OS implementation of the OSK layer. In particular, - * _mali_ukk_get_big_block() directly calls _mali_ukk_mem_mmap directly, and - * will communicate its own ukk_private word through the ukk_private member - * here. The common code itself will not inspect or modify the ukk_private - * word, and so it may be safely used for whatever purposes necessary to - * integrate Mali Memory handling into the OS. - * - * The uku_private member is currently reserved for use by the user-side - * implementation of the U/K interface. Its value must be zero. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [out] Returns user-space virtual address for the mapping */ - u32 size; /**< [in] Size of the requested mapping */ - u32 phys_addr; /**< [in] Physical address - could be offset, depending on caller+callee convention */ - u32 cookie; /**< [out] Returns a cookie for use in munmap calls */ - void *uku_private; /**< [in] User-side Private word used by U/K interface */ - void *ukk_private; /**< [in] Kernel-side Private word used by U/K interface */ -} _mali_uk_mem_mmap_s; - -/** @brief Arguments to _mali_ukk_mem_munmap() - * - * The cookie and mapping members must be that returned from the same previous - * call to _mali_ukk_mem_mmap(). The size member must correspond to cookie - * and mapping - that is, it must be the value originally supplied to a call to - * _mali_ukk_mem_mmap that returned the values of mapping and cookie. - * - * An error will be returned if an attempt is made to unmap only part of the - * originally obtained range, or to unmap more than was originally obtained. - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - void *mapping; /**< [in] The mapping returned from mmap call */ - u32 size; /**< [in] The size passed to mmap call */ - u32 cookie; /**< [in] Cookie from mmap call */ -} _mali_uk_mem_munmap_s; -/** @} */ /* end group _mali_uk_memory */ - -#if USING_MALI_PMM - -/** @defgroup _mali_uk_pmm U/K Power Management Module - * @{ */ - -/** @brief Power management event message identifiers. - * - * U/K events start after id 200, and can range up to 999 - * Adding new events will require updates to the PMM mali_pmm_event_id type - */ -#define _MALI_PMM_EVENT_UK_EXAMPLE 201 - -/** @brief Generic PMM message data type, that will be dependent on the event msg - */ -typedef u32 mali_pmm_message_data; - - -/** @brief Arguments to _mali_ukk_pmm_event_message() - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - u32 id; /**< [in] event id */ - mali_pmm_message_data data; /**< [in] specific data associated with the event */ -} _mali_uk_pmm_message_s; - -/** @} */ /* end group _mali_uk_pmm */ -#endif /* USING_MALI_PMM */ - -/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module - * @{ */ - -/** @brief VSYNC events - * - * These events are reported when DDK starts to wait for vsync and when the - * vsync has occured and the DDK can continue on the next frame. - */ -typedef enum _mali_uk_vsync_event -{ - _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0, - _MALI_UK_VSYNC_EVENT_END_WAIT -} _mali_uk_vsync_event; - -/** @brief Arguments to _mali_ukk_vsync_event() - * - */ -typedef struct -{ - void *ctx; /**< [in,out] user-kernel context (trashed on output) */ - _mali_uk_vsync_event event; /**< [in] VSYNCH event type */ -} _mali_uk_vsync_event_report_s; - -/** @} */ /* end group _mali_uk_vsync */ - -/** @} */ /* end group u_k_api */ - -/** @} */ /* end group uddapi */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/common/mali_ukk.h b/drivers/media/video/samsung/mali/common/mali_ukk.h index 94efdf5..8ff2002 100644 --- a/drivers/media/video/samsung/mali/common/mali_ukk.h +++ b/drivers/media/video/samsung/mali/common/mali_ukk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -17,7 +17,7 @@ #define __MALI_UKK_H__ #include "mali_osk.h" -#include "mali_uk_types.h" +#include "../linux/mali_uk_types.h" #ifdef __cplusplus extern "C" @@ -139,14 +139,6 @@ extern "C" * (_mali_osk_mem_mapregion_init()) functions will collaborate on the * meaning of ukk_private member. On other OSs, it may be unused by both * U/K and OSK layers - * - On OS systems (not including direct function call U/K interface - * implementations), _mali_ukk_get_big_block() may succeed, but the subsequent - * copying to user space may fail. - * - A problem scenario exists: some memory has been reserved by - * _mali_ukk_get_big_block(), but the user-mode will be unaware of it (it will - * never receive any information about this memory). In this case, the U/K - * implementation must do everything necessary to 'rollback' the \em atomic - * _mali_ukk_get_big_block() transaction. * - Therefore, on error inside the U/K interface implementation itself, * it will be as though the _mali_ukk function itself had failed, and cleaned * up after itself. @@ -233,7 +225,7 @@ _mali_osk_errcode_t _mali_ukk_close( void **context ); * allocated, and a pointer to this memory written into the system_info member * of _mali_uk_get_system_info_s. * - * @param args see _mali_uk_get_system_info_size_s in "mali_uk_types.h" + * @param args see _mali_uk_get_system_info_size_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_get_system_info_size( _mali_uk_get_system_info_size_s *args ); @@ -270,7 +262,7 @@ _mali_osk_errcode_t _mali_ukk_get_system_info_size( _mali_uk_get_system_info_siz * destination address for pointer-patching to occur. When NULL, it is unused, an no pointer-patching occurs in the * common code. * - * @param args see _mali_uk_get_system_info_s in "mali_uk_types.h" + * @param args see _mali_uk_get_system_info_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_get_system_info( _mali_uk_get_system_info_s *args ); @@ -279,24 +271,37 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args * * Sleeps until notified or a timeout occurs. Returns information about the notification. * - * @param args see _mali_uk_wait_for_notification_s in "mali_uk_types.h" + * @param args see _mali_uk_wait_for_notification_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_wait_for_notification( _mali_uk_wait_for_notification_s *args ); /** @brief Post a notification to the notification queue of this application. * - * @param args see _mali_uk_post_notification_s in "mali_uk_types.h" + * @param args see _mali_uk_post_notification_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_post_notification( _mali_uk_post_notification_s *args ); /** @brief Verifies if the user and kernel side of this API are compatible. * - * @param args see _mali_uk_get_api_version_s in "mali_uk_types.h" + * @param args see _mali_uk_get_api_version_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_get_api_version( _mali_uk_get_api_version_s *args ); + +/** @brief Get the user space settings applicable for calling process. + * + * @param args see _mali_uk_get_user_settings_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args); + +/** @brief Get a user space setting applicable for calling process. + * + * @param args see _mali_uk_get_user_setting_s in "mali_utgard_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args); + /** @} */ /* end group _mali_uk_core */ @@ -324,7 +329,7 @@ _mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args * @note This function is for Mali-MMU builds \b only. It should not be called * when the drivers are built without Mali-MMU support. * - * @param args see \ref _mali_uk_init_mem_s in mali_uk_types.h + * @param args see \ref _mali_uk_init_mem_s in mali_utgard_uk_types.h * @return _MALI_OSK_ERR_OK on success, otherwise a suitable * _mali_osk_errcode_t on failure. */ @@ -340,43 +345,18 @@ _mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args ); * @note This function is for Mali-MMU builds \b only. It should not be called * when the drivers are built without Mali-MMU support. * - * @param args see \ref _mali_uk_term_mem_s in mali_uk_types.h + * @param args see \ref _mali_uk_term_mem_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_term_mem( _mali_uk_term_mem_s *args ); -/** @brief Map a block of memory into the current user process - * - * Allocates a minimum of minimum_size_requested bytes of MALI memory and maps it into the current - * process space. The number of bytes allocated is returned in args->block_size. - * - * This is only used for Mali-nonMMU mode. - * - * @param args see _mali_uk_get_big_block_s in "mali_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_get_big_block( _mali_uk_get_big_block_s *args ); - -/** @brief Unmap a block of memory from the current user process - * - * Frees allocated MALI memory and unmaps it from the current process space. The previously allocated memory - * is indicated by the cookie as returned by _mali_ukk_get_big_block(). - * - * This is only used for Mali-nonMMU mode. - * - * @param args see _mali_uk_free_big_block_s in "mali_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_free_big_block( _mali_uk_free_big_block_s *args ); - /** @brief Map Mali Memory into the current user process * * Maps Mali memory into the current user process in a generic way. * * This function is to be used for Mali-MMU mode. The function is available in both Mali-MMU and Mali-nonMMU modes, - * but should not be called by a user process in Mali-nonMMU mode. In Mali-nonMMU mode, the function is callable - * from the kernel side, and is used to implement _mali_ukk_get_big_block() in this case. + * but should not be called by a user process in Mali-nonMMU mode. * * The implementation and operation of _mali_ukk_mem_mmap() is dependant on whether the driver is built for Mali-MMU * or Mali-nonMMU: @@ -392,9 +372,6 @@ _mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args ); * they are unnecsessary; the \em Mali-virtual address range must be used for * programming Mali structures. * - * This means that in the first (nonMMU) case, the caller must manage the physical address allocations. The caller - * in this case is _mali_ukk_get_big_block(), which does indeed manage the Mali physical address ranges. - * * In the second (MMU) case, _mali_ukk_mem_mmap() handles management of * CPU-virtual and CPU-physical ranges, but the \em caller must manage the * \em Mali-virtual address range from the user-side. @@ -403,7 +380,7 @@ _mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args ); * It is not possible for a process to accidentally corrupt another process' * \em Mali-virtual address space. * - * @param args see _mali_uk_mem_mmap_s in "mali_uk_types.h" + * @param args see _mali_uk_mem_mmap_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_mmap( _mali_uk_mem_mmap_s *args ); @@ -413,42 +390,42 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args ); * Unmaps Mali memory from the current user process in a generic way. This only operates on Mali memory supplied * from _mali_ukk_mem_mmap(). * - * @param args see _mali_uk_mem_munmap_s in "mali_uk_types.h" + * @param args see _mali_uk_mem_munmap_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_munmap( _mali_uk_mem_munmap_s *args ); /** @brief Determine the buffer size necessary for an MMU page table dump. - * @param args see _mali_uk_query_mmu_page_table_dump_size_s in mali_uk_types.h + * @param args see _mali_uk_query_mmu_page_table_dump_size_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_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args ); /** @brief Dump MMU Page tables. - * @param args see _mali_uk_dump_mmu_page_table_s in mali_uk_types.h + * @param args see _mali_uk_dump_mmu_page_table_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_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args ); /** @brief Map a physically contiguous range of memory into Mali - * @param args see _mali_uk_map_external_mem_s in mali_uk_types.h + * @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. */ _mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args ); /** @brief Unmap a physically contiguous range of memory from Mali - * @param args see _mali_uk_unmap_external_mem_s in mali_uk_types.h + * @param args see _mali_uk_unmap_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. */ _mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args ); #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 /** @brief Map UMP memory into Mali - * @param args see _mali_uk_attach_ump_mem_s in mali_uk_types.h + * @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. */ _mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args ); /** @brief Unmap UMP memory from Mali - * @param args see _mali_uk_release_ump_mem_s in mali_uk_types.h + * @param args see _mali_uk_release_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. */ _mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args ); @@ -492,7 +469,7 @@ _mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args * @note if implemented, this function is entirely platform-dependant, and does * not exist in common code. * - * @param args see _mali_uk_va_to_mali_pa_s in "mali_uk_types.h" + * @param args see _mali_uk_va_to_mali_pa_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_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args ); @@ -519,20 +496,16 @@ _mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args ); * existing one returned, otherwise the new job is started and the status field args->status is set to * _MALI_UK_START_JOB_STARTED. * - * If an existing lower priority job is returned, args->returned_user_job_ptr contains a - * pointer to the returned job and the status field args->status is set to - * _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED. - * * Job completion can be awaited with _mali_ukk_wait_for_notification(). * - * @param args see _mali_uk_pp_start_job_s in "mali_uk_types.h" + * @param args see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h" * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. */ _mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args ); /** @brief Returns the number of Fragment Processors in the system * - * @param args see _mali_uk_get_pp_number_of_cores_s in "mali_uk_types.h" + * @param args see _mali_uk_get_pp_number_of_cores_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_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args ); @@ -542,22 +515,18 @@ _mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_ * This function may only be called when _mali_ukk_get_pp_number_of_cores() indicated at least one Fragment * Processor core is available. * - * @param args see _mali_uk_get_pp_core_version_s in "mali_uk_types.h" + * @param args see _mali_uk_get_pp_core_version_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_get_pp_core_version( _mali_uk_get_pp_core_version_s *args ); -/** @brief Abort any PP jobs with the given ID. +/** @brief Disable Write-back unit(s) on specified job * - * Jobs internally queued or currently running on the hardware is to be stopped/aborted. - * Jobs aborted are reported via the normal job completion system. - * Any jobs, running or internally queued should be aborted imediately. - * Normal notifiction procedures to report on the status of these jobs. - * - * - * @param args see _malu_uk_pp_abort_job_s in "mali_uk_types.h" + * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h" */ -void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s *args ); +void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args); + + /** @} */ /* end group _mali_uk_pp */ @@ -580,20 +549,16 @@ void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s *args ); * existing one returned, otherwise the new job is started and the status field args->status is set to * _MALI_UK_START_JOB_STARTED. * - * If an existing lower priority job is returned, args->returned_user_job_ptr contains a pointer to - * the returned job and the status field args->status is set to - * _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED. - * * Job completion can be awaited with _mali_ukk_wait_for_notification(). * - * @param args see _mali_uk_gp_start_job_s in "mali_uk_types.h" + * @param args see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h" * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. */ _mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args ); /** @brief Returns the number of Vertex Processors in the system. * - * @param args see _mali_uk_get_gp_number_of_cores_s in "mali_uk_types.h" + * @param args see _mali_uk_get_gp_number_of_cores_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_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args ); @@ -603,7 +568,7 @@ _mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_ * This function may only be called when _mali_uk_get_gp_number_of_cores() indicated at least one Vertex * Processor core is available. * - * @param args see _mali_uk_get_gp_core_version_s in "mali_uk_types.h" + * @param args see _mali_uk_get_gp_core_version_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_get_gp_core_version( _mali_uk_get_gp_core_version_s *args ); @@ -613,85 +578,47 @@ _mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_ * After receiving notification that a Vertex Processor job was suspended from * _mali_ukk_wait_for_notification() you can use this function to resume or abort the job. * - * @param args see _mali_uk_gp_suspend_response_s in "mali_uk_types.h" + * @param args see _mali_uk_gp_suspend_response_s in "mali_utgard_uk_types.h" * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure. */ _mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args ); -/** @brief Abort any GP jobs with the given ID. - * - * Jobs internally queued or currently running on the hardware is to be stopped/aborted. - * Jobs aborted are reported via the normal job completion system. - * - * Any jobs, running or internally queued should be aborted imediately. - * Normal notifiction procedures to report on the status of these jobs. - * - * @param args see _mali_uk_gp_abort_job_s in "mali_uk_types.h" - */ -void _mali_ukk_gp_abort_job( _mali_uk_gp_abort_job_s *args ); /** @} */ /* end group _mali_uk_gp */ -#if USING_MALI_PMM -/** @addtogroup _mali_uk_pmm U/K Power Management Module - * @{ */ - -/* @brief Power Management Module event message - * - * @note The event message can fail to be sent due to OOM but this is - * stored in the PMM state machine to be handled later - * - * @param args see _mali_uk_pmm_event_message_s in "mali_uk_types.h" - */ -void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args ); -/** @} */ /* end group _mali_uk_pmm */ -#endif /* USING_MALI_PMM */ - #if MALI_TIMELINE_PROFILING_ENABLED /** @addtogroup _mali_uk_profiling U/K Timeline profiling module * @{ */ /** @brief Start recording profiling events. * - * @param args see _mali_uk_profiling_start_s in "mali_uk_types.h" + * @param args see _mali_uk_profiling_start_s in "mali_utgard_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args); /** @brief Add event to profiling buffer. * - * @param args see _mali_uk_profiling_add_event_s in "mali_uk_types.h" + * @param args see _mali_uk_profiling_add_event_s in "mali_utgard_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args); /** @brief Stop recording profiling events. * - * @param args see _mali_uk_profiling_stop_s in "mali_uk_types.h" + * @param args see _mali_uk_profiling_stop_s in "mali_utgard_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args); /** @brief Retrieve a recorded profiling event. * - * @param args see _mali_uk_profiling_get_event_s in "mali_uk_types.h" + * @param args see _mali_uk_profiling_get_event_s in "mali_utgard_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args); /** @brief Clear recorded profiling events. * - * @param args see _mali_uk_profiling_clear_s in "mali_uk_types.h" + * @param args see _mali_uk_profiling_clear_s in "mali_utgard_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args); -/** @brief Get the profiling config applicable for calling process. - * - * @param args see _mali_uk_profiling_get_config_s in "mali_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args); - -/** @brief Transfer software counters from user to kernel space - * - * @param args see _mali_uk_transfer_sw_counters_s in "mali_uk_types.h" - */ -_mali_osk_errcode_t _mali_ukk_transfer_sw_counters(_mali_uk_sw_counters_s *args); - /** @} */ /* end group _mali_uk_profiling */ #endif @@ -704,12 +631,23 @@ _mali_osk_errcode_t _mali_ukk_transfer_sw_counters(_mali_uk_sw_counters_s *args) * waiting is finished. This information can then be used in kernel space to * complement the GPU utilization metric. * - * @param args see _mali_uk_vsync_event_report_s in "mali_uk_types.h" + * @param args see _mali_uk_vsync_event_report_s in "mali_utgard_uk_types.h" */ _mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args); /** @} */ /* end group _mali_uk_vsync */ +/** @addtogroup _mali_sw_counters_report U/K Software counter reporting + * @{ */ + +/** @brief Report software counters. + * + * @param args see _mali_uk_sw_counters_report_s in "mali_uk_types.h" + */ +_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args); + +/** @} */ /* end group _mali_sw_counters_report */ + /** @} */ /* end group u_k_api */ /** @} */ /* end group uddapi */ diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c new file mode 100644 index 0000000..681c2b0 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c @@ -0,0 +1,88 @@ +/** + * 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_osk.h" +#include "mali_kernel_common.h" +#include "mali_uk_types.h" +#include "mali_user_settings_db.h" +#include "mali_session.h" + +static u32 mali_user_settings[_MALI_UK_USER_SETTING_MAX]; +const char *_mali_uk_user_setting_descriptions[] = _MALI_UK_USER_SETTING_DESCRIPTIONS; + +static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value) +{ + 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_SETTINGS_CHANGED, sizeof(_mali_uk_settings_changed_s)); + _mali_uk_settings_changed_s *data = notobj->result_buffer; + data->setting = setting; + data->value = value; + + mali_session_send_notification(session, notobj); + } + mali_session_unlock(); +} + +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 (mali_user_settings[setting] != value) + { + notify = MALI_TRUE; + } + + mali_user_settings[setting] = value; + + if (notify) + { + mali_user_settings_notify(setting, value); + } +} + +u32 mali_get_user_setting(_mali_uk_user_setting_t setting) +{ + MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0); + + return mali_user_settings[setting]; +} + +_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args) +{ + _mali_uk_user_setting_t setting; + MALI_DEBUG_ASSERT_POINTER(args); + + setting = args->setting; + + if (0 <= setting && _MALI_UK_USER_SETTING_MAX > setting) + { + args->value = mali_user_settings[setting]; + return _MALI_OSK_ERR_OK; + } + else + { + return _MALI_OSK_ERR_INVALID_ARGS; + } +} + +_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args) +{ + MALI_DEBUG_ASSERT_POINTER(args); + + _mali_osk_memcpy(args->settings, mali_user_settings, (sizeof(u32) * _MALI_UK_USER_SETTING_MAX)); + + return _MALI_OSK_ERR_OK; +} diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h b/drivers/media/video/samsung/mali/common/mali_user_settings_db.h new file mode 100644 index 0000000..fbb9415 --- /dev/null +++ b/drivers/media/video/samsung/mali/common/mali_user_settings_db.h @@ -0,0 +1,40 @@ +/** + * 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_USER_SETTINGS_DB_H__ +#define __MALI_USER_SETTINGS_DB_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "mali_uk_types.h" + +/** @brief Set Mali user setting in DB + * + * Update the DB with a new value for \a setting. If the value is different from theprevious set value running sessions will be notified of the change. + * + * @param setting the setting to be changed + * @param value the new value to set + */ +void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value); + +/** @brief Get current Mali user setting value from DB + * + * @param setting the setting to extract + * @return the value of the selected setting + */ +u32 mali_get_user_setting(_mali_uk_user_setting_t setting); + +#ifdef __cplusplus +} +#endif +#endif /* __MALI_KERNEL_USER_SETTING__ */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm.c deleted file mode 100644 index 7041391..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.c +++ /dev/null @@ -1,1024 +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. - */ - -/** - * @file mali_pmm.c - * Implementation of the power management module for the kernel device driver - */ - -#if USING_MALI_PMM - -#include "mali_ukk.h" -#include "mali_kernel_common.h" -#include "mali_kernel_subsystem.h" - -#include "mali_pmm.h" -#include "mali_pmm_system.h" -#include "mali_pmm_state.h" -#include "mali_pmm_policy.h" -#include "mali_pmm_pmu.h" -#include "mali_platform.h" -#include "mali_kernel_pm.h" - -/* Internal PMM subsystem state */ -static _mali_pmm_internal_state_t *pmm_state = NULL; -/* Mali kernel subsystem id */ -static mali_kernel_subsystem_identifier mali_subsystem_pmm_id = -1; - -#define GET_PMM_STATE_PTR (pmm_state) - -/* Internal functions */ -static _mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource); -static void pmm_event_process( void ); -_mali_osk_errcode_t malipmm_irq_uhandler(void *data); -void malipmm_irq_bhandler(void *data); - -/** @brief Start the PMM subsystem - * - * @param id Subsystem id to uniquely identify this subsystem - * @return _MALI_OSK_ERR_OK if the system started successfully, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t malipmm_kernel_subsystem_start( mali_kernel_subsystem_identifier id ); - -/** @brief Perform post start up of the PMM subsystem - * - * Post start up includes initializing the current policy, now that the system is - * completely started - to stop policies turning off hardware during the start up - * - * @param id the unique subsystem id - * @return _MALI_OSK_ERR_OK if the post startup was successful, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifier id ); - -/** @brief Terminate the PMM subsystem - * - * @param id the unique subsystem id - */ -void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ); - -#if MALI_STATE_TRACKING -u32 malipmm_subsystem_dump_state( char *buf, u32 size ); -#endif - - -/* This will be one of the subsystems in the array of subsystems: - static struct mali_kernel_subsystem * subsystems[]; - found in file: mali_kernel_core.c -*/ -struct mali_kernel_subsystem mali_subsystem_pmm= -{ - malipmm_kernel_subsystem_start, /* startup */ - NULL, /*malipmm_kernel_subsystem_terminate,*/ /* shutdown */ - malipmm_kernel_load_complete, /* loaded all subsystems */ - NULL, - NULL, - NULL, - NULL, -#if MALI_STATE_TRACKING - malipmm_subsystem_dump_state, /* dump_state */ -#endif -}; - -#if PMM_OS_TEST - -u32 power_test_event = 0; -mali_bool power_test_flag = MALI_FALSE; -_mali_osk_timer_t *power_test_timer = NULL; - -void _mali_osk_pmm_power_up_done(mali_pmm_message_data data) -{ - MALI_PRINT(("POWER TEST OS UP DONE\n")); -} - -void _mali_osk_pmm_power_down_done(mali_pmm_message_data data) -{ - MALI_PRINT(("POWER TEST OS DOWN DONE\n")); -} - -/** - * Symbian OS Power Up call to the driver - */ -void power_test_callback( void *arg ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - power_test_flag = MALI_TRUE; - _mali_osk_irq_schedulework( pmm->irq ); -} - -void power_test_start() -{ - power_test_timer = _mali_osk_timer_init(); - _mali_osk_timer_setcallback( power_test_timer, power_test_callback, NULL ); - - /* First event is power down */ - power_test_event = MALI_PMM_EVENT_OS_POWER_DOWN; - _mali_osk_timer_add( power_test_timer, 10000 ); -} - -mali_bool power_test_check() -{ - if( power_test_flag ) - { - _mali_uk_pmm_message_s event = { - NULL, - 0, - 1 }; - event.id = power_test_event; - - power_test_flag = MALI_FALSE; - - /* Send event */ - _mali_ukk_pmm_event_message( &event ); - - /* Switch to next event to test */ - if( power_test_event == MALI_PMM_EVENT_OS_POWER_DOWN ) - { - power_test_event = MALI_PMM_EVENT_OS_POWER_UP; - } - else - { - power_test_event = MALI_PMM_EVENT_OS_POWER_DOWN; - } - _mali_osk_timer_add( power_test_timer, 5000 ); - - return MALI_TRUE; - } - - return MALI_FALSE; -} - -void power_test_end() -{ - _mali_osk_timer_del( power_test_timer ); - _mali_osk_timer_term( power_test_timer ); - power_test_timer = NULL; -} - -#endif - -void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - _mali_osk_notification_t *msg; - mali_pmm_message_t *event; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(args); - - MALIPMM_DEBUG_PRINT( ("PMM: sending message\n") ); - -#if MALI_PMM_TRACE && MALI_PMM_TRACE_SENT_EVENTS - _mali_pmm_trace_event_message( args, MALI_FALSE ); -#endif - - msg = _mali_osk_notification_create( MALI_PMM_NOTIFICATION_TYPE, sizeof( mali_pmm_message_t ) ); - - if( msg ) - { - event = (mali_pmm_message_t *)msg->result_buffer; - event->id = args->id; - event->ts = _mali_osk_time_tickcount(); - event->data = args->data; - - _mali_osk_atomic_inc( &(pmm->messages_queued) ); - - if( args->id > MALI_PMM_EVENT_INTERNALS ) - { - /* Internal PMM message */ - _mali_osk_notification_queue_send( pmm->iqueue, msg ); - #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) - pmm->imessages_sent++; - #endif - } - else - { - /* Real event */ - _mali_osk_notification_queue_send( pmm->queue, msg ); - #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) - pmm->messages_sent++; - #endif - } - } - else - { - MALI_PRINT_ERROR( ("PMM: Could not send message %d", args->id) ); - /* Make note of this OOM - which has caused a missed event */ - pmm->missed++; - } - - /* Schedule time to look at the event or the fact we couldn't create an event */ - _mali_osk_irq_schedulework( pmm->irq ); -} - -mali_pmm_state _mali_pmm_state( void ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - if( pmm && (mali_subsystem_pmm_id != -1) ) - { - return pmm->state; - } - - /* No working subsystem yet */ - return MALI_PMM_STATE_UNAVAILABLE; -} - - -mali_pmm_core_mask _mali_pmm_cores_list( void ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - return pmm->cores_registered; -} - -mali_pmm_core_mask _mali_pmm_cores_powered( void ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - return pmm->cores_powered; -} - - -_mali_osk_errcode_t _mali_pmm_list_policies( - u32 policy_list_size, - mali_pmm_policy *policy_list, - u32 *policies_available ) -{ - /* TBD - This is currently a stub function for basic power management */ - - MALI_ERROR( _MALI_OSK_ERR_UNSUPPORTED ); -} - -_mali_osk_errcode_t _mali_pmm_set_policy( mali_pmm_policy policy ) -{ - /* TBD - This is currently a stub function for basic power management */ - -/* TBD - When this is not a stub... include tracing... -#if MALI_PMM_TRACE - _mali_pmm_trace_policy_change( old, newpolicy ); -#endif -*/ - MALI_ERROR( _MALI_OSK_ERR_UNSUPPORTED ); -} - -_mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy ) -{ - if( policy ) - { - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - if( pmm ) - { - *policy = pmm->policy; - MALI_SUCCESS; - } - else - { - *policy = MALI_PMM_POLICY_NONE; - MALI_ERROR( _MALI_OSK_ERR_FAULT ); - } - } - - /* No return argument */ - MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS ); -} - -#if ( MALI_PMM_TRACE || MALI_STATE_TRACKING ) - -/* Event names - order must match mali_pmm_event_id enum */ -static char *pmm_trace_events[] = { - "OS_POWER_UP", - "OS_POWER_DOWN", - "JOB_SCHEDULED", - "JOB_QUEUED", - "JOB_FINISHED", - "TIMEOUT", -}; - -/* State names - order must match mali_pmm_state enum */ -static char *pmm_trace_state[] = { - "UNAVAILABLE", - "SYSTEM ON", - "SYSTEM OFF", - "SYSTEM TRANSITION", -}; - -/* Policy names - order must match mali_pmm_policy enum */ -static char *pmm_trace_policy[] = { - "NONE", - "ALWAYS ON", - "JOB CONTROL", -}; - -/* Status names - order must match mali_pmm_status enum */ -static char *pmm_trace_status[] = { - "MALI_PMM_STATUS_IDLE", /**< PMM is waiting next event */ - "MALI_PMM_STATUS_POLICY_POWER_DOWN", /**< Policy initiated power down */ - "MALI_PMM_STATUS_POLICY_POWER_UP", /**< Policy initiated power down */ - "MALI_PMM_STATUS_OS_WAITING", /**< PMM is waiting for OS power up */ - "MALI_PMM_STATUS_OS_POWER_DOWN", /**< OS initiated power down */ - "MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS", - "MALI_PMM_STATUS_DVFS_PAUSE", /**< PMM DVFS Status Pause */ - "MALI_PMM_STATUS_OS_POWER_UP", /**< OS initiated power up */ - "MALI_PMM_STATUS_OFF", /**< PMM is not active */ -}; - -#endif /* MALI_PMM_TRACE || MALI_STATE_TRACKING */ -#if MALI_PMM_TRACE - -/* UK event names - order must match mali_pmm_event_id enum */ -static char *pmm_trace_events_uk[] = { - "UKS", - "UK_EXAMPLE", -}; - -/* Internal event names - order must match mali_pmm_event_id enum */ -static char *pmm_trace_events_internal[] = { - "INTERNALS", - "INTERNAL_POWER_UP_ACK", - "INTERNAL_POWER_DOWN_ACK", -}; - -void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate ) -{ - const char *dname; - const char *cname; - const char *ename; - - if( old != newstate ) - { - if( newstate == 0 ) - { - dname = "NO cores"; - } - else - { - dname = pmm_trace_get_core_name( newstate ); - } - - /* These state checks only work if the assumption that only cores can be - * turned on or turned off in seperate actions is true. If core power states can - * be toggled (some one, some off) at the same time, this check does not work - */ - if( old > newstate ) - { - /* Cores have turned off */ - cname = pmm_trace_get_core_name( old - newstate ); - ename = "OFF"; - } - else - { - /* Cores have turned on */ - cname = pmm_trace_get_core_name( newstate - old ); - ename = "ON"; - } - MALI_PRINT( ("PMM Trace: Hardware %s ON, %s just turned %s. { 0x%08x -> 0x%08x }", dname, cname, ename, old, newstate) ); - } -} - -void _mali_pmm_trace_state_change( mali_pmm_state old, mali_pmm_state newstate ) -{ - if( old != newstate ) - { - MALI_PRINT( ("PMM Trace: State changed from %s to %s", pmm_trace_state[old], pmm_trace_state[newstate]) ); - } -} - -void _mali_pmm_trace_policy_change( mali_pmm_policy old, mali_pmm_policy newpolicy ) -{ - if( old != newpolicy ) - { - MALI_PRINT( ("PMM Trace: Policy changed from %s to %s", pmm_trace_policy[old], pmm_trace_policy[newpolicy]) ); - } -} - -void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool received ) -{ - const char *ename; - const char *dname; - const char *tname; - const char *format = "PMM Trace: Event %s { (%d) %s, %d ticks, (0x%x) %s }"; - - MALI_DEBUG_ASSERT_POINTER(event); - - tname = (received) ? "received" : "sent"; - - if( event->id >= MALI_PMM_EVENT_INTERNALS ) - { - ename = pmm_trace_events_internal[((int)event->id) - MALI_PMM_EVENT_INTERNALS]; - } - else if( event->id >= MALI_PMM_EVENT_UKS ) - { - ename = pmm_trace_events_uk[((int)event->id) - MALI_PMM_EVENT_UKS]; - } - else - { - ename = pmm_trace_events[event->id]; - } - - switch( event->id ) - { - case MALI_PMM_EVENT_OS_POWER_UP: - case MALI_PMM_EVENT_OS_POWER_DOWN: - dname = "os event"; - break; - - case MALI_PMM_EVENT_JOB_SCHEDULED: - case MALI_PMM_EVENT_JOB_QUEUED: - case MALI_PMM_EVENT_JOB_FINISHED: - case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK: - case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK: - dname = pmm_trace_get_core_name( (mali_pmm_core_mask)event->data ); - break; - - case MALI_PMM_EVENT_TIMEOUT: - dname = "timeout start"; - /* Print data with a different format */ - format = "PMM Trace: Event %s { (%d) %s, %d ticks, %d ticks %s }"; - break; - default: - dname = "unknown data"; - } - - MALI_PRINT( (format, tname, (u32)event->id, ename, event->ts, (u32)event->data, dname) ); -} - -#endif /* MALI_PMM_TRACE */ - - -/****************** Mali Kernel API *****************/ - -_mali_osk_errcode_t malipmm_kernel_subsystem_start( mali_kernel_subsystem_identifier id ) -{ - mali_subsystem_pmm_id = id; - MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(PMU, malipmm_create)); - MALI_SUCCESS; -} - -_mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource) -{ - /* Create PMM state memory */ - MALI_DEBUG_ASSERT( pmm_state == NULL ); - pmm_state = (_mali_pmm_internal_state_t *) _mali_osk_malloc(sizeof(*pmm_state)); - MALI_CHECK_NON_NULL( pmm_state, _MALI_OSK_ERR_NOMEM ); - - /* All values get 0 as default */ - _mali_osk_memset(pmm_state, 0, sizeof(*pmm_state)); - - /* Set up the initial PMM state */ - pmm_state->waiting = 0; - pmm_state->status = MALI_PMM_STATUS_IDLE; - pmm_state->state = MALI_PMM_STATE_UNAVAILABLE; /* Until a core registers */ - - /* Set up policy via compile time option for the moment */ -#if MALI_PMM_ALWAYS_ON - pmm_state->policy = MALI_PMM_POLICY_ALWAYS_ON; -#else - pmm_state->policy = MALI_PMM_POLICY_JOB_CONTROL; -#endif - -#if MALI_PMM_TRACE - _mali_pmm_trace_policy_change( MALI_PMM_POLICY_NONE, pmm_state->policy ); -#endif - - /* Set up assumes all values are initialized to NULL or MALI_FALSE, so - * we can exit halfway through set up and perform clean up - */ - -#if USING_MALI_PMU - if( mali_pmm_pmu_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup; - pmm_state->pmu_initialized = MALI_TRUE; -#endif - pmm_state->queue = _mali_osk_notification_queue_init(); - if( !pmm_state->queue ) goto pmm_fail_cleanup; - - pmm_state->iqueue = _mali_osk_notification_queue_init(); - if( !pmm_state->iqueue ) goto pmm_fail_cleanup; - - /* We are creating an IRQ handler just for the worker thread it gives us */ - pmm_state->irq = _mali_osk_irq_init( _MALI_OSK_IRQ_NUMBER_PMM, - malipmm_irq_uhandler, - malipmm_irq_bhandler, - NULL, - NULL, - (void *)pmm_state, /* PMM state is passed to IRQ */ - "PMM handler" ); - - if( !pmm_state->irq ) goto pmm_fail_cleanup; - - pmm_state->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 75); - if( !pmm_state->lock ) goto pmm_fail_cleanup; - - if( _mali_osk_atomic_init( &(pmm_state->messages_queued), 0 ) != _MALI_OSK_ERR_OK ) - { - goto pmm_fail_cleanup; - } - - MALIPMM_DEBUG_PRINT( ("PMM: subsystem created, policy=%d\n", pmm_state->policy) ); - - MALI_SUCCESS; - -pmm_fail_cleanup: - MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") ); - if( pmm_state ) - { - if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock ); - if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq ); - if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue ); - if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue ); -#if USING_MALI_PMU - if( pmm_state->pmu_initialized ) - { - _mali_osk_resource_type_t t = PMU; - mali_pmm_pmu_deinit(&t); - } -#endif /* USING_MALI_PMU */ - - _mali_osk_free(pmm_state); - pmm_state = NULL; - } - MALI_ERROR( _MALI_OSK_ERR_FAULT ); -} - -_mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifier id ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - MALIPMM_DEBUG_PRINT( ("PMM: subsystem loaded, policy initializing\n") ); - -#if PMM_OS_TEST - power_test_start(); -#endif - - /* Initialize the profile now the system has loaded - so that cores are - * not turned off during start up - */ - return pmm_policy_init( pmm ); -} - -void malipmm_force_powerup( void ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_LOCK(pmm); - pmm->status = MALI_PMM_STATUS_OFF; - MALI_PMM_UNLOCK(pmm); - - /* flush PMM workqueue */ - _mali_osk_flush_workqueue( pmm->irq ); - - if (pmm->cores_powered == 0) - { - malipmm_powerup(pmm->cores_registered); - } -} - -void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id ) -{ - /* Check this is the right system */ - MALI_DEBUG_ASSERT( id == mali_subsystem_pmm_id ); - MALI_DEBUG_ASSERT_POINTER(pmm_state); - - if( pmm_state ) - { -#if PMM_OS_TEST - power_test_end(); -#endif - /* Get the lock so we can shutdown */ - MALI_PMM_LOCK(pmm_state); -#if MALI_STATE_TRACKING - pmm_state->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - pmm_state->status = MALI_PMM_STATUS_OFF; -#if MALI_STATE_TRACKING - pmm_state->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - MALI_PMM_UNLOCK(pmm_state); - _mali_osk_pmm_ospmm_cleanup(); - pmm_policy_term(pmm_state); - _mali_osk_irq_term( pmm_state->irq ); - _mali_osk_notification_queue_term( pmm_state->queue ); - _mali_osk_notification_queue_term( pmm_state->iqueue ); - if (pmm_state->cores_registered) malipmm_powerdown(pmm_state->cores_registered,MALI_POWER_MODE_LIGHT_SLEEP); -#if USING_MALI_PMU - if( pmm_state->pmu_initialized ) - { - _mali_osk_resource_type_t t = PMU; - mali_pmm_pmu_deinit(&t); - } -#endif /* USING_MALI_PMU */ - - _mali_osk_atomic_term( &(pmm_state->messages_queued) ); - MALI_PMM_LOCK_TERM(pmm_state); - _mali_osk_free(pmm_state); - pmm_state = NULL; - } - - MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") ); -} - -_mali_osk_errcode_t malipmm_powerup( u32 cores ) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - - /* If all the cores are powered down, power up the MALI */ - if (pmm->cores_powered == 0) { - mali_platform_power_mode_change(MALI_POWER_MODE_ON); -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - /* Initiate the power up */ - if (_mali_osk_pmm_dev_activate() < 0) { - MALI_PRINT(("PMM: Try again PD_G3D enable\n")); - if (mali_pd_enable() < 0) { - MALI_PRINT(("PMM: Mali PMM device activate failed\n")); - err = _MALI_OSK_ERR_FAULT; - return err; - } - } -#endif - } - -#if USING_MALI_PMU - err = mali_pmm_pmu_powerup( cores ); -#endif - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - mali_platform_powerup(cores); -#endif - - return err; -} - -_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode ) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - mali_platform_powerdown(cores); -#endif - -#if USING_MALI_PMU - err = mali_pmm_pmu_powerdown( cores ); -#endif - - /* If all cores are powered down, power off the MALI */ - if (pmm->cores_powered == 0) - { -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - /* Initiate the power down */ - _mali_osk_pmm_dev_idle(); -#endif - mali_platform_power_mode_change(power_mode); - } - return err; -} - -_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core ) -{ - _mali_osk_errcode_t err; - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - - if( pmm == NULL ) - { - /* PMM state has not been created, this is because the PMU resource has not been - * created yet. - * This probably means that the PMU resource has not been specfied as the first - * resource in the config file - */ - MALI_PRINT_ERROR( ("PMM: Cannot register core %s because the PMU resource has not been\n initialized. Please make sure the PMU resource is the first resource in the\n resource configuration.\n", - pmm_trace_get_core_name(core)) ); - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - MALI_PMM_LOCK(pmm); - -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - - /* Check if the core is registered more than once in PMM */ - MALI_DEBUG_ASSERT( (pmm->cores_registered & core) == 0 ); - - MALIPMM_DEBUG_PRINT( ("PMM: core registered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) ); - -#if !MALI_PMM_NO_PMU - /* Make sure the core is powered up */ - err = malipmm_powerup( core ); -#else - err = _MALI_OSK_ERR_OK; -#endif - if( _MALI_OSK_ERR_OK == err ) - { -#if MALI_PMM_TRACE - mali_pmm_core_mask old_power = pmm->cores_powered; -#endif - /* Assume a registered core is now powered up and idle */ - pmm->cores_registered |= core; - pmm->cores_idle |= core; - pmm->cores_powered |= core; - pmm_update_system_state( pmm ); - -#if MALI_PMM_TRACE - _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); -#endif - } - else - { - MALI_PRINT_ERROR( ("PMM: Error(%d) powering up registered core: (0x%x) %s\n", - err, core, pmm_trace_get_core_name(core)) ); - } - -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); - - return err; -} - -void malipmm_core_unregister( mali_pmm_core_id core ) -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - - MALI_PMM_LOCK(pmm); -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - - /* Check if the core is registered in PMM */ - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, core ); - - MALIPMM_DEBUG_PRINT( ("PMM: core unregistered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) ); - - { -#if MALI_PMM_TRACE - mali_pmm_core_mask old_power = pmm->cores_powered; -#endif - - /* Remove the core from the system */ - pmm->cores_idle &= (~core); - pmm->cores_powered &= (~core); - pmm->cores_pend_down &= (~core); - pmm->cores_pend_up &= (~core); - pmm->cores_ack_down &= (~core); - pmm->cores_ack_up &= (~core); - - pmm_update_system_state( pmm ); - -#if MALI_PMM_TRACE - _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); -#endif - } - -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); -} -void malipmm_core_power_down_okay( mali_pmm_core_id core ) -{ - _mali_uk_pmm_message_s event = { - NULL, - MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK, - 0 }; - - event.data = core; - - _mali_ukk_pmm_event_message( &event ); -} - -void malipmm_set_policy_check() -{ - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - MALI_DEBUG_ASSERT_POINTER(pmm); - pmm->check_policy = MALI_TRUE; - - /* To check the policy we need to schedule some work */ - _mali_osk_irq_schedulework( pmm->irq ); -} - -_mali_osk_errcode_t malipmm_irq_uhandler(void *data) -{ - MALIPMM_DEBUG_PRINT( ("PMM: uhandler - not expected to be used\n") ); - - MALI_SUCCESS; -} - -void malipmm_irq_bhandler(void *data) -{ - _mali_pmm_internal_state_t *pmm; - pmm = (_mali_pmm_internal_state_t *)data; - MALI_DEBUG_ASSERT_POINTER(pmm); - -#if PMM_OS_TEST - if( power_test_check() ) return; -#endif - - MALI_PMM_LOCK(pmm); -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - /* Quick out when we are shutting down */ - if( pmm->status == MALI_PMM_STATUS_OFF ) - { - - #if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; - #endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); - return; - } - - MALIPMM_DEBUG_PRINT( ("PMM: bhandler - Processing event\n") ); - - if( pmm->missed > 0 ) - { - MALI_PRINT_ERROR( ("PMM: Failed to send %d events", pmm->missed) ); - pmm_fatal_reset( pmm ); - } - - if( pmm->check_policy ) - { - pmm->check_policy = MALI_FALSE; - pmm_policy_check_policy(pmm); - } - else - { - /* Perform event processing */ - pmm_event_process(); - if( pmm->fatal_power_err ) - { - /* Try a reset */ - pmm_fatal_reset( pmm ); - } - } - -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); -} - -static void pmm_event_process( void ) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_osk_notification_t *msg = NULL; - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - mali_pmm_message_t *event; - u32 process_messages; - - MALI_DEBUG_ASSERT_POINTER(pmm); - - - /* Max number of messages to process before exiting - as we shouldn't stay - * processing the messages for a long time - */ - process_messages = _mali_osk_atomic_read( &(pmm->messages_queued) ); - - while( process_messages > 0 ) - { - /* Check internal message queue first */ - err = _mali_osk_notification_queue_dequeue( pmm->iqueue, &msg ); - - if( err != _MALI_OSK_ERR_OK ) - { - if( pmm->status == MALI_PMM_STATUS_IDLE || pmm->status == MALI_PMM_STATUS_OS_WAITING || pmm->status == MALI_PMM_STATUS_DVFS_PAUSE) - { - if( pmm->waiting > 0 ) pmm->waiting--; - - /* We aren't busy changing state, so look at real events */ - err = _mali_osk_notification_queue_dequeue( pmm->queue, &msg ); - - if( err != _MALI_OSK_ERR_OK ) - { - pmm->no_events++; - MALIPMM_DEBUG_PRINT( ("PMM: event_process - No message to process\n") ); - /* Nothing to do - so return */ - return; - } - else - { - #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) - pmm->messages_received++; - #endif - } - } - else - { - /* Waiting for an internal message */ - pmm->waiting++; - MALIPMM_DEBUG_PRINT( ("PMM: event_process - Waiting for internal message, messages queued=%d\n", pmm->waiting) ); - return; - } - } - else - { - #if (MALI_PMM_TRACE || MALI_STATE_TRACKING) - pmm->imessages_received++; - #endif - } - - MALI_DEBUG_ASSERT_POINTER( msg ); - /* Check the message type matches */ - MALI_DEBUG_ASSERT( msg->notification_type == MALI_PMM_NOTIFICATION_TYPE ); - - event = msg->result_buffer; - - _mali_osk_atomic_dec( &(pmm->messages_queued) ); - process_messages--; - - #if MALI_PMM_TRACE - /* Trace before we process the event in case we have an error */ - _mali_pmm_trace_event_message( event, MALI_TRUE ); - #endif - err = pmm_policy_process( pmm, event ); - - - if( err != _MALI_OSK_ERR_OK ) - { - MALI_PRINT_ERROR( ("PMM: Error(%d) in policy %d when processing event message with id: %d", - err, pmm->policy, event->id) ); - } - - /* Delete notification */ - _mali_osk_notification_delete ( msg ); - - if( pmm->fatal_power_err ) - { - /* Nothing good has happened - exit */ - return; - } - - - #if MALI_PMM_TRACE - MALI_PRINT( ("PMM Trace: Event processed, msgs (sent/read) = %d/%d, int msgs (sent/read) = %d/%d, no events = %d, waiting = %d\n", - pmm->messages_sent, pmm->messages_received, pmm->imessages_sent, pmm->imessages_received, pmm->no_events, pmm->waiting) ); - #endif - } - - if( pmm->status == MALI_PMM_STATUS_IDLE && pmm->waiting > 0 ) - { - /* For events we ignored whilst we were busy, add a new - * scheduled time to look at them */ - _mali_osk_irq_schedulework( pmm->irq ); - } -} - -#if MALI_STATE_TRACKING -u32 malipmm_subsystem_dump_state(char *buf, u32 size) -{ - int len = 0; - _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; - - if( !pmm ) - { - len += _mali_osk_snprintf(buf + len, size + len, "PMM: Null state\n"); - } - else - { - len += _mali_osk_snprintf(buf+len, size+len, "Locks:\n PMM lock acquired: %s\n", - pmm->mali_pmm_lock_acquired ? "true" : "false"); - len += _mali_osk_snprintf(buf+len, size+len, - "PMM state:\n Previous status: %s\n Status: %s\n Current event: %s\n Policy: %s\n Check policy: %s\n State: %s\n", - pmm_trace_status[pmm->mali_last_pmm_status], pmm_trace_status[pmm->status], - pmm_trace_events[pmm->mali_new_event_status], pmm_trace_policy[pmm->policy], - pmm->check_policy ? "true" : "false", pmm_trace_state[pmm->state]); - len += _mali_osk_snprintf(buf+len, size+len, - "PMM cores:\n Cores registered: %d\n Cores powered: %d\n Cores idle: %d\n" - " Cores pending down: %d\n Cores pending up: %d\n Cores ack down: %d\n Cores ack up: %d\n", - pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down, - pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up); - len += _mali_osk_snprintf(buf+len, size+len, "PMM misc:\n PMU init: %s\n Messages queued: %d\n" - " Waiting: %d\n No events: %d\n Missed events: %d\n Fatal power error: %s\n", - pmm->pmu_initialized ? "true" : "false", _mali_osk_atomic_read(&(pmm->messages_queued)), - pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err ? "true" : "false"); - } - return len; -} -#endif /* MALI_STATE_TRACKING */ - -#endif /* USING_MALI_PMM */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm.h deleted file mode 100644 index 5170650..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.h +++ /dev/null @@ -1,348 +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. - */ - -/** - * @file mali_pmm.h - * Defines the power management module for the kernel device driver - */ - -#ifndef __MALI_PMM_H__ -#define __MALI_PMM_H__ - -/* For mali_pmm_message_data and MALI_PMM_EVENT_UK_* defines */ -#include "mali_uk_types.h" -#include "mali_platform.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @defgroup pmmapi Power Management Module APIs - * - * @{ - */ - -/** OS event tester */ -#define PMM_OS_TEST 0 - -/** @brief Compile option to turn on/off tracing */ -#define MALI_PMM_TRACE 0 -#define MALI_PMM_TRACE_SENT_EVENTS 0 - -/** @brief Compile option to switch between always on or job control PMM policy */ -#define MALI_PMM_ALWAYS_ON 0 - -/** @brief Overrides hardware PMU and uses software simulation instead - * @note This even stops intialization of PMU and cores being powered on at start up - */ -#define MALI_PMM_NO_PMU 0 - -/** @brief PMM debug print to control debug message level */ -#define MALIPMM_DEBUG_PRINT(args) \ - MALI_DEBUG_PRINT(3, args) - - -/** @brief power management event message identifiers. - */ -/* These must match up with the pmm_trace_events & pmm_trace_events_internal - * arrays - */ -typedef enum mali_pmm_event_id -{ - MALI_PMM_EVENT_OS_POWER_UP = 0, /**< OS power up event */ - MALI_PMM_EVENT_OS_POWER_DOWN = 1, /**< OS power down event */ - MALI_PMM_EVENT_JOB_SCHEDULED = 2, /**< Job scheduled to run event */ - MALI_PMM_EVENT_JOB_QUEUED = 3, /**< Job queued (but not run) event */ - MALI_PMM_EVENT_JOB_FINISHED = 4, /**< Job finished event */ - MALI_PMM_EVENT_TIMEOUT = 5, /**< Time out timer has expired */ - MALI_PMM_EVENT_DVFS_PAUSE = 6, /**< Mali device pause event */ - MALI_PMM_EVENT_DVFS_RESUME = 7, /**< Mali device resume event */ - - MALI_PMM_EVENT_UKS = 200, /**< Events from the user-side start here */ - MALI_PMM_EVENT_UK_EXAMPLE = _MALI_PMM_EVENT_UK_EXAMPLE, - - MALI_PMM_EVENT_INTERNALS = 1000, - MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK = 1001, /**< Internal power up acknowledgement */ - MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK = 1002, /**< Internal power down acknowledgment */ -} mali_pmm_event_id; - - -/** @brief Use this when the power up/down callbacks do not need any OS data. */ -#define MALI_PMM_NO_OS_DATA 1 - - -/* @brief Geometry and pixel processor identifiers for the PMM - * - * @note these match the ARM Mali 400 PMU hardware definitions, apart from the "SYSTEM" - */ -typedef enum mali_pmm_core_id_tag -{ - MALI_PMM_CORE_SYSTEM = 0x00000000, /**< All of the Mali hardware */ - MALI_PMM_CORE_GP = 0x00000001, /**< Mali GP2 */ - MALI_PMM_CORE_L2 = 0x00000002, /**< Level 2 cache */ - MALI_PMM_CORE_PP0 = 0x00000004, /**< Mali 200 pixel processor 0 */ - MALI_PMM_CORE_PP1 = 0x00000008, /**< Mali 200 pixel processor 1 */ - MALI_PMM_CORE_PP2 = 0x00000010, /**< Mali 200 pixel processor 2 */ - MALI_PMM_CORE_PP3 = 0x00000020, /**< Mali 200 pixel processor 3 */ - MALI_PMM_CORE_PP_ALL = 0x0000003C /**< Mali 200 pixel processors 0-3 */ -} mali_pmm_core_id; - - -/* @brief PMM bitmask of mali_pmm_core_ids - */ -typedef u32 mali_pmm_core_mask; - -/* @brief PMM event timestamp type - */ -typedef u32 mali_pmm_timestamp; - -/** @brief power management event message struct - */ -typedef struct _mali_pmm_message -{ - mali_pmm_event_id id; /**< event id */ - mali_pmm_message_data data; /**< specific data associated with the event */ - mali_pmm_timestamp ts; /**< timestamp the event was placed in the event queue */ -} mali_pmm_message_t; - - - -/** @brief the state of the power management module. - */ -/* These must match up with the pmm_trace_state array */ -typedef enum mali_pmm_state_tag -{ - MALI_PMM_STATE_UNAVAILABLE = 0, /**< PMM is not available */ - MALI_PMM_STATE_SYSTEM_ON = 1, /**< All of the Mali hardware is on */ - MALI_PMM_STATE_SYSTEM_OFF = 2, /**< All of the Mali hardware is off */ - MALI_PMM_STATE_SYSTEM_TRANSITION = 3 /**< System is changing state */ -} mali_pmm_state; - - -/** @brief a power management policy. - */ -/* These must match up with the pmm_trace_policy array */ -typedef enum mali_pmm_policy_tag -{ - MALI_PMM_POLICY_NONE = 0, /**< No policy */ - MALI_PMM_POLICY_ALWAYS_ON = 1, /**< Always on policy */ - MALI_PMM_POLICY_JOB_CONTROL = 2, /**< Job control policy */ - MALI_PMM_POLICY_RUNTIME_JOB_CONTROL = 3 /**< Run time power management control policy */ -} mali_pmm_policy; - -/** @brief Function to power up MALI - * - * @param cores core mask to power up the cores - * - * @return error code if MALI fails to power up - */ -_mali_osk_errcode_t malipmm_powerup( u32 cores ); - -/** @brief Function to power down MALI - * - * @param cores core mask to power down the cores - * @param The power mode to which MALI transitions - * - * @return error code if MALI fails to power down - */ -_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode ); - -/** @brief Function to report to the OS when the power down has finished - * - * @param data The event message data that initiated the power down - */ -void _mali_osk_pmm_power_down_done(mali_pmm_message_data data); - -/** @brief Function to report to the OS when the power up has finished - * - * @param data The event message data that initiated the power up - */ -void _mali_osk_pmm_power_up_done(mali_pmm_message_data data); - -/** @brief Function to report that DVFS operation done - * - * @param data The event message data - */ -void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data); - -#if MALI_POWER_MGMT_TEST_SUITE -/** @brief Function to notify power management events - * - * @param data The event message data - */ -void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id event_id); - -#endif - -/** @brief Function to power up MALI - * - * @note powers up the MALI during MALI device driver is unloaded - */ -void malipmm_force_powerup( void ); - -/** @brief Function to report the OS that device is idle - * - * @note inform the OS that device is idle - */ -_mali_osk_errcode_t _mali_osk_pmm_dev_idle( void ); - -/** @brief Function to report the OS to activate device - * - * @note inform the os that device needs to be activated - */ -int _mali_osk_pmm_dev_activate( void ); - -/** @brief Function to report OS PMM for cleanup - * - * @note Function to report OS PMM for cleanup - */ -void _mali_osk_pmm_ospmm_cleanup( void ); - -/** @brief Queries the current state of the PMM software - * - * @note the state of the PMM can change after this call has returned - * - * @return the current PMM state value - */ -mali_pmm_state _mali_pmm_state( void ); - -/** @brief List of cores that are registered with the PMM - * - * This will return the cores that have been currently registered with the PMM, - * which is a bitwise OR of the mali_pmm_core_id_tags. A value of 0x0 means that - * there are no cores registered. - * - * @note the list of cores can change after this call has returned - * - * @return a bit mask representing all the cores that have been registered with the PMM - */ -mali_pmm_core_mask _mali_pmm_cores_list( void ); - -/** @brief List of cores that are powered up in the PMM - * - * This will return the subset of the cores that can be listed using mali_pmm_cores_ - * list, that have power. It is a bitwise OR of the mali_pmm_core_id_tags. A value of - * 0x0 means that none of the cores registered are powered. - * - * @note the list of cores can change after this call has returned - * - * @return a bit mask representing all the cores that are powered up - */ -mali_pmm_core_mask _mali_pmm_cores_powered( void ); - - -/** @brief List of power management policies that are supported by the PMM - * - * Given an empty array of policies - policy_list - which contains the number - * of entries as specified by - policy_list_size, this function will populate - * the list with the available policies. If the policy_list is too small for - * all the policies then only policy_list_size entries will be returned. If the - * policy_list is bigger than the number of available policies then, the extra - * entries will be set to MALI_PMM_POLICY_NONE. - * The function will also update available_policies with the number of policies - * that are available, even if it exceeds the policy_list_size. - * The function will succeed if all policies could be returned, else it will - * fail if none or only a subset of policies could be returned. - * The function will also fail if no policy_list is supplied, though - * available_policies is optional. - * - * @note this is a STUB function and is not yet implemented - * - * @param policy_list_size is the number of policies that can be returned in - * the policy_list argument - * @param policy_list is an array of policies that should be populated with - * the list of policies that are supported by the PMM - * @param policies_available optional argument, if non-NULL will be set to the - * number of policies available - * @return _MALI_OSK_ERR_OK if the policies could be listed, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t _mali_pmm_list_policies( - u32 policy_list_size, - mali_pmm_policy *policy_list, - u32 *policies_available ); - -/** @brief Set the power management policy in the PMM - * - * Given a valid supported policy, this function will change the PMM to use - * this new policy - * The function will fail if the policy given is invalid or unsupported. - * - * @note this is a STUB function and is not yet implemented - * - * @param policy the new policy to be set - * @return _MALI_OSK_ERR_OK if the policy could be set, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t _mali_pmm_set_policy( mali_pmm_policy policy ); - -/** @brief Get the current power management policy in the PMM - * - * Given a pointer to a policy data type, this function will return the current - * policy that is in effect for the PMM. This maybe out of date if there is a - * pending set policy call that has not been serviced. - * The function will fail if the policy given is NULL. - * - * @note the policy of the PMM can change after this call has returned - * - * @param policy a pointer to a policy that can be updated to the current - * policy - * @return _MALI_OSK_ERR_OK if the policy could be returned, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy ); - -#if MALI_PMM_TRACE - -/** @brief Indicates when a hardware state change occurs in the PMM - * - * @param old a mask of the cores indicating the previous state of the cores - * @param newstate a mask of the cores indicating the new current state of the cores - */ -void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate ); - -/** @brief Indicates when a state change occurs in the PMM - * - * @param old the previous state for the PMM - * @param newstate the new current state of the PMM - */ -void _mali_pmm_trace_state_change( mali_pmm_state old, mali_pmm_state newstate ); - -/** @brief Indicates when a policy change occurs in the PMM - * - * @param old the previous policy for the PMM - * @param newpolicy the new current policy of the PMM - */ -void _mali_pmm_trace_policy_change( mali_pmm_policy old, mali_pmm_policy newpolicy ); - -/** @brief Records when an event message is read by the event system - * - * @param event the message details - * @param received MALI_TRUE when the message is received by the PMM, else it is being sent - */ -void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool received ); - -#endif /* MALI_PMM_TRACE */ - -/** @brief Dumps the current state of OS PMM thread - */ -#if MALI_STATE_TRACKING -u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ); -#endif /* MALI_STATE_TRACKING */ - -/** @} */ /* end group pmmapi */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_PMM_H__ */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c deleted file mode 100644 index a8160ac..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c +++ /dev/null @@ -1,350 +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. - */ - -/** - * @file mali_pmm_pmu.c - * Mali driver functions for Mali 400 PMU hardware - */ -#include "mali_kernel_common.h" -#include "mali_osk.h" -#include "mali_platform.h" - -#if USING_MALI_PMU -#if USING_MALI_PMM - -#include "mali_pmm.h" - -/* Internal test on/off */ -#define PMU_TEST 0 - -#if MALI_POWER_MGMT_TEST_SUITE -#include "mali_platform_pmu_internal_testing.h" -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - -/** @brief PMU hardware info - */ -typedef struct platform_pmu -{ - u32 reg_base_addr; /**< PMU registers base address */ - u32 reg_size; /**< PMU registers size */ - const char *name; /**< PMU name */ - u32 irq_num; /**< PMU irq number */ - - mali_io_address reg_mapped; /**< IO-mapped pointer to registers */ -} platform_pmu_t; - -static platform_pmu_t *pmu_info = NULL; - -/** @brief Register layout for hardware PMU - */ -typedef enum { - PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */ - PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */ - PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */ - PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */ - PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */ - PMU_REG_ADDR_MGMT_INT_STAT = 0x14, /*< Interrupt status register */ - PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */ - PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Software delay register */ - PMU_REG_ADDR_MGMT_MASTER_PWR_UP = 0x24, /*< Master power up register */ - PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */ -} pmu_reg_addr_mgmt_addr; - -/* Internal functions */ -static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address); -static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val); -static mali_pmm_core_mask pmu_translate_cores_to_pmu(mali_pmm_core_mask cores); -#if PMU_TEST -static void pmm_pmu_dump_regs( platform_pmu_t *pmu ); -static pmm_pmu_test( platform_pmu_t *pmu, u32 cores ); -#endif - -_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource) -{ - - if( resource->type == PMU ) - { - if( (resource->base == 0) || - (resource->description == NULL) ) - { - /* NOTE: We currently don't care about any other resource settings */ - MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n")); - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info)); - MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM ); - - /* All values get 0 as default */ - _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info)); - - pmu_info->reg_base_addr = resource->base; - pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE; - pmu_info->name = resource->description; - pmu_info->irq_num = resource->irq; - - if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) ) - { - MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n", - pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); - goto cleanup; - } - else - { - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n", - pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); - } - - pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name ); - - if( 0 == pmu_info->reg_mapped ) - { - MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name)); - _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size ); - goto cleanup; - } - else - { - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n", - (u32) pmu_info->reg_mapped, - ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1, - pmu_info->name)); - } - - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name)); - -#if PMU_TEST - pmu_test(pmu_info, (MALI_PMM_CORE_GP)); - pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0)); -#endif - - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) ); - } - else - { - /* Didn't expect a different resource */ - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - MALI_SUCCESS; - -cleanup: - _mali_osk_free(pmu_info); - pmu_info = NULL; - MALI_ERROR(_MALI_OSK_ERR_NOMEM); -} - -_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type) -{ - if (*type == PMU) - { - if( pmu_info ) - { - _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped); - _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size); - _mali_osk_free(pmu_info); - pmu_info = NULL; - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") ); - } - } - else - { - /* Didn't expect a different resource */ - MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); - } - - MALI_SUCCESS; - -} - -_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores) -{ - u32 stat; - u32 timeout; - u32 cores_pmu; - - MALI_DEBUG_ASSERT_POINTER(pmu_info); - MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power down (0x%x)\n", cores) ); - - cores_pmu = pmu_translate_cores_to_pmu(cores); - pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_DOWN, cores_pmu ); - - /* Wait for cores to be powered down */ - timeout = 10; /* 10ms */ - do - { - /* Get status of sleeping cores */ - stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); - stat &= cores_pmu; - if( stat == cores_pmu ) break; /* All cores we wanted are now asleep */ - _mali_osk_time_ubusydelay(1000); /* 1ms */ - timeout--; - } while( timeout > 0 ); - - if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); - - MALI_SUCCESS; -} - -_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores) -{ - u32 cores_pmu; - u32 stat; - u32 timeout; - - MALI_DEBUG_ASSERT_POINTER(pmu_info); - MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ - MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) ); - - /* Don't use interrupts - just poll status */ - pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 ); - cores_pmu = pmu_translate_cores_to_pmu(cores); - pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu ); - - timeout = 10; /* 10ms */ - do - { - /* Get status of sleeping cores */ - stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); - stat &= cores_pmu; - if( stat == 0 ) break; /* All cores we wanted are now awake */ - _mali_osk_time_ubusydelay(1000); /* 1ms */ - timeout--; - } while( timeout > 0 ); - - if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); - - MALI_SUCCESS; -} - - -/***** INTERNAL *****/ - -/** @brief Internal PMU function to translate the cores bit mask - * into something the hardware PMU understands - * - * @param cores PMM cores bitmask - * @return PMU hardware cores bitmask - */ -static u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores) -{ - /* For Mali 400 PMU the cores mask is already the same as what - * the hardware PMU expects. - * For other hardware, some translation can be done here, by - * translating the MALI_PMM_CORE_* bits into specific hardware - * bits - */ - return cores; -} - -/** @brief Internal PMU function to read a PMU register - * - * @param pmu handle that identifies the PMU hardware - * @param relative_address relative PMU hardware address to read from - * @return 32-bit value that was read from the address - */ -static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address) -{ - u32 read_val; - - MALI_DEBUG_ASSERT_POINTER(pmu); - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); - - read_val = _mali_osk_mem_ioread32(pmu->reg_mapped, relative_address); - - MALI_DEBUG_PRINT( 5, ("PMU: reg_read: %s Addr:0x%04X Val:0x%08x\n", - pmu->name, relative_address, read_val)); - - return read_val; -} - -/** @brief Internal PMU function to write to a PMU register - * - * @param pmu handle that identifies the PMU hardware - * @param relative_address relative PMU hardware address to write to - * @param new_val new 32-bit value to write into the address - */ -static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val) -{ - MALI_DEBUG_ASSERT_POINTER(pmu); - MALI_DEBUG_ASSERT((relative_address & 0x03) == 0); - MALI_DEBUG_ASSERT(relative_address < pmu->reg_size); - - MALI_DEBUG_PRINT( 5, ("PMU: reg_write: %s Addr:0x%04X Val:0x%08x\n", - pmu->name, relative_address, new_val)); - - _mali_osk_mem_iowrite32(pmu->reg_mapped, relative_address, new_val); -} - -#if PMU_TEST - -/***** TEST *****/ - -static void pmu_dump_regs( platform_pmu_t *pmu ) -{ - u32 addr; - for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 ) - { - MALI_PRINT( ("PMU_REG: 0x%08x: 0x%04x\n", (addr + pmu->reg_base_addr), pmu_reg_read( pmu, addr ) ) ); - } -} - -/* This function is an internal test for the PMU without any Mali h/w interaction */ -static void pmu_test( platform_pmu_t *pmu, u32 cores ) -{ - u32 stat; - u32 timeout; - - MALI_PRINT( ("PMU_TEST: Start\n") ); - - pmu_dump_regs( pmu ); - - MALI_PRINT( ("PMU_TEST: Power down cores: 0x%x\n", cores) ); - _mali_pmm_pmu_power_down( pmu, cores, MALI_TRUE ); - - stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); - MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == cores ? "SUCCESS" : "FAIL" ) ); - - pmu_dump_regs( pmu ); - - MALI_PRINT( ("PMU_TEST: Power up cores: 0x%x\n", cores) ); - _mali_pmm_pmu_power_up( pmu, cores, MALI_FALSE ); - - MALI_PRINT( ("PMU_TEST: Waiting for power up...\n") ); - timeout = 1000; /* 1 sec */ - while( !_mali_pmm_pmu_irq_power_up(pmu) && timeout > 0 ) - { - _mali_osk_time_ubusydelay(1000); /* 1ms */ - timeout--; - } - - MALI_PRINT( ("PMU_TEST: Waited %dms for interrupt\n", (1000-timeout)) ); - stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS ); - MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == 0 ? "SUCCESS" : "FAIL" ) ); - - _mali_pmm_pmu_irq_power_up_clear(pmu); - - pmu_dump_regs( pmu ); - - MALI_PRINT( ("PMU_TEST: Finish\n") ); -} -#endif /* PMU_TEST */ - -#if MALI_POWER_MGMT_TEST_SUITE - -u32 pmu_get_power_up_down_info(void) -{ - return pmu_reg_read(pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS); -} - -#endif /* MALI_POWER_MGMT_TEST_SUITE */ -#endif /* USING_MALI_PMM */ -#endif /* USING_MALI_PMU */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h deleted file mode 100644 index 7525cac..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h +++ /dev/null @@ -1,86 +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. - */ -/** - * @file mali_platform.h - * Platform specific Mali driver functions - */ - -#include "mali_osk.h" - -#if !USING_MALI_PMM -/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */ -#define MALI_PLATFORM_SYSTEM 0 -#endif - -#if USING_MALI_PMM -#if USING_MALI_PMU -#include "mali_pmm.h" - -/** @brief Platform specific setup and initialisation of MALI - * - * This is called from the entrypoint of the driver to initialize the platform - * When using PMM, it is also called from the PMM start up to initialise the - * system PMU - * - * @param resource This is NULL when called on first driver start up, else it will - * be a pointer to a PMU resource - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource); - -/** @brief Platform specific deinitialisation of MALI - * - * This is called on the exit of the driver to terminate the platform - * When using PMM, it is also called from the PMM termination code to clean up the - * system PMU - * - * @param type This is NULL when called on driver exit, else it will - * be a pointer to a PMU resource type (not the full resource) - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type); - -/** @brief Platform specific powerdown sequence of MALI - * - * Called as part of platform init if there is no PMM support, else the - * PMM will call it. - * - * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will - * be a mask of cores to power down based on the mali_pmm_core_id enum - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores); - -/** @brief Platform specific powerup sequence of MALI - * - * Called as part of platform deinit if there is no PMM support, else the - * PMM will call it. - * - * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will - * be a mask of cores to power down based on the mali_pmm_core_id enum - * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error. - */ -_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores); - -#if MALI_POWER_MGMT_TEST_SUITE -#if USING_MALI_PMM -#if USING_MALI_PMU -/** @brief function to get status of individual cores - * - * This function is used by power management test suite to get the status of powered up/down the number - * of cores - * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization. - */ -u32 pmu_get_power_up_down_info(void); -#endif -#endif -#endif -#endif -#endif diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c deleted file mode 100644 index 87b6ec2..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c +++ /dev/null @@ -1,243 +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. - */ - -/** - * @file mali_pmm_policy.c - * Implementation of the common routines for power management module - * policies - */ - -#if USING_MALI_PMM - -#include "mali_ukk.h" -#include "mali_kernel_common.h" - -#include "mali_pmm.h" -#include "mali_pmm_system.h" -#include "mali_pmm_state.h" -#include "mali_pmm_policy.h" - -#include "mali_pmm_policy_alwayson.h" -#include "mali_pmm_policy_jobcontrol.h" - -/* Call back function for timer expiration */ -static void pmm_policy_timer_callback( void *arg ); - -_mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 timeout, mali_pmm_event_id id ) -{ - MALI_DEBUG_ASSERT_POINTER(pptimer); - - /* All values get 0 as default */ - _mali_osk_memset(pptimer, 0, sizeof(*pptimer)); - - pptimer->timer = _mali_osk_timer_init(); - if( pptimer->timer ) - { - _mali_osk_timer_setcallback( pptimer->timer, pmm_policy_timer_callback, (void *)pptimer ); - pptimer->timeout = timeout; - pptimer->event_id = id; - MALI_SUCCESS; - } - - return _MALI_OSK_ERR_FAULT; -} - -static void pmm_policy_timer_callback( void *arg ) -{ - _pmm_policy_timer_t *pptimer = (_pmm_policy_timer_t *)arg; - - MALI_DEBUG_ASSERT_POINTER(pptimer); - MALI_DEBUG_ASSERT( pptimer->set ); - - /* Set timer expired and flag there is a policy to check */ - pptimer->expired = MALI_TRUE; - malipmm_set_policy_check(); -} - - -void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer ) -{ - MALI_DEBUG_ASSERT_POINTER(pptimer); - - _mali_osk_timer_del( pptimer->timer ); - _mali_osk_timer_term( pptimer->timer ); - pptimer->timer = NULL; -} - -mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer ) -{ - MALI_DEBUG_ASSERT_POINTER(pptimer); - MALI_DEBUG_ASSERT_POINTER(pptimer->timer); - - if( !(pptimer->set) ) - { - pptimer->set = MALI_TRUE; - pptimer->expired = MALI_FALSE; - pptimer->start = _mali_osk_time_tickcount(); - _mali_osk_timer_add( pptimer->timer, pptimer->timeout ); - return MALI_TRUE; - } - - return MALI_FALSE; -} - -mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer ) -{ - MALI_DEBUG_ASSERT_POINTER(pptimer); - MALI_DEBUG_ASSERT_POINTER(pptimer->timer); - - if( pptimer->set ) - { - _mali_osk_timer_del( pptimer->timer ); - pptimer->set = MALI_FALSE; - pptimer->expired = MALI_FALSE; - return MALI_TRUE; - } - - return MALI_FALSE; -} - -mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer ) -{ - MALI_DEBUG_ASSERT_POINTER(pptimer); - - if( pptimer->expired ) - { - _mali_uk_pmm_message_s event = { - NULL, - MALI_PMM_EVENT_TIMEOUT, /* Assume timeout id, but set it below */ - 0 }; - - event.id = pptimer->event_id; - event.data = (mali_pmm_message_data)pptimer->start; - - /* Don't need to do any other notification with this timer */ - pptimer->expired = MALI_FALSE; - /* Unset timer so it is free to be set again */ - pptimer->set = MALI_FALSE; - - _mali_ukk_pmm_event_message( &event ); - - return MALI_TRUE; - } - - return MALI_FALSE; -} - -mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start ) -{ - return (_mali_osk_time_after( other_start, timer_start ) == 0); -} - - -_mali_osk_errcode_t pmm_policy_init(_mali_pmm_internal_state_t *pmm) -{ - _mali_osk_errcode_t err; - - MALI_DEBUG_ASSERT_POINTER(pmm); - - switch( pmm->policy ) - { - case MALI_PMM_POLICY_ALWAYS_ON: - { - err = pmm_policy_init_always_on(); - } - break; - - case MALI_PMM_POLICY_JOB_CONTROL: - { - err = pmm_policy_init_job_control(pmm); - } - break; - - case MALI_PMM_POLICY_NONE: - default: - err = _MALI_OSK_ERR_FAULT; - } - - return err; -} - -void pmm_policy_term(_mali_pmm_internal_state_t *pmm) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - - switch( pmm->policy ) - { - case MALI_PMM_POLICY_ALWAYS_ON: - { - pmm_policy_term_always_on(); - } - break; - - case MALI_PMM_POLICY_JOB_CONTROL: - { - pmm_policy_term_job_control(); - } - break; - - case MALI_PMM_POLICY_NONE: - default: - MALI_PRINT_ERROR( ("PMM: Invalid policy terminated %d\n", pmm->policy) ); - } -} - - -_mali_osk_errcode_t pmm_policy_process(_mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event) -{ - _mali_osk_errcode_t err; - - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(event); - - switch( pmm->policy ) - { - case MALI_PMM_POLICY_ALWAYS_ON: - { - err = pmm_policy_process_always_on( pmm, event ); - } - break; - - case MALI_PMM_POLICY_JOB_CONTROL: - { - err = pmm_policy_process_job_control( pmm, event ); - } - break; - - case MALI_PMM_POLICY_NONE: - default: - err = _MALI_OSK_ERR_FAULT; - } - - return err; -} - - -void pmm_policy_check_policy( _mali_pmm_internal_state_t *pmm ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - - switch( pmm->policy ) - { - case MALI_PMM_POLICY_JOB_CONTROL: - { - pmm_policy_check_job_control(); - } - break; - - default: - /* Nothing needs to be done */ - break; - } -} - - -#endif /* USING_MALI_PMM */ - diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h deleted file mode 100644 index 75ac8c8..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h +++ /dev/null @@ -1,155 +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. - */ - -/** - * @file mali_pmm_policy.h - * Defines the power management module policies - */ - -#ifndef __MALI_PMM_POLICY_H__ -#define __MALI_PMM_POLICY_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup pmmapi Power Management Module APIs - * - * @{ - * - * @defgroup pmmapi_policy Power Management Module Policies - * - * @{ - */ - -/** @brief Generic timer for use with policies - */ -typedef struct _pmm_policy_timer -{ - u32 timeout; /**< Timeout for this timer in ticks */ - mali_pmm_event_id event_id; /**< Event id that will be raised when timer expires */ - _mali_osk_timer_t *timer; /**< Timer */ - mali_bool set; /**< Timer set */ - mali_bool expired; /**< Timer expired - event needs to be raised */ - u32 start; /**< Timer start ticks */ -} _pmm_policy_timer_t; - -/** @brief Policy timer initialization - * - * This will create a timer for use in policies, but won't start it - * - * @param pptimer An empty timer structure to be initialized - * @param timeout Timeout in ticks for the timer - * @param id Event id that will be raised on timeout - * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 timeout, mali_pmm_event_id id ); - -/** @brief Policy timer termination - * - * This will clean up a timer that was previously used in policies, it - * will also stop it if started - * - * @param pptimer An initialized timer structure to be terminated - */ -void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer ); - -/** @brief Policy timer start - * - * This will start a previously created timer for use in policies - * When the timer expires after the initialized timeout it will raise - * a PMM event of the event id given on initialization - * As data for the event it will pass the start time of the timer - * - * @param pptimer A previously initialized policy timer - * @return MALI_TRUE if the timer was started, MALI_FALSE if it is already started - */ -mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer ); - -/** @brief Policy timer stop - * - * This will stop a previously created timer for use in policies - * - * @param pptimer A previously started policy timer - * @return MALI_TRUE if the timer was stopped, MALI_FALSE if it is already stopped - */ -mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer ); - -/** @brief Policy timer stop - * - * This raise an event for an expired timer - * - * @param pptimer An expired policy timer - * @return MALI_TRUE if an event was raised, else MALI_FALSE - */ -mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer ); - -/** @brief Policy timer valid checker - * - * This will check that a timer was started after a given time - * - * @param timer_start Time the timer was started - * @param other_start Time when another event or action occurred - * @return MALI_TRUE if the timer was started after the other time, else MALI_FALSE - */ -mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start ); - - -/** @brief Common policy initialization - * - * This will initialize the current policy - * - * @note Any previously initialized policy should be terminated first - * - * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_init( _mali_pmm_internal_state_t *pmm ); - -/** @brief Common policy termination - * - * This will terminate the current policy. - * @note This can be called when a policy has not been initialized - */ -void pmm_policy_term( _mali_pmm_internal_state_t *pmm ); - -/** @brief Common policy state changer - * - * Given the next available event message, this routine passes it to - * the current policy for processing - * - * @param pmm internal PMM state - * @param event PMM event to process - * @return _MALI_OSK_ERR_OK if the policy state completed okay, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_process( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ); - - -/** @brief Common policy checker - * - * If a policy timer fires then this function will be called to - * allow the policy to take the correct action - * - * @param pmm internal PMM state - */ -void pmm_policy_check_policy( _mali_pmm_internal_state_t *pmm ); - -/** @} */ /* End group pmmapi_policy */ -/** @} */ /* End group pmmapi */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_PMM_POLICY_H__ */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c deleted file mode 100644 index 0a6b471..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c +++ /dev/null @@ -1,80 +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. - */ - -/** - * @file mali_pmm_policy_alwayson.c - * Implementation of the power management module policy - always on - */ - -#if USING_MALI_PMM - -#include "mali_ukk.h" -#include "mali_kernel_common.h" - -#include "mali_pmm.h" -#include "mali_pmm_system.h" -#include "mali_pmm_state.h" -#include "mali_pmm_policy_alwayson.h" - -_mali_osk_errcode_t pmm_policy_init_always_on(void) -{ - /* Nothing to set up */ - MALI_SUCCESS; -} - -void pmm_policy_term_always_on(void) -{ - /* Nothing to tear down */ -} - -_mali_osk_errcode_t pmm_policy_process_always_on( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(event); - - switch( event->id ) - { - case MALI_PMM_EVENT_OS_POWER_DOWN: - /* We aren't going to do anything, but signal so we don't block the OS - * NOTE: This may adversely affect any jobs Mali is currently running - */ - _mali_osk_pmm_power_down_done( event->data ); - break; - - case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK: - case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK: - /* Not expected in this policy */ - MALI_DEBUG_ASSERT( MALI_FALSE ); - break; - - case MALI_PMM_EVENT_OS_POWER_UP: - /* Nothing to do */ - _mali_osk_pmm_power_up_done( event->data ); - break; - - case MALI_PMM_EVENT_JOB_SCHEDULED: - case MALI_PMM_EVENT_JOB_QUEUED: - case MALI_PMM_EVENT_JOB_FINISHED: - /* Nothing to do - we are always on */ - break; - - case MALI_PMM_EVENT_TIMEOUT: - /* Not expected in this policy */ - MALI_DEBUG_ASSERT( MALI_FALSE ); - break; - - default: - MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND); - } - - MALI_SUCCESS; -} - -#endif diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h deleted file mode 100644 index da13224..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h +++ /dev/null @@ -1,62 +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. - */ - -/** - * @file mali_pmm_policy_alwayson.h - * Defines the power management module policy for always on - */ - -#ifndef __MALI_PMM_POLICY_ALWAYSON_H__ -#define __MALI_PMM_POLICY_ALWAYSON_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup pmmapi_policy Power Management Module Policies - * - * @{ - */ - -/** @brief Always on policy initialization - * - * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_init_always_on(void); - -/** @brief Always on policy termination - */ -void pmm_policy_term_always_on(void); - -/** @brief Always on policy state changer - * - * Given the next available event message, this routine processes it - * for the policy and changes state as needed. - * - * Always on policy will ignore all events and keep the Mali cores on - * all the time - * - * @param pmm internal PMM state - * @param event PMM event to process - * @return _MALI_OSK_ERR_OK if the policy state completed okay, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_process_always_on( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ); - -/** @} */ /* End group pmmapi_policies */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_PMM_POLICY_ALWAYSON_H__ */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c deleted file mode 100644 index 237d702..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c +++ /dev/null @@ -1,470 +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. - */ - -/** - * @file mali_pmm_policy_jobcontrol.c - * Implementation of the power management module policy - job control - */ - -#if USING_MALI_PMM - -#include "mali_ukk.h" -#include "mali_kernel_common.h" -#include "mali_platform.h" - -#include "mali_pmm.h" -#include "mali_pmm_system.h" -#include "mali_pmm_state.h" -#include "mali_pmm_policy.h" -#include "mali_pmm_policy_jobcontrol.h" - -typedef struct _pmm_policy_data_job_control -{ - _pmm_policy_timer_t latency; /**< Latency timeout timer for all cores */ - u32 core_active_start; /**< Last time a core was set to active */ - u32 timeout; /**< Timeout in ticks for latency timer */ -} _pmm_policy_data_job_control_t; - - -/* @ brief Local data for this policy - */ -static _pmm_policy_data_job_control_t *data_job_control = NULL; - -/* @brief Set up the timeout if it hasn't already been set and if there are active cores */ -static void job_control_timeout_setup( _mali_pmm_internal_state_t *pmm, _pmm_policy_timer_t *pptimer ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(pptimer); - - /* Do we have an inactivity time out and some powered cores? */ - if( pptimer->timeout > 0 && pmm->cores_powered != 0 ) - { - /* Is the system idle and all the powered cores are idle? */ - if( pmm->status == MALI_PMM_STATUS_IDLE && pmm->cores_idle == pmm->cores_powered ) - { - if( pmm_policy_timer_start(pptimer) ) - { - MALIPMM_DEBUG_PRINT( ("PMM policy - Job control: Setting in-activity latency timer\n") ); - } - } - else - { - /* We are not idle so there is no need for an inactivity timer - */ - if( pmm_policy_timer_stop(pptimer) ) - { - MALIPMM_DEBUG_PRINT( ("PMM policy - Job control: Removing in-activity latency timer\n") ); - } - } - } -} - -/* @brief Check the validity of the timeout - and if there is one set */ -static mali_bool job_control_timeout_valid( _mali_pmm_internal_state_t *pmm, _pmm_policy_timer_t *pptimer, u32 timer_start ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(pptimer); - - /* Not a valid timer! */ - if( pptimer->timeout == 0 ) return MALI_FALSE; - - /* Are some cores powered and are they all idle? */ - if( (pmm->cores_powered != 0) && (pmm->cores_idle == pmm->cores_powered) ) - { - /* Has latency timeout started after the last core was active? */ - if( pmm_policy_timer_valid( timer_start, data_job_control->core_active_start ) ) - { - return MALI_TRUE; - } - else - { - MALIPMM_DEBUG_PRINT( ("PMM: In-activity latency time out ignored - out of date\n") ); - } - } - else - { - if( pmm->cores_powered == 0 ) - { - MALIPMM_DEBUG_PRINT( ("PMM: In-activity latency time out ignored - cores already off\n") ); - } - else - { - MALIPMM_DEBUG_PRINT( ("PMM: In-activity latency time out ignored - cores active\n") ); - } - } - - return MALI_FALSE; -} - -_mali_osk_errcode_t pmm_policy_init_job_control( _mali_pmm_internal_state_t *pmm ) -{ - _mali_osk_errcode_t err; - MALI_DEBUG_ASSERT_POINTER( pmm ); - MALI_DEBUG_ASSERT( data_job_control == NULL ); - - data_job_control = (_pmm_policy_data_job_control_t *) _mali_osk_malloc(sizeof(*data_job_control)); - MALI_CHECK_NON_NULL( data_job_control, _MALI_OSK_ERR_NOMEM ); - - data_job_control->core_active_start = _mali_osk_time_tickcount(); - data_job_control->timeout = MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT; - - err = pmm_policy_timer_init( &data_job_control->latency, data_job_control->timeout, MALI_PMM_EVENT_TIMEOUT ); - if( err != _MALI_OSK_ERR_OK ) - { - _mali_osk_free( data_job_control ); - data_job_control = NULL; - return err; - } - - /* Start the latency timeout */ - job_control_timeout_setup( pmm, &data_job_control->latency ); - - MALI_SUCCESS; -} - -void pmm_policy_term_job_control(void) -{ - if( data_job_control != NULL ) - { - pmm_policy_timer_term( &data_job_control->latency ); - _mali_osk_free( data_job_control ); - data_job_control = NULL; - } -} - -static void pmm_policy_job_control_job_queued( _mali_pmm_internal_state_t *pmm ) -{ - mali_pmm_core_mask cores; - mali_pmm_core_mask cores_subset; - - /* Make sure that all cores are powered in this - * simple policy - */ - cores = pmm->cores_registered; - cores_subset = pmm_cores_to_power_up( pmm, cores ); - if( cores_subset != 0 ) - { - /* There are some cores that need powering up */ - if( !pmm_invoke_power_up( pmm ) ) - { - /* Need to wait until finished */ - pmm->status = MALI_PMM_STATUS_POLICY_POWER_UP; - } - } -} - -_mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ) -{ - mali_pmm_core_mask cores; - mali_pmm_core_mask cores_subset; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(event); - MALI_DEBUG_ASSERT_POINTER(data_job_control); - - MALIPMM_DEBUG_PRINT( ("PMM: Job control policy process start - status=%d\n", pmm->status) ); - - /* Mainly the data is the cores */ - cores = pmm_cores_from_event_data( pmm, event ); - -#if MALI_STATE_TRACKING - pmm->mali_last_pmm_status = pmm->status; -#endif /* MALI_STATE_TRACKING */ - - switch( pmm->status ) - { - /**************** IDLE ****************/ - case MALI_PMM_STATUS_IDLE: - switch( event->id ) - { - case MALI_PMM_EVENT_OS_POWER_UP: - /* Not expected in this state */ - break; - - case MALI_PMM_EVENT_JOB_SCHEDULED: - - /* Update idle cores to indicate active - remove these! */ - pmm_cores_set_active( pmm, cores ); - /* Remember when this happened */ - data_job_control->core_active_start = event->ts; -#if MALI_POWER_MGMT_TEST_SUITE - _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_JOB_SCHEDULED); -#endif - - /*** FALL THROUGH to QUEUED to check POWER UP ***/ - - case MALI_PMM_EVENT_JOB_QUEUED: - - pmm_policy_job_control_job_queued( pmm ); -#if MALI_POWER_MGMT_TEST_SUITE - _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_JOB_QUEUED); -#endif - break; - - case MALI_PMM_EVENT_DVFS_PAUSE: - - cores_subset = pmm_cores_to_power_down( pmm, cores, MALI_FALSE ); - if ( cores_subset != 0 ) - { - if ( !pmm_power_down_okay( pmm ) ) - { - pmm->is_dvfs_active = 1; - pmm->status = MALI_PMM_STATUS_OS_POWER_DOWN; - pmm_save_os_event_data( pmm, event->data ); - break; - } - } - pmm->status = MALI_PMM_STATUS_DVFS_PAUSE; - _mali_osk_pmm_dvfs_operation_done(0); - break; - - case MALI_PMM_EVENT_OS_POWER_DOWN: - - /* Need to power down all cores even if we need to wait for them */ - cores_subset = pmm_cores_to_power_down( pmm, cores, MALI_FALSE ); - if( cores_subset != 0 ) - { - /* There are some cores that need powering down */ - if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) - { - /* We need to wait until they are idle */ - - pmm->status = MALI_PMM_STATUS_OS_POWER_DOWN; - /* Save the OS data to respond later */ - pmm_save_os_event_data( pmm, event->data ); - /* Exit this case - as we have to wait */ - break; - } - } - else - { - mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); - - } - /* Set waiting status */ - pmm->status = MALI_PMM_STATUS_OS_WAITING; - /* All cores now down - respond to OS power event */ - _mali_osk_pmm_power_down_done( event->data ); - break; - - case MALI_PMM_EVENT_JOB_FINISHED: - - /* Update idle cores - add these! */ - pmm_cores_set_idle( pmm, cores ); -#if MALI_POWER_MGMT_TEST_SUITE - _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_JOB_FINISHED); -#endif - if( data_job_control->timeout > 0 ) - { - /* Wait for time out to fire */ - break; - } - /* For job control policy - turn off all cores */ - cores = pmm->cores_powered; - - /*** FALL THROUGH to TIMEOUT TEST as NO TIMEOUT ***/ - - case MALI_PMM_EVENT_TIMEOUT: - - /* Main job control policy - turn off cores after inactivity */ - if( job_control_timeout_valid( pmm, &data_job_control->latency, (u32)event->data ) ) - { - /* Valid timeout of inactivity - so find out if we can power down - * immedately - if we can't then this means the cores are still in fact - * active - */ - cores_subset = pmm_cores_to_power_down( pmm, cores, MALI_TRUE ); - if( cores_subset != 0 ) - { - /* Check if we can really power down, if not then we are not - * really in-active - */ - if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_LIGHT_SLEEP ) ) - { - pmm_power_down_cancel( pmm ); - } - } - /* else there are no cores powered up! */ - } -#if MALI_POWER_MGMT_TEST_SUITE - _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_TIMEOUT); -#endif - break; - - default: - /* Unexpected event */ - MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND); - } - break; - - /******************DVFS PAUSE**************/ - case MALI_PMM_STATUS_DVFS_PAUSE: - switch ( event->id ) - { - case MALI_PMM_EVENT_DVFS_RESUME: - - if ( pmm->cores_powered != 0 ) - { - pmm->cores_ack_down =0; - pmm_power_down_cancel( pmm ); - pmm->status = MALI_PMM_STATUS_IDLE; - } - else - { - pmm_policy_job_control_job_queued( pmm ); - } - _mali_osk_pmm_dvfs_operation_done( 0 ); - break; - - case MALI_PMM_EVENT_OS_POWER_DOWN: - /* Set waiting status */ - pmm->status = MALI_PMM_STATUS_OS_WAITING; - if ( pmm->cores_powered != 0 ) - { - if ( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) - { - _mali_osk_pmm_power_down_done( 0 ); - break; - } - } - else - { - mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP); - } - _mali_osk_pmm_power_down_done( 0 ); - break; - default: - break; - } - break; - - /**************** POWER UP ****************/ - case MALI_PMM_STATUS_OS_POWER_UP: - case MALI_PMM_STATUS_POLICY_POWER_UP: - switch( event->id ) - { - case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK: - /* Make sure cores powered off equal what we expect */ - MALI_DEBUG_ASSERT( cores == pmm->cores_pend_up ); - pmm_cores_set_up_ack( pmm, cores ); - - if( pmm_invoke_power_up( pmm ) ) - { - if( pmm->status == MALI_PMM_STATUS_OS_POWER_UP ) - { - /* Get the OS data and respond to the power up */ - _mali_osk_pmm_power_up_done( pmm_retrieve_os_event_data( pmm ) ); - } - pmm->status = MALI_PMM_STATUS_IDLE; - } - break; - - default: - /* Unexpected event */ - MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND); - } - break; - - /**************** POWER DOWN ****************/ - case MALI_PMM_STATUS_OS_POWER_DOWN: - case MALI_PMM_STATUS_POLICY_POWER_DOWN: - switch( event->id ) - { - - case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK: - - pmm_cores_set_down_ack( pmm, cores ); - - if ( pmm->is_dvfs_active == 1 ) - { - if( pmm_power_down_okay( pmm ) ) - { - pmm->is_dvfs_active = 0; - pmm->status = MALI_PMM_STATUS_DVFS_PAUSE; - _mali_osk_pmm_dvfs_operation_done( pmm_retrieve_os_event_data( pmm ) ); - } - break; - } - - /* Now check if we can power down */ - if( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) ) - { - if( pmm->status == MALI_PMM_STATUS_OS_POWER_DOWN ) - { - /* Get the OS data and respond to the power down */ - _mali_osk_pmm_power_down_done( pmm_retrieve_os_event_data( pmm ) ); - } - pmm->status = MALI_PMM_STATUS_OS_WAITING; - } - break; - - default: - /* Unexpected event */ - MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND); - } - break; - - case MALI_PMM_STATUS_OS_WAITING: - switch( event->id ) - { - case MALI_PMM_EVENT_OS_POWER_UP: - cores_subset = pmm_cores_to_power_up( pmm, cores ); - if( cores_subset != 0 ) - { - /* There are some cores that need powering up */ - if( !pmm_invoke_power_up( pmm ) ) - { - /* Need to wait until power up complete */ - pmm->status = MALI_PMM_STATUS_OS_POWER_UP; - /* Save the OS data to respond later */ - pmm_save_os_event_data( pmm, event->data ); - /* Exit this case - as we have to wait */ - break; - } - } - pmm->status = MALI_PMM_STATUS_IDLE; - /* All cores now up - respond to OS power up event */ - _mali_osk_pmm_power_up_done( event->data ); - break; - - default: - /* All other messages are ignored in this state */ - break; - } - break; - - default: - /* Unexpected state */ - MALI_ERROR(_MALI_OSK_ERR_FAULT); - } - - /* Set in-activity latency timer - if required */ - job_control_timeout_setup( pmm, &data_job_control->latency ); - - /* Update the PMM state */ - pmm_update_system_state( pmm ); -#if MALI_STATE_TRACKING - pmm->mali_new_event_status = event->id; -#endif /* MALI_STATE_TRACKING */ - - MALIPMM_DEBUG_PRINT( ("PMM: Job control policy process end - status=%d and event=%d\n", pmm->status,event->id) ); - - MALI_SUCCESS; -} - -void pmm_policy_check_job_control() -{ - MALI_DEBUG_ASSERT_POINTER(data_job_control); - - /* Latency timer must have expired raise the event */ - pmm_policy_timer_raise_event(&data_job_control->latency); -} - - -#endif /* USING_MALI_PMM */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h deleted file mode 100644 index dcfa438..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h +++ /dev/null @@ -1,80 +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. - */ - -/** - * @file mali_pmm_policy.h - * Defines the power management module policies - */ - -#ifndef __MALI_PMM_POLICY_JOBCONTROL_H__ -#define __MALI_PMM_POLICY_JOBCONTROL_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup pmmapi_policy Power Management Module Policies - * - * @{ - */ - -/** @brief The jobcontrol policy inactivity latency timeout (in ticks) - * before the hardware is switched off - * - * @note Setting this low whilst tracing or producing debug output can - * cause alot of timeouts to fire which can affect the PMM behaviour - */ -#define MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT 50 - -/** @brief Job control policy initialization - * - * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_init_job_control(_mali_pmm_internal_state_t *pmm); - -/** @brief Job control policy termination - */ -void pmm_policy_term_job_control(void); - -/** @brief Job control policy state changer - * - * Given the next available event message, this routine processes it - * for the policy and changes state as needed. - * - * Job control policy depends on events from the Mali cores, and will - * power down all cores after an inactivity latency timeout. It will - * power the cores back on again when a job is scheduled to run. - * - * @param pmm internal PMM state - * @param event PMM event to process - * @return _MALI_OSK_ERR_OK if the policy state completed okay, or a suitable - * _mali_osk_errcode_t otherwise. - */ -_mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ); - -/** @brief Job control policy checker - * - * The latency timer has fired and we need to raise the correct event to - * handle it - * - * @param pmm internal PMM state - */ -void pmm_policy_check_job_control(void); - -/** @} */ /* End group pmmapi_policy */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_PMM_POLICY_JOBCONTROL_H__ */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c deleted file mode 100644 index d529b9a..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c +++ /dev/null @@ -1,716 +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. - */ - -#if USING_MALI_PMM - -#include "mali_ukk.h" -#include "mali_kernel_common.h" -#include "mali_kernel_subsystem.h" - -#include "mali_pmm.h" -#include "mali_pmm_state.h" -#include "mali_pmm_system.h" - -#include "mali_kernel_core.h" -#include "mali_platform.h" - -#define SIZEOF_CORES_LIST 6 - -/* NOTE: L2 *MUST* be first on the list so that it - * is correctly powered on first and powered off last - */ -static mali_pmm_core_id cores_list[] = { MALI_PMM_CORE_L2, - MALI_PMM_CORE_GP, - MALI_PMM_CORE_PP0, - MALI_PMM_CORE_PP1, - MALI_PMM_CORE_PP2, - MALI_PMM_CORE_PP3 }; - - - -void pmm_update_system_state( _mali_pmm_internal_state_t *pmm ) -{ - mali_pmm_state state; - - MALI_DEBUG_ASSERT_POINTER(pmm); - - if( pmm->cores_registered == 0 ) - { - state = MALI_PMM_STATE_UNAVAILABLE; - } - else if( pmm->cores_powered == 0 ) - { - state = MALI_PMM_STATE_SYSTEM_OFF; - } - else if( pmm->cores_powered == pmm->cores_registered ) - { - state = MALI_PMM_STATE_SYSTEM_ON; - } - else - { - /* Some other state where not everything is on or off */ - state = MALI_PMM_STATE_SYSTEM_TRANSITION; - } - -#if MALI_PMM_TRACE - _mali_pmm_trace_state_change( pmm->state, state ); -#endif - pmm->state = state; -} - -mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ) -{ - mali_pmm_core_mask cores; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_DEBUG_ASSERT_POINTER(event); - - switch( event->id ) - { - case MALI_PMM_EVENT_OS_POWER_UP: - case MALI_PMM_EVENT_OS_POWER_DOWN: - /* All cores - the system */ - cores = pmm->cores_registered; - break; - - case MALI_PMM_EVENT_JOB_SCHEDULED: - case MALI_PMM_EVENT_JOB_QUEUED: - case MALI_PMM_EVENT_JOB_FINISHED: - case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK: - case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK: - /* Currently the main event data is only the cores - * for these messages - */ - cores = (mali_pmm_core_mask)event->data; - if( cores == MALI_PMM_CORE_SYSTEM ) - { - cores = pmm->cores_registered; - } - else if( cores == MALI_PMM_CORE_PP_ALL ) - { - /* Get the subset of registered PP cores */ - cores = (pmm->cores_registered & MALI_PMM_CORE_PP_ALL); - } - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - break; - - default: - /* Assume timeout messages - report cores still powered */ - cores = pmm->cores_powered; - break; - } - - return cores; -} - -mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) -{ - mali_pmm_core_mask cores_subset; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - - /* Check that cores aren't pending power down when asked for power up */ - MALI_DEBUG_ASSERT( pmm->cores_pend_down == 0 ); - - cores_subset = (~(pmm->cores_powered) & cores); - if( cores_subset != 0 ) - { - /* There are some cores that need powering up */ - pmm->cores_pend_up = cores_subset; - } - - return cores_subset; -} - -mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only ) -{ - mali_pmm_core_mask cores_subset; - _mali_osk_errcode_t err; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - - /* Check that cores aren't pending power up when asked for power down */ - MALI_DEBUG_ASSERT( pmm->cores_pend_up == 0 ); - - cores_subset = (pmm->cores_powered & cores); - if( cores_subset != 0 ) - { - int n; - volatile mali_pmm_core_mask *ppowered = &(pmm->cores_powered); - - /* There are some cores that need powering up, but we may - * need to wait until they are idle - */ - for( n = SIZEOF_CORES_LIST-1; n >= 0; n-- ) - { - if( (cores_list[n] & cores_subset) != 0 ) - { - /* Core is to be powered down */ - pmm->cores_pend_down |= cores_list[n]; - - /* Can't hold the power lock, when acessing subsystem mutex via - * the core power call. - * Due to terminatation of driver requiring a subsystem mutex - * and then power lock held to unregister a core. - * This does mean that the following function could fail - * as the core is unregistered before we tell it to power - * down, but it does not matter as we are terminating - */ -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); - /* Signal the core to power down - * If it is busy (not idle) it will set a pending power down flag - * (as long as we don't want to only immediately power down). - * If it isn't busy it will move out of the idle queue right - * away - */ - err = mali_core_signal_power_down( cores_list[n], immediate_only ); - MALI_PMM_LOCK(pmm); - -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - - /* Re-read cores_subset in case it has changed */ - cores_subset = (*ppowered & cores); - - if( err == _MALI_OSK_ERR_OK ) - { - /* We moved an idle core to the power down queue - * which means it is now acknowledged (if it is still - * registered) - */ - pmm->cores_ack_down |= (cores_list[n] & cores_subset); - } - else - { - MALI_DEBUG_PRINT(1,("PMM: In pmm_cores_to_power_down, the error and cores powered are..%x....%x",err,*ppowered)); - MALI_DEBUG_ASSERT( err == _MALI_OSK_ERR_BUSY || - (err == _MALI_OSK_ERR_FAULT && - (*ppowered & cores_list[n]) == 0) ); - /* If we didn't move a core - it must be active, so - * leave it pending, so we get an acknowledgement (when - * not in immediate only mode) - * Alternatively we are shutting down and the core has - * been unregistered - */ - } - } - } - } - - return cores_subset; -} - -void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm ) -{ - int n; - mali_pmm_core_mask pd, ad; - _mali_osk_errcode_t err; - volatile mali_pmm_core_mask *pregistered; - - MALI_DEBUG_ASSERT_POINTER(pmm); - - MALIPMM_DEBUG_PRINT( ("PMM: Cancelling power down\n") ); - - pd = pmm->cores_pend_down; - ad = pmm->cores_ack_down; - /* Clear the pending cores so that they don't move to the off - * queue if they haven't already - */ - pmm->cores_pend_down = 0; - pmm->cores_ack_down = 0; - pregistered = &(pmm->cores_registered); - - /* Power up all the pending power down cores - just so - * we make sure the system is in a known state, as a - * pending core might have sent an acknowledged message - * which hasn't been read yet. - */ - for( n = 0; n < SIZEOF_CORES_LIST; n++ ) - { - if( (cores_list[n] & pd) != 0 ) - { - /* Can't hold the power lock, when acessing subsystem mutex via - * the core power call. - * Due to terminatation of driver requiring a subsystem mutex - * and then power lock held to unregister a core. - * This does mean that the following power up function could fail - * as the core is unregistered before we tell it to power - * up, but it does not matter as we are terminating - */ -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); - /* As we are cancelling - only move the cores back to the queue - - * no reset needed - */ - err = mali_core_signal_power_up( cores_list[n], MALI_TRUE ); - MALI_PMM_LOCK(pmm); -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - /* Update pending list with the current registered cores */ - pd &= (*pregistered); - - if( err != _MALI_OSK_ERR_OK ) - { - MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_BUSY && - ((cores_list[n] & ad) == 0)) || - (err == _MALI_OSK_ERR_FAULT && - (*pregistered & cores_list[n]) == 0) ); - /* If we didn't power up a core - it must be active and - * hasn't actually tried to power down - this is expected - * for cores that haven't acknowledged - * Alternatively we are shutting down and the core has - * been unregistered - */ - } - } - } - /* Only used in debug builds */ - MALI_IGNORE(ad); -} - - -mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - - return ( pmm->cores_pend_down == pmm->cores_ack_down ? MALI_TRUE : MALI_FALSE ); -} - -mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode ) -{ - _mali_osk_errcode_t err; - MALI_DEBUG_ASSERT_POINTER(pmm); - - /* Check that cores are pending power down during power down invoke */ - MALI_DEBUG_ASSERT( pmm->cores_pend_down != 0 ); - /* Check that cores are not pending power up during power down invoke */ - MALI_DEBUG_ASSERT( pmm->cores_pend_up == 0 ); - - if( !pmm_power_down_okay( pmm ) ) - { - MALIPMM_DEBUG_PRINT( ("PMM: Waiting for cores to go idle for power off - 0x%08x / 0x%08x\n", - pmm->cores_pend_down, pmm->cores_ack_down) ); - return MALI_FALSE; - } - else - { - pmm->cores_powered &= ~(pmm->cores_pend_down); -#if !MALI_PMM_NO_PMU - err = malipmm_powerdown( pmm->cores_pend_down, power_mode); -#else - err = _MALI_OSK_ERR_OK; -#endif - - if( err == _MALI_OSK_ERR_OK ) - { -#if MALI_PMM_TRACE - mali_pmm_core_mask old_power = pmm->cores_powered; -#endif - /* Remove powered down cores from idle and powered list */ - pmm->cores_idle &= ~(pmm->cores_pend_down); - /* Reset pending/acknowledged status */ - pmm->cores_pend_down = 0; - pmm->cores_ack_down = 0; -#if MALI_PMM_TRACE - _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); -#endif - } - else - { - pmm->cores_powered |= pmm->cores_pend_down; - MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power down cores - (0x%x) %s", - pmm->cores_pend_down, pmm_trace_get_core_name(pmm->cores_pend_down)) ); - pmm->fatal_power_err = MALI_TRUE; - } - } - - return MALI_TRUE; -} - - -mali_bool pmm_power_up_okay( _mali_pmm_internal_state_t *pmm ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - - return ( pmm->cores_pend_up == pmm->cores_ack_up ? MALI_TRUE : MALI_FALSE ); -} - - -mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm ) -{ - _mali_osk_errcode_t err; - - MALI_DEBUG_ASSERT_POINTER(pmm); - - /* Check that cores are pending power up during power up invoke */ - MALI_DEBUG_ASSERT( pmm->cores_pend_up != 0 ); - /* Check that cores are not pending power down during power up invoke */ - MALI_DEBUG_ASSERT( pmm->cores_pend_down == 0 ); - - if( pmm_power_up_okay( pmm ) ) - { - /* Power up has completed - sort out subsystem core status */ - - int n; - /* Use volatile to access, so that it is updated if any cores are unregistered */ - volatile mali_pmm_core_mask *ppendup = &(pmm->cores_pend_up); -#if MALI_PMM_TRACE - mali_pmm_core_mask old_power = pmm->cores_powered; -#endif - /* Move cores into idle queues */ - for( n = 0; n < SIZEOF_CORES_LIST; n++ ) - { - if( (cores_list[n] & (*ppendup)) != 0 ) - { - /* Can't hold the power lock, when acessing subsystem mutex via - * the core power call. - * Due to terminatation of driver requiring a subsystem mutex - * and then power lock held to unregister a core. - * This does mean that the following function could fail - * as the core is unregistered before we tell it to power - * up, but it does not matter as we are terminating - */ -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); - err = mali_core_signal_power_up( cores_list[n], MALI_FALSE ); - MALI_PMM_LOCK(pmm); - -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - - if( err != _MALI_OSK_ERR_OK ) - { - MALI_DEBUG_PRINT(1,("In pmm_invoke_power_up:: The error and pending cores to be powered up are...%x...%x",err,*ppendup)); - MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_FAULT && - (*ppendup & cores_list[n]) == 0) ); - /* We only expect this to fail when we are shutting down - * and the core has been unregistered - */ - } - } - } - /* Finished power up - add cores to idle and powered list */ - pmm->cores_powered |= (*ppendup); - pmm->cores_idle |= (*ppendup); - /* Reset pending/acknowledge status */ - pmm->cores_pend_up = 0; - pmm->cores_ack_up = 0; - -#if MALI_PMM_TRACE - _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); -#endif - return MALI_TRUE; - } - else - { -#if !MALI_PMM_NO_PMU - /* Power up must now be done */ - err = malipmm_powerup( pmm->cores_pend_up ); -#else - err = _MALI_OSK_ERR_OK; -#endif - if( err != _MALI_OSK_ERR_OK ) - { - MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power up cores - (0x%x) %s", - pmm->cores_pend_up, pmm_trace_get_core_name(pmm->cores_pend_up)) ); - pmm->fatal_power_err = MALI_TRUE; - } - else - { - /* TBD - Update core status immediately rather than use event message */ - _mali_uk_pmm_message_s event = { - NULL, - MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK, - 0 }; - /* All the cores that were pending power up, have now completed power up */ - event.data = pmm->cores_pend_up; - _mali_ukk_pmm_event_message( &event ); - MALIPMM_DEBUG_PRINT( ("PMM: Sending ACK to power up") ); - } - } - - /* Always return false, as we need an interrupt to acknowledge - * when power up is complete - */ - return MALI_FALSE; -} - -mali_pmm_core_mask pmm_cores_set_active( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - - pmm->cores_idle &= (~cores); - return pmm->cores_idle; -} - -mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - - pmm->cores_idle |= (cores); - return pmm->cores_idle; -} - -mali_pmm_core_mask pmm_cores_set_down_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - - /* Check core is not pending a power down */ - MALI_DEBUG_ASSERT( (pmm->cores_pend_down & cores) != 0 ); - /* Check core has not acknowledged power down more than once */ - MALI_DEBUG_ASSERT( (pmm->cores_ack_down & cores) == 0 ); - - pmm->cores_ack_down |= (cores); - - return pmm->cores_ack_down; -} - -void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm ) -{ - _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; - _mali_osk_notification_t *msg = NULL; - mali_pmm_status status; - MALI_DEBUG_ASSERT_POINTER(pmm); - MALIPMM_DEBUG_PRINT( ("PMM: Fatal Reset called") ); - - MALI_DEBUG_ASSERT( pmm->status != MALI_PMM_STATUS_OFF ); - - /* Reset the common status */ - pmm->waiting = 0; - pmm->missed = 0; - pmm->fatal_power_err = MALI_FALSE; - pmm->no_events = 0; - pmm->check_policy = MALI_FALSE; - pmm->cores_pend_down = 0; - pmm->cores_pend_up = 0; - pmm->cores_ack_down = 0; - pmm->cores_ack_up = 0; - pmm->is_dvfs_active = 0; -#if MALI_PMM_TRACE - pmm->messages_sent = 0; - pmm->messages_received = 0; - pmm->imessages_sent = 0; - pmm->imessages_received = 0; - MALI_PRINT( ("PMM Trace: *** Fatal reset occurred ***") ); -#endif - - /* Set that we are unavailable whilst resetting */ - pmm->state = MALI_PMM_STATE_UNAVAILABLE; - status = pmm->status; - pmm->status = MALI_PMM_STATUS_OFF; - - /* We want all cores powered */ - pmm->cores_powered = pmm->cores_registered; - /* The cores may not be idle, but this state will be rectified later */ - pmm->cores_idle = pmm->cores_registered; - - /* So power on any cores that are registered */ - if( pmm->cores_registered != 0 ) - { - int n; - volatile mali_pmm_core_mask *pregistered = &(pmm->cores_registered); -#if !MALI_PMM_NO_PMU - err = malipmm_powerup( pmm->cores_registered ); -#endif - if( err != _MALI_OSK_ERR_OK ) - { - /* This is very bad as we can't even be certain the cores are now - * powered up - */ - MALI_PRINT_ERROR( ("PMM: Failed to perform PMM reset!\n") ); - /* TBD driver exit? */ - } - - for( n = SIZEOF_CORES_LIST-1; n >= 0; n-- ) - { - if( (cores_list[n] & (*pregistered)) != 0 ) - { -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 0; -#endif /* MALI_STATE_TRACKING */ - - MALI_PMM_UNLOCK(pmm); - /* Core is now active - so try putting it in the idle queue */ - err = mali_core_signal_power_up( cores_list[n], MALI_FALSE ); - MALI_PMM_LOCK(pmm); -#if MALI_STATE_TRACKING - pmm->mali_pmm_lock_acquired = 1; -#endif /* MALI_STATE_TRACKING */ - - /* We either succeeded, or we were not off anyway, or we have - * just be deregistered - */ - MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_OK) || - (err == _MALI_OSK_ERR_BUSY) || - (err == _MALI_OSK_ERR_FAULT && - (*pregistered & cores_list[n]) == 0) ); - } - } - } - - /* Unblock any pending OS event */ - if( status == MALI_PMM_STATUS_OS_POWER_UP ) - { - /* Get the OS data and respond to the power up */ - _mali_osk_pmm_power_up_done( pmm_retrieve_os_event_data( pmm ) ); - } - if( status == MALI_PMM_STATUS_OS_POWER_DOWN ) - { - /* Get the OS data and respond to the power down - * NOTE: We are not powered down at this point due to power problems, - * so we are lying to the system, but something bad has already - * happened and we are trying unstick things - * TBD - Add busy loop to power down cores? - */ - _mali_osk_pmm_power_down_done( pmm_retrieve_os_event_data( pmm ) ); - } - - /* Purge the event queues */ - do - { - if( _mali_osk_notification_queue_dequeue( pmm->iqueue, &msg ) == _MALI_OSK_ERR_OK ) - { - _mali_osk_notification_delete ( msg ); - break; - } - } while (MALI_TRUE); - - do - { - if( _mali_osk_notification_queue_dequeue( pmm->queue, &msg ) == _MALI_OSK_ERR_OK ) - { - _mali_osk_notification_delete ( msg ); - break; - } - } while (MALI_TRUE); - - /* Return status/state to normal */ - pmm->status = MALI_PMM_STATUS_IDLE; - pmm_update_system_state(pmm); -} - -mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores ); - - /* Check core is not pending a power up */ - MALI_DEBUG_ASSERT( (pmm->cores_pend_up & cores) != 0 ); - /* Check core has not acknowledged power up more than once */ - MALI_DEBUG_ASSERT( (pmm->cores_ack_up & cores) == 0 ); - - pmm->cores_ack_up |= (cores); - - return pmm->cores_ack_up; -} - -void pmm_save_os_event_data(_mali_pmm_internal_state_t *pmm, mali_pmm_message_data data) -{ - MALI_DEBUG_ASSERT_POINTER(pmm); - /* Check that there is no saved data */ - MALI_DEBUG_ASSERT( pmm->os_data == 0 ); - /* Can't store zero data - as retrieve check will fail */ - MALI_DEBUG_ASSERT( data != 0 ); - - pmm->os_data = data; -} - -mali_pmm_message_data pmm_retrieve_os_event_data(_mali_pmm_internal_state_t *pmm) -{ - mali_pmm_message_data data; - - MALI_DEBUG_ASSERT_POINTER(pmm); - /* Check that there is saved data */ - MALI_DEBUG_ASSERT( pmm->os_data != 0 ); - - /* Get data, and clear the saved version */ - data = pmm->os_data; - pmm->os_data = 0; - - return data; -} - -/* Create list of core names to look up - * We are doing it this way to overcome the need for - * either string allocation, or stack space, so we - * use constant strings instead - */ -typedef struct pmm_trace_corelist -{ - mali_pmm_core_mask id; - const char *name; -} pmm_trace_corelist_t; - -static pmm_trace_corelist_t pmm_trace_cores[] = { - { MALI_PMM_CORE_SYSTEM, "SYSTEM" }, - { MALI_PMM_CORE_GP, "GP" }, - { MALI_PMM_CORE_L2, "L2" }, - { MALI_PMM_CORE_PP0, "PP0" }, - { MALI_PMM_CORE_PP1, "PP1" }, - { MALI_PMM_CORE_PP2, "PP2" }, - { MALI_PMM_CORE_PP3, "PP3" }, - { MALI_PMM_CORE_PP_ALL, "PP (all)" }, - { (MALI_PMM_CORE_GP | MALI_PMM_CORE_L2 | MALI_PMM_CORE_PP0), - "GP+L2+PP0" }, - { (MALI_PMM_CORE_GP | MALI_PMM_CORE_PP0), - "GP+PP0" }, - { (MALI_PMM_CORE_GP | MALI_PMM_CORE_L2 | MALI_PMM_CORE_PP0 | MALI_PMM_CORE_PP1), - "GP+L2+PP0+PP1" }, - { (MALI_PMM_CORE_GP | MALI_PMM_CORE_PP0 | MALI_PMM_CORE_PP1), - "GP+PP0+PP1" }, - { 0, NULL } /* Terminator of list */ -}; - -const char *pmm_trace_get_core_name( mali_pmm_core_mask cores ) -{ - const char *dname = NULL; - int cl; - - /* Look up name in corelist */ - cl = 0; - while( pmm_trace_cores[cl].name != NULL ) - { - if( pmm_trace_cores[cl].id == cores ) - { - dname = pmm_trace_cores[cl].name; - break; - } - cl++; - } - - if( dname == NULL ) - { - /* We don't know a good short-hand for the configuration */ - dname = "[multi-core]"; - } - - return dname; -} - -#endif /* USING_MALI_PMM */ - diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h deleted file mode 100644 index 4768344..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h +++ /dev/null @@ -1,290 +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 __MALI_PMM_STATE_H__ -#define __MALI_PMM_STATE_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup pmmapi Power Management Module APIs - * - * @{ - * - * @defgroup pmmapi_state Power Management Module State - * - * @{ - */ - -/* Check that the subset is really a subset of cores */ -#define MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( cores, subset ) \ - MALI_DEBUG_ASSERT( ((~(cores)) & (subset)) == 0 ) - - -/* Locking macros */ -#define MALI_PMM_LOCK(pmm) \ - _mali_osk_lock_wait( pmm->lock, _MALI_OSK_LOCKMODE_RW ) -#define MALI_PMM_UNLOCK(pmm) \ - _mali_osk_lock_signal( pmm->lock, _MALI_OSK_LOCKMODE_RW ) -#define MALI_PMM_LOCK_TERM(pmm) \ - _mali_osk_lock_term( pmm->lock ) - -/* Notification type for messages */ -#define MALI_PMM_NOTIFICATION_TYPE 0 - -/** @brief Status of the PMM state machine - */ -typedef enum mali_pmm_status_tag -{ - MALI_PMM_STATUS_IDLE, /**< PMM is waiting next event */ - MALI_PMM_STATUS_POLICY_POWER_DOWN, /**< Policy initiated power down */ - MALI_PMM_STATUS_POLICY_POWER_UP, /**< Policy initiated power down */ - MALI_PMM_STATUS_OS_WAITING, /**< PMM is waiting for OS power up */ - MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */ - MALI_PMM_STATUS_DVFS_PAUSE, /**< PMM DVFS Status Pause */ - MALI_PMM_STATUS_OS_POWER_UP, /**< OS initiated power up */ - MALI_PMM_STATUS_OFF, /**< PMM is not active */ -} mali_pmm_status; - - -/** @brief Internal state of the PMM - */ -typedef struct _mali_pmm_internal_state -{ - mali_pmm_status status; /**< PMM state machine */ - mali_pmm_policy policy; /**< PMM policy */ - mali_bool check_policy; /**< PMM policy needs checking */ - mali_pmm_state state; /**< PMM state */ - mali_pmm_core_mask cores_registered; /**< Bitmask of cores registered */ - mali_pmm_core_mask cores_powered; /**< Bitmask of cores powered up */ - mali_pmm_core_mask cores_idle; /**< Bitmask of cores idle */ - mali_pmm_core_mask cores_pend_down; /**< Bitmask of cores pending power down */ - mali_pmm_core_mask cores_pend_up; /**< Bitmask of cores pending power up */ - mali_pmm_core_mask cores_ack_down; /**< Bitmask of cores acknowledged power down */ - mali_pmm_core_mask cores_ack_up; /**< Bitmask of cores acknowledged power up */ - - _mali_osk_notification_queue_t *queue; /**< PMM event queue */ - _mali_osk_notification_queue_t *iqueue; /**< PMM internal event queue */ - _mali_osk_irq_t *irq; /**< PMM irq handler */ - _mali_osk_lock_t *lock; /**< PMM lock */ - - mali_pmm_message_data os_data; /**< OS data sent via the OS events */ - - mali_bool pmu_initialized; /**< PMU initialized */ - - _mali_osk_atomic_t messages_queued; /**< PMM event messages queued */ - u32 waiting; /**< PMM waiting events - due to busy */ - u32 no_events; /**< PMM called to process when no events */ - - u32 missed; /**< PMM missed events due to OOM */ - mali_bool fatal_power_err; /**< PMM has had a fatal power error? */ - u32 is_dvfs_active; /**< PMM DVFS activity */ - -#if MALI_STATE_TRACKING - mali_pmm_status mali_last_pmm_status; /**< The previous PMM status */ - mali_pmm_event_id mali_new_event_status;/**< The type of the last PMM event */ - mali_bool mali_pmm_lock_acquired; /**< Is the PMM lock held somewhere or not */ -#endif - -#if (MALI_PMM_TRACE || MALI_STATE_TRACKING) - u32 messages_sent; /**< Total event messages sent */ - u32 messages_received; /**< Total event messages received */ - u32 imessages_sent; /**< Total event internal messages sent */ - u32 imessages_received; /**< Total event internal messages received */ -#endif -} _mali_pmm_internal_state_t; - -/** @brief Sets that a policy needs a check before processing events - * - * A timer or something has expired that needs dealing with - */ -void malipmm_set_policy_check(void); - -/** @brief Update the PMM externally viewable state depending on the current PMM internal state - * - * @param pmm internal PMM state - * @return MALI_TRUE if the timeout is valid, else MALI_FALSE - */ -void pmm_update_system_state( _mali_pmm_internal_state_t *pmm ); - -/** @brief Returns the core mask from the event data - if applicable - * - * @param pmm internal PMM state - * @param event event message to get the core mask from - * @return mask of cores that is relevant to this event message - */ -mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event ); - -/** @brief Sort out which cores need to be powered up from the given core mask - * - * All cores that can be powered up will be put into a pending state - * - * @param pmm internal PMM state - * @param cores mask of cores to check if they need to be powered up - * @return mask of cores that need to be powered up, this can be 0 if all cores - * are powered up already - */ -mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); - -/** @brief Sort out which cores need to be powered down from the given core mask - * - * All cores that can be powered down will be put into a pending state. If they - * can be powered down immediately they will also be acknowledged that they can be - * powered down. If the immediate_only flag is set, then only those cores that - * can be acknowledged for power down will be put into a pending state. - * - * @param pmm internal PMM state - * @param cores mask of cores to check if they need to be powered down - * @param immediate_only MALI_TRUE means that only cores that can power down now will - * be put into a pending state - * @return mask of cores that need to be powered down, this can be 0 if all cores - * are powered down already - */ -mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only ); - -/** @brief Cancel an invokation to power down (pmm_invoke_power_down) - * - * @param pmm internal PMM state - */ -void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm ); - -/** @brief Check if a call to invoke power down should succeed, or fail - * - * This will report MALI_FALSE if some of the cores are still active and need - * to acknowledge that they are ready to power down - * - * @param pmm internal PMM state - * @return MALI_TRUE if the pending cores to power down have acknowledged they - * can power down, else MALI_FALSE - */ -mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm ); - -/** @brief Try to make all the pending cores power down - * - * If all the pending cores have acknowledged they can power down, this will call the - * PMU power down function to turn them off - * - * @param pmm internal PMM state - * @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE - */ -mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode ); - -/** @brief Check if all the pending cores to power up have done so - * - * This will report MALI_FALSE if some of the cores are still powered off - * and have not acknowledged that they have powered up - * - * @param pmm internal PMM state - * @return MALI_TRUE if the pending cores to power up have acknowledged they - * are now powered up, else MALI_FALSE - */ -mali_bool pmm_power_up_okay( _mali_pmm_internal_state_t *pmm ); - -/** @brief Try to make all the pending cores power up - * - * If all the pending cores have acknowledged they have powered up, this will - * make the cores start processing jobs again, else this will call the PMU - * power up function to turn them on, and the PMM is then expected to wait for an - * interrupt to acknowledge the power up - * - * @param pmm internal PMM state - * @return MALI_TRUE if the pending cores have been powered up, else MALI_FALSE - */ -mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm ); - -/** @brief Set the cores that are now active in the system - * - * Updates which cores are active and returns which cores are still idle - * - * @param pmm internal PMM state - * @param cores mask of cores to set to active - * @return mask of all the cores that are idle - */ -mali_pmm_core_mask pmm_cores_set_active( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); - -/** @brief Set the cores that are now idle in the system - * - * Updates which cores are idle and returns which cores are still idle - * - * @param pmm internal PMM state - * @param cores mask of cores to set to idle - * @return mask of all the cores that are idle - */ -mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); - -/** @brief Set the cores that have acknowledged a pending power down - * - * Updates which cores have acknowledged the pending power down and are now ready - * to be turned off - * - * @param pmm internal PMM state - * @param cores mask of cores that have acknowledged the pending power down - * @return mask of all the cores that have acknowledged the power down - */ -mali_pmm_core_mask pmm_cores_set_down_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); - -/** @brief Set the cores that have acknowledged a pending power up - * - * Updates which cores have acknowledged the pending power up and are now - * fully powered and ready to run jobs - * - * @param pmm internal PMM state - * @param cores mask of cores that have acknowledged the pending power up - * @return mask of all the cores that have acknowledged the power up - */ -mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores ); - - -/** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues - * - * This will try and make all the cores powered up and reset the PMM state - * to its initial state after core registration - all cores powered but not - * pending or active. - * All events in the event queues will be thrown away. - * - * @note: Any pending power down will be cancelled including the OS calling for power down - */ -void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm ); - -/** @brief Save the OS specific data for an OS power up/down event - * - * @param pmm internal PMM state - * @param data OS specific event data - */ -void pmm_save_os_event_data(_mali_pmm_internal_state_t *pmm, mali_pmm_message_data data); - -/** @brief Retrieve the OS specific data for an OS power up/down event - * - * This will clear the stored OS data, as well as return it. - * - * @param pmm internal PMM state - * @return OS specific event data that was saved previously - */ -mali_pmm_message_data pmm_retrieve_os_event_data(_mali_pmm_internal_state_t *pmm); - - -/** @brief Get a human readable name for the cores in a core mask - * - * @param core the core mask - * @return string containing a name relating to the given core mask - */ -const char *pmm_trace_get_core_name( mali_pmm_core_mask core ); - -/** @} */ /* End group pmmapi_state */ -/** @} */ /* End group pmmapi */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_PMM_STATE_H__ */ diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h deleted file mode 100644 index eccd35b..0000000 --- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h +++ /dev/null @@ -1,61 +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 __MALI_PMM_SYSTEM_H__ -#define __MALI_PMM_SYSTEM_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @addtogroup pmmapi Power Management Module APIs - * - * @{ - * - * @defgroup pmmapi_system Power Management Module System Functions - * - * @{ - */ - -extern struct mali_kernel_subsystem mali_subsystem_pmm; - -/** @brief Register a core with the PMM, which will power up - * the core - * - * @param core the core to register with the PMM - * @return error if the core cannot be powered up - */ -_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core ); - -/** @brief Unregister a core with the PMM - * - * @param core the core to unregister with the PMM - */ -void malipmm_core_unregister( mali_pmm_core_id core ); - -/** @brief Acknowledge that a power down is okay to happen - * - * A core should not be running a job, or be in the idle queue when this - * is called. - * - * @param core the core that can now be powered down - */ -void malipmm_core_power_down_okay( mali_pmm_core_id core ); - -/** @} */ /* End group pmmapi_system */ -/** @} */ /* End group pmmapi */ - -#ifdef __cplusplus -} -#endif - -#endif /* __MALI_PMM_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 new file mode 100644 index 0000000..7c78947 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h @@ -0,0 +1,28 @@ +/* + * 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/include/linux/mali/mali_utgard_counters.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h new file mode 100644 index 0000000..40822f7 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h @@ -0,0 +1,264 @@ +/* + * 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_COUNTERS_H_ +#define _MALI_UTGARD_COUNTERS_H_ + +typedef struct +{ + void *unused; +} mali_cinstr_counter_info; + +typedef enum +{ + MALI_CINSTR_COUNTER_SOURCE_EGL = 0, + MALI_CINSTR_COUNTER_SOURCE_OPENGLES = 1000, + MALI_CINSTR_COUNTER_SOURCE_OPENVG = 2000, + MALI_CINSTR_COUNTER_SOURCE_GP = 3000, + MALI_CINSTR_COUNTER_SOURCE_PP = 4000, +} cinstr_counter_source; + +#define MALI_CINSTR_EGL_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_EGL +#define MALI_CINSTR_EGL_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_EGL + 999) + +#define MALI_CINSTR_GLES_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENGLES +#define MALI_CINSTR_GLES_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 999) + +#define MALI_CINSTR_VG_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENVG +#define MALI_CINSTR_VG_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENVG + 999) + +#define MALI_CINSTR_GP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_GP +#define MALI_CINSTR_GP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_GP + 999) + +#define MALI_CINSTR_PP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_PP +#define MALI_CINSTR_PP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_PP + 999) + + +typedef enum +{ + /* EGL counters */ + + MALI_CINSTR_EGL_BLIT_TIME = MALI_CINSTR_COUNTER_SOURCE_EGL + 0, + + /* Last counter in the EGL set */ + MALI_CINSTR_EGL_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_EGL + 1, + + /* GLES counters */ + + MALI_CINSTR_GLES_DRAW_ELEMENTS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 0, + MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_INDICES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 1, + MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 2, + MALI_CINSTR_GLES_DRAW_ARRAYS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 3, + MALI_CINSTR_GLES_DRAW_ARRAYS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 4, + MALI_CINSTR_GLES_DRAW_POINTS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 5, + MALI_CINSTR_GLES_DRAW_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 6, + MALI_CINSTR_GLES_DRAW_LINE_LOOP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 7, + MALI_CINSTR_GLES_DRAW_LINE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 8, + MALI_CINSTR_GLES_DRAW_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 9, + MALI_CINSTR_GLES_DRAW_TRIANGLE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 10, + MALI_CINSTR_GLES_DRAW_TRIANGLE_FAN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 11, + MALI_CINSTR_GLES_NON_VBO_DATA_COPY_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 12, + MALI_CINSTR_GLES_UNIFORM_BYTES_COPIED_TO_MALI = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 13, + MALI_CINSTR_GLES_UPLOAD_TEXTURE_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 14, + MALI_CINSTR_GLES_UPLOAD_VBO_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 15, + MALI_CINSTR_GLES_NUM_FLUSHES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 16, + MALI_CINSTR_GLES_NUM_VSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 17, + MALI_CINSTR_GLES_NUM_FSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 18, + MALI_CINSTR_GLES_VSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 19, + MALI_CINSTR_GLES_FSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 20, + MALI_CINSTR_GLES_INPUT_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 21, + MALI_CINSTR_GLES_VXCACHE_HIT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 22, + MALI_CINSTR_GLES_VXCACHE_MISS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 23, + MALI_CINSTR_GLES_VXCACHE_COLLISION = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 24, + MALI_CINSTR_GLES_CULLED_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 25, + MALI_CINSTR_GLES_CULLED_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 26, + MALI_CINSTR_GLES_BACKFACE_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 27, + MALI_CINSTR_GLES_GBCLIP_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 28, + MALI_CINSTR_GLES_GBCLIP_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 29, + MALI_CINSTR_GLES_TRIANGLES_DRAWN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 30, + MALI_CINSTR_GLES_DRAWCALL_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 31, + MALI_CINSTR_GLES_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 32, + MALI_CINSTR_GLES_INDEPENDENT_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 33, + MALI_CINSTR_GLES_STRIP_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 34, + MALI_CINSTR_GLES_FAN_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 35, + MALI_CINSTR_GLES_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 36, + MALI_CINSTR_GLES_INDEPENDENT_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 37, + MALI_CINSTR_GLES_STRIP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 38, + MALI_CINSTR_GLES_LOOP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 39, + MALI_CINSTR_GLES_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 40, + + /* Last counter in the GLES set */ + MALI_CINSTR_GLES_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 41, + + /* OpenVG counters */ + + MALI_CINSTR_VG_MASK_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 0, + MALI_CINSTR_VG_CLEAR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 1, + MALI_CINSTR_VG_APPEND_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 2, + MALI_CINSTR_VG_APPEND_PATH_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 3, + MALI_CINSTR_VG_MODIFY_PATH_COORDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 4, + MALI_CINSTR_VG_TRANSFORM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 5, + MALI_CINSTR_VG_INTERPOLATE_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 6, + MALI_CINSTR_VG_PATH_LENGTH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 7, + MALI_CINSTR_VG_POINT_ALONG_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 8, + MALI_CINSTR_VG_PATH_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 9, + MALI_CINSTR_VG_PATH_TRANSFORMED_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 10, + MALI_CINSTR_VG_DRAW_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 11, + MALI_CINSTR_VG_CLEAR_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 12, + MALI_CINSTR_VG_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 13, + MALI_CINSTR_VG_GET_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 14, + MALI_CINSTR_VG_COPY_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 15, + MALI_CINSTR_VG_DRAW_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 16, + MALI_CINSTR_VG_SET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 17, + MALI_CINSTR_VG_WRITE_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 18, + MALI_CINSTR_VG_GET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 19, + MALI_CINSTR_VG_READ_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 20, + MALI_CINSTR_VG_COPY_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 21, + MALI_CINSTR_VG_COLOR_MATRIX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 22, + MALI_CINSTR_VG_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 23, + MALI_CINSTR_VG_SEPARABLE_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 24, + MALI_CINSTR_VG_GAUSSIAN_BLUR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 25, + MALI_CINSTR_VG_LOOKUP_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 26, + MALI_CINSTR_VG_LOOKUP_SINGLE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 27, + MALI_CINSTR_VG_CONTEXT_CREATE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 28, + MALI_CINSTR_VG_STROKED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 29, + MALI_CINSTR_VG_STROKED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 30, + MALI_CINSTR_VG_STROKED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 31, + MALI_CINSTR_VG_STROKED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 32, + MALI_CINSTR_VG_FILLED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 33, + MALI_CINSTR_VG_FILLED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 34, + MALI_CINSTR_VG_FILLED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 35, + MALI_CINSTR_VG_FILLED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 36, + MALI_CINSTR_VG_DRAW_PATH_CALLS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 37, + MALI_CINSTR_VG_TRIANGLES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 38, + MALI_CINSTR_VG_VERTICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 39, + MALI_CINSTR_VG_INDICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 40, + MALI_CINSTR_VG_FILLED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 41, + MALI_CINSTR_VG_STROKED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 42, + MALI_CINSTR_VG_FILL_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 43, + MALI_CINSTR_VG_DRAW_FILLED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 44, + MALI_CINSTR_VG_STROKE_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 45, + MALI_CINSTR_VG_DRAW_STROKED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 46, + MALI_CINSTR_VG_DRAW_PAINT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 47, + MALI_CINSTR_VG_DATA_STRUCTURES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 48, + MALI_CINSTR_VG_MEM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 49, + MALI_CINSTR_VG_RSW_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 50, + + /* Last counter in the VG set */ + MALI_CINSTR_VG_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 51, + + /* Mali GP counters */ + + MALI_CINSTR_GP_DEPRECATED_0 = MALI_CINSTR_COUNTER_SOURCE_GP + 0, + MALI_CINSTR_GP_ACTIVE_CYCLES_GP = MALI_CINSTR_COUNTER_SOURCE_GP + 1, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 2, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_STORER = MALI_CINSTR_COUNTER_SOURCE_GP + 3, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_LOADER = MALI_CINSTR_COUNTER_SOURCE_GP + 4, + MALI_CINSTR_GP_CYCLES_VERTEX_LOADER_WAITING_FOR_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 5, + MALI_CINSTR_GP_NUMBER_OF_WORDS_READ = MALI_CINSTR_COUNTER_SOURCE_GP + 6, + MALI_CINSTR_GP_NUMBER_OF_WORDS_WRITTEN = MALI_CINSTR_COUNTER_SOURCE_GP + 7, + MALI_CINSTR_GP_NUMBER_OF_READ_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 8, + MALI_CINSTR_GP_NUMBER_OF_WRITE_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 9, + MALI_CINSTR_GP_NUMBER_OF_VERTICES_PROCESSED = MALI_CINSTR_COUNTER_SOURCE_GP + 10, + MALI_CINSTR_GP_NUMBER_OF_VERTICES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 11, + MALI_CINSTR_GP_NUMBER_OF_PRIMITIVES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 12, + MALI_CINSTR_GP_RESERVED_13 = MALI_CINSTR_COUNTER_SOURCE_GP + 13, + MALI_CINSTR_GP_NUMBER_OF_BACKFACE_CULLINGS_DONE = MALI_CINSTR_COUNTER_SOURCE_GP + 14, + MALI_CINSTR_GP_NUMBER_OF_COMMANDS_WRITTEN_TO_TILES = MALI_CINSTR_COUNTER_SOURCE_GP + 15, + MALI_CINSTR_GP_NUMBER_OF_MEMORY_BLOCKS_ALLOCATED = MALI_CINSTR_COUNTER_SOURCE_GP + 16, + MALI_CINSTR_GP_RESERVED_17 = MALI_CINSTR_COUNTER_SOURCE_GP + 17, + MALI_CINSTR_GP_RESERVED_18 = MALI_CINSTR_COUNTER_SOURCE_GP + 18, + MALI_CINSTR_GP_NUMBER_OF_VERTEX_LOADER_CACHE_MISSES = MALI_CINSTR_COUNTER_SOURCE_GP + 19, + MALI_CINSTR_GP_RESERVED_20 = MALI_CINSTR_COUNTER_SOURCE_GP + 20, + MALI_CINSTR_GP_RESERVED_21 = MALI_CINSTR_COUNTER_SOURCE_GP + 21, + MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 22, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 23, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_LIST_WRITER = MALI_CINSTR_COUNTER_SOURCE_GP + 24, + MALI_CINSTR_GP_ACTIVE_CYCLES_THROUGH_THE_PREPARE_LIST_COMMANDS = MALI_CINSTR_COUNTER_SOURCE_GP + 25, + MALI_CINSTR_GP_RESERVED_26 = MALI_CINSTR_COUNTER_SOURCE_GP + 26, + MALI_CINSTR_GP_ACTIVE_CYCLES_PRIMITIVE_ASSEMBLY = MALI_CINSTR_COUNTER_SOURCE_GP + 27, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_VERTEX_FETCHER = MALI_CINSTR_COUNTER_SOURCE_GP + 28, + MALI_CINSTR_GP_RESERVED_29 = MALI_CINSTR_COUNTER_SOURCE_GP + 29, + MALI_CINSTR_GP_ACTIVE_CYCLES_BOUNDINGBOX_AND_COMMAND_GENERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 30, + MALI_CINSTR_GP_RESERVED_31 = MALI_CINSTR_COUNTER_SOURCE_GP + 31, + MALI_CINSTR_GP_ACTIVE_CYCLES_SCISSOR_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 32, + MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 33, + MALI_CINSTR_GP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_GP + 900, + + /* Mali PP counters */ + + MALI_CINSTR_PP_ACTIVE_CLOCK_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 0, + MALI_CINSTR_PP_TOTAL_CLOCK_CYCLES_COUNT_REMOVED = MALI_CINSTR_COUNTER_SOURCE_PP + 1, + MALI_CINSTR_PP_TOTAL_BUS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 2, + MALI_CINSTR_PP_TOTAL_BUS_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 3, + MALI_CINSTR_PP_BUS_READ_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 4, + MALI_CINSTR_PP_BUS_WRITE_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 5, + MALI_CINSTR_PP_BUS_READ_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 6, + MALI_CINSTR_PP_BUS_WRITE_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 7, + MALI_CINSTR_PP_RESERVED_08 = MALI_CINSTR_COUNTER_SOURCE_PP + 8, + MALI_CINSTR_PP_TILE_WRITEBACK_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 9, + MALI_CINSTR_PP_STORE_UNIT_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 10, + MALI_CINSTR_PP_RESERVED_11 = MALI_CINSTR_COUNTER_SOURCE_PP + 11, + MALI_CINSTR_PP_PALETTE_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 12, + MALI_CINSTR_PP_TEXTURE_CACHE_UNCOMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 13, + MALI_CINSTR_PP_POLYGON_LIST_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 14, + 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_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, + MALI_CINSTR_PP_TEXTURE_CACHE_COMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 22, + MALI_CINSTR_PP_LOAD_UNIT_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 23, + MALI_CINSTR_PP_POLYGON_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 24, + MALI_CINSTR_PP_PIXEL_RECTANGLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 25, + MALI_CINSTR_PP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 26, + MALI_CINSTR_PP_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 27, + MALI_CINSTR_PP_STALL_CYCLES_POLYGON_LIST_READER = MALI_CINSTR_COUNTER_SOURCE_PP + 28, + MALI_CINSTR_PP_STALL_CYCLES_TRIANGLE_SETUP = MALI_CINSTR_COUNTER_SOURCE_PP + 29, + MALI_CINSTR_PP_QUAD_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 30, + MALI_CINSTR_PP_FRAGMENT_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 31, + MALI_CINSTR_PP_FRAGMENT_REJECTED_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 32, + MALI_CINSTR_PP_FRAGMENT_REJECTED_FWD_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 33, + MALI_CINSTR_PP_FRAGMENT_PASSED_ZSTENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 34, + MALI_CINSTR_PP_PATCHES_REJECTED_EARLY_Z_STENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 35, + MALI_CINSTR_PP_PATCHES_EVALUATED = MALI_CINSTR_COUNTER_SOURCE_PP + 36, + MALI_CINSTR_PP_INSTRUCTION_COMPLETED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 37, + MALI_CINSTR_PP_INSTRUCTION_FAILED_RENDEZVOUS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 38, + MALI_CINSTR_PP_INSTRUCTION_FAILED_VARYING_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 39, + MALI_CINSTR_PP_INSTRUCTION_FAILED_TEXTURE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 40, + MALI_CINSTR_PP_INSTRUCTION_FAILED_LOAD_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 41, + MALI_CINSTR_PP_INSTRUCTION_FAILED_TILE_READ_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 42, + MALI_CINSTR_PP_INSTRUCTION_FAILED_STORE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 43, + MALI_CINSTR_PP_RENDEZVOUS_BREAKAGE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 44, + MALI_CINSTR_PP_PIPELINE_BUBBLES_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 45, + MALI_CINSTR_PP_TEXTURE_MAPPER_MULTIPASS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 46, + MALI_CINSTR_PP_TEXTURE_MAPPER_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 47, + MALI_CINSTR_PP_VERTEX_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 48, + MALI_CINSTR_PP_VERTEX_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 49, + MALI_CINSTR_PP_VARYING_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 50, + MALI_CINSTR_PP_VARYING_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 51, + MALI_CINSTR_PP_VARYING_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 52, + MALI_CINSTR_PP_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 53, + MALI_CINSTR_PP_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 54, + MALI_CINSTR_PP_TEXTURE_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 55, + MALI_CINSTR_PP_PALETTE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 200 only */ + MALI_CINSTR_PP_PALETTE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 200 only */ + MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 400 class only */ + MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 400 class only */ + MALI_CINSTR_PP_LOAD_STORE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 58, + MALI_CINSTR_PP_LOAD_STORE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 59, + MALI_CINSTR_PP_PROGRAM_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 60, + MALI_CINSTR_PP_PROGRAM_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 61, + MALI_CINSTR_PP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 900, +} cinstr_counters_m200_t; + +#endif /*_MALI_UTGARD_COUNTERS_H_*/ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h new file mode 100644 index 0000000..31af4cf --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h @@ -0,0 +1,80 @@ +/* + * 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_IOCTL_H__ +#define __MALI_UTGARD_IOCTL_H__ + +#include +#include +#include /* file system operations */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @file mali_kernel_ioctl.h + * Interface to the Linux device driver. + * This file describes the interface needed to use the Linux device driver. + * Its interface is designed to used by the HAL implementation through a thin arch layer. + */ + +/** + * ioctl commands + */ + +#define MALI_IOC_BASE 0x82 +#define MALI_IOC_CORE_BASE (_MALI_UK_CORE_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_MEMORY_BASE (_MALI_UK_MEMORY_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_PP_BASE (_MALI_UK_PP_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_GP_BASE (_MALI_UK_GP_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE) +#define MALI_IOC_VSYNC_BASE (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE) + +#define MALI_IOC_GET_SYSTEM_INFO_SIZE _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO_SIZE, _mali_uk_get_system_info_s *) +#define MALI_IOC_GET_SYSTEM_INFO _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO, _mali_uk_get_system_info_s *) +#define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *) +#define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *) +#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_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 *) +#define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *) +#define MALI_IOC_MEM_TERM _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *) +#define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *) +#define MALI_IOC_MEM_UNMAP_EXT _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_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_ATTACH_UMP _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s *) +#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_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 *) +#define MALI_IOC_PP_CORE_VERSION_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * ) +#define MALI_IOC_PP_DISABLE_WB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_DISABLE_WB, _mali_uk_pp_disable_wb_s * ) +#define MALI_IOC_GP2_START_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *) +#define MALI_IOC_GP2_NUMBER_OF_CORES_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *) +#define MALI_IOC_GP2_CORE_VERSION_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *) +#define MALI_IOC_GP2_SUSPEND_RESPONSE _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *) +#define MALI_IOC_PROFILING_START _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_START, _mali_uk_profiling_start_s *) +#define MALI_IOC_PROFILING_ADD_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_ADD_EVENT, _mali_uk_profiling_add_event_s*) +#define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *) +#define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *) +#define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *) +#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_get_user_settings_s *) +#define MALI_IOC_PROFILING_REPORT_SW_COUNTERS _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_REPORT_SW_COUNTERS, _mali_uk_sw_counters_report_s *) +#define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *) + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UTGARD_IOCTL_H__ */ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h new file mode 100644 index 0000000..129526f --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h @@ -0,0 +1,121 @@ +/* + * 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_EVENTS_H_ +#define _MALI_UTGARD_PROFILING_EVENTS_H_ + +/* + * The event ID is a 32 bit value consisting of different fields + * reserved, 4 bits, for future use + * event type, 4 bits, cinstr_profiling_event_type_t + * event channel, 8 bits, the source of the event. + * event data, 16 bit field, data depending on event type + */ + +/** + * Specifies what kind of event this is + */ +typedef enum +{ + MALI_PROFILING_EVENT_TYPE_SINGLE = 0 << 24, + MALI_PROFILING_EVENT_TYPE_START = 1 << 24, + MALI_PROFILING_EVENT_TYPE_STOP = 2 << 24, + MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24, + MALI_PROFILING_EVENT_TYPE_RESUME = 4 << 24, +} cinstr_profiling_event_type_t; + + +/** + * Secifies the channel/source of the event + */ +typedef enum +{ + MALI_PROFILING_EVENT_CHANNEL_SOFTWARE = 0 << 16, + MALI_PROFILING_EVENT_CHANNEL_GP0 = 1 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP0 = 5 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP1 = 6 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP2 = 7 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP3 = 8 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP4 = 9 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP5 = 10 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP6 = 11 << 16, + MALI_PROFILING_EVENT_CHANNEL_PP7 = 12 << 16, + MALI_PROFILING_EVENT_CHANNEL_GPU = 21 << 16, +} cinstr_profiling_event_channel_t; + + +#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16) +#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16) + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME = 1, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH = 2, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS = 3, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4, + 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_UMP_TRY_LOCK = 53, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK = 54, + MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK = 55, +} cinstr_profiling_event_reason_single_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1, +} cinstr_profiling_event_reason_start_stop_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT = 27, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC = 28, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_QUEUE_BUFFER = 34, + MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_DEQUEUE_BUFFER = 35, +} cinstr_profiling_event_reason_suspend_resume_sw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx) + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT = 1, + MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH = 2, +} cinstr_profiling_event_reason_single_hw_t; + +/** + * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel + */ +typedef enum +{ + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0, + MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1, +} cinstr_profiling_event_reason_single_gpu_t; + +#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/ diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h new file mode 100644 index 0000000..512b1e2 --- /dev/null +++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h @@ -0,0 +1,1133 @@ +/* + * 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_uk_types.h + * Defines the types and constants used in the user-kernel interface + */ + +#ifndef __MALI_UTGARD_UK_TYPES_H__ +#define __MALI_UTGARD_UK_TYPES_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup uddapi Unified Device Driver (UDD) APIs + * + * @{ + */ + +/** + * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs + * + * @{ + */ + +/** @defgroup _mali_uk_core U/K Core + * @{ */ + +/** Definition of subsystem numbers, to assist in creating a unique identifier + * for each U/K call. + * + * @see _mali_uk_functions */ +typedef enum +{ + _MALI_UK_CORE_SUBSYSTEM, /**< Core Group of U/K calls */ + _MALI_UK_MEMORY_SUBSYSTEM, /**< Memory Group of U/K calls */ + _MALI_UK_PP_SUBSYSTEM, /**< Fragment Processor Group of U/K calls */ + _MALI_UK_GP_SUBSYSTEM, /**< Vertex Processor Group of U/K calls */ + _MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */ + _MALI_UK_PMM_SUBSYSTEM, /**< Power Management Module Group of U/K calls */ + _MALI_UK_VSYNC_SUBSYSTEM, /**< VSYNC Group of U/K calls */ +} _mali_uk_subsystem_t; + +/** Within a function group each function has its unique sequence number + * to assist in creating a unique identifier for each U/K call. + * + * An ordered pair of numbers selected from + * ( \ref _mali_uk_subsystem_t,\ref _mali_uk_functions) will uniquely identify the + * U/K call across all groups of functions, and all functions. */ +typedef enum +{ + /** Core functions */ + + _MALI_UK_OPEN = 0, /**< _mali_ukk_open() */ + _MALI_UK_CLOSE, /**< _mali_ukk_close() */ + _MALI_UK_GET_SYSTEM_INFO_SIZE, /**< _mali_ukk_get_system_info_size() */ + _MALI_UK_GET_SYSTEM_INFO, /**< _mali_ukk_get_system_info() */ + _MALI_UK_WAIT_FOR_NOTIFICATION, /**< _mali_ukk_wait_for_notification() */ + _MALI_UK_GET_API_VERSION, /**< _mali_ukk_get_api_version() */ + _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] */ + + /** Memory functions */ + + _MALI_UK_INIT_MEM = 0, /**< _mali_ukk_init_mem() */ + _MALI_UK_TERM_MEM, /**< _mali_ukk_term_mem() */ + _MALI_UK_GET_BIG_BLOCK, /**< _mali_ukk_get_big_block() */ + _MALI_UK_FREE_BIG_BLOCK, /**< _mali_ukk_free_big_block() */ + _MALI_UK_MAP_MEM, /**< _mali_ukk_mem_mmap() */ + _MALI_UK_UNMAP_MEM, /**< _mali_ukk_mem_munmap() */ + _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */ + _MALI_UK_DUMP_MMU_PAGE_TABLE, /**< _mali_ukk_mem_dump_mmu_page_table() */ + _MALI_UK_ATTACH_UMP_MEM, /**< _mali_ukk_attach_ump_mem() */ + _MALI_UK_RELEASE_UMP_MEM, /**< _mali_ukk_release_ump_mem() */ + _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() */ + + /** Common functions for each core */ + + _MALI_UK_START_JOB = 0, /**< Start a Fragment/Vertex Processor Job on a core */ + _MALI_UK_GET_NUMBER_OF_CORES, /**< Get the number of Fragment/Vertex Processor cores */ + _MALI_UK_GET_CORE_VERSION, /**< Get the Fragment/Vertex Processor version compatible with all cores */ + + /** Fragment Processor Functions */ + + _MALI_UK_PP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_pp_start_job() */ + _MALI_UK_GET_PP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_pp_number_of_cores() */ + _MALI_UK_GET_PP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_pp_core_version() */ + _MALI_UK_PP_DISABLE_WB, /**< _mali_ukk_pp_job_disable_wb() */ + + /** Vertex Processor Functions */ + + _MALI_UK_GP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_gp_start_job() */ + _MALI_UK_GET_GP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_gp_number_of_cores() */ + _MALI_UK_GET_GP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_gp_core_version() */ + _MALI_UK_GP_SUSPEND_RESPONSE, /**< _mali_ukk_gp_suspend_response() */ + + /** Profiling functions */ + + _MALI_UK_PROFILING_START = 0, /**< __mali_uku_profiling_start() */ + _MALI_UK_PROFILING_ADD_EVENT, /**< __mali_uku_profiling_add_event() */ + _MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */ + _MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */ + _MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */ + _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */ + _MALI_UK_PROFILING_REPORT_SW_COUNTERS,/**< __mali_uku_profiling_report_sw_counters() */ + + /** VSYNC reporting fuctions */ + _MALI_UK_VSYNC_EVENT_REPORT = 0, /**< _mali_ukk_vsync_event_report() */ + +} _mali_uk_functions; + +/** @brief Get the size necessary for system info + * + * @see _mali_ukk_get_system_info_size() + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [out] size of buffer necessary to hold system information data, in bytes */ +} _mali_uk_get_system_info_size_s; + + +/** @defgroup _mali_uk_getsysteminfo U/K Get System Info + * @{ */ + +/** + * Type definition for the core version number. + * Used when returning the version number read from a core + * + * Its format is that of the 32-bit Version register for a particular core. + * Refer to the "Mali200 and MaliGP2 3D Graphics Processor Technical Reference + * Manual", ARM DDI 0415C, for more information. + */ +typedef u32 _mali_core_version; + +/** + * Enum values for the different modes the driver can be put in. + * Normal is the default mode. The driver then uses a job queue and takes job objects from the clients. + * Job completion is reported using the _mali_ukk_wait_for_notification call. + * The driver blocks this io command until a job has completed or failed or a timeout occurs. + * + * The 'raw' mode is reserved for future expansion. + */ +typedef enum _mali_driver_mode +{ + _MALI_DRIVER_MODE_RAW = 1, /**< Reserved for future expansion */ + _MALI_DRIVER_MODE_NORMAL = 2 /**< Normal mode of operation */ +} _mali_driver_mode; + +/** @brief List of possible cores + * + * add new entries to the end of this enum */ +typedef enum _mali_core_type +{ + _MALI_GP2 = 2, /**< MaliGP2 Programmable Vertex Processor */ + _MALI_200 = 5, /**< Mali200 Programmable Fragment Processor */ + _MALI_400_GP = 6, /**< Mali400 Programmable Vertex Processor */ + _MALI_400_PP = 7, /**< Mali400 Programmable Fragment Processor */ + /* insert new core here, do NOT alter the existing values */ +} _mali_core_type; + +/** @brief Information about each Mali Core + * + * Information is stored in a linked list, which is stored entirely in the + * buffer pointed to by the system_info member of the + * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info() + * + * Both Fragment Processor (PP) and Vertex Processor (GP) cores are represented + * by this struct. + * + * The type is reported by the type field, _mali_core_info::_mali_core_type. + * + * Each core is given a unique Sequence number identifying it, the core_nr + * member. + * + * Flags are taken directly from the resource's flags, and are currently unused. + * + * Multiple mali_core_info structs are linked in a single linked list using the next field + */ +typedef struct _mali_core_info +{ + _mali_core_type type; /**< Type of core */ + _mali_core_version version; /**< Core Version, as reported by the Core's Version Register */ + u32 reg_address; /**< Address of Registers */ + u32 core_nr; /**< Sequence number */ + u32 flags; /**< Flags. Currently Unused. */ + struct _mali_core_info * next; /**< Next core in Linked List */ +} _mali_core_info; + +/** @brief Capabilities of Memory Banks + * + * These may be used to restrict memory banks for certain uses. They may be + * used when access is not possible (e.g. Bus does not support access to it) + * or when access is possible but not desired (e.g. Access is slow). + * + * In the case of 'possible but not desired', there is no way of specifying + * the flags as an optimization hint, so that the memory could be used as a + * last resort. + * + * @see _mali_mem_info + */ +typedef enum _mali_bus_usage +{ + + _MALI_PP_READABLE = (1<<0), /** Readable by the Fragment Processor */ + _MALI_PP_WRITEABLE = (1<<1), /** Writeable by the Fragment Processor */ + _MALI_GP_READABLE = (1<<2), /** Readable by the Vertex Processor */ + _MALI_GP_WRITEABLE = (1<<3), /** Writeable by the Vertex Processor */ + _MALI_CPU_READABLE = (1<<4), /** Readable by the CPU */ + _MALI_CPU_WRITEABLE = (1<<5), /** Writeable by the CPU */ + _MALI_MMU_READABLE = _MALI_PP_READABLE | _MALI_GP_READABLE, /** Readable by the MMU (including all cores behind it) */ + _MALI_MMU_WRITEABLE = _MALI_PP_WRITEABLE | _MALI_GP_WRITEABLE, /** Writeable by the MMU (including all cores behind it) */ +} _mali_bus_usage; + +/** @brief Information about the Mali Memory system + * + * Information is stored in a linked list, which is stored entirely in the + * buffer pointed to by the system_info member of the + * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info() + * + * Each element of the linked list describes a single Mali Memory bank. + * Each allocation can only come from one bank, and will not cross multiple + * banks. + * + * Each bank is uniquely identified by its identifier member. On Mali-nonMMU + * systems, to allocate from this bank, the value of identifier must be passed + * as the type_id member of the _mali_uk_get_big_block_s arguments to + * _mali_ukk_get_big_block. + * + * On Mali-MMU systems, there is only one bank, which describes the maximum + * possible address range that could be allocated (which may be much less than + * the available physical memory) + * + * The flags member describes the capabilities of the memory. It is an error + * to attempt to build a job for a particular core (PP or GP) when the memory + * regions used do not have the capabilities for supporting that core. This + * would result in a job abort from the Device Driver. + * + * For example, it is correct to build a PP job where read-only data structures + * are taken from a memory with _MALI_PP_READABLE set and + * _MALI_PP_WRITEABLE clear, and a framebuffer with _MALI_PP_WRITEABLE set and + * _MALI_PP_READABLE clear. However, it would be incorrect to use a framebuffer + * where _MALI_PP_WRITEABLE is clear. + */ +typedef struct _mali_mem_info +{ + u32 size; /**< Size of the memory bank in bytes */ + _mali_bus_usage flags; /**< Capabilitiy flags of the memory */ + u32 maximum_order_supported; /**< log2 supported size */ + u32 identifier; /**< Unique identifier, to be used in allocate calls */ + struct _mali_mem_info * next; /**< Next List Link */ +} _mali_mem_info; + +/** @brief Info about the whole Mali system. + * + * This Contains a linked list of the cores and memory banks available. Each + * list pointer will remain inside the system_info buffer supplied in the + * _mali_uk_get_system_info_s arguments to a _mali_ukk_get_system_info call. + * + * The has_mmu member must be inspected to ensure the correct group of + * Memory function calls is obtained - that is, those for either Mali-MMU + * or Mali-nonMMU. @see _mali_uk_memory + */ +typedef struct _mali_system_info +{ + _mali_core_info * core_info; /**< List of _mali_core_info structures */ + _mali_mem_info * mem_info; /**< List of _mali_mem_info structures */ + u32 has_mmu; /**< Non-zero if Mali-MMU present. Zero otherwise. */ + _mali_driver_mode drivermode; /**< Reserved. Must always be _MALI_DRIVER_MODE_NORMAL */ +} _mali_system_info; + +/** @brief Arguments to _mali_ukk_get_system_info() + * + * A buffer of the size returned by _mali_ukk_get_system_info_size() must be + * allocated, and the pointer to this buffer must be written into the + * system_info member. The buffer must be suitably aligned for storage of + * the _mali_system_info structure - for example, one returned by + * _mali_osk_malloc(), which will be suitably aligned for any structure. + * + * The ukk_private member must be set to zero by the user-side. Under an OS + * implementation, the U/K interface must write in the user-side base address + * into the ukk_private member, so that the common code in + * _mali_ukk_get_system_info() can determine how to adjust the pointers such + * that they are sensible from user space. Leaving ukk_private as NULL implies + * that no pointer adjustment is necessary - which will be the case on a + * bare-metal/RTOS system. + * + * @see _mali_system_info + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [in] size of buffer provided to store system information data */ + _mali_system_info * system_info; /**< [in,out] pointer to buffer to store system information data. No initialisation of buffer required on input. */ + u32 ukk_private; /**< [in] Kernel-side private word inserted by certain U/K interface implementations. Caller must set to Zero. */ +} _mali_uk_get_system_info_s; +/** @} */ /* end group _mali_uk_getsysteminfo */ + +/** @} */ /* end group _mali_uk_core */ + + +/** @defgroup _mali_uk_gp U/K Vertex Processor + * @{ */ + +/** @defgroup _mali_uk_gp_suspend_response_s Vertex Processor Suspend Response + * @{ */ + +/** @brief Arguments for _mali_ukk_gp_suspend_response() + * + * When _mali_wait_for_notification() receives notification that a + * Vertex Processor job was suspended, you need to send a response to indicate + * what needs to happen with this job. You can either abort or resume the job. + * + * - set @c code to indicate response code. This is either @c _MALIGP_JOB_ABORT or + * @c _MALIGP_JOB_RESUME_WITH_NEW_HEAP to indicate you will provide a new heap + * for the job that will resolve the out of memory condition for the job. + * - copy the @c cookie value from the @c _mali_uk_gp_job_suspended_s notification; + * this is an identifier for the suspended job + * - set @c arguments[0] and @c arguments[1] to zero if you abort the job. If + * you resume it, @c argument[0] should specify the Mali start address for the new + * heap and @c argument[1] the Mali end address of the heap. + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * + */ +typedef enum _maligp_job_suspended_response_code +{ + _MALIGP_JOB_ABORT, /**< Abort the Vertex Processor job */ + _MALIGP_JOB_RESUME_WITH_NEW_HEAP /**< Resume the Vertex Processor job with a new heap */ +} _maligp_job_suspended_response_code; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [in] cookie from the _mali_uk_gp_job_suspended_s notification */ + _maligp_job_suspended_response_code code; /**< [in] abort or resume response code, see \ref _maligp_job_suspended_response_code */ + u32 arguments[2]; /**< [in] 0 when aborting a job. When resuming a job, the Mali start and end address for a new heap to resume the job with */ +} _mali_uk_gp_suspend_response_s; + +/** @} */ /* end group _mali_uk_gp_suspend_response_s */ + +/** @defgroup _mali_uk_gpstartjob_s Vertex Processor Start Job + * @{ */ + +/** @brief Status indicating the result of starting a Vertex or Fragment processor job */ +typedef enum +{ + _MALI_UK_START_JOB_STARTED, /**< Job started */ + _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE /**< Job could not be started at this time. Try starting the job again */ +} _mali_uk_start_job_status; + +/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job */ + +typedef enum +{ + _MALI_UK_JOB_STATUS_END_SUCCESS = 1<<(16+0), + _MALI_UK_JOB_STATUS_END_OOM = 1<<(16+1), + _MALI_UK_JOB_STATUS_END_ABORT = 1<<(16+2), + _MALI_UK_JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3), + _MALI_UK_JOB_STATUS_END_HANG = 1<<(16+4), + _MALI_UK_JOB_STATUS_END_SEG_FAULT = 1<<(16+5), + _MALI_UK_JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6), + _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7), + _MALI_UK_JOB_STATUS_END_SHUTDOWN = 1<<(16+8), + _MALI_UK_JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9) +} _mali_uk_job_status; + +#define MALIGP2_NUM_REGS_FRAME (6) + +/** @brief Arguments for _mali_ukk_gp_start_job() + * + * To start a Vertex Processor job + * - associate the request with a reference to a @c mali_gp_job_info by setting + * user_job_ptr to the address of the @c mali_gp_job_info of the job. + * - set @c priority to the priority of the @c mali_gp_job_info + * - specify a timeout for the job by setting @c watchdog_msecs to the number of + * milliseconds the job is allowed to run. Specifying a value of 0 selects the + * default timeout in use by the device driver. + * - copy the frame registers from the @c mali_gp_job_info into @c frame_registers. + * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero + * for a non-instrumented build. For an instrumented build you can use up + * to two performance counters. Set the corresponding bit in @c perf_counter_flag + * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify + * the source of what needs to get counted (e.g. number of vertex loader + * cache hits). For source id values, see ARM DDI0415A, Table 3-60. + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * + * When @c _mali_ukk_gp_start_job() returns @c _MALI_OSK_ERR_OK, status contains the + * result of the request (see \ref _mali_uk_start_job_status). If the job could + * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be + * tried again. + * + * After the job has started, @c _mali_wait_for_notification() will be notified + * that the job finished or got suspended. It may get suspended due to + * resource shortage. If it finished (see _mali_ukk_wait_for_notification()) + * the notification will contain a @c _mali_uk_gp_job_finished_s result. If + * it got suspended the notification will contain a @c _mali_uk_gp_job_suspended_s + * result. + * + * The @c _mali_uk_gp_job_finished_s contains the job status (see \ref _mali_uk_job_status), + * the number of milliseconds the job took to render, and values of core registers + * when the job finished (irq status, performance counters, renderer list + * address). A job has finished succesfully when its status is + * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering + * the job, or software detected the job is taking more than watchdog_msecs to + * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. + * If the hardware detected a bus error while accessing memory associated with the + * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. + * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to + * stop the job but the job didn't start on the hardware yet, e.g. when the + * driver shutdown. + * + * In case the job got suspended, @c _mali_uk_gp_job_suspended_s contains + * the @c user_job_ptr identifier used to start the job with, the @c reason + * why the job stalled (see \ref _maligp_job_suspended_reason) and a @c cookie + * to identify the core on which the job stalled. This @c cookie will be needed + * when responding to this nofication by means of _mali_ukk_gp_suspend_response(). + * (see _mali_ukk_gp_suspend_response()). The response is either to abort or + * resume the job. If the job got suspended due to an out of memory condition + * you may be able to resolve this by providing more memory and resuming the job. + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 user_job_ptr; /**< [in] identifier for the job in user space, a @c mali_gp_job_info* */ + u32 priority; /**< [in] job priority. A lower number means higher priority */ + u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job */ + 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) */ + u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 frame_builder_id; /**< [in] id of the originating frame builder */ + u32 flush_id; /**< [in] flush id within the originating frame builder */ +} _mali_uk_gp_start_job_s; + +#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */ +#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE (1<<1) /**< Enable performance counter SRC1 for a job */ + +/** @} */ /* end group _mali_uk_gpstartjob_s */ + +typedef struct +{ + u32 user_job_ptr; /**< [out] identifier for the job in user space */ + _mali_uk_job_status status; /**< [out] status of finished job */ + u32 heap_current_addr; /**< [out] value of the GP PLB PL heap start address register */ + u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */ + u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */ +} _mali_uk_gp_job_finished_s; + +typedef enum _maligp_job_suspended_reason +{ + _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY /**< Polygon list builder unit (PLBU) has run out of memory */ +} _maligp_job_suspended_reason; + +typedef struct +{ + u32 user_job_ptr; /**< [out] identifier for the job in user space */ + _maligp_job_suspended_reason reason; /**< [out] reason why the job stalled */ + u32 cookie; /**< [out] identifier for the core in kernel space on which the job stalled */ +} _mali_uk_gp_job_suspended_s; + +/** @} */ /* end group _mali_uk_gp */ + + +/** @defgroup _mali_uk_pp U/K Fragment Processor + * @{ */ + +#define _MALI_PP_MAX_SUB_JOBS 8 + +#define _MALI_PP_MAX_FRAME_REGISTERS ((0x058/4)+1) + +#define _MALI_PP_MAX_WB_REGISTERS ((0x02C/4)+1) + +/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job + * @{ */ + +/** @brief Arguments for _mali_ukk_pp_start_job() + * + * To start a Fragment Processor job + * - associate the request with a reference to a mali_pp_job by setting + * @c user_job_ptr to the address of the @c mali_pp_job of the job. + * - set @c priority to the priority of the mali_pp_job + * - specify a timeout for the job by setting @c watchdog_msecs to the number of + * milliseconds the job is allowed to run. Specifying a value of 0 selects the + * default timeout in use by the device driver. + * - copy the frame registers from the @c mali_pp_job into @c frame_registers. + * For MALI200 you also need to copy the write back 0,1 and 2 registers. + * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero + * for a non-instrumented build. For an instrumented build you can use up + * to two performance counters. Set the corresponding bit in @c perf_counter_flag + * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify + * the source of what needs to get counted (e.g. number of vertex loader + * cache hits). For source id values, see ARM DDI0415A, Table 3-60. + * - pass in the user-kernel context in @c ctx that was returned from _mali_ukk_open() + * + * When _mali_ukk_pp_start_job() returns @c _MALI_OSK_ERR_OK, @c status contains the + * result of the request (see \ref _mali_uk_start_job_status). If the job could + * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be + * tried again. + * + * After the job has started, _mali_wait_for_notification() will be notified + * when the job finished. The notification will contain a + * @c _mali_uk_pp_job_finished_s result. It contains the @c user_job_ptr + * identifier used to start the job with, the job @c status (see \ref _mali_uk_job_status), + * the number of milliseconds the job took to render, and values of core registers + * when the job finished (irq status, performance counters, renderer list + * address). A job has finished succesfully when its status is + * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering + * the job, or software detected the job is taking more than @c watchdog_msecs to + * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG. + * If the hardware detected a bus error while accessing memory associated with the + * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT. + * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to + * stop the job but the job didn't start on the hardware yet, e.g. when the + * driver shutdown. + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 user_job_ptr; /**< [in] identifier for the job in user space */ + u32 priority; /**< [in] job priority. A lower number means higher priority */ + u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< [in] core specific registers associated with first sub job, see ARM DDI0415A */ + u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_FRAME registers for sub job 1-7 */ + u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_STACK registers for sub job 1-7 */ + 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 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) */ + u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */ + u32 frame_builder_id; /**< [in] id of the originating frame builder */ + u32 flush_id; /**< [in] flush id within the originating frame builder */ +} _mali_uk_pp_start_job_s; +/** @} */ /* end group _mali_uk_ppstartjob_s */ + +typedef struct +{ + u32 user_job_ptr; /**< [out] identifier for the job in user space */ + _mali_uk_job_status status; /**< [out] status of finished job */ + u32 perf_counter0[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 0 (see ARM DDI0415A), one for each sub job */ + 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; + +/** + * Flags to indicate write-back units + */ +typedef enum +{ + _MALI_UK_PP_JOB_WB0 = 1, + _MALI_UK_PP_JOB_WB1 = 2, + _MALI_UK_PP_JOB_WB2 = 4, +} _mali_uk_pp_job_wbx_flag; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 fb_id; /**< [in] Frame builder ID of job to disable WB units for */ + u32 flush_id; /**< [in] Flush ID of job to disable WB units for */ + _mali_uk_pp_job_wbx_flag wbx; /**< [in] write-back units to disable */ +} _mali_uk_pp_disable_wb_s; + + +/** @} */ /* end group _mali_uk_pp */ + + +/** @addtogroup _mali_uk_core U/K Core + * @{ */ + +/** @defgroup _mali_uk_waitfornotification_s Wait For Notification + * @{ */ + +/** @brief Notification type encodings + * + * Each Notification type is an ordered pair of (subsystem,id), and is unique. + * + * The encoding of subsystem,id into a 32-bit word is: + * encoding = (( subsystem << _MALI_NOTIFICATION_SUBSYSTEM_SHIFT ) & _MALI_NOTIFICATION_SUBSYSTEM_MASK) + * | (( id << _MALI_NOTIFICATION_ID_SHIFT ) & _MALI_NOTIFICATION_ID_MASK) + * + * @see _mali_uk_wait_for_notification_s + */ +typedef enum +{ + /** core notifications */ + + _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20, + _MALI_NOTIFICATION_APPLICATION_QUIT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40, + _MALI_NOTIFICATION_SETTINGS_CHANGED = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x80, + + /** Fragment Processor notifications */ + + _MALI_NOTIFICATION_PP_FINISHED = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10, + + /** Vertex Processor notifications */ + + _MALI_NOTIFICATION_GP_FINISHED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x10, + _MALI_NOTIFICATION_GP_STALLED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x20, + +} _mali_uk_notification_type; + +/** to assist in splitting up 32-bit notification value in subsystem and id value */ +#define _MALI_NOTIFICATION_SUBSYSTEM_MASK 0xFFFF0000 +#define _MALI_NOTIFICATION_SUBSYSTEM_SHIFT 16 +#define _MALI_NOTIFICATION_ID_MASK 0x0000FFFF +#define _MALI_NOTIFICATION_ID_SHIFT 0 + + +/** @brief Enumeration of possible settings which match mali_setting_t in user space + * + * + */ +typedef enum +{ + _MALI_UK_USER_SETTING_SW_EVENTS_ENABLE = 0, + _MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_DEPTHBUFFER_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_STENCILBUFFER_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_PER_TILE_COUNTERS_CAPTURE_ENABLED, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_COMPOSITOR, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_WINDOW, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_OTHER, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, + _MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, + _MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, + _MALI_UK_USER_SETTING_MAX, +} _mali_uk_user_setting_t; + +/* See mali_user_settings_db.c */ +extern const char *_mali_uk_user_setting_descriptions[]; +#define _MALI_UK_USER_SETTING_DESCRIPTIONS \ +{ \ + "sw_events_enable", \ + "colorbuffer_capture_enable", \ + "depthbuffer_capture_enable", \ + "stencilbuffer_capture_enable", \ + "per_tile_counters_enable", \ + "buffer_capture_compositor", \ + "buffer_capture_window", \ + "buffer_capture_other", \ + "buffer_capture_n_frames", \ + "buffer_capture_resize_factor", \ + "sw_counters_enable", \ +}; + +/** @brief struct to hold the value to a particular setting as seen in the kernel space + */ +typedef struct +{ + _mali_uk_user_setting_t setting; + u32 value; +} _mali_uk_settings_changed_s; + +/** @brief Arguments for _mali_ukk_wait_for_notification() + * + * On successful return from _mali_ukk_wait_for_notification(), the members of + * this structure will indicate the reason for notification. + * + * Specifically, the source of the notification can be identified by the + * subsystem and id fields of the mali_uk_notification_type in the code.type + * member. The type member is encoded in a way to divide up the types into a + * subsystem field, and a per-subsystem ID field. See + * _mali_uk_notification_type for more information. + * + * Interpreting the data union member depends on the notification type: + * + * - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS + * - The kernel side is shutting down. No further + * _mali_uk_wait_for_notification() calls should be made. + * - In this case, the value of the data union member is undefined. + * - This is used to indicate to the user space client that it should close + * the connection to the Mali Device Driver. + * - type == _MALI_NOTIFICATION_PP_FINISHED + * - The notification data is of type _mali_uk_pp_job_finished_s. It contains the user_job_ptr + * identifier used to start the job with, the job status, the number of milliseconds the job took to render, + * and values of core registers when the job finished (irq status, performance counters, renderer list + * address). + * - A job has finished succesfully when its status member is _MALI_UK_JOB_STATUS_FINISHED. + * - If the hardware detected a timeout while rendering the job, or software detected the job is + * taking more than watchdog_msecs (see _mali_ukk_pp_start_job()) to complete, the status member will + * indicate _MALI_UK_JOB_STATUS_HANG. + * - If the hardware detected a bus error while accessing memory associated with the job, status will + * indicate _MALI_UK_JOB_STATUS_SEG_FAULT. + * - Status will indicate MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to stop the job but the job + * didn't start the hardware yet, e.g. when the driver closes. + * - type == _MALI_NOTIFICATION_GP_FINISHED + * - The notification data is of type _mali_uk_gp_job_finished_s. The notification is similar to that of + * type == _MALI_NOTIFICATION_PP_FINISHED, except that several other GP core register values are returned. + * The status values have the same meaning for type == _MALI_NOTIFICATION_PP_FINISHED. + * - type == _MALI_NOTIFICATION_GP_STALLED + * - The nofication data is of type _mali_uk_gp_job_suspended_s. It contains the user_job_ptr + * identifier used to start the job with, the reason why the job stalled and a cookie to identify the core on + * which the job stalled. + * - The reason member of gp_job_suspended is set to _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY + * when the polygon list builder unit has run out of memory. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_notification_type type; /**< [out] Type of notification available */ + union + { + _mali_uk_gp_job_suspended_s gp_job_suspended;/**< [out] Notification data for _MALI_NOTIFICATION_GP_STALLED notification type */ + _mali_uk_gp_job_finished_s gp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_GP_FINISHED notification type */ + _mali_uk_pp_job_finished_s pp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_PP_FINISHED notification type */ + _mali_uk_settings_changed_s setting_changed;/**< [out] Notification data for _MALI_NOTIFICAATION_SETTINGS_CHANGED notification type */ + } data; +} _mali_uk_wait_for_notification_s; + +/** @brief Arguments for _mali_ukk_post_notification() + * + * Posts the specified notification to the notification queue for this application. + * This is used to send a quit message to the callback thread. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_notification_type type; /**< [in] Type of notification to post */ +} _mali_uk_post_notification_s; + +/** @} */ /* end group _mali_uk_waitfornotification_s */ + +/** @defgroup _mali_uk_getapiversion_s Get API Version + * @{ */ + +/** helpers for Device Driver API version handling */ + +/** @brief Encode a version ID from a 16-bit input + * + * @note the input is assumed to be 16 bits. It must not exceed 16 bits. */ +#define _MAKE_VERSION_ID(x) (((x) << 16UL) | (x)) + +/** @brief Check whether a 32-bit value is likely to be Device Driver API + * version ID. */ +#define _IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF)) + +/** @brief Decode a 16-bit version number from a 32-bit Device Driver API version + * ID */ +#define _GET_VERSION(x) (((x) >> 16UL) & 0xFFFF) + +/** @brief Determine whether two 32-bit encoded version IDs match */ +#define _IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y)))) + +/** + * API version define. + * Indicates the version of the kernel API + * The version is a 16bit integer incremented on each API change. + * The 16bit integer is stored twice in a 32bit integer + * For example, for version 1 the value would be 0x00010001 + */ +#define _MALI_API_VERSION 14 +#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION) + +/** + * The API version is a 16-bit integer stored in both the lower and upper 16-bits + * of a 32-bit value. The 16-bit API version value is incremented on each API + * change. Version 1 would be 0x00010001. Used in _mali_uk_get_api_version_s. + */ +typedef u32 _mali_uk_api_version; + +/** @brief Arguments for _mali_uk_get_api_version() + * + * The user-side interface version must be written into the version member, + * encoded using _MAKE_VERSION_ID(). It will be compared to the API version of + * the kernel-side interface. + * + * On successful return, the version member will be the API version of the + * kernel-side interface. _MALI_UK_API_VERSION macro defines the current version + * of the API. + * + * The compatible member must be checked to see if the version of the user-side + * interface is compatible with the kernel-side interface, since future versions + * of the interface may be backwards compatible. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_api_version version; /**< [in,out] API version of user-side interface. */ + int compatible; /**< [out] @c 1 when @version is compatible, @c 0 otherwise */ +} _mali_uk_get_api_version_s; +/** @} */ /* end group _mali_uk_getapiversion_s */ + +/** @defgroup _mali_uk_get_user_settings_s Get user space settings */ + +/** @brief struct to keep the matching values of the user space settings within certain context + * + * Each member of the settings array corresponds to a matching setting in the user space and its value is the value + * of that particular setting. + * + * All settings are given reference to the context pointed to by the ctx pointer. + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 settings[_MALI_UK_USER_SETTING_MAX]; /**< [out] The values for all settings */ +} _mali_uk_get_user_settings_s; + +/** @brief struct to hold the value of a particular setting from the user space within a given context + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_user_setting_t setting; /**< [in] setting to get */ + u32 value; /**< [out] value of setting */ +} _mali_uk_get_user_setting_s; + +/** @} */ /* end group _mali_uk_core */ + + +/** @defgroup _mali_uk_memory U/K Memory + * @{ */ + +/** @brief Arguments for _mali_ukk_init_mem(). */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 mali_address_base; /**< [out] start of MALI address space */ + u32 memory_size; /**< [out] total MALI address space available */ +} _mali_uk_init_mem_s; + +/** @brief Arguments for _mali_ukk_term_mem(). */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ +} _mali_uk_term_mem_s; + +/** @note Mali-MMU only */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 phys_addr; /**< [in] physical address */ + u32 size; /**< [in] size */ + u32 mali_address; /**< [in] mali address to map the physical memory to */ + u32 rights; /**< [in] rights necessary for accessing memory */ + u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_map_external_mem_s; + +/** Flag for _mali_uk_map_external_mem_s and _mali_uk_attach_ump_mem_s */ +#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0) + +/** @note Mali-MMU only */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_unmap_external_mem_s; + +/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure id */ + u32 size; /**< [in] size */ + u32 mali_address; /**< [in] mali address to map the physical memory to */ + u32 rights; /**< [in] rights necessary for accessing memory */ + u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */ + u32 cookie; /**< [out] identifier for mapped memory object in kernel space */ +} _mali_uk_attach_ump_mem_s; + +/** @note Mali-MMU only; will be supported in future version */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 cookie; /**< [in] identifier for mapped memory object in kernel space */ +} _mali_uk_release_ump_mem_s; + +/** @brief Arguments for _mali_ukk_va_to_mali_pa() + * + * if size is zero or not a multiple of the system's page size, it will be + * rounded up to the next multiple of the page size. This will occur before + * any other use of the size parameter. + * + * if va is not PAGE_SIZE aligned, it will be rounded down to the next page + * boundary. + * + * The range (va) to ((u32)va)+(size-1) inclusive will be checked for physical + * contiguity. + * + * The implementor will check that the entire physical range is allowed to be mapped + * into user-space. + * + * Failure will occur if either of the above are not satisfied. + * + * Otherwise, the physical base address of the range is returned through pa, + * va is updated to be page aligned, and size is updated to be a non-zero + * multiple of the system's pagesize. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *va; /**< [in,out] Virtual address of the start of the range */ + u32 pa; /**< [out] Physical base address of the range */ + u32 size; /**< [in,out] Size of the range, in bytes. */ +} _mali_uk_va_to_mali_pa_s; + + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [out] size of MMU page table information (registers + page tables) */ +} _mali_uk_query_mmu_page_table_dump_size_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 size; /**< [in] size of buffer to receive mmu page table information */ + void *buffer; /**< [in,out] buffer to receive mmu page table information */ + u32 register_writes_size; /**< [out] size of MMU register dump */ + u32 *register_writes; /**< [out] pointer within buffer where MMU register dump is stored */ + u32 page_table_dump_size; /**< [out] size of MMU page table dump */ + u32 *page_table_dump; /**< [out] pointer within buffer where MMU page table dump is stored */ +} _mali_uk_dump_mmu_page_table_s; + +/** @} */ /* end group _mali_uk_memory */ + + +/** @addtogroup _mali_uk_pp U/K Fragment Processor + * @{ */ + +/** @brief Arguments for _mali_ukk_get_pp_number_of_cores() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_pp_number_of_cores(), @c number_of_cores + * will contain the number of Fragment Processor cores in the system. + */ +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 */ +} _mali_uk_get_pp_number_of_cores_s; + +/** @brief Arguments for _mali_ukk_get_pp_core_version() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_pp_core_version(), @c version contains + * the version that all Fragment Processor cores are compatible with. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ +} _mali_uk_get_pp_core_version_s; + +/** @} */ /* end group _mali_uk_pp */ + + +/** @addtogroup _mali_uk_gp U/K Vertex Processor + * @{ */ + +/** @brief Arguments for _mali_ukk_get_gp_number_of_cores() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_gp_number_of_cores(), @c number_of_cores + * will contain the number of Vertex Processor cores in the system. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 number_of_cores; /**< [out] number of Vertex Processor cores in the system */ +} _mali_uk_get_gp_number_of_cores_s; + +/** @brief Arguments for _mali_ukk_get_gp_core_version() + * + * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open() + * - Upon successful return from _mali_ukk_get_gp_core_version(), @c version contains + * the version that all Vertex Processor cores are compatible with. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */ +} _mali_uk_get_gp_core_version_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 limit; /**< [in,out] The desired limit for number of events to record on input, actual limit on output */ +} _mali_uk_profiling_start_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 event_id; /**< [in] event id to register (see enum mali_profiling_events for values) */ + u32 data[5]; /**< [in] event specific data */ +} _mali_uk_profiling_add_event_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 count; /**< [out] The number of events sampled */ +} _mali_uk_profiling_stop_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 index; /**< [in] which index to get (starting at zero) */ + u64 timestamp; /**< [out] timestamp of event */ + u32 event_id; /**< [out] event id of event (see enum mali_profiling_events for values) */ + u32 data[5]; /**< [out] event specific data */ +} _mali_uk_profiling_get_event_s; + +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ +} _mali_uk_profiling_clear_s; + +/** @} */ /* end group _mali_uk_gp */ + + +/** @addtogroup _mali_uk_memory U/K Memory + * @{ */ + +/** @brief Arguments to _mali_ukk_mem_mmap() + * + * Use of the phys_addr member depends on whether the driver is compiled for + * Mali-MMU or nonMMU: + * - in the nonMMU case, this is the physical address of the memory as seen by + * the CPU (which may be a constant offset from that used by Mali) + * - in the MMU case, this is the Mali Virtual base address of the memory to + * allocate, and the particular physical pages used to back the memory are + * entirely determined by _mali_ukk_mem_mmap(). The details of the physical pages + * are not reported to user-space for security reasons. + * + * The cookie member must be stored for use later when freeing the memory by + * calling _mali_ukk_mem_munmap(). In the Mali-MMU case, the cookie is secure. + * + * The ukk_private word must be set to zero when calling from user-space. On + * Kernel-side, the OS implementation of the U/K interface can use it to + * communicate data to the OS implementation of the OSK layer. In particular, + * _mali_ukk_get_big_block() directly calls _mali_ukk_mem_mmap directly, and + * will communicate its own ukk_private word through the ukk_private member + * here. The common code itself will not inspect or modify the ukk_private + * word, and so it may be safely used for whatever purposes necessary to + * integrate Mali Memory handling into the OS. + * + * The uku_private member is currently reserved for use by the user-side + * implementation of the U/K interface. Its value must be zero. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; /**< [out] Returns user-space virtual address for the mapping */ + u32 size; /**< [in] Size of the requested mapping */ + u32 phys_addr; /**< [in] Physical address - could be offset, depending on caller+callee convention */ + u32 cookie; /**< [out] Returns a cookie for use in munmap calls */ + void *uku_private; /**< [in] User-side Private word used by U/K interface */ + void *ukk_private; /**< [in] Kernel-side Private word used by U/K interface */ +} _mali_uk_mem_mmap_s; + +/** @brief Arguments to _mali_ukk_mem_munmap() + * + * The cookie and mapping members must be that returned from the same previous + * call to _mali_ukk_mem_mmap(). The size member must correspond to cookie + * and mapping - that is, it must be the value originally supplied to a call to + * _mali_ukk_mem_mmap that returned the values of mapping and cookie. + * + * An error will be returned if an attempt is made to unmap only part of the + * originally obtained range, or to unmap more than was originally obtained. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + void *mapping; /**< [in] The mapping returned from mmap call */ + u32 size; /**< [in] The size passed to mmap call */ + u32 cookie; /**< [in] Cookie from mmap call */ +} _mali_uk_mem_munmap_s; +/** @} */ /* end group _mali_uk_memory */ + +/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module + * @{ */ + +/** @brief VSYNC events + * + * These events are reported when DDK starts to wait for vsync and when the + * vsync has occured and the DDK can continue on the next frame. + */ +typedef enum _mali_uk_vsync_event +{ + _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0, + _MALI_UK_VSYNC_EVENT_END_WAIT +} _mali_uk_vsync_event; + +/** @brief Arguments to _mali_ukk_vsync_event() + * + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + _mali_uk_vsync_event event; /**< [in] VSYNCH event type */ +} _mali_uk_vsync_event_report_s; + +/** @} */ /* end group _mali_uk_vsync */ + +/** @defgroup _mali_uk_sw_counters_report U/K Software Counter Reporting + * @{ */ + +/** @brief Software counter values + * + * Values recorded for each of the software counters during a single renderpass. + */ +typedef struct +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32* counters; /**< [in] The array of counter values */ + u32 num_counters; /**< [in] The number of elements in counters array */ +} _mali_uk_sw_counters_report_s; + +/** @} */ /* end group _mali_uk_sw_counters_report */ + +/** @} */ /* end group u_k_api */ + +/** @} */ /* end group uddapi */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MALI_UTGARD_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c b/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c deleted file mode 100644 index 04f57d9..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c +++ /dev/null @@ -1,72 +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. - */ - -/** - * @file mali_device_pause_resume.c - * Implementation of the Mali pause/resume functionality - */ -#if USING_MALI_PMM -#include -#include -#include -#include "mali_osk.h" -#include "mali_kernel_common.h" -#include "mali_platform.h" -#include "mali_linux_pm.h" -#include "mali_device_pause_resume.h" -#include "mali_pmm.h" -#include "mali_kernel_license.h" -#ifdef CONFIG_PM -#if MALI_LICENSE_IS_GPL - -/* Mali Pause Resume APIs */ -int mali_dev_pause() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND) - || (mali_device_state == _MALI_DEVICE_SUSPEND) ) - { - err = -EPERM; - } - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err)) - { - mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_SUSPEND; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_pause); - -int mali_dev_resume() -{ - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) - || (mali_device_state == _MALI_DEVICE_SUSPEND) ) - { - err = -EPERM; - } - if (!err) - { - mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread); - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - } - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -EXPORT_SYMBOL(mali_dev_resume); - -#endif /* MALI_LICENSE_IS_GPL */ -#endif /* CONFIG_PM */ -#endif /* USING_MALI_PMM */ diff --git a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h deleted file mode 100644 index 155a3e6..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h +++ /dev/null @@ -1,19 +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 __MALI_DEVICE_PAUSE_RESUME_H__ -#define __MALI_DEVICE_PAUSE_RESUME_H__ - -#if USING_MALI_PMM -int mali_dev_pause(void); -int mali_dev_resume(void); -#endif /* USING_MALI_PMM */ - -#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h b/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h index 7e3a216..6fc59a7 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -44,8 +44,10 @@ extern "C" #define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *) #define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *) #define MALI_IOC_POST_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *) -#define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, _mali_uk_get_big_block_s *) -#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, _mali_uk_free_big_block_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_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 *) #define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *) #define MALI_IOC_MEM_TERM _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *) #define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *) @@ -57,9 +59,7 @@ extern "C" #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 *) #define MALI_IOC_PP_CORE_VERSION_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * ) -#define MALI_IOC_PP_ABORT_JOB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_ABORT_JOB, _mali_uk_pp_abort_job_s * ) #define MALI_IOC_GP2_START_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *) -#define MALI_IOC_GP2_ABORT_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_ABORT_JOB, _mali_uk_gp_abort_job_s *) #define MALI_IOC_GP2_NUMBER_OF_CORES_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *) #define MALI_IOC_GP2_CORE_VERSION_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *) #define MALI_IOC_GP2_SUSPEND_RESPONSE _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *) @@ -68,8 +68,7 @@ extern "C" #define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *) #define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *) #define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *) -#define MALI_IOC_TRANSFER_SW_COUNTERS _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_TRANSFER_SW_COUNTERS, _mali_uk_sw_counters_s *) -#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_profiling_get_config_s *) +#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_get_user_settings_s *) #define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *) #ifdef __cplusplus diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c index 05762ca..3de368e 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c @@ -1,5 +1,5 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -15,31 +15,31 @@ #include /* kernel module definitions */ #include /* file system operations */ #include /* character device definitions */ -#include /* memory mananger definitions */ -#include - -/* the mali kernel subsystem types */ -#include "mali_kernel_subsystem.h" - -/* A memory subsystem always exists, so no need to conditionally include it */ +#include /* memory mananger definitions */ +#include #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_kernel_core.h" - #include "mali_osk.h" #include "mali_kernel_linux.h" #include "mali_ukk.h" -#include "mali_kernel_ioctl.h" #include "mali_ukk_wrappers.h" #include "mali_kernel_pm.h" -#include "mali_linux_pm.h" - #include "mali_kernel_sysfs.h" - -/* */ +#include "mali_platform.h" #include "mali_kernel_license.h" -#include "mali_platform.h" +/* Streamline support for the Mali driver */ +#if defined(CONFIG_TRACEPOINTS) && MALI_TIMELINE_PROFILING_ENABLED +/* 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); @@ -58,23 +58,15 @@ int mali_major = 0; module_param(mali_major, int, S_IRUGO); /* r--r--r-- */ MODULE_PARM_DESC(mali_major, "Device major number"); -int mali_benchmark = 0; -module_param(mali_benchmark, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */ -MODULE_PARM_DESC(mali_benchmark, "Bypass Mali hardware when non-zero"); - -extern int mali_hang_check_interval; 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"); -extern int mali_max_job_runtime; 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"); -#if defined(USING_MALI400_L2_CACHE) 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"); -#endif #if MALI_TIMELINE_PROFILING_ENABLED extern int mali_boot_profiling; @@ -82,6 +74,10 @@ 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 +/* 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-- */ @@ -154,7 +150,6 @@ MODULE_PARM_DESC(step3_vol, "Mali Current step3_vol"); #endif #endif #endif -#endif extern int mali_gpu_clk; module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */ @@ -167,7 +162,8 @@ 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"); -extern _mali_device_power_states mali_dvfs_device_state; +#endif + static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */ @@ -202,53 +198,74 @@ struct file_operations mali_fops = int mali_driver_init(void) { - int err; -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - err = _mali_dev_platform_register(); - if (err) - { - return err; - } -#endif -#endif -#endif - err = mali_kernel_constructor(); - if (_MALI_OSK_ERR_OK != err) - { -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - _mali_dev_platform_unregister(); -#endif -#endif -#endif - MALI_PRINT(("Failed to initialize driver (error %d)\n", err)); - return -EFAULT; - } + int ret = 0; - /* print build options */ - MALI_DEBUG_PRINT(2, ("%s\n", __malidrv_build_info())); + 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)); - return 0; + 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; + + ret = map_errcode(mali_platform_init()); + if (0 != ret) goto platform_init_failed; + + mali_osk_low_level_mem_init(); + + ret = map_errcode(mali_initialize_subsystems()); + if (0 != ret) goto initialize_subsystems_failed; + + ret = initialize_sysfs(); + if (0 != ret) goto initialize_sysfs_failed; + + 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) { - mali_kernel_destructor(); + MALI_DEBUG_PRINT(2, ("\n")); + MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION)); -#if USING_MALI_PMM -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM + /* No need to terminate sysfs, this will be done automatically along with device termination */ + + mali_terminate_subsystems(); + + mali_osk_low_level_mem_term(); + + mali_platform_deinit(); + + terminate_kernel_device(); _mali_dev_platform_unregister(); + +#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; #endif -#endif -#endif + + MALI_PRINT(("Mali device driver unloaded\n")); } -/* called from _mali_osk_init */ -int initialize_kernel_device(void) +static int initialize_kernel_device(void) { int err; dev_t dev = 0; @@ -284,28 +301,25 @@ int initialize_kernel_device(void) goto init_cdev_err; } - err = mali_sysfs_register(&device, dev, mali_dev_name); - if (err) - { - goto init_sysfs_err; - } - /* Success! */ return 0; -init_sysfs_err: - cdev_del(&device.cdev); init_cdev_err: unregister_chrdev_region(dev, 1/*count*/); init_chrdev_err: return err; } -/* called from _mali_osk_term */ -void terminate_kernel_device(void) +static int initialize_sysfs(void) { dev_t dev = MKDEV(mali_major, 0); - + return mali_sysfs_register(&device, dev, mali_dev_name); +} + +static void terminate_kernel_device(void) +{ + dev_t dev = MKDEV(mali_major, 0); + mali_sysfs_unregister(&device, dev, mali_dev_name); /* unregister char device */ @@ -421,12 +435,6 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return -ENOTTY; } - if (_MALI_DEVICE_SHUTDOWN == mali_dvfs_device_state) - { - MALI_DEBUG_PRINT(7, ("system is shutdown \n")); - return 0; - } - switch(cmd) { case MALI_IOC_GET_SYSTEM_INFO_SIZE: @@ -449,6 +457,10 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); break; + case MALI_IOC_GET_USER_SETTINGS: + err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); + break; + #if MALI_TIMELINE_PROFILING_ENABLED case MALI_IOC_PROFILING_START: err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); @@ -471,8 +483,26 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, break; case MALI_IOC_PROFILING_GET_CONFIG: - err = profiling_get_config_wrapper(session_data, (_mali_uk_profiling_get_config_s __user *)arg); + /* Deprecated: still compatible with get_user_settings */ + err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); + break; + + case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: + err = profiling_report_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_report_s __user *)arg); + break; +#else + + case MALI_IOC_PROFILING_START: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_ADD_EVENT: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_STOP: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_GET_EVENT: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_CLEAR: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_GET_CONFIG: /* FALL-THROUGH */ + case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: /* FALL-THROUGH */ + MALI_DEBUG_PRINT(2, ("Profiling not supported\n")); + err = -ENOTTY; break; + #endif case MALI_IOC_MEM_INIT: @@ -499,14 +529,6 @@ 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; - case MALI_IOC_MEM_GET_BIG_BLOCK: - err = mem_get_big_block_wrapper(filp, (_mali_uk_get_big_block_s __user *)arg); - break; - - case MALI_IOC_MEM_FREE_BIG_BLOCK: - err = mem_free_big_block_wrapper(session_data, (_mali_uk_free_big_block_s __user *)arg); - break; - #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 case MALI_IOC_MEM_ATTACH_UMP: @@ -530,10 +552,6 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); break; - case MALI_IOC_PP_ABORT_JOB: - err = pp_abort_job_wrapper(session_data, (_mali_uk_pp_abort_job_s __user *)arg); - break; - case MALI_IOC_PP_NUMBER_OF_CORES_GET: err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); break; @@ -542,12 +560,12 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); break; - case MALI_IOC_GP2_START_JOB: - err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); + case MALI_IOC_PP_DISABLE_WB: + err = pp_disable_wb_wrapper(session_data, (_mali_uk_pp_disable_wb_s __user *)arg); break; - case MALI_IOC_GP2_ABORT_JOB: - err = gp_abort_job_wrapper(session_data, (_mali_uk_gp_abort_job_s __user *)arg); + case MALI_IOC_GP2_START_JOB: + err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); break; case MALI_IOC_GP2_NUMBER_OF_CORES_GET: @@ -565,10 +583,11 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case MALI_IOC_VSYNC_EVENT_REPORT: err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); break; -#if MALI_TRACEPOINTS_ENABLED - case MALI_IOC_TRANSFER_SW_COUNTERS: - err = transfer_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_s __user *)arg); -#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")); + err = -ENOTTY; break; default: @@ -586,9 +605,3 @@ module_exit(mali_driver_exit); MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE); MODULE_AUTHOR("ARM Ltd."); MODULE_VERSION(SVN_REV_STRING); - -#if MALI_TRACEPOINTS_ENABLED -/* Create the trace points (otherwise we just get code to call a tracepoint) */ -#define CREATE_TRACE_POINTS -#include "mali_linux_trace.h" -#endif diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h index 9c7668c..22dc9a4 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -28,8 +28,10 @@ struct mali_dev #endif }; -_mali_osk_errcode_t initialize_kernel_device(void); -void terminate_kernel_device(void); +#if MALI_LICENSE_IS_GPL +/* Defined in mali_osk_irq.h */ +extern struct workqueue_struct * mali_wq; +#endif void mali_osk_low_level_mem_init(void); void mali_osk_low_level_mem_term(void); diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c index f06ea4b..1d861f5 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c @@ -1,5 +1,5 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -10,615 +10,211 @@ /** * @file mali_kernel_pm.c - * Implementation of the Linux Power Management for Mali GPU kernel driver + * Linux Power Management integration */ -#if USING_MALI_PMM #include - -#ifdef CONFIG_PM_RUNTIME -#include -#endif /* CONFIG_PM_RUNTIME */ - #include #include #include #include - -#include -#include -#include - -#include "mali_platform.h" +#include +#ifdef CONFIG_PM_RUNTIME +#include +#endif #include "mali_osk.h" #include "mali_uk_types.h" -#include "mali_pmm.h" -#include "mali_ukk.h" #include "mali_kernel_common.h" #include "mali_kernel_license.h" -#include "mali_kernel_pm.h" -#include "mali_device_pause_resume.h" #include "mali_linux_pm.h" +#include "mali_pm.h" +#include "mali_platform.h" -#ifdef MALI_REBOOTNOTIFIER -_mali_osk_atomic_t mali_shutdown_state; -#include +#if ! MALI_LICENSE_IS_GPL +#undef CONFIG_PM_RUNTIME #endif -#if MALI_GPU_UTILIZATION -#include "mali_kernel_utilization.h" -#endif /* MALI_GPU_UTILIZATION */ - -#if MALI_POWER_MGMT_TEST_SUITE -#ifdef CONFIG_PM -#include "mali_linux_pm_testsuite.h" -#include "mali_platform_pmu_internal_testing.h" -unsigned int pwr_mgmt_status_reg = 0; -#endif /* CONFIG_PM */ -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - -static int is_os_pmm_thread_waiting = 0; - -/* kernel should be configured with power management support */ -#ifdef CONFIG_PM - -/* License should be GPL */ -#if MALI_LICENSE_IS_GPL - -/* Linux kernel major version */ -#define LINUX_KERNEL_MAJOR_VERSION 2 - -/* Linux kernel minor version */ -#define LINUX_KERNEL_MINOR_VERSION 6 - -/* Linux kernel development version */ -#define LINUX_KERNEL_DEVELOPMENT_VERSION 29 - -#ifdef CONFIG_PM_DEBUG -static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = { - [_MALI_DEVICE_SUSPEND] = "suspend", - [_MALI_DEVICE_RESUME] = "resume", - [_MALI_DVFS_PAUSE_EVENT] = "dvfs_pause", - [_MALI_DVFS_RESUME_EVENT] = "dvfs_resume", -}; - -#endif /* CONFIG_PM_DEBUG */ - #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 -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -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 /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -/* Power management thread pointer */ -struct task_struct *pm_thread; - -/* dvfs power management thread */ -struct task_struct *dvfs_pm_thread; - -/* is wake up needed */ -short is_wake_up_needed = 0; -int timeout_fired = 2; -unsigned int is_mali_pmm_testsuite_enabled = 0; - -_mali_device_power_states mali_device_state = _MALI_DEVICE_RESUME; -_mali_device_power_states mali_dvfs_device_state = _MALI_DEVICE_RESUME; -_mali_osk_lock_t *lock; - -#if MALI_POWER_MGMT_TEST_SUITE - -const char* const mali_pmm_recording_events[_MALI_DEVICE_MAX_PMM_EVENTS] = { - [_MALI_DEVICE_PMM_TIMEOUT_EVENT] = "timeout", - [_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS] = "job_scheduling", - [_MALI_DEVICE_PMM_REGISTERED_CORES] = "cores", - -}; - -unsigned int mali_timeout_event_recording_on = 0; -unsigned int mali_job_scheduling_events_recording_on = 0; -unsigned int is_mali_pmu_present = 0; -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - -/* Function prototypes */ -static int mali_pm_probe(struct platform_device *pdev); -static int mali_pm_remove(struct platform_device *pdev); -static void mali_pm_shutdown(struct platform_device *pdev); - -/* Mali device suspend function */ -static int mali_pm_suspend(struct device *dev); - -/* Mali device resume function */ -static int mali_pm_resume(struct device *dev); - -/* Run time suspend and resume functions */ -#ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -static int mali_device_runtime_suspend(struct device *dev); -static int mali_device_runtime_resume(struct device *dev); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -/* OS suspend and resume callbacks */ -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON -#ifndef CONFIG_PM_RUNTIME -#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state); -#else -static int mali_pm_os_suspend(struct device *dev); +static int mali_runtime_suspend(struct device *dev); +static int mali_runtime_resume(struct device *dev); #endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -static int mali_pm_os_resume(struct platform_device *pdev); +#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_pm_os_resume(struct device *dev); +static int mali_os_suspend(struct device *dev); +static int mali_os_resume(struct device *dev); #endif -#endif /* CONFIG_PM_RUNTIME */ -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ - -/* OS Hibernation suspend callback */ -static int mali_pm_os_suspend_on_hibernation(struct device *dev); - -/* OS Hibernation resume callback */ -static int mali_pm_os_resume_on_hibernation(struct device *dev); - -static void _mali_release_pm(struct device* device); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -static const struct dev_pm_ops mali_dev_pm_ops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +static const struct dev_pm_ops mali_dev_pm_ops = +{ #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - .runtime_suspend = mali_device_runtime_suspend, - .runtime_resume = mali_device_runtime_resume, -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -#ifndef CONFIG_PM_RUNTIME -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON - .suspend = mali_pm_os_suspend, - .resume = mali_pm_os_resume, -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - .freeze = mali_pm_os_suspend_on_hibernation, - .poweroff = mali_pm_os_suspend_on_hibernation, - .thaw = mali_pm_os_resume_on_hibernation, - .restore = mali_pm_os_resume_on_hibernation, -}; + .runtime_suspend = mali_runtime_suspend, + .runtime_resume = mali_runtime_resume, + .runtime_idle = NULL, +#else + .suspend = mali_os_suspend, + .resume = mali_os_resume, #endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -struct pm_ext_ops mali_pm_operations = { - .base = { - .freeze = mali_pm_os_suspend_on_hibernation, - .thaw = mali_pm_os_resume_on_hibernation, - .poweroff = mali_pm_os_resume_on_hibernation, - .restore = mali_pm_os_resume_on_hibernation, + .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_pm_probe, - .remove = mali_pm_remove, - .shutdown = mali_pm_shutdown, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -#ifndef CONFIG_PM_RUNTIME -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON - .suspend = mali_pm_os_suspend, - .resume = mali_pm_os_resume, -#endif /* CONFIG_PM_RUNTIME */ -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ - .pm = &mali_pm_operations, + +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 = { + .driver = + { .name = "mali_dev", .owner = THIS_MODULE, +#if MALI_LICENSE_IS_GPL .bus = &platform_bus_type, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) .pm = &mali_dev_pm_ops, #endif - }, + }, }; -/* Mali GPU platform device */ -struct platform_device mali_gpu_device = { - .name = "mali_dev", - .id = 0, - .dev.release = _mali_release_pm +#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) { - MALI_DEBUG_PRINT(4, ("OSPMM: MALI Platform device removed\n" )); } - -#if MALI_POWER_MGMT_TEST_SUITE -void mali_is_pmu_present(void) +struct platform_device mali_gpu_device = { - int temp = 0; - temp = pmu_get_power_up_down_info(); - if (4095 == temp) - { - is_mali_pmu_present = 0; - } - else - { - is_mali_pmu_present = 1; - } -} -#endif /* MALI_POWER_MGMT_TEST_SUITE */ -#endif /* MALI_LICENSE_IS_GPL */ - -#if MALI_LICENSE_IS_GPL - -static int mali_wait_for_power_management_policy_event(void) -{ - int err = 0; - for (; ;) - { - set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) - { - err = -EINTR; - break; - } - if (is_wake_up_needed == 1) - { - break; - } - schedule(); - } - __set_current_state(TASK_RUNNING); - is_wake_up_needed =0; - return err; -} + .name = "mali_dev", + .id = 0, + .dev.release = _mali_release_pm +}; -/** This function is invoked when mali device is suspended - */ -int mali_device_suspend(unsigned int event_id, struct task_struct **pwr_mgmt_thread) +/** This function is called when the device is probed */ +static int mali_probe(struct platform_device *pdev) { - int err = 0; - _mali_uk_pmm_message_s event = { - NULL, - event_id, - timeout_fired}; - *pwr_mgmt_thread = current; - MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being suspended\n" )); - _mali_ukk_pmm_event_message(&event); - is_os_pmm_thread_waiting = 1; - err = mali_wait_for_power_management_policy_event(); - is_os_pmm_thread_waiting = 0; - return err; + return 0; } -/** This function is called when Operating system wants to power down - * the mali GPU device. - */ -static int mali_pm_suspend(struct device *dev) +static int mali_remove(struct platform_device *pdev) { - int err = 0; - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - if ((mali_device_state == _MALI_DEVICE_SUSPEND)) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; - } -#if MALI_DVFS_ENABLED - mali_utilization_suspend(); -#endif - err = mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread); - mali_device_state = _MALI_DEVICE_SUSPEND; - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -#ifndef CONFIG_PM_RUNTIME -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state) -#else -static int mali_pm_os_suspend(struct device *dev) +#ifdef CONFIG_PM_RUNTIME + pm_runtime_disable(&pdev->dev); #endif -{ - int err = 0; - err = mali_pm_suspend(NULL); - return err; + return 0; } -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy) { - int err = 0; switch (event) { case PM_SUSPEND_PREPARE: - err = mali_pm_suspend(NULL); - break; - + MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n")); + mali_pm_os_suspend(); + break; case PM_POST_SUSPEND: - err = mali_pm_resume(NULL); - break; + MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n")); + mali_pm_os_resume(); + break; default: - break; + break; } return 0; } -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -/** This function is called when mali GPU device is to be resumed. - */ -int mali_device_resume(unsigned int event_id, struct task_struct **pwr_mgmt_thread) -{ - int err = 0; - _mali_uk_pmm_message_s event = { - NULL, - event_id, - timeout_fired}; - *pwr_mgmt_thread = current; - MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being resumed\n" )); - _mali_ukk_pmm_event_message(&event); - MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power up event is scheduled\n" )); - is_os_pmm_thread_waiting = 1; - err = mali_wait_for_power_management_policy_event(); - is_os_pmm_thread_waiting = 0; - return err; -} - -/** This function is called when mali GPU device is to be resumed - */ -static int mali_pm_resume(struct device *dev) -{ - int err = 0; - - _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); - -#ifdef CONFIG_REGULATOR - mali_regulator_enable(); -#endif - - if (mali_device_state == _MALI_DEVICE_RESUME) - { - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; - } - err = mali_device_resume(MALI_PMM_EVENT_OS_POWER_UP, &pm_thread); - mali_device_state = _MALI_DEVICE_RESUME; - mali_dvfs_device_state = _MALI_DEVICE_RESUME; - _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); - return err; -} - -#ifndef CONFIG_PM_RUNTIME -#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON -#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION)) -static int mali_pm_os_resume(struct platform_device *pdev) -#else -static int mali_pm_os_resume(struct device *dev) #endif -{ - int err = 0; - err = mali_pm_resume(NULL); - return err; -} -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -static int mali_pm_os_suspend_on_hibernation(struct device *dev) -{ - int err = 0; - err = mali_pm_suspend(NULL); - return err; -} -static int mali_pm_os_resume_on_hibernation(struct device *dev) -{ - int err = 0; - err = mali_pm_resume(NULL); - return err; -} #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -/** This function is called when runtime suspend of mali device is required. - */ -static int mali_device_runtime_suspend(struct device *dev) -{ - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time suspended \n" )); - return 0; -} -/** This function is called when runtime resume of mali device is required. - */ -static int mali_device_runtime_resume(struct device *dev) +static int mali_runtime_suspend(struct device *dev) { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time Resumed \n" )); - return 0; + MALI_DEBUG_PRINT(3, ("mali_runtime_suspend() called\n")); + mali_pm_runtime_suspend(); + return 0; /* all ok */ } -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ -#ifdef CONFIG_PM_DEBUG - -/** This function is used for debugging purposes when the user want to see - * which power management operations are supported for - * mali device. - */ -static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) +static int mali_runtime_resume(struct device *dev) { - char *str = buf; -#if !MALI_POWER_MGMT_TEST_SUITE - int pm_counter = 0; - for (pm_counter = 0; pm_counter<_MALI_MAX_DEBUG_OPERATIONS; pm_counter++) - { - str += sprintf(str, "%s ", mali_states[pm_counter]); - } -#else - str += sprintf(str, "%d ",pwr_mgmt_status_reg); -#endif - if (str != buf) - { - *(str-1) = '\n'; - } - return (str-buf); + MALI_DEBUG_PRINT(3, ("mali_runtime_resume() called\n")); + mali_pm_runtime_resume(); + return 0; /* all ok */ } -/** This function is called when user wants to suspend the mali GPU device in order - * to simulate the power up and power down events. - */ -static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - int err = 0; - -#if MALI_POWER_MGMT_TEST_SUITE - int test_flag_dvfs = 0; - pwr_mgmt_status_reg = 0; - mali_is_pmu_present(); - #endif - if (!strncmp(buf,mali_states[_MALI_DEVICE_SUSPEND],strlen(mali_states[_MALI_DEVICE_SUSPEND]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI suspend Power operation is scheduled\n" )); - err = mali_pm_suspend(NULL); - } -#if MALI_POWER_MGMT_TEST_SUITE - else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Device get number of registerd cores\n" )); - pwr_mgmt_status_reg = _mali_pmm_cores_list(); - return count; - } - else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI timeout event recording is enabled\n" )); - mali_timeout_event_recording_on = 1; - } - else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Job scheduling events recording is enabled\n" )); - mali_job_scheduling_events_recording_on = 1; - } -#endif /* MALI_POWER_MGMT_TEST_SUITE */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) - else if (!strncmp(buf,mali_states[_MALI_DEVICE_RESUME],strlen(mali_states[_MALI_DEVICE_RESUME]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" )); - err = mali_pm_resume(NULL); - } - else if (!strncmp(buf,mali_states[_MALI_DVFS_PAUSE_EVENT],strlen(mali_states[_MALI_DVFS_PAUSE_EVENT]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Pause Power operation is scheduled\n" )); - err = mali_dev_pause(); -#if MALI_POWER_MGMT_TEST_SUITE - test_flag_dvfs = 1; -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - } - else if (!strncmp(buf,mali_states[_MALI_DVFS_RESUME_EVENT],strlen(mali_states[_MALI_DVFS_RESUME_EVENT]))) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Resume Power operation is scheduled\n" )); - err = mali_dev_resume(); -#if MALI_POWER_MGMT_TEST_SUITE - test_flag_dvfs = 1; -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - } - else - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Invalid Power Mode Operation selected\n" )); - } -#if MALI_POWER_MGMT_TEST_SUITE - if (test_flag_dvfs == 1) - { - if (err) - { - pwr_mgmt_status_reg = 2; - } - else - { - pwr_mgmt_status_reg = 1; - } - } - else - { - if (1 == is_mali_pmu_present) - { - pwr_mgmt_status_reg = pmu_get_power_up_down_info(); - } - } -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - return count; -} - -/* Device attribute file */ -static DEVICE_ATTR(file, 0644, show_file, store_file); -#endif /* CONFIG_PM_DEBUG */ - -static int mali_pm_remove(struct platform_device *pdev) +static int mali_os_suspend(struct platform_device *pdev, pm_message_t state) { -#ifdef CONFIG_PM_DEBUG - device_remove_file(&mali_gpu_device.dev, &dev_attr_file); -#endif /* CONFIG_PM_DEBUG */ -#ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - pm_runtime_disable(&pdev->dev); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - return 0; + MALI_DEBUG_PRINT(3, ("mali_os_suspend(old) called\n")); + mali_pm_os_suspend(); + return 0; /* all ok */ } -int mali_pd_enable(void) +static int mali_os_resume(struct platform_device *pdev) { - return exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev); + MALI_DEBUG_PRINT(3, ("mali_os_resume(old) called\n")); + mali_pm_os_resume(); + return 0; /* all ok */ } -static void mali_pm_shutdown(struct platform_device *pdev) -{ - MALI_PRINT(("Mali shutdown!!\n")); - mali_dvfs_device_state =_MALI_DEVICE_SHUTDOWN; - exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev); - return; -} +#else -/** This function is called when the device is probed */ -static int mali_pm_probe(struct platform_device *pdev) +static int mali_os_suspend(struct device *dev) { -#ifdef CONFIG_PM_DEBUG - int err; - err = device_create_file(&mali_gpu_device.dev, &dev_attr_file); - if (err) - { - MALI_DEBUG_PRINT(4, ("PMMDEBUG: Error in creating device file\n" )); - } -#endif /* CONFIG_PM_DEBUG */ - return 0; + MALI_DEBUG_PRINT(3, ("mali_os_suspend(new) called\n")); + mali_pm_os_suspend(); + return 0; /* all ok */ } -#ifdef MALI_REBOOTNOTIFIER -static int mali_reboot_notify(struct notifier_block *this, - unsigned long code, void *unused) + +static int mali_os_resume(struct device *dev) { - _mali_osk_atomic_inc_return(&mali_shutdown_state); - mali_dvfs_device_state = _MALI_DEVICE_SHUTDOWN; - MALI_PRINT(("REBOOT Notifier for mali\n")); - return NOTIFY_DONE; + MALI_DEBUG_PRINT(3, ("mali_os_resume(new) called\n")); + mali_pm_os_resume(); + return 0; /* all ok */ } -static struct notifier_block mali_reboot_notifier = { - .notifier_call = mali_reboot_notify, -}; + #endif /** This function is called when Mali GPU device is initialized @@ -626,50 +222,34 @@ static struct notifier_block mali_reboot_notifier = { int _mali_dev_platform_register(void) { int err; -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON + +#ifdef CONFIG_PM_RUNTIME set_mali_parent_power_domain((void *)&mali_gpu_device); #endif #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON err = register_pm_notifier(&mali_pwr_notif_block); if (err) { return err; } -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -#ifdef MALI_REBOOTNOTIFIER - _mali_osk_atomic_init(&mali_shutdown_state, 0); - err = register_reboot_notifier(&mali_reboot_notifier); - if (err) { - MALI_PRINT(("Failed to setup reboot notifier\n")); - return err; - } #endif +#if MALI_LICENSE_IS_GPL err = platform_device_register(&mali_gpu_device); - lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if (!err) { err = platform_driver_register(&mali_plat_driver); if (err) { - _mali_osk_lock_term(lock); #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON unregister_pm_notifier(&mali_pwr_notif_block); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -#ifdef MALI_REBOOTNOTIFIER - unregister_reboot_notifier(&mali_reboot_notifier); #endif - platform_device_unregister(&mali_gpu_device); } } +#endif + return err; } @@ -677,33 +257,12 @@ int _mali_dev_platform_register(void) */ void _mali_dev_platform_unregister(void) { - _mali_osk_lock_term(lock); - #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON unregister_pm_notifier(&mali_pwr_notif_block); -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ - -#ifdef MALI_REBOOTNOTIFIER - unregister_reboot_notifier(&mali_reboot_notifier); #endif + +#if MALI_LICENSE_IS_GPL platform_driver_unregister(&mali_plat_driver); platform_device_unregister(&mali_gpu_device); +#endif } - -int mali_get_ospmm_thread_state(void) -{ - return is_os_pmm_thread_waiting; -} - -#endif /* MALI_LICENSE_IS_GPL */ -#endif /* CONFIG_PM */ - -#if MALI_STATE_TRACKING -u32 mali_pmm_dump_os_thread_state( char *buf, u32 size ) -{ - return snprintf(buf, size, "OSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false"); -} -#endif /* MALI_STATE_TRACKING */ -#endif /* USING_MALI_PMM */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h index 1c44439..6ef7270 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -11,10 +11,7 @@ #ifndef __MALI_KERNEL_PM_H__ #define __MALI_KERNEL_PM_H__ -#ifdef USING_MALI_PMM int _mali_dev_platform_register(void); void _mali_dev_platform_unregister(void); -#endif /* USING_MALI_PMM */ -int mali_pd_enable(void); #endif /* __MALI_KERNEL_PM_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c index 6dcf052..64853d7 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c @@ -1,5 +1,5 @@ -/* - * Copyright (C) 2010 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. @@ -9,28 +9,741 @@ */ -/** - * @file mali_kernel_sysfs.c - * Implementation of some sysfs data exports - */ +/** + * @file mali_kernel_sysfs.c + * Implementation of some sysfs data exports + */ + +#include +#include +#include +#include +#include +#include +#include "mali_kernel_license.h" +#include "mali_kernel_common.h" +#include "mali_kernel_linux.h" +#include "mali_ukk.h" + +#if MALI_LICENSE_IS_GPL + +#include +#include +#include +#include +#include "mali_kernel_sysfs.h" +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include +#include "mali_osk_profiling.h" +#endif +#include "mali_pm.h" +#include "mali_cluster.h" +#include "mali_group.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_l2_cache.h" +#include "mali_hw_core.h" +#include "mali_kernel_core.h" +#include "mali_user_settings_db.h" +#include "mali_device_pause_resume.h" + +#define POWER_BUFFER_SIZE 3 + +static struct dentry *mali_debugfs_dir = NULL; + +typedef enum +{ + _MALI_DEVICE_SUSPEND, + _MALI_DEVICE_RESUME, + _MALI_DEVICE_DVFS_PAUSE, + _MALI_DEVICE_DVFS_RESUME, + _MALI_MAX_EVENTS +} _mali_device_debug_power_events; + +static const char* const mali_power_events[_MALI_MAX_EVENTS] = { + [_MALI_DEVICE_SUSPEND] = "suspend", + [_MALI_DEVICE_RESUME] = "resume", + [_MALI_DEVICE_DVFS_PAUSE] = "dvfs_pause", + [_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume", +}; + +static u32 virtual_power_status_register=0; +static char pwr_buf[POWER_BUFFER_SIZE]; + +static int open_copy_private_data(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + +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); + } + else + { + val = mali_gp_core_get_counter_src1(gp_core); + } + + if (MALI_HW_CORE_NO_COUNTER == val) + { + r = sprintf(buf, "-1\n"); + } + else + { + r = sprintf(buf, "%u\n", val); + } + return simple_read_from_buffer(ubuf, cnt, gpos, buf, r); +} + +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; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + if (0 == src_id) + { + if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val)) + { + return 0; + } + } + + *gpos += cnt; + return cnt; +} + +static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id) +{ + char buf[64]; + long val; + int ret; + u32 ci; + struct mali_cluster *cluster; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + struct mali_gp_core *gp_core = mali_group_get_gp_core(group); + if (NULL != gp_core) + { + if (0 == src_id) + { + if (MALI_TRUE != mali_gp_core_set_counter_src0(gp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val)) + { + 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; + return cnt; +} + +static ssize_t gp_gpx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 0); +} + +static ssize_t gp_gpx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 1); +} + +static ssize_t gp_gpx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 0); +} + +static ssize_t gp_gpx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 1); +} + +static ssize_t gp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 0); +} + +static ssize_t gp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos) +{ + return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 1); +} + +static const struct file_operations gp_gpx_counter_src0_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = gp_gpx_counter_src0_read, + .write = gp_gpx_counter_src0_write, +}; + +static const struct file_operations gp_gpx_counter_src1_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = gp_gpx_counter_src1_read, + .write = gp_gpx_counter_src1_write, +}; + +static const struct file_operations gp_all_counter_src0_fops = { + .owner = THIS_MODULE, + .write = gp_all_counter_src0_write, +}; + +static const struct file_operations gp_all_counter_src1_fops = { + .owner = THIS_MODULE, + .write = gp_all_counter_src1_write, +}; + +static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + 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); + } + else + { + val = mali_pp_core_get_counter_src1(pp_core); + } + + if (MALI_HW_CORE_NO_COUNTER == val) + { + r = sprintf(buf, "-1\n"); + } + else + { + r = sprintf(buf, "%u\n", val); + } + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +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; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + if (0 == src_id) + { + if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val)) + { + return 0; + } + } + + *ppos += cnt; + return cnt; +} + +static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + char buf[64]; + long val; + int ret; + u32 ci; + struct mali_cluster *cluster; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + struct mali_pp_core *pp_core = mali_group_get_pp_core(group); + if (NULL != pp_core) + { + if (0 == src_id) + { + if (MALI_TRUE != mali_pp_core_set_counter_src0(pp_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val)) + { + 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; + return cnt; +} + +static ssize_t pp_ppx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t pp_ppx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t pp_ppx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t pp_ppx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t pp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t pp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static const struct file_operations pp_ppx_counter_src0_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = pp_ppx_counter_src0_read, + .write = pp_ppx_counter_src0_write, +}; + +static const struct file_operations pp_ppx_counter_src1_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = pp_ppx_counter_src1_read, + .write = pp_ppx_counter_src1_write, +}; + +static const struct file_operations pp_all_counter_src0_fops = { + .owner = THIS_MODULE, + .write = pp_all_counter_src0_write, +}; + +static const struct file_operations pp_all_counter_src1_fops = { + .owner = THIS_MODULE, + .write = pp_all_counter_src1_write, +}; + + + -#include -#include -#include "mali_kernel_license.h" -#include "mali_kernel_linux.h" -#include "mali_ukk.h" -#if MALI_LICENSE_IS_GPL -#include -#include -#include -#include -#include "mali_kernel_subsystem.h" -#include "mali_kernel_sysfs.h" -#include "mali_kernel_profiling.h" +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]; + int r; + u32 val; + struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data; + + if (0 == src_id) + { + val = mali_l2_cache_core_get_counter_src0(l2_core); + } + else + { + val = mali_l2_cache_core_get_counter_src1(l2_core); + } + + if (MALI_HW_CORE_NO_COUNTER == val) + { + r = sprintf(buf, "-1\n"); + } + else + { + r = sprintf(buf, "%u\n", val); + } + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t l2_l2x_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data; + char buf[64]; + long val; + int ret; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + if (0 == src_id) + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_core, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_core, (u32)val)) + { + return 0; + } + } + + *ppos += cnt; + return cnt; +} + +static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id) +{ + char buf[64]; + long val; + int ret; + u32 l2_id; + struct mali_l2_cache_core *l2_cache; + + if (cnt >= sizeof(buf)) + { + return -EINVAL; + } + + if (copy_from_user(&buf, ubuf, cnt)) + { + return -EFAULT; + } + + buf[cnt] = 0; + + ret = strict_strtol(buf, 10, &val); + if (ret < 0) + { + return ret; + } + + if (val < 0) + { + /* any negative input will disable counter */ + val = MALI_HW_CORE_NO_COUNTER; + } + + l2_id = 0; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + while (NULL != l2_cache) + { + if (0 == src_id) + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val)) + { + return 0; + } + } + else + { + if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val)) + { + return 0; + } + } + + /* try next L2 */ + l2_id++; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + } + + *ppos += cnt; + return cnt; +} + +static ssize_t l2_l2x_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t l2_l2x_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t l2_l2x_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t l2_l2x_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static ssize_t l2_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0); +} + +static ssize_t l2_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +{ + return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1); +} + +static const struct file_operations l2_l2x_counter_src0_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = l2_l2x_counter_src0_read, + .write = l2_l2x_counter_src0_write, +}; + +static const struct file_operations l2_l2x_counter_src1_fops = { + .owner = THIS_MODULE, + .open = open_copy_private_data, + .read = l2_l2x_counter_src1_read, + .write = l2_l2x_counter_src1_write, +}; + +static const struct file_operations l2_all_counter_src0_fops = { + .owner = THIS_MODULE, + .write = l2_all_counter_src0_write, +}; + +static const struct file_operations l2_all_counter_src1_fops = { + .owner = THIS_MODULE, + .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) +{ + + memset(pwr_buf,0,POWER_BUFFER_SIZE); + virtual_power_status_register = 0; + 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; + } + } + 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) +{ + file->f_pos = offset; + return 0; +} + +static const struct file_operations power_events_fops = { + .owner = THIS_MODULE, + .read = power_events_read, + .write = power_events_write, + .llseek = power_events_seek, +}; -static struct dentry *mali_debugfs_dir = NULL; #if MALI_STATE_TRACKING static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v) @@ -72,13 +785,13 @@ static const struct file_operations mali_seq_internal_state_fops = { #endif /* MALI_STATE_TRACKING */ -#if MALI_TIMELINE_PROFILING_ENABLED +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED 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_profiling_is_recording() ? 1 : 0); + r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -111,16 +824,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_profiling_is_recording()) + if (MALI_TRUE == _mali_osk_profiling_is_recording()) { MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); return -EFAULT; } /* check if we need to clear out an old recording first */ - if (MALI_TRUE == _mali_profiling_have_recording()) + if (MALI_TRUE == _mali_osk_profiling_have_recording()) { - if (_MALI_OSK_ERR_OK != _mali_profiling_clear()) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear()) { MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); return -EFAULT; @@ -128,7 +841,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf } /* start recording profiling data */ - if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) { MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); return -EFAULT; @@ -140,7 +853,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_profiling_stop(&count)) + if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count)) { MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); return -EFAULT; @@ -164,7 +877,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_profiling_have_recording()) + if (MALI_TRUE != _mali_osk_profiling_have_recording()) { return NULL; } @@ -184,13 +897,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_profiling_have_recording()) + if (MALI_TRUE != _mali_osk_profiling_have_recording()) { return NULL; } /* check if the next entry actually is avaiable */ - if (_mali_profiling_get_count() <= (u32)(*spos + 1)) + if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1)) { return NULL; } @@ -215,7 +928,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_profiling_get_event(index, ×tamp, &event_id, data)) + if (_MALI_OSK_ERR_OK == _mali_osk_profiling_get_event(index, ×tamp, &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; @@ -243,68 +956,89 @@ static const struct file_operations profiling_events_fops = { .llseek = seq_lseek, .release = seq_release, }; +#endif -static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[64]; - int r; + size_t r; + u32 mem = _mali_ukk_report_memory_usage(); - r = sprintf(buf, "%u\n", _mali_profiling_get_default_enable_state() ? 1 : 0); + r = snprintf(buf, 64, "%u\n", mem); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } -static ssize_t profiling_proc_default_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) +static const struct file_operations memory_usage_fops = { + .owner = THIS_MODULE, + .read = memory_used_read, +}; + + +static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { - char buf[64]; unsigned long val; int ret; + _mali_uk_user_setting_t setting; + char buf[32]; - if (cnt >= sizeof(buf)) - { - return -EINVAL; - } - - if (copy_from_user(&buf, ubuf, cnt)) + cnt = min(cnt, sizeof(buf) - 1); + if (copy_from_user(buf, ubuf, cnt)) { return -EFAULT; } - - buf[cnt] = 0; + buf[cnt] = '\0'; ret = strict_strtoul(buf, 10, &val); - if (ret < 0) + if (0 != ret) { return ret; } - _mali_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE); + /* Update setting */ + setting = (_mali_uk_user_setting_t)(filp->private_data); + mali_set_user_setting(setting, val); *ppos += cnt; return cnt; } -static const struct file_operations profiling_proc_default_enable_fops = { - .owner = THIS_MODULE, - .read = profiling_proc_default_enable_read, - .write = profiling_proc_default_enable_write, -}; -#endif - -static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +static ssize_t user_settings_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[64]; size_t r; - u32 mem = _mali_ukk_report_memory_usage(); + u32 value; + _mali_uk_user_setting_t setting; - r = snprintf(buf, 64, "%u\n", mem); + setting = (_mali_uk_user_setting_t)(filp->private_data); + value = mali_get_user_setting(setting); + + r = snprintf(buf, 64, "%u\n", value); return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } -static const struct file_operations memory_usage_fops = { +static const struct file_operations user_settings_fops = { .owner = THIS_MODULE, - .read = memory_used_read, + .open = open_copy_private_data, + .read = user_settings_read, + .write = user_settings_write, }; +static int mali_sysfs_user_settings_register(void) +{ + struct dentry *mali_user_settings_dir = debugfs_create_dir("userspace_settings", mali_debugfs_dir); + + if (mali_user_settings_dir != NULL) + { + int i; + for (i = 0; i < _MALI_UK_USER_SETTING_MAX; i++) + { + debugfs_create_file(_mali_uk_user_setting_descriptions[i], 0600, mali_user_settings_dir, (void*)i, &user_settings_fops); + } + } + + return 0; +} + int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) { int err = 0; @@ -334,8 +1068,151 @@ 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 */ -#if MALI_TIMELINE_PROFILING_ENABLED - struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_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 + struct dentry *mali_profiling_dir; +#endif + + 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_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; + + 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); + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + 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) + { + 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 */ + } + + /* try next group */ + gi++; + group = mali_cluster_get_group(cluster, gi); + } + + /* try next cluster */ + ci++; + cluster = mali_cluster_get_global_cluster(ci); + } + } + + mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir); + if (mali_pp_dir != NULL) + { + struct dentry *mali_pp_all_dir; + u32 ci; + struct mali_cluster *cluster; + + 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); + } + + ci = 0; + cluster = mali_cluster_get_global_cluster(ci); + while (NULL != cluster) + { + u32 gi = 0; + struct mali_group *group = mali_cluster_get_group(cluster, gi); + while (NULL != group) + { + 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) + { + 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); + } + } + + /* try next group */ + gi++; + group = mali_cluster_get_group(cluster, gi); + } + + /* try next cluster */ + ci++; + cluster = mali_cluster_get_global_cluster(ci); + } + } + + mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir); + if (mali_l2_dir != NULL) + { + struct dentry *mali_l2_all_dir; + u32 l2_id; + struct mali_l2_cache_core *l2_cache; + + 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); + } + + l2_id = 0; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + while (NULL != l2_cache) + { + char buf[16]; + struct dentry *mali_l2_l2x_dir; + _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id); + mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir); + if (NULL != mali_l2_l2x_dir) + { + 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); + } + + /* try next L2 */ + l2_id++; + l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); + } + } + + debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); + +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); if (mali_profiling_dir != NULL) { struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); @@ -344,7 +1221,7 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); if (mali_profiling_proc_default_dir != NULL) { - debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, NULL, &profiling_proc_default_enable_fops); + debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops); } } debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); @@ -356,7 +1233,11 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); #endif - debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); + if (mali_sysfs_user_settings_register()) + { + /* Failed to create the debugfs entries for the user settings DB. */ + MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n")); + } } } @@ -385,7 +1266,7 @@ int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_d #else -/* Dummy implementations for when the sysfs API isn't available. */ +/* Dummy implementations for non-GPL */ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) { diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h index f68b4e1..d79a886 100644 --- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h +++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 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_linux_pm.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h index a8c0c52..10f633e 100644 --- a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h +++ b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h @@ -1,5 +1,6 @@ + /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -11,8 +12,6 @@ #ifndef __MALI_LINUX_PM_H__ #define __MALI_LINUX_PM_H__ -#if USING_MALI_PMM - #ifdef CONFIG_PM /* Number of power states supported for making power up and down */ typedef enum @@ -20,7 +19,6 @@ typedef enum _MALI_DEVICE_SUSPEND, /* Suspend */ _MALI_DEVICE_RESUME, /* Resume */ _MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */ - _MALI_DEVICE_SHUTDOWN, /* Power off states*/ } _mali_device_power_states; /* Number of DVFS events */ @@ -49,5 +47,4 @@ int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread); int mali_get_ospmm_thread_state(void); #endif /* CONFIG_PM */ -#endif /* USING_MALI_PMM */ #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 index 7b1bff9..7d811bd 100644 --- a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h +++ b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -10,9 +10,7 @@ #ifndef __MALI_LINUX_PM_TESTSUITE_H__ #define __MALI_LINUX_PM_TESTSUITE_H__ -#if USING_MALI_PMM -#if MALI_POWER_MGMT_TEST_SUITE -#ifdef CONFIG_PM +#if MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) typedef enum { @@ -29,9 +27,6 @@ extern unsigned int pwr_mgmt_status_reg; extern unsigned int is_mali_pmm_testsuite_enabled; extern unsigned int is_mali_pmu_present; -#endif /* CONFIG_PM */ -#endif /* MALI_POWER_MGMT_TEST_SUITE */ -#endif /* USING_MALI_PMM */ -#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */ - +#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_linux_trace.h b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h index 3ce1e50..09afcb3 100644 --- a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h +++ b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h @@ -1,93 +1,125 @@ -#if !defined(_TRACE_MALI_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_MALI_H +/* + * 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. + */ + +#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ) +#define MALI_LINUX_TRACE_H +#include #include #include -#undef TRACE_SYSTEM +#undef TRACE_SYSTEM #define TRACE_SYSTEM mali -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) +#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM) + +#define TRACE_INCLUDE_PATH . #define TRACE_INCLUDE_FILE mali_linux_trace /** - * mali_timeline_event - called from the central collection point (_mali_profiling_add_event) - * @event_id: ORed together bitfields representing a type of event - * In the future we might add - * @timestamp - * @data[5] - this currently includes thread and process id's - we should have EGLConfig or similar too + * Define the tracepoint used to communicate the status of a GPU. Called + * when a GPU turns on or turns off. + * + * @param event_id The type of the event. This parameter is a bitfield + * encoding the type of the event. * - * Just make a record of the event_id, we'll decode it elsewhere + * @param d0 First data parameter. + * @param d1 Second data parameter. + * @param d2 Third data parameter. + * @param d3 Fourth data parameter. + * @param d4 Fifth data parameter. */ TRACE_EVENT(mali_timeline_event, - TP_PROTO(unsigned int event_id), + TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, + unsigned int d2, unsigned int d3, unsigned int d4), - TP_ARGS(event_id), + TP_ARGS(event_id, d0, d1, d2, d3, d4), - TP_STRUCT__entry( - __field( int, event_id ) - ), + TP_STRUCT__entry( + __field(unsigned int, event_id) + __field(unsigned int, d0) + __field(unsigned int, d1) + __field(unsigned int, d2) + __field(unsigned int, d3) + __field(unsigned int, d4) + ), - TP_fast_assign( - __entry->event_id = event_id; - ), + TP_fast_assign( + __entry->event_id = event_id; + __entry->d0 = d0; + __entry->d1 = d1; + __entry->d2 = d2; + __entry->d3 = d3; + __entry->d4 = d4; + ), - TP_printk("event=%d", __entry->event_id) + TP_printk("event=%d", __entry->event_id) ); /** - * mali_hw_counter - called from the ???? - * @event_id: event being counted - * In the future we might add - * @timestamp ?? + * Define a tracepoint used to regsiter the value of a hardware counter. + * Hardware counters belonging to the vertex or fragment processor are + * reported via this tracepoint each frame, whilst L2 cache hardware + * counters are reported continuously. * - * Just make a record of the event_id and value + * @param counter_id The counter ID. + * @param value The value of the counter. */ -TRACE_EVENT(mali_hw_counter, +TRACE_EVENT(mali_hw_counter, - TP_PROTO(unsigned int event_id, unsigned int value), + TP_PROTO(unsigned int counter_id, unsigned int value), - TP_ARGS(event_id, value), + TP_ARGS(counter_id, value), - TP_STRUCT__entry( - __field( int, event_id ) - __field( int, value ) - ), + TP_STRUCT__entry( + __field(unsigned int, counter_id) + __field(unsigned int, value) + ), - TP_fast_assign( - __entry->event_id = event_id; - ), + TP_fast_assign( + __entry->counter_id = counter_id; + ), - TP_printk("event %d = %d", __entry->event_id, __entry->value) + TP_printk("event %d = %d", __entry->counter_id, __entry->value) ); /** - * mali_sw_counter - * @event_id: counter id + * Define a tracepoint used to send a bundle of software counters. + * + * @param counters The bundle of counters. */ -TRACE_EVENT(mali_sw_counter, +TRACE_EVENT(mali_sw_counters, - TP_PROTO(unsigned int event_id, signed long long value), + TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters), - TP_ARGS(event_id, value), + TP_ARGS(pid, tid, surface_id, counters), TP_STRUCT__entry( - __field( int, event_id ) - __field( long long, value ) + __field(pid_t, pid) + __field(pid_t, tid) + __field(void *, surface_id) + __field(unsigned int *, counters) ), TP_fast_assign( - __entry->event_id = event_id; + __entry->pid = pid; + __entry->tid = tid; + __entry->surface_id = surface_id; + __entry->counters = counters; ), - TP_printk("event %d = %lld", __entry->event_id, __entry->value) + TP_printk("counters were %s", __entry->counters == NULL? "NULL" : "not NULL") ); -#endif /* _TRACE_MALI_H */ - -#undef TRACE_INCLUDE_PATH -#undef linux -#define TRACE_INCLUDE_PATH . +#endif /* MALI_LINUX_TRACE_H */ -/* This part must be outside protection */ +/* This part must exist outside the header guard. */ #include + diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h b/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h index 41cb462..f87739b 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h +++ b/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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_irq.c b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c index c597b9e..ddfe564 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -15,11 +15,12 @@ #include /* For memory allocation */ #include +#include #include "mali_osk.h" -#include "mali_kernel_core.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 @@ -31,7 +32,10 @@ typedef struct _mali_osk_irq_t_struct 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; -static struct workqueue_struct *mali_irq_wq=NULL; +#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 *); @@ -58,6 +62,23 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl 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 *)) */ @@ -107,14 +128,14 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl 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 (!mali_benchmark && irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM) + if (irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM) { if (-1 == irqnum) { @@ -131,10 +152,12 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl } } - if (mali_irq_wq == NULL) +#if MALI_LICENSE_IS_GPL + if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum ) { - mali_irq_wq = create_singlethread_workqueue("mali-pmm-wq"); + pmm_wq = create_singlethread_workqueue("mali-pmm-wq"); } +#endif return irq_object; } @@ -142,29 +165,54 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq ) { mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq; - queue_work_on(0, mali_irq_wq,&irq_object->work_queue_irq_handle); +#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 ) { - flush_workqueue(mali_irq_wq ); +#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_irq_wq != NULL) - { - flush_workqueue(mali_irq_wq); - destroy_workqueue(mali_irq_wq); - mali_irq_wq = NULL; - } - - if (!mali_benchmark) +#if MALI_LICENSE_IS_GPL + if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM ) { - free_irq(irq_object->irqnum, irq_object); + flush_workqueue(pmm_wq); + destroy_workqueue(pmm_wq); } +#endif + free_irq(irq_object->irqnum, irq_object); kfree(irq_object); flush_scheduled_work(); } diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c index aad6fc6..0297c77 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -51,7 +51,7 @@ typedef enum struct _mali_osk_lock_t_struct { _mali_osk_internal_locktype type; - unsigned long flags; + unsigned long flags; union { spinlock_t spinlock; @@ -61,6 +61,15 @@ struct _mali_osk_lock_t_struct MALI_DEBUG_CODE( /** original flags for debug checking */ _mali_osk_lock_flags_t orig_flags; + + /* 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 */ }; @@ -71,11 +80,11 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial /* Validate parameters: */ /* Flags acceptable */ MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK - | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ - | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE - | _MALI_OSK_LOCKFLAG_READERWRITER - | _MALI_OSK_LOCKFLAG_ORDERED - | _MALI_OSK_LOCKFLAG_ONELOCK )) ); + | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ + | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE + | _MALI_OSK_LOCKFLAG_READERWRITER + | _MALI_OSK_LOCKFLAG_ORDERED + | _MALI_OSK_LOCKFLAG_ONELOCK )) ); /* Spinlocks are always non-interruptable */ MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)) || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK)); @@ -126,14 +135,35 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial sema_init( &lock->obj.sema, 1 ); } - MALI_DEBUG_CODE( - /* Debug tracking of flags */ - lock->orig_flags = flags; - ); /* MALI_DEBUG_CODE */ +#ifdef DEBUG + /* Debug tracking of flags */ + lock->orig_flags = flags; + + /* Debug tracking of lock owner */ + lock->owner = 0; + lock->nOwners = 0; +#endif /* DEBUG */ return lock; } +#ifdef DEBUG +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; +} +#endif /* DEBUG */ + _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode) { _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; @@ -162,6 +192,7 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX: if ( down_interruptible(&lock->obj.sema) ) { + MALI_PRINT_ERROR(("Can not lock mutex\n")); err = _MALI_OSK_ERR_RESTARTSYSCALL; } break; @@ -188,6 +219,31 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_ break; } +#ifdef DEBUG + /* This thread is now the owner of this lock */ + if (_MALI_OSK_ERR_OK == err) + { + 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); + dump_stack(); + } + 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 + return err; } @@ -205,6 +261,37 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode ) MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) ); +#ifdef DEBUG + /* 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); + dump_stack(); + } + /* 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; + } + } +#endif /* DEBUG */ + switch ( lock->type ) { case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN: diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c index c0aecb8..5767912 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -76,12 +76,7 @@ static void _allocation_list_item_release(AllocationList * item); /* Variable declarations */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) -spinlock_t allocation_list_spinlock = SPIN_LOCK_UNLOCKED; -#else -DEFINE_SPINLOCK(allocation_list_spinlock); -#endif - +static DEFINE_SPINLOCK(allocation_list_spinlock); static AllocationList * pre_allocated_memory = (AllocationList*) NULL ; static int pre_allocated_memory_size_current = 0; #ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB @@ -124,9 +119,9 @@ static u32 _kernel_page_allocate(void) { struct page *new_page; u32 linux_phys_addr; - + new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD); - + if ( NULL == new_page ) { return 0; @@ -145,7 +140,7 @@ static void _kernel_page_release(u32 physical_address) #if 1 dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL); #endif - + unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT ); MALI_DEBUG_ASSERT_POINTER( unmap_page ); __free_page( unmap_page ); @@ -155,19 +150,19 @@ static AllocationList * _allocation_list_item_get(void) { AllocationList *item = NULL; unsigned long flags; - + spin_lock_irqsave(&allocation_list_spinlock,flags); if ( pre_allocated_memory ) { item = pre_allocated_memory; pre_allocated_memory = pre_allocated_memory->next; pre_allocated_memory_size_current -= PAGE_SIZE; - + spin_unlock_irqrestore(&allocation_list_spinlock,flags); return item; } spin_unlock_irqrestore(&allocation_list_spinlock,flags); - + item = _mali_osk_malloc( sizeof(AllocationList) ); if ( NULL == item) { @@ -197,7 +192,7 @@ static void _allocation_list_item_release(AllocationList * item) return; } spin_unlock_irqrestore(&allocation_list_spinlock,flags); - + _kernel_page_release(item->physaddr); _mali_osk_free( item ); } @@ -244,7 +239,6 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) _mali_uk_mem_munmap_s args = {0, }; mali_memory_allocation * descriptor; mali_vma_usage_tracker * vma_usage_tracker; - MappingInfo *mappingInfo; MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma)); vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data; @@ -254,11 +248,6 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) vma_usage_tracker->references--; - descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie; - - mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info; - mappingInfo->vma = vma; - if (0 != vma_usage_tracker->references) { MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references)); @@ -268,6 +257,8 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma) /** @note args->context unused, initialized to 0. * Instead, we use the memory_session from the cookie */ + descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie; + args.cookie = (u32)descriptor; args.mapping = descriptor->mapping; args.size = descriptor->size; diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c index ab571c1..3def446 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -18,27 +18,10 @@ #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" /* exports initialize/terminate_kernel_device() definition of mali_osk_low_level_mem_init() and term */ +#include "mali_kernel_linux.h" #include #include "arch/config.h" /* contains the configuration of the arch we are compiling for */ -/* is called from mali_kernel_constructor in common code */ -_mali_osk_errcode_t _mali_osk_init( void ) -{ - if (0 != initialize_kernel_device()) MALI_ERROR(_MALI_OSK_ERR_FAULT); - - mali_osk_low_level_mem_init(); - - MALI_SUCCESS; -} - -/* is called from mali_kernel_deconstructor in common code */ -void _mali_osk_term( void ) -{ - mali_osk_low_level_mem_term(); - terminate_kernel_device(); -} - _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]); diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c index 871505a..7bb470f 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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/media/video/samsung/mali/linux/mali_osk_misc.c index e37e8c0..ad486db 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -33,7 +33,7 @@ u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ) va_list args; va_start(args, fmt); - res = vsnprintf(buf, (size_t)size, fmt, args); + res = vscnprintf(buf, (size_t)size, fmt, args); va_end(args); return res; @@ -42,6 +42,7 @@ u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... ) void _mali_osk_abort(void) { /* make a simple fault by dereferencing a NULL pointer */ + dump_stack(); *(int *)0 = 0; } diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c index eef839f..c14c0d5 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -15,8 +15,6 @@ #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_pmm.h" -#include "mali_pmm_state.h" /* needed to detect kernel version specific code */ #include @@ -67,12 +65,8 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) /* OPT Recycling of notification objects */ _mali_osk_notification_wrapper_t *notification; - if (MALI_PMM_NOTIFICATION_TYPE == type) { - if (size != sizeof(mali_pmm_message_t)) - return NULL; - } - - notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, GFP_KERNEL ); + notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, + GFP_KERNEL | __GFP_HIGH | __GFP_REPEAT); if (NULL == notification) { MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n")); @@ -92,7 +86,6 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size ) } /* set up the non-allocating fields */ - notification->data.magic_code = 0x31415926; notification->data.notification_type = type; notification->data.result_buffer_size = size; @@ -107,8 +100,6 @@ void _mali_osk_notification_delete( _mali_osk_notification_t *object ) notification = container_of( object, _mali_osk_notification_wrapper_t, data ); - /* Remove from the list */ - list_del(¬ification->list); /* Free the container */ kfree(notification); } @@ -169,15 +160,7 @@ _mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list); *result = &(wrapper_object->data); list_del_init(&wrapper_object->list); - - if (wrapper_object->data.magic_code != 0x31415926) { - MALI_PRINT(("SEC WARNING : list entry magic_code not match : %x\n", wrapper_object->data.magic_code)); - MALI_PRINT(("SEC WARNING : list entry notification type : %x\n", wrapper_object->data.notification_type)); - MALI_PRINT(("SEC WARNING : list entry result buffer size : %x\n", wrapper_object->data.result_buffer_size)); - MALI_PRINT(("SEC WARNING : list entry result buffer : %x\n", wrapper_object->data.result_buffer)); - } else { - ret = _MALI_OSK_ERR_OK; - } + ret = _MALI_OSK_ERR_OK; } up(&queue->mutex); diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c index 2438cbc..20fb7b4 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c @@ -1,5 +1,5 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. +/** + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -18,193 +18,67 @@ #ifdef CONFIG_PM_RUNTIME #include #endif /* CONFIG_PM_RUNTIME */ - #include - #include "mali_platform.h" #include "mali_osk.h" #include "mali_uk_types.h" -#include "mali_pmm.h" #include "mali_kernel_common.h" #include "mali_kernel_license.h" #include "mali_linux_pm.h" -#include "mali_linux_pm_testsuite.h" - -#if MALI_LICENSE_IS_GPL -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON -#ifdef CONFIG_PM_RUNTIME -static int is_runtime =0; -#endif /* CONFIG_PM_RUNTIME */ -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* MALI_LICENSE_IS_GPL */ - -#if MALI_POWER_MGMT_TEST_SUITE - -#ifdef CONFIG_PM -unsigned int mali_pmm_events_triggered_mask = 0; -#endif /* CONFIG_PM */ - -void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id mali_pmm_event) -{ -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - - switch (mali_pmm_event) - { - case MALI_PMM_EVENT_JOB_QUEUED: - if (mali_job_scheduling_events_recording_on == 1) - { - mali_pmm_events_triggered_mask |= (1<<0); - } - break; - - case MALI_PMM_EVENT_JOB_SCHEDULED: - if (mali_job_scheduling_events_recording_on == 1) - { - mali_pmm_events_triggered_mask |= (1<<1); - } - break; - - case MALI_PMM_EVENT_JOB_FINISHED: - if (mali_job_scheduling_events_recording_on == 1) - { - mali_pmm_events_triggered_mask |= (1<<2); - mali_job_scheduling_events_recording_on = 0; - pwr_mgmt_status_reg = mali_pmm_events_triggered_mask; - } - break; - - case MALI_PMM_EVENT_TIMEOUT: - if (mali_timeout_event_recording_on == 1) - { - pwr_mgmt_status_reg = (1<<3); - mali_timeout_event_recording_on = 0; - } - break; - - default: +#include "mali_kernel_license.h" - break; +#if ! MALI_LICENSE_IS_GPL +#undef CONFIG_PM_RUNTIME +#endif - } -#endif /* CONFIG_PM */ +extern struct platform_device mali_gpu_device; -#endif /* MALI_LICENSE_IS_GPL */ -} -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - -/** This function is called when the Mali device has completed power up - * operation. - */ -void _mali_osk_pmm_power_up_done(mali_pmm_message_data data) -{ -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - is_wake_up_needed = 1; - wake_up_process(pm_thread); - MALI_DEBUG_PRINT(4, ("OSPMM: MALI OSK Power up Done\n" )); - return; -#endif /* CONFIG_PM */ -#endif /* MALI_LICENSE_IS_GPL */ -} +#ifdef CONFIG_PM_RUNTIME +static mali_bool have_runtime_reference = MALI_FALSE; +#endif -/** This function is called when the Mali device has completed power down - * operation. - */ -void _mali_osk_pmm_power_down_done(mali_pmm_message_data data) +void _mali_osk_pm_dev_enable(void) { -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - is_wake_up_needed = 1; -#if MALI_POWER_MGMT_TEST_SUITE - if (is_mali_pmu_present == 0) - { - pwr_mgmt_status_reg = _mali_pmm_cores_list(); - } -#endif /* MALI_POWER_MGMT_TEST_SUITE */ - wake_up_process(pm_thread); - MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power down Done\n" )); - return; - -#endif /* CONFIG_PM */ -#endif /* MALI_LICENSE_IS_GPL */ +#ifdef CONFIG_PM_RUNTIME + pm_runtime_enable(&(mali_gpu_device.dev)); +#endif } -/** This function is invoked when mali device is idle. -*/ -_mali_osk_errcode_t _mali_osk_pmm_dev_idle(void) +/* NB: Function is not thread safe */ +_mali_osk_errcode_t _mali_osk_pm_dev_idle(void) { - _mali_osk_errcode_t err = 0; -#if MALI_LICENSE_IS_GPL #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - err = pm_runtime_put_sync(&(mali_gpu_device.dev)); - if(err) + if (MALI_TRUE == have_runtime_reference) { - MALI_DEBUG_PRINT(4, ("OSPMM: Error in _mali_osk_pmm_dev_idle\n" )); + 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 /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ -#endif /* MALI_LICENSE_IS_GPL */ - return err; +#endif + return _MALI_OSK_ERR_OK; } -/** This funtion is invoked when mali device needs to be activated. -*/ -int _mali_osk_pmm_dev_activate(void) +/* NB: Function is not thread safe */ +_mali_osk_errcode_t _mali_osk_pm_dev_activate(void) { - -#if MALI_LICENSE_IS_GPL #ifdef CONFIG_PM_RUNTIME -#if MALI_PMM_RUNTIME_JOB_CONTROL_ON - int err = 0; - if(is_runtime == 0) + if (MALI_TRUE != have_runtime_reference) { - pm_suspend_ignore_children(&(mali_gpu_device.dev), true); - pm_runtime_enable(&(mali_gpu_device.dev)); + int err; err = pm_runtime_get_sync(&(mali_gpu_device.dev)); - is_runtime = 1; - } - else - { - err = pm_runtime_get_sync(&(mali_gpu_device.dev)); - } - if(err < 0) - { - MALI_PRINT(("OSPMM: Error in _mali_osk_pmm_dev_activate, err : %d\n",err )); - } -#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */ -#endif /* CONFIG_PM_RUNTIME */ -#endif /* MALI_LICENSE_IS_GPL */ - - return err; -} - -void _mali_osk_pmm_ospmm_cleanup( void ) -{ -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - int thread_state; - thread_state = mali_get_ospmm_thread_state(); - if (thread_state) - { - _mali_osk_pmm_dvfs_operation_done(0); + 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 /* CONFIG_PM */ -#endif /* MALI_LICENSE_IS_GPL */ +#endif + return _MALI_OSK_ERR_OK; } - -void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data) -{ -#if MALI_LICENSE_IS_GPL -#ifdef CONFIG_PM - is_wake_up_needed = 1; - wake_up_process(dvfs_pm_thread); - MALI_DEBUG_PRINT(4, ("OSPMM: MALI OSK DVFS Operation done\n" )); - return; -#endif /* CONFIG_PM */ -#endif /* MALI_LICENSE_IS_GPL */ -} - - diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c deleted file mode 100644 index 98d3937..0000000 --- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include "mali_linux_trace.h" -#include "mali_osk.h" - -/* The Linux trace point for hardware activity (idle vs running) */ -void _mali_osk_profiling_add_event(u32 event_id, u32 data0) -{ - trace_mali_timeline_event(event_id); -} - -/* The Linux trace point for hardware counters */ -void _mali_osk_profiling_add_counter(u32 event_id, u32 data0) -{ - trace_mali_hw_counter(event_id, data0); -} - -/* This table stores the event to be counted by each counter - * 0xFFFFFFFF is a special value which means disable counter - */ -//TODO at the moment this table is indexed by the magic numbers -//listed in gator_events_mali.c. In future these numbers should -//be shared through the mali_linux_trace.h header -u32 counter_table[17] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF}; - -/* Called by gator.ko to populate the table above */ -int _mali_osk_counter_event(u32 counter, u32 event) -{ - /* Remember what has been set, and that a change has occured - * When a job actually starts the code will program the registers - */ - //TODO as above these magic numbers need to be moved to a header file - if( counter >=5 && counter < 17 ) { - counter_table[counter] = event; - - return 1; - } else { - printk("mali rjc: counter out of range (%d,%d)\n", counter, event); - } - - return 0; -} -EXPORT_SYMBOL(_mali_osk_counter_event); - diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c new file mode 100644 index 0000000..75c888d --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c @@ -0,0 +1,262 @@ +/* + * 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 + +#include "mali_kernel_common.h" +#include "mali_osk.h" +#include "mali_ukk.h" +#include "mali_uk_types.h" +#include "mali_osk_profiling.h" +#include "mali_linux_trace.h" +#include "mali_gp.h" +#include "mali_pp.h" +#include "mali_l2_cache.h" +#include "mali_user_settings_db.h" + +_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) +{ + if (MALI_TRUE == auto_start) + { + mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE); + } + + return _MALI_OSK_ERR_OK; +} + +void _mali_osk_profiling_term(void) +{ + /* Nothing to do */ +} + +_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +u32 _mali_osk_profiling_get_count(void) +{ + return 0; +} + +_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + /* Nothing to do */ + return _MALI_OSK_ERR_OK; +} + +mali_bool _mali_osk_profiling_is_recording(void) +{ + return MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return MALI_FALSE; +} + +void _mali_osk_profiling_report_sw_counters(u32 *counters) +{ + trace_mali_sw_counters(_mali_osk_get_pid(), _mali_osk_get_tid(), NULL, counters); +} + + +_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; +} + +/** + * Called by gator.ko to set HW counters + * + * @param counter_id The counter ID. + * @param event_id Event ID that the counter should count (HW counter value from TRM). + * + * @return 1 on success, 0 on failure. + */ +int _mali_profiling_set_event(u32 counter_id, s32 event_id) +{ + + if (counter_id == COUNTER_VP_C0) + { + struct mali_gp_core* gp_core = mali_gp_get_global_gp_core(); + if (NULL != gp_core) + { + if (MALI_TRUE == mali_gp_core_set_counter_src0(gp_core, event_id)) + { + return 1; + } + } + } + else if (counter_id == COUNTER_VP_C1) + { + struct mali_gp_core* gp_core = mali_gp_get_global_gp_core(); + if (NULL != gp_core) + { + if (MALI_TRUE == mali_gp_core_set_counter_src1(gp_core, event_id)) + { + return 1; + } + } + } + else if (counter_id >= COUNTER_FP0_C0 && counter_id <= COUNTER_FP3_C1) + { + 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) + { + 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; + } + } + } + } + else if (counter_id >= COUNTER_L2_C0 && counter_id <= COUNTER_L2_C1) + { + u32 core_id = (counter_id - COUNTER_L2_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; + if (0 == counter_src) + { + if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id)) + { + return 1; + } + } + else + { + if (MALI_TRUE == mali_l2_cache_core_set_counter_src1(l2_cache_core, event_id)) + { + return 1; + } + } + } + } + + return 0; +} + +/** + * Called by gator.ko to retrieve the L2 cache counter values for the first L2 cache. + * The L2 cache counters are unique in that they are polled by gator, rather than being + * 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. + */ +void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1) +{ + struct mali_l2_cache_core *l2_cache = mali_l2_cache_core_get_glob_l2_core(0); /* @@@@ TODO: Fix hardcoded limit of maximum 1 L2 cache */ + if (NULL != l2_cache) + { + 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); + /* @@@@ TODO: add error checking, if needed; src == MALI_HW_CORE_NO_COUNTER if not able to get value */ + } + 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) + +/** + * Called by gator to control the production of profiling information at runtime. + */ +void _mali_profiling_control(u32 action, u32 value) +{ + switch(action) + { + case FBDUMP_CONTROL_ENABLE: + mali_set_user_setting(_MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, (value == 0 ? MALI_FALSE : MALI_TRUE)); + break; + case FBDUMP_CONTROL_RATE: + mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, value); + break; + case SW_COUNTER_ENABLE: + mali_set_user_setting(_MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, value); + break; + case FBDUMP_CONTROL_RESIZE_FACTOR: + mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, value); + break; + default: + break; /* Ignore unimplemented actions */ + } +} + +EXPORT_SYMBOL(_mali_profiling_set_event); +EXPORT_SYMBOL(_mali_profiling_get_counters); +EXPORT_SYMBOL(_mali_profiling_control); diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c new file mode 100644 index 0000000..9a423d2 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c @@ -0,0 +1,308 @@ +/* + * 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) +{ + u32 cur_index = _mali_osk_atomic_inc_return(&profile_insert_index) - 1; + + if (prof_state != MALI_PROFILING_STATE_RUNNING || cur_index >= profile_entry_count) + { + /* + * Not in recording mode, or buffer is full + * Decrement index again, and early out + */ + _mali_osk_atomic_dec(&profile_insert_index); + return; + } + + profile_entries[cur_index].timestamp = _mali_timestamp_get(); + profile_entries[cur_index].event_id = event_id; + profile_entries[cur_index].data[0] = data0; + profile_entries[cur_index].data[1] = data1; + profile_entries[cur_index].data[2] = data2; + profile_entries[cur_index].data[3] = data3; + profile_entries[cur_index].data[4] = data4; + + _mali_osk_atomic_inc(&profile_entries_written); +} + +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); + + 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); + } + _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 (prof_state != MALI_PROFILING_STATE_RETURN) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + if (index >= _mali_osk_atomic_read(&profile_entries_written)) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_FAULT; + } + + *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]; + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_OK; +} + +inline _mali_osk_errcode_t _mali_osk_profiling_clear(void) +{ + _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW); + + if (prof_state != MALI_PROFILING_STATE_RETURN) + { + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */ + } + + prof_state = MALI_PROFILING_STATE_IDLE; + profile_entry_count = 0; + _mali_osk_atomic_init(&profile_insert_index, 0); + _mali_osk_atomic_init(&profile_entries_written, 0); + if (NULL != profile_entries) + { + _mali_osk_vfree(profile_entries); + profile_entries = NULL; + } + + _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW); + return _MALI_OSK_ERR_OK; +} + +mali_bool _mali_osk_profiling_is_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE; +} + +mali_bool _mali_osk_profiling_have_recording(void) +{ + return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE; +} + +_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args) +{ + return _mali_osk_profiling_start(&args->limit); +} + +_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args) +{ + /* Always add process and thread identificator in the first two data elements for events from user space */ + _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]); + return _MALI_OSK_ERR_OK; +} + +_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args) +{ + return _mali_osk_profiling_stop(&args->count); +} + +_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args) +{ + return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data); +} + +_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args) +{ + return _mali_osk_profiling_clear(); +} + +_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args) +{ + _mali_osk_profiling_report_sw_counters(args->counters); + return _MALI_OSK_ERR_OK; +} + diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h index 6aacf17..83ee906 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h +++ b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -22,11 +22,109 @@ extern "C" { #endif -#define MALI_STATIC_INLINE static inline +#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/linux/mali_osk_timers.c b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c index 0454756..e5829a3 100644 --- a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c +++ b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -34,7 +34,7 @@ _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); + MALI_DEBUG_ASSERT_POINTER(tim); tim->timer.expires = _mali_osk_time_tickcount() + ticks_to_expire; add_timer(&(tim->timer)); } diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c b/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c new file mode 100644 index 0000000..ce0561d --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c @@ -0,0 +1,73 @@ +/* + * 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_osk_wait_queue.c + * Implemenation of the OS abstraction layer for the kernel device driver + */ + +#include +#include +#include + +#include "mali_osk.h" +#include "mali_kernel_common.h" + +struct _mali_osk_wait_queue_t_struct +{ + wait_queue_head_t wait_queue; +}; + +_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void ) +{ + _mali_osk_wait_queue_t* ret = NULL; + + ret = kmalloc(sizeof(_mali_osk_wait_queue_t), GFP_KERNEL); + + if (NULL == ret) + { + return ret; + } + + init_waitqueue_head(&ret->wait_queue); + MALI_DEBUG_ASSERT(!waitqueue_active(&ret->wait_queue)); + + return ret; +} + +void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ) +{ + MALI_DEBUG_ASSERT_POINTER( queue ); + MALI_DEBUG_PRINT(6, ("Adding to wait queue %p\n", queue)); + wait_event(queue->wait_queue, condition()); +} + +void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue ) +{ + MALI_DEBUG_ASSERT_POINTER( queue ); + + /* if queue is empty, don't attempt to wake up its elements */ + if (!waitqueue_active(&queue->wait_queue)) return; + + MALI_DEBUG_PRINT(6, ("Waking up elements in wait queue %p ....\n", queue)); + + wake_up_all(&queue->wait_queue); + + MALI_DEBUG_PRINT(6, ("... elements in wait queue %p woken up\n", queue)); +} + +void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue ) +{ + /* Parameter validation */ + MALI_DEBUG_ASSERT_POINTER( queue ); + + /* Linux requires no explicit termination of wait queues */ + kfree(queue); +} diff --git a/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c new file mode 100644 index 0000000..f3b0a2c --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c @@ -0,0 +1,65 @@ +/** + * 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_power_up_down.c + */ + +#include +#include +#include +#include "mali_osk.h" +#include "mali_kernel_common.h" +#include "mali_pmu.h" +#include "linux/mali/mali_utgard.h" + +/* Mali PMU power up/down APIs */ + +int mali_pmu_powerup(void) +{ + struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core(); + + MALI_DEBUG_PRINT(5, ("Mali PMU: Power up\n")); + + if (NULL == pmu) + { + return -ENXIO; + } + + if (_MALI_OSK_ERR_OK != mali_pmu_powerup_all(pmu)) + { + return -EFAULT; + } + + return 0; +} + +EXPORT_SYMBOL(mali_pmu_powerup); + +int mali_pmu_powerdown(void) +{ + struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core(); + + MALI_DEBUG_PRINT(5, ("Mali PMU: Power down\n")); + + if (NULL == pmu) + { + return -ENXIO; + } + + if (_MALI_OSK_ERR_OK != mali_pmu_powerdown_all(pmu)) + { + return -EFAULT; + } + + return 0; +} + +EXPORT_SYMBOL(mali_pmu_powerdown); diff --git a/drivers/media/video/samsung/mali/linux/mali_profiling_events.h b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h new file mode 100644 index 0000000..2639a40 --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h @@ -0,0 +1,17 @@ +/* + * 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_EVENTS_H__ +#define __MALI_PROFILING_EVENTS_H__ + +/* Simple wrapper in order to find the OS specific location of this file */ +#include + +#endif /* __MALI_PROFILING_EVENTS_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_uk_types.h b/drivers/media/video/samsung/mali/linux/mali_uk_types.h new file mode 100644 index 0000000..b535e6c --- /dev/null +++ b/drivers/media/video/samsung/mali/linux/mali_uk_types.h @@ -0,0 +1,19 @@ +/* + * 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_UK_TYPES_H__ +#define __MALI_UK_TYPES_H__ + +#include "regs/mali_200_regs.h" + +/* Simple wrapper in order to find the OS specific location of this file */ +#include "../include/linux/mali/mali_utgard_uk_types.h" + +#endif /* __MALI_UK_TYPES_H__ */ diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c index 59eafe2..6eb2df3 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -14,7 +14,7 @@ #include "mali_ukk.h" #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_ukk_wrappers.h" int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs) @@ -140,3 +140,23 @@ int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_p return 0; } + +int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs) +{ + _mali_uk_get_user_settings_s kargs; + _mali_osk_errcode_t err; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + + kargs.ctx = session_data; + err = _mali_ukk_get_user_settings(&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_get_user_settings_s))) return -EFAULT; + + return 0; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c index 58ff1de..7070016 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -13,7 +13,7 @@ #include "mali_ukk.h" #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_ukk_wrappers.h" int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs) @@ -36,6 +36,7 @@ int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_sta 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))) { /* @@ -53,22 +54,6 @@ int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_sta return 0; } -int gp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_abort_job_s __user *uargs) -{ - _mali_uk_gp_abort_job_s kargs; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_abort_job_s))) return -EFAULT; - - kargs.ctx = session_data; - _mali_ukk_gp_abort_job(&kargs); - - return 0; -} - - int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs) { _mali_uk_get_gp_core_version_s kargs; diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c index 0b98e41..260f257 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -13,7 +13,7 @@ #include "mali_ukk.h" #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_ukk_wrappers.h" int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs) @@ -257,80 +257,3 @@ err_exit: if (kargs.buffer) _mali_osk_vfree(kargs.buffer); return rc; } - - - -int mem_get_big_block_wrapper( struct file * filp, _mali_uk_get_big_block_s __user * argument ) -{ - _mali_uk_get_big_block_s uk_args; - _mali_osk_errcode_t err_code; - - /* validate input */ - /* the session_data pointer was validated by caller */ - MALI_CHECK_NON_NULL( argument, -EINVAL); - - /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */ - if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_get_big_block_s)) ) - { - return -EFAULT; - } - - /* This interface inserts something into the ukk_private word */ - uk_args.ukk_private = (u32)filp; - uk_args.ctx = filp->private_data; - err_code = _mali_ukk_get_big_block( &uk_args ); - - /* Do not leak the private word back into user space */ - uk_args.ukk_private = 0; - - if ( _MALI_OSK_ERR_OK != err_code ) - { - return map_errcode(err_code); - } - - /* From this point on, we must roll-back any failing action to preserve the - * meaning of the U/K interface (e.g. when excluded) */ - - /* transfer response back to user space */ - if ( 0 != copy_to_user(argument, &uk_args, sizeof(_mali_uk_get_big_block_s)) ) - { - /* Roll-back - the _mali_uk_get_big_block call succeeded, so all - * values in uk_args will be correct */ - _mali_uk_free_big_block_s uk_args_rollback = {0, }; - - uk_args_rollback.ctx = uk_args.ctx; - uk_args_rollback.cookie = uk_args.cookie; - err_code = _mali_ukk_free_big_block( &uk_args_rollback ); - - if ( _MALI_OSK_ERR_OK != err_code ) - { - /* error in DEBUG and RELEASE */ - MALI_PRINT_ERROR( ("Failed to rollback get_big_block: %.8X\n", (u32)err_code) ); - } - return -EFAULT; - } - - return 0; -} - -int mem_free_big_block_wrapper(struct mali_session_data *session_data, _mali_uk_free_big_block_s __user * argument) -{ - _mali_uk_free_big_block_s uk_args; - _mali_osk_errcode_t err_code; - - /* validate input */ - /* the session_data pointer was validated by caller */ - MALI_CHECK_NON_NULL( argument, -EINVAL ); - - /* get call arguments from user space. get_user returns 0 on success */ - if ( 0 != get_user(uk_args.cookie, &argument->cookie) ) - { - return -EFAULT; - } - - uk_args.ctx = session_data; - err_code = _mali_ukk_free_big_block( &uk_args ); - - /* Return the error that _mali_ukk_free_big_block produced */ - return map_errcode(err_code); -} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c index 31e2a6a..c11c61b 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -13,7 +13,7 @@ #include "mali_ukk.h" #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_ukk_wrappers.h" int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs) @@ -35,36 +35,6 @@ int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_sta err = _mali_ukk_pp_start_job(&kargs); if (_MALI_OSK_ERR_OK != err) return map_errcode(err); - if (0 != put_user(kargs.returned_user_job_ptr, &uargs->returned_user_job_ptr) || - 0 != put_user(kargs.status, &uargs->status)) - { - /* - * If this happens, then user space will not know that the job was actually started, - * and if we return a queued job, then user space will still think that one is still queued. - * This will typically lead to a deadlock in user space. - * This could however only happen if user space deliberately passes a user buffer which - * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user(). - * The official Mali driver will never attempt to do that, and kernel space should not be affected. - * That is why we do not bother to do a complex rollback in this very very very rare case. - */ - return -EFAULT; - } - - return 0; -} - -int pp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_abort_job_s __user *uargs) -{ - _mali_uk_pp_abort_job_s kargs; - - MALI_CHECK_NON_NULL(uargs, -EINVAL); - MALI_CHECK_NON_NULL(session_data, -EINVAL); - - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_abort_job_s))) return -EFAULT; - - kargs.ctx = session_data; - _mali_ukk_pp_abort_job(&kargs); - return 0; } @@ -101,3 +71,18 @@ int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk return 0; } + +int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs) +{ + _mali_uk_pp_disable_wb_s kargs; + + MALI_CHECK_NON_NULL(uargs, -EINVAL); + MALI_CHECK_NON_NULL(session_data, -EINVAL); + + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_disable_wb_s))) return -EFAULT; + + kargs.ctx = session_data; + _mali_ukk_pp_job_disable_wb(&kargs); + + return 0; +} diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c index 17366be..7324d9d 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -9,11 +9,12 @@ */ #include /* file system operations */ #include /* user space access */ +#include #include "mali_ukk.h" #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_ukk_wrappers.h" int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs) @@ -133,51 +134,49 @@ int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_pro return 0; } -int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs) +int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs) { - _mali_uk_profiling_get_config_s kargs; + _mali_uk_sw_counters_report_s kargs; _mali_osk_errcode_t err; + u32 *counter_buffer; MALI_CHECK_NON_NULL(uargs, -EINVAL); - kargs.ctx = session_data; - err = _mali_ukk_profiling_get_config(&kargs); - if (_MALI_OSK_ERR_OK != err) + if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s))) { - return map_errcode(err); + return -EFAULT; } - if (0 != put_user(kargs.enable_events, &uargs->enable_events)) - { - return -EFAULT; + /* make sure that kargs.num_counters is [at least somewhat] sane */ + if (kargs.num_counters > 10000) { + MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n")); + return -EINVAL; } - return 0; -} + counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL); + if (NULL == counter_buffer) + { + return -ENOMEM; + } -#if MALI_TRACEPOINTS_ENABLED -int transfer_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_s __user *uargs) -{ - _mali_uk_sw_counters_s kargs; - _mali_osk_errcode_t err; + if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters)) + { + kfree(counter_buffer); + return -EFAULT; + } - MALI_CHECK_NON_NULL(uargs, -EINVAL); - - kargs.ctx = session_data; + kargs.ctx = session_data; + kargs.counters = counter_buffer; - if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_s))) - { - return -EFAULT; - } + err = _mali_ukk_sw_counters_report(&kargs); - err = _mali_ukk_transfer_sw_counters(&kargs); + kfree(counter_buffer); - if (_MALI_OSK_ERR_OK != err) - { - return map_errcode(err); - } + if (_MALI_OSK_ERR_OK != err) + { + return map_errcode(err); + } - return 0; + return 0; } -#endif diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c index 80a6afd..f9b5a3e 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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. @@ -13,7 +13,7 @@ #include "mali_ukk.h" #include "mali_osk.h" #include "mali_kernel_common.h" -#include "mali_kernel_session_manager.h" +#include "mali_session.h" #include "mali_ukk_wrappers.h" diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h index 184ce8d..b568ce7 100644 --- a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h +++ b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -28,6 +28,7 @@ int get_system_info_size_wrapper(struct mali_session_data *session_data, _mali_u int get_system_info_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_s __user *uargs); 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); 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); @@ -41,14 +42,11 @@ int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_atta 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 */ -int mem_get_big_block_wrapper( struct file * filp, _mali_uk_get_big_block_s __user * argument ); -int mem_free_big_block_wrapper( struct mali_session_data *session_data, _mali_uk_free_big_block_s __user * argument); int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs); -int pp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_abort_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); int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs); +int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs); int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs); -int gp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_abort_job_s __user *uargs); int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs); int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs); int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs); @@ -58,14 +56,10 @@ int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs); int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs); int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs); -int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs); +int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs); int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs); -#if MALI_TRACEPOINTS_ENABLED -int transfer_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_s __user *uargs); -#endif - int map_errcode( _mali_osk_errcode_t err ); #ifdef __cplusplus diff --git a/drivers/media/video/samsung/mali/platform/default/mali_platform.c b/drivers/media/video/samsung/mali/platform/default/mali_platform.c index 44f877e..9e64ce7 100644 --- a/drivers/media/video/samsung/mali/platform/default/mali_platform.c +++ b/drivers/media/video/samsung/mali/platform/default/mali_platform.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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. @@ -39,3 +39,5 @@ 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 index 70cfa14..6e55dee 100644 --- a/drivers/media/video/samsung/mali/platform/mali_platform.h +++ b/drivers/media/video/samsung/mali/platform/mali_platform.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -21,12 +21,7 @@ #ifdef CONFIG_CPU_EXYNOS4210 #define MALI_DVFS_STEPS 2 #else -#define MALI_DVFS_STEPS 4 -#endif - -#if !USING_MALI_PMM -/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */ -#define MALI_PLATFORM_SYSTEM 0 +#define MALI_DVFS_STEPS 5 #endif /* @Enable or Disable Mali GPU Bottom Lock feature */ @@ -34,6 +29,9 @@ #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 @@ -42,9 +40,9 @@ extern "C" { */ typedef enum mali_power_mode_tag { - MALI_POWER_MODE_ON, - MALI_POWER_MODE_LIGHT_SLEEP, - MALI_POWER_MODE_DEEP_SLEEP, + 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 @@ -65,22 +63,8 @@ _mali_osk_errcode_t mali_platform_deinit(void); /** @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. + * 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. */ 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 new file mode 100644 index 0000000..cb95dc6 --- /dev/null +++ b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c @@ -0,0 +1,66 @@ +/* + * 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 index 0fc4503..792b9a9 100644 --- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c +++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. 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 index 9e6edba..f8d76dc 100644 --- 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 @@ -1,414 +1 @@ -/* - * 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. - */ - -/** - * @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 -#include -#include -#include - -#include - -#ifdef CONFIG_CPU_FREQ -#include -#include -#define EXYNOS4_ASV_ENABLED -#endif - -#include "mali_device_pause_resume.h" -#include - -#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},}; - -/*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*100)/100))} }; - -/*dvfs status*/ -mali_dvfs_currentstatus maliDvfsStatus; -int mali_dvfs_control=0; - -/*dvfs table*/ -mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ - /*step 0*/{160 ,1000000 , 950000}, - /*step 1*/{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(160MHz), L2(266MHz) */ - {1000000, 1100000}, /* S */ - {1000000, 1100000}, /* A */ - { 950000, 1000000}, /* B */ - { 950000, 1000000}, /* C */ - { 950000, 950000}, /* D */ -}; - -static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = { - /* L3(160MHz), L2(266MHz)) */ - {1000000, 1100000}, /* SS */ - {1000000, 1100000}, /* A1 */ - {1000000, 1100000}, /* A2 */ - { 950000, 1000000}, /* B1 */ - { 950000, 1000000}, /* B2 */ - { 950000, 1000000}, /* C1 */ - { 950000, 1000000}, /* C2 */ - { 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 if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) -#else - if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) -#endif - level=1; - else if (utilization < mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) - level=0; - else - level = maliDvfsStatus.currentStep; - } else { - if ((mali_dvfs_control > 0) && (mali_dvfs_control < mali_dvfs[1].clock)) - level=0; - else - level=1; - } - - 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 +/* * 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 #include #include #include #include #ifdef CONFIG_CPU_FREQ #include #include #define EXYNOS4_ASV_ENABLED #endif #include "mali_device_pause_resume.h" #include #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},}; /*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*100)/100))} }; /*dvfs status*/ mali_dvfs_currentstatus maliDvfsStatus; int mali_dvfs_control=0; /*dvfs table*/ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ /*step 0*/{160 ,1000000 , 950000}, /*step 1*/{267 ,1000000 ,1000000} }; #ifdef EXYNOS4_ASV_ENABLED #define ASV_8_LEVEL 8 #define ASV_5_LEVEL 5 #define ASV_LEVEL_SUPPORT 0 static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { /* L3(160MHz), L2(266MHz) */ {1000000, 1100000}, /* S */ {1000000, 1100000}, /* A */ { 950000, 1000000}, /* B */ { 950000, 1000000}, /* C */ { 950000, 950000}, /* D */ }; static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = { /* L3(160MHz), L2(266MHz)) */ {1000000, 1100000}, /* SS */ {1000000, 1100000}, /* A1 */ {1000000, 1100000}, /* A2 */ { 950000, 1000000}, /* B1 */ { 950000, 1000000}, /* B2 */ { 950000, 1000000}, /* C1 */ { 950000, 1000000}, /* C2 */ { 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 if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) #else if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) #endif level=1; else if (utilization < mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) level=0; else level = maliDvfsStatus.currentStep; } else { if ((mali_dvfs_control > 0) && (mali_dvfs_control < mali_dvfs[1].clock)) level=0; else level=1; } return level; } #ifdef EXYNOS4_ASV_ENABLED static mali_bool mali_dvfs_table_update(void) { unsigned int exynos_result_of_asv_group; unsigned int i; exynos_result_of_asv_group = exynos_result_of_asv & 0xf; MALI_PRINT(("exynos_result_of_asv_group = 0x%x\n", exynos_result_of_asv_group)); if (ASV_LEVEL_SUPPORT) { //asv level information will be added. 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 { 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 \ No newline at end of file diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c index 397ba942..e8e5129 100644 --- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c +++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010 ARM Limited. All rights reserved. +/* Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -19,7 +18,7 @@ #include "mali_linux_pm.h" #if USING_MALI_PMM -#include "mali_pmm.h" +#include "mali_pm.h" #endif #include @@ -32,8 +31,9 @@ #include #endif -#if MALI_TIMELINE_PROFILING_ENABLED -#include "mali_kernel_profiling.h" +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED +#include "mali_osk_profiling.h" +#include "cinstr/mali_cinstr_profiling_events_m200.h" #endif #include @@ -58,12 +58,20 @@ typedef struct mali_runtime_resumeTag{ int vol; }mali_runtime_resume_table; -mali_runtime_resume_table mali_runtime_resume = {266, 900000}; +mali_runtime_resume_table mali_runtime_resume = {350, 950000}; /* 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; @@ -76,11 +84,11 @@ static struct clk *mali_clock = 0; static unsigned int GPU_MHZ = 1000000; -int mali_gpu_clk = 266; -int mali_gpu_vol = 900000; +int mali_gpu_clk = 350; +int mali_gpu_vol = 950000; #if MALI_DVFS_ENABLED -#define MALI_DVFS_DEFAULT_STEP 0 +#define MALI_DVFS_DEFAULT_STEP 2 #endif #if MALI_VOLTAGE_LOCK int mali_lock_vol = 0; @@ -134,7 +142,6 @@ int mali_regulator_get_usecount(void) 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")); @@ -142,11 +149,11 @@ void mali_regulator_disable(void) } 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) { - bPoweroff = 0; if( IS_ERR_OR_NULL(g3d_regulator) ) { MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n")); @@ -154,6 +161,7 @@ void mali_regulator_enable(void) } 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) @@ -196,8 +204,8 @@ void mali_regulator_set_voltage(int min_uV, int max_uV) MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, min_uV, max_uV, 1, 0, 0); @@ -206,8 +214,8 @@ void mali_regulator_set_voltage(int min_uV, int max_uV) regulator_set_voltage(g3d_regulator,min_uV,max_uV); voltage = regulator_get_voltage(g3d_regulator); -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, voltage, 0, 2, 0, 0); @@ -398,18 +406,20 @@ mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz) if (clk_enable(mali_clock) < 0) return MALI_FALSE; -#if MALI_TIMELINE_PROFILING_ENABLED - _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + unsigned long previous_rate = 0; + previous_rate = clk_get_rate(mali_clock); + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, - rate, 0, 0, 0, 0); + previous_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 | +#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED + _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, rate, 1, 0, 0, 0); @@ -434,8 +444,6 @@ static mali_bool init_mali_clock(void) { mali_bool ret = MALI_TRUE; - gpu_power_state = 0; - if (mali_clock != 0) return ret; // already initialized @@ -475,15 +483,15 @@ static mali_bool init_mali_clock(void) 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; - + gpu_power_state=0; + bPoweroff=1; + return MALI_TRUE; #ifdef CONFIG_REGULATOR err_regulator: regulator_put(g3d_regulator); @@ -526,12 +534,13 @@ static _mali_osk_errcode_t enable_mali_clocks(void) 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 (mali_gpu_clk <= mali_runtime_resume.clk) - set_mali_dvfs_current_step(5); +#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); @@ -547,8 +556,10 @@ 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 /* lock/unlock CPU freq by Mali */ cpufreq_unlock_by_mali(); +#endif MALI_SUCCESS; } @@ -569,7 +580,7 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on) { #if MALI_PMM_RUNTIME_JOB_CONTROL_ON MALI_DEBUG_PRINT(3,("_mali_osk_pmm_dev_activate \n")); - _mali_osk_pmm_dev_activate(); + _mali_osk_pm_dev_activate(); #else //MALI_PMM_RUNTIME_JOB_CONTROL_ON void __iomem *status; u32 timeout; @@ -586,14 +597,14 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on) timeout--; _mali_osk_time_ubusydelay(100); } + MALI_PRINTF(("MALI Power domain enabled")); #endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON } else { #if MALI_PMM_RUNTIME_JOB_CONTROL_ON MALI_DEBUG_PRINT( 4,("_mali_osk_pmm_dev_idle\n")); - _mali_osk_pmm_dev_idle(); - + _mali_osk_pm_dev_idle(); #else //MALI_PMM_RUNTIME_JOB_CONTROL_ON void __iomem *status; u32 timeout; @@ -611,6 +622,7 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on) timeout--; _mali_osk_time_ubusydelay( 100); } + MALI_PRINTF(("MALI Power domain disabled")); #endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON } @@ -714,7 +726,51 @@ u32 pmu_get_power_up_down_info(void) _mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) { - MALI_SUCCESS; + 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 diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c index 8293d6e..2d47dba 100644 --- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c +++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -27,7 +27,7 @@ #include "mali_device_pause_resume.h" #include -#define MAX_MALI_DVFS_STEPS 4 +#define MAX_MALI_DVFS_STEPS 5 #define MALI_DVFS_WATING 10 // msec #ifdef CONFIG_CPU_FREQ @@ -35,10 +35,12 @@ #define EXYNOS4_ASV_ENABLED #endif +#include + static int bMaliDvfsRun=0; static _mali_osk_atomic_t bottomlock_status; -static int bottom_lock_step; +int bottom_lock_step = 0; typedef struct mali_dvfs_tableTag{ unsigned int clock; @@ -73,7 +75,10 @@ mali_dvfs_step step[MALI_DVFS_STEPS]={ #if (MALI_DVFS_STEPS > 2) /*step 2 clk*/ {350, 950000}, #if (MALI_DVFS_STEPS > 3) - /*step 3 clk*/ {440, 1025000} + /*step 3 clk*/ {440, 1025000}, +#if (MALI_DVFS_STEPS > 4) + /*step 4 clk*/ {533, 1075000} +#endif #endif #endif #endif @@ -86,17 +91,21 @@ mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ #if (MALI_DVFS_STEPS > 2) /*step 2*/{0}, #if (MALI_DVFS_STEPS > 3) - /*step 3*/{0} + /*step 3*/{0}, +#if (MALI_DVFS_STEPS > 4) + /*step 4*/{0} +#endif #endif #endif #endif }; /* dvfs information */ -// L0 = 440Mhz, 1.025V -// L1 = 350Mhz, 0.95V -// L2 = 266Mhz, 0.90V -// L3 = 160Mhz, 0.875V +// 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; @@ -114,7 +123,13 @@ int step2_down = 85; int step3_clk = 440; int step3_vol = 1025000; int step2_up = 90; -int step3_down = 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 @@ -123,7 +138,8 @@ mali_dvfs_table mali_dvfs_all[MAX_MALI_DVFS_STEPS]={ {160 ,1000000 , 875000}, {266 ,1000000 , 900000}, {350 ,1000000 , 950000}, - {440 ,1000000 , 1025000} }; + {440 ,1000000 , 1025000}, + {533 ,1000000 , 1075000} }; mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ {160 ,1000000 , 875000}, @@ -132,7 +148,10 @@ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ #if (MALI_DVFS_STEPS > 2) {350 ,1000000 , 950000}, #if (MALI_DVFS_STEPS > 3) - {440 ,1000000 ,1025000} + {440 ,1000000 ,1025000}, +#if (MALI_DVFS_STEPS > 4) + {533 ,1000000 ,1075000} +#endif #endif #endif #endif @@ -145,7 +164,10 @@ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ #if (MALI_DVFS_STEPS > 2) {85 , 90}, #if (MALI_DVFS_STEPS > 3) - {90 ,100} + {85 ,90}, +#if (MALI_DVFS_STEPS > 4) + {95 ,100} +#endif #endif #endif #endif @@ -154,19 +176,48 @@ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ #ifdef EXYNOS4_ASV_ENABLED #define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */ -static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS][ASV_LEVEL] = { +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) */ + { 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) */ + { 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) */ + { 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] = { + { 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(533Mhz) */ +#endif #endif +#endif +#endif +}; +#endif /* ASV_LEVEL */ /*dvfs status*/ mali_dvfs_currentstatus maliDvfsStatus; @@ -279,10 +330,12 @@ static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) } #ifdef EXYNOS4_ASV_ENABLED - if (mali_dvfs[step].clock == 160) - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); - else - exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); + if (samsung_rev() < EXYNOS4412_REV_2_0) { + if (mali_dvfs[step].clock == 160) + exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V); + else + exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V); + } #endif @@ -290,11 +343,13 @@ static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) /*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; } @@ -335,11 +390,30 @@ extern unsigned int exynos_result_of_asv; static mali_bool mali_dvfs_table_update(void) { unsigned int i; - - for (i = 0; i < MALI_DVFS_STEPS; i++) { - MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv)); - mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv]; - MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); + unsigned int step_num = MALI_DVFS_STEPS; + + if(soc_is_exynos4412()) { + if (exynos_armclk_max == 1000000) { + step_num = MALI_DVFS_STEPS - 1; + for (i = 0; i < step_num; i++) { + MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv]; + MALI_PRINT(("mali_dvfs[%d].vol = %d 1ghz_type\n", i, mali_dvfs[i].vol)); + } + } else if (samsung_rev() >= EXYNOS4412_REV_2_0) { + for (i = 0; i < step_num; i++) { + MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv]; + MALI_PRINT(("mali_dvfs[%d].vol = %d 1.6ghz_type\n", i, mali_dvfs[i].vol)); + } + } else { + step_num = MALI_DVFS_STEPS - 1; + for (i = 0; i < step_num; i++) { + MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv)); + mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv]; + MALI_PRINT(("mali_dvfs[%d].vol = %d 1.4ghz_type\n", i, mali_dvfs[i].vol)); + } + } } return MALI_TRUE; @@ -354,7 +428,6 @@ static unsigned int decideNextStatus(unsigned int utilization) if (mali_runtime_resumed >= 0) { level = mali_runtime_resumed; mali_runtime_resumed = -1; - return level; } if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold @@ -369,6 +442,9 @@ static unsigned int decideNextStatus(unsigned int utilization) 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) { @@ -400,6 +476,10 @@ static unsigned int decideNextStatus(unsigned int utilization) #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 @@ -422,12 +502,18 @@ static unsigned int decideNextStatus(unsigned int utilization) step[i].clk = mali_dvfs_all[2].clock; } maliDvfsStatus.currentStep = 2; - } else { + } 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); @@ -440,6 +526,10 @@ static unsigned int decideNextStatus(unsigned int utilization) #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 @@ -577,6 +667,22 @@ static void mali_dvfs_work_handler(struct work_struct *w) 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 @@ -587,6 +693,7 @@ static void mali_dvfs_work_handler(struct work_struct *w) 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")); @@ -641,8 +748,10 @@ int change_dvfs_tableset(int change_clk, int change_step) 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 { + } 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)); @@ -655,11 +764,13 @@ int change_dvfs_tableset(int change_clk, int change_step) /*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; @@ -684,10 +795,8 @@ int mali_dvfs_bottom_lock_push(int lock_step) 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); + 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); } } diff --git a/drivers/media/video/samsung/mali/readme.txt b/drivers/media/video/samsung/mali/readme.txt new file mode 100644 index 0000000..3acc51c --- /dev/null +++ b/drivers/media/video/samsung/mali/readme.txt @@ -0,0 +1,28 @@ +Building the Mali Device Driver for Linux +----------------------------------------- + +Build the Mali Device Driver for Linux by running the following make command: + +KDIR= USING_UMP= BUILD= \ +TARGET_PLATFORM= CONFIG= make + +where + kdir_path: Path to your Linux Kernel directory + ump_option: 1 = Enable UMP support(*) + 0 = disable UMP support + build_option: debug = debug build of driver + release = release build of driver + target_platform: Name of the sub-folder in platform/ that contains the + required mali_platform.c file. + your_config: Name of the sub-folder to find the required config.h(**) file + ("arch-" will be prepended) + +(*) For newer Linux Kernels, the Module.symvers file for the UMP device driver + must be available. The UMP_SYMVERS_FILE variable in the Makefile should + point to this file. This file is generated when the UMP driver is built. + +(**) The config.h file contains the configuration parameters needed, like where the + Mali GPU is located, interrupts it uses, memory and so on. + +The result will be a mali.ko file, which can be loaded into the Linux kernel +by using the insmod command. diff --git a/drivers/media/video/samsung/mali/regs/mali_200_regs.h b/drivers/media/video/samsung/mali/regs/mali_200_regs.h index e9da7ab..59e92c8 100644 --- a/drivers/media/video/samsung/mali/regs/mali_200_regs.h +++ b/drivers/media/video/samsung/mali/regs/mali_200_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -51,7 +51,7 @@ enum mali200_mgmt_ctrl_mgmt { #endif MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET = (1<<5), MALI200_REG_VAL_CTRL_MGMT_START_RENDERING = (1<<6), -#if defined(USING_MALI400) +#if defined(USING_MALI400) || defined(USING_MALI450) MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7), #endif }; @@ -72,7 +72,7 @@ enum mali200_mgmt_irq { MALI400PP_REG_VAL_IRQ_RESET_COMPLETED = (1<<12), }; -#if defined USING_MALI200 +#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 |\ @@ -83,7 +83,7 @@ enum mali200_mgmt_irq { 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 +#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 |\ @@ -102,14 +102,14 @@ enum mali200_mgmt_irq { #error "No supported mali core defined" #endif -#if defined USING_MALI200 +#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 +#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 |\ @@ -134,11 +134,14 @@ enum mali200_mgmt_status { enum mali200_render_unit { MALI200_REG_ADDR_FRAME = 0x0000, + MALI200_REG_ADDR_STACK = 0x0030 }; -#if defined USING_MALI200 +#if defined(USING_MALI200) #define MALI200_NUM_REGS_FRAME ((0x04C/4)+1) -#elif defined USING_MALI400 +#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" @@ -150,21 +153,20 @@ enum mali200_wb_unit { MALI200_REG_ADDR_WB2 = 0x0300 }; +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 */ -#if defined USING_MALI200 -#define MALI_PP_PRODUCT_ID 0xC807 -#elif defined USING_MALI400 +#define MALI200_PP_PRODUCT_ID 0xC807 #define MALI300_PP_PRODUCT_ID 0xCE07 #define MALI400_PP_PRODUCT_ID 0xCD07 -#define MALI_PP_PRODUCT_ID MALI400_PP_PRODUCT_ID -#else -#error "No supported mali core defined" -#endif +#define MALI450_PP_PRODUCT_ID 0xCF07 #endif /* _MALI200_REGS_H_ */ diff --git a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h index 14719a3..21c83c0 100644 --- a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h +++ b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -12,9 +12,9 @@ #define _MALIGP2_CONROL_REGS_H_ /** - * These are the different geometry processor controll registers. + * These are the different geometry processor control registers. * Their usage is to control and monitor the operation of the - * Vertex Shader and the Polygon List Builer in the geometry processor. + * Vertex Shader and the Polygon List Builder in the geometry processor. * Addresses are in 32-bit word relative sizes. * @see [P0081] "Geometry Processor Data Structures" for details */ @@ -60,7 +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) +#if defined(USING_MALI400) || defined(USING_MALI450) MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10), #endif } mgp_contr_reg_val_cmd; @@ -84,7 +84,7 @@ 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 +#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) @@ -97,7 +97,7 @@ typedef enum #endif /* Mask defining all IRQs in MaliGP2 */ -#if defined USING_MALI200 +#if defined(USING_MALI200) #define MALIGP2_REG_VAL_IRQ_MASK_ALL \ (\ MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ @@ -112,7 +112,7 @@ typedef enum MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR) -#elif defined USING_MALI400 +#elif defined(USING_MALI400) || defined(USING_MALI450) #define MALIGP2_REG_VAL_IRQ_MASK_ALL \ (\ MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ @@ -139,7 +139,7 @@ typedef enum #endif /* Mask defining the IRQs in MaliGP2 which we use*/ -#if defined USING_MALI200 +#if defined(USING_MALI200) #define MALIGP2_REG_VAL_IRQ_MASK_USED \ (\ MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ @@ -150,7 +150,7 @@ typedef enum MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \ MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \ MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR) -#elif defined USING_MALI400 +#elif defined(USING_MALI400) || defined(USING_MALI450) #define MALIGP2_REG_VAL_IRQ_MASK_USED \ (\ MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \ @@ -197,15 +197,10 @@ typedef enum MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR ) /* This should be in the top 16 bit of the version register of gp.*/ -#if defined(USING_MALI200) -#define MALI_GP_PRODUCT_ID 0xA07 -#elif defined(USING_MALI400) +#define MALI200_GP_PRODUCT_ID 0xA07 #define MALI300_GP_PRODUCT_ID 0xC07 #define MALI400_GP_PRODUCT_ID 0xB07 -#define MALI_GP_PRODUCT_ID MALI400_GP_PRODUCT_ID -#else -#error "No supported mali core defined" -#endif +#define MALI450_GP_PRODUCT_ID 0xD07 /** * The different sources for instrumented on the geometry processor. diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c index cddfa58..a6b1d76 100644 --- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c +++ b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h index 442c6e0..3279dae 100644 --- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h +++ b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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.c b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c index cddfa58..a6b1d76 100644 --- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c +++ b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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/media/video/samsung/mali/timestamp-default/mali_timestamp.h index 470eac9..94b842a 100644 --- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h +++ b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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/tvout/Kconfig b/drivers/media/video/samsung/tvout/Kconfig index 176efeb..da7bda7 100644 --- a/drivers/media/video/samsung/tvout/Kconfig +++ b/drivers/media/video/samsung/tvout/Kconfig @@ -62,6 +62,16 @@ config HDMI_CONTROLLED_BY_EXT_IC For example, the H/W has HDMI level shifter then it should be turned on when HPD interrupt comes. +config HDMI_TX_STRENGTH + bool "Tuning TX amplitude" + depends on VIDEO_TVOUT && ARCH_EXYNOS4 + default n + ---help--- + Say y here if the H/W needs to be tuned for TX amplitude. + HDMI driver will take the values registered at board file + and apply them through HDMI phy i2c according to the requested + channel number. + config HDMI_SWITCH_HPD bool "HDMI HPD switch uevent driver support" depends on HDMI_HPD diff --git a/drivers/media/video/samsung/tvout/hw_if/hdcp.c b/drivers/media/video/samsung/tvout/hw_if/hdcp.c index 569de28..41caf19 100644 --- a/drivers/media/video/samsung/tvout/hw_if/hdcp.c +++ b/drivers/media/video/samsung/tvout/hw_if/hdcp.c @@ -379,7 +379,9 @@ static int s5p_hdcp_read_bcaps(void) if (s5p_ddc_read(HDCP_Bcaps, BCAPS_SIZE, &bcaps) < 0) goto bcaps_read_err; - if (s5p_hdmi_ctrl_status() == false || !s5p_hdmi_reg_get_hpd_status() || on_stop_process) + if (s5p_hdmi_ctrl_status() == false || + !s5p_hdmi_reg_get_hpd_status() || + on_stop_process) goto bcaps_read_err; writeb(bcaps, hdmi_base + S5P_HDMI_HDCP_BCAPS); @@ -532,7 +534,8 @@ static void s5p_hdcp_reset_auth(void) unsigned long spin_flags; if (s5p_hdmi_ctrl_status() == false || - !s5p_hdmi_reg_get_hpd_status() || on_stop_process) + !s5p_hdmi_reg_get_hpd_status() || + on_stop_process) return; spin_lock_irqsave(&hdcp_info.reset_lock, spin_flags); @@ -956,9 +959,12 @@ check_ri_err: static void s5p_hdcp_work(void *arg) { + s5p_tvout_mutex_lock(); if (!hdcp_info.hdcp_enable || s5p_hdmi_ctrl_status() == false || - !s5p_hdmi_reg_get_hpd_status() || on_stop_process) + !s5p_hdmi_reg_get_hpd_status() || on_stop_process) { + s5p_tvout_mutex_unlock(); return; + } if (hdcp_info.event & HDCP_EVENT_READ_BKSV_START) { if (s5p_hdcp_bksv() < 0) @@ -987,13 +993,16 @@ static void s5p_hdcp_work(void *arg) else hdcp_info.event &= ~HDCP_EVENT_CHECK_RI_START; } + s5p_tvout_mutex_unlock(); return; work_err: if (!hdcp_info.hdcp_enable || s5p_hdmi_ctrl_status() == false || !s5p_hdmi_reg_get_hpd_status() || on_stop_process) { + s5p_tvout_mutex_unlock(); return; } s5p_hdcp_reset_auth(); + s5p_tvout_mutex_unlock(); } irqreturn_t s5p_hdcp_irq_handler(int irq, void *dev_id) @@ -1121,3 +1130,8 @@ int s5p_hdcp_encrypt_stop(bool on) return 0; } + +void s5p_hdcp_flush_work(void) +{ + flush_workqueue(hdcp_wq); +} diff --git a/drivers/media/video/samsung/tvout/hw_if/hdmi.c b/drivers/media/video/samsung/tvout/hw_if/hdmi.c index dfb3152..67099af 100644 --- a/drivers/media/video/samsung/tvout/hw_if/hdmi.c +++ b/drivers/media/video/samsung/tvout/hw_if/hdmi.c @@ -871,10 +871,10 @@ static void s5p_hdmi_print_phy_config(void) printk(KERN_WARNING "read buffer :\n"); - for (i = 1; i < size; i++) { + for (i = 0; i < size; i++) { printk("0x%02x", read_buffer[i]); - if (i % 8) + if ((i+1) % 8) printk(" "); else printk("\n"); @@ -1146,6 +1146,58 @@ void s5p_hdmi_reg_sw_reset(void) s5p_hdmi_ctrl_clock(0); } +#ifdef CONFIG_HDMI_TX_STRENGTH +int s5p_hdmi_phy_set_tx_strength(u8 ch, u8 *value) +{ + u8 buff[2]; + + if (ch & TX_EMP_LVL) { /* REG10 BIT7:4 */ + buff[0] = HDMI_PHY_I2C_REG10; + buff[1] = (value[TX_EMP_LVL_VAL] & 0x0f) << 4; + if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + goto err_exit; + } + + if (ch & TX_AMP_LVL) { /* REG10 BIT3:0, REG0F BIT7 */ + buff[0] = HDMI_PHY_I2C_REG10; + buff[1] = (value[TX_AMP_LVL_VAL] & 0x0e) >> 1; + if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + goto err_exit; + buff[0] = HDMI_PHY_I2C_REG0F; + buff[1] = (value[TX_AMP_LVL_VAL] & 0x01) << 7; + if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + goto err_exit; + } + + if (ch & TX_LVL_CH0) { /* REG04 BIT7:6 */ + buff[0] = HDMI_PHY_I2C_REG04; + buff[1] = (value[TX_LVL_CH0_VAL] & 0x3) << 6; + if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + goto err_exit; + } + + if (ch & TX_LVL_CH1) { /* REG13 BIT1:0 */ + buff[0] = HDMI_PHY_I2C_REG13; + buff[1] = (value[TX_LVL_CH1_VAL] & 0x3); + if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + goto err_exit; + } + + if (ch & TX_LVL_CH2) { /* REG17 BIT1:0 */ + buff[0] = HDMI_PHY_I2C_REG17; + buff[1] = (value[TX_LVL_CH2_VAL] & 0x3); + if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0) + goto err_exit; + } + + return 0; + +err_exit: + pr_err("%s: failed to set tx strength\n", __func__); + return -1; +} +#endif + int s5p_hdmi_phy_power(bool on) { u32 size; diff --git a/drivers/media/video/samsung/tvout/hw_if/hw_if.h b/drivers/media/video/samsung/tvout/hw_if/hw_if.h index 11bda99..e437b0a 100644 --- a/drivers/media/video/samsung/tvout/hw_if/hw_if.h +++ b/drivers/media/video/samsung/tvout/hw_if/hw_if.h @@ -364,6 +364,27 @@ struct s5p_hdmi_v_format { u8 mhl_vsync; }; +#ifdef CONFIG_HDMI_TX_STRENGTH +#define HDMI_PHY_I2C_REG10 0x10 +#define HDMI_PHY_I2C_REG0F 0x0F +#define HDMI_PHY_I2C_REG04 0x04 +#define HDMI_PHY_I2C_REG13 0x13 +#define HDMI_PHY_I2C_REG17 0x17 + +#define TX_EMP_LVL 0x10 +#define TX_AMP_LVL 0x08 +#define TX_LVL_CH0 0x04 +#define TX_LVL_CH1 0x02 +#define TX_LVL_CH2 0x01 + +#define TX_EMP_LVL_VAL 0 +#define TX_AMP_LVL_VAL 1 +#define TX_LVL_CH0_VAL 2 +#define TX_LVL_CH1_VAL 3 +#define TX_LVL_CH2_VAL 4 + +extern int s5p_hdmi_phy_set_tx_strength(u8 ch, u8 *value); +#endif extern int s5p_hdmi_phy_power(bool on); extern s32 s5p_hdmi_phy_config( enum phy_freq freq, enum s5p_hdmi_color_depth cd); @@ -750,6 +771,7 @@ extern int s5p_hdcp_encrypt_stop(bool on); extern int __init s5p_hdcp_init(void); extern int s5p_hdcp_start(void); extern int s5p_hdcp_stop(void); +extern void s5p_hdcp_flush_work(void); /**************************************** * Definitions for sdo ctrl class @@ -1000,6 +1022,10 @@ struct s5p_tvif_ctrl_private_data { struct device *bus_dev; /* for BusFreq with Opp */ #endif struct device *dev; /* hpd device pointer */ +#ifdef CONFIG_HDMI_TX_STRENGTH + u8 tx_ch; + u8 *tx_val; +#endif }; #endif /* _SAMSUNG_TVOUT_HW_IF_H_ */ diff --git a/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c b/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c index a0169cb..5e78a3c 100644 --- a/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c +++ b/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c @@ -241,7 +241,7 @@ static void s5p_mixer_ctrl_clock(bool on) clk_enable(s5p_mixer_ctrl_private.clk[ACLK].ptr); - // Restore mixer_base address + /* Restore mixer_base address */ s5p_mixer_init(s5p_mixer_ctrl_private.reg_mem.base); } else { clk_disable(s5p_mixer_ctrl_private.clk[ACLK].ptr); @@ -252,7 +252,7 @@ static void s5p_mixer_ctrl_clock(bool on) clk_disable(s5p_mixer_ctrl_private.clk[MUX].ptr); - // Set mixer_base address to NULL + /* Set mixer_base address to NULL */ s5p_mixer_init(NULL); } } @@ -267,7 +267,7 @@ void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer) { struct s5ptvfb_user_scaling scaling; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -278,12 +278,16 @@ void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer) s5p_mixer_set_priority(layer, s5p_mixer_ctrl_private.layer[layer].priority); s5p_mixer_set_pre_mul_mode(layer, - s5p_mixer_ctrl_private.layer[layer].pre_mul_mode); + s5p_mixer_ctrl_private.layer[layer]. + pre_mul_mode); s5p_mixer_set_chroma_key(layer, - s5p_mixer_ctrl_private.layer[layer].chroma_enable, - s5p_mixer_ctrl_private.layer[layer].chroma_key); + s5p_mixer_ctrl_private.layer[layer]. + chroma_enable, + s5p_mixer_ctrl_private.layer[layer]. + chroma_key); s5p_mixer_set_layer_blend(layer, - s5p_mixer_ctrl_private.layer[layer].layer_blend); + s5p_mixer_ctrl_private.layer[layer]. + layer_blend); s5p_mixer_set_alpha(layer, s5p_mixer_ctrl_private.layer[layer].alpha); s5p_mixer_set_grp_layer_dst_pos(layer, @@ -299,7 +303,8 @@ void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer) } } -int s5p_mixer_ctrl_set_pixel_format(enum s5p_mixer_layer layer, u32 bpp, u32 trans_len) +int s5p_mixer_ctrl_set_pixel_format( + enum s5p_mixer_layer layer, u32 bpp, u32 trans_len) { enum s5p_mixer_color_fmt format; @@ -322,7 +327,7 @@ int s5p_mixer_ctrl_set_pixel_format(enum s5p_mixer_layer layer, u32 bpp, u32 tra s5p_mixer_ctrl_private.layer[layer].format = format; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -351,7 +356,7 @@ int s5p_mixer_ctrl_enable_layer(enum s5p_mixer_layer layer) tvout_err("invalid layer\n"); return -1; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -384,7 +389,7 @@ int s5p_mixer_ctrl_disable_layer(enum s5p_mixer_layer layer) return -1; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -523,7 +528,7 @@ int s5p_mixer_ctrl_set_dst_win_pos(enum s5p_mixer_layer layer, s5p_mixer_ctrl_private.layer[layer].dst_x = (u32)dst_x; s5p_mixer_ctrl_private.layer[layer].dst_y = (u32)dst_y; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -551,7 +556,7 @@ int s5p_mixer_ctrl_set_src_win_pos(enum s5p_mixer_layer layer, s5p_mixer_ctrl_private.layer[layer].width = w; s5p_mixer_ctrl_private.layer[layer].height = h; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -559,7 +564,8 @@ int s5p_mixer_ctrl_set_src_win_pos(enum s5p_mixer_layer layer, #endif { if (s5p_mixer_ctrl_private.running) - s5p_mixer_set_grp_layer_src_pos(layer, src_x, src_y, w, w, h); + s5p_mixer_set_grp_layer_src_pos( + layer, src_x, src_y, w, w, h); } return 0; @@ -577,7 +583,7 @@ int s5p_mixer_ctrl_set_buffer_address(enum s5p_mixer_layer layer, s5p_mixer_ctrl_private.layer[layer].fb_addr = start_addr; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -602,7 +608,7 @@ int s5p_mixer_ctrl_set_chroma_key(enum s5p_mixer_layer layer, s5p_mixer_ctrl_private.layer[layer].chroma_enable = enabled; s5p_mixer_ctrl_private.layer[layer].chroma_key = chroma.key; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -709,7 +715,7 @@ int s5p_mixer_ctrl_set_alpha_blending(enum s5p_mixer_layer layer, case PIXEL_BLENDING: tvout_dbg("pixel blending\n"); s5p_mixer_ctrl_private.layer[layer].pixel_blend = true; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -723,7 +729,7 @@ int s5p_mixer_ctrl_set_alpha_blending(enum s5p_mixer_layer layer, tvout_dbg("layer blending : alpha value = 0x%x\n", alpha); s5p_mixer_ctrl_private.layer[layer].layer_blend = true; s5p_mixer_ctrl_private.layer[layer].alpha = alpha; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -739,7 +745,7 @@ int s5p_mixer_ctrl_set_alpha_blending(enum s5p_mixer_layer layer, tvout_dbg("alpha blending off\n"); s5p_mixer_ctrl_private.layer[layer].pixel_blend = false; s5p_mixer_ctrl_private.layer[layer].layer_blend = false; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -780,7 +786,7 @@ int s5p_mixer_ctrl_scaling(enum s5p_mixer_layer layer, s5p_mixer_ctrl_private.layer[layer].ver = scaling.ver; s5p_mixer_ctrl_private.layer[layer].hor = scaling.hor; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return 0; @@ -796,7 +802,8 @@ int s5p_mixer_ctrl_mux_clk(struct clk *ptr) { if (clk_set_parent(s5p_mixer_ctrl_private.clk[MUX].ptr, ptr)) { tvout_err("unable to set parent %s of clock %s.\n", - ptr->name, s5p_mixer_ctrl_private.clk[MUX].ptr->name); + ptr->name, + s5p_mixer_ctrl_private.clk[MUX].ptr->name); return -1; } @@ -828,6 +835,12 @@ bool s5p_mixer_ctrl_get_vsync_interrupt() return s5p_mixer_ctrl_private.vsync_interrupt_enable; } +void s5p_mixer_ctrl_disable_vsync_interrupt() +{ + if (s5p_mixer_ctrl_private.running) + s5p_mixer_set_vsync_interrupt(false); +} + void s5p_mixer_ctrl_clear_pend_all(void) { if (s5p_mixer_ctrl_private.running) @@ -840,7 +853,7 @@ void s5p_mixer_ctrl_stop(void) tvout_dbg("running(%d)\n", s5p_mixer_ctrl_private.running); if (s5p_mixer_ctrl_private.running) { -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -848,11 +861,12 @@ void s5p_mixer_ctrl_stop(void) { s5p_mixer_set_vsync_interrupt(false); - for (i = 0; i < S5PTV_VP_BUFF_CNT -1; i++) + for (i = 0; i < S5PTV_VP_BUFF_CNT-1; i++) s5ptv_vp_buff.copy_buff_idxs[i] = i; s5ptv_vp_buff.curr_copy_idx = 0; - s5ptv_vp_buff.vp_access_buff_idx = S5PTV_VP_BUFF_CNT - 1; + s5ptv_vp_buff.vp_access_buff_idx = + S5PTV_VP_BUFF_CNT - 1; s5p_mixer_stop(); s5p_mixer_ctrl_clock(0); @@ -1006,10 +1020,24 @@ int s5p_mixer_ctrl_start( s5p_mixer_init_csc_coef_default(csc_for_coeff); s5p_mixer_init_display_mode(disp, out, csc); +#ifndef __CONFIG_HDMI_SUPPORT_FULL_RANGE__ if (!s5p_tvif_get_q_range() || out == TVOUT_HDMI_RGB) mixer_video_limiter = true; else mixer_video_limiter = false; +#else + /* full range */ + if ((out == TVOUT_HDMI_RGB && disp == TVOUT_480P_60_4_3) || + (out != TVOUT_HDMI_RGB && s5p_tvif_get_q_range())) { + mixer_video_limiter = false; + for (i = MIXER_BG_COLOR_0; i <= MIXER_BG_COLOR_2; i++) + s5p_mixer_ctrl_private.bg_color[i].color_y = 0; + } else { /* limited range */ + mixer_video_limiter = true; + for (i = MIXER_BG_COLOR_0; i <= MIXER_BG_COLOR_2; i++) + s5p_mixer_ctrl_private.bg_color[i].color_y = 16; + } +#endif s5p_mixer_set_video_limiter(s5p_mixer_ctrl_private.v_layer.y_min, s5p_mixer_ctrl_private.v_layer.y_max, diff --git a/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c b/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c index 93cb640..43e7a1f 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c +++ b/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c @@ -49,6 +49,12 @@ #if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) #include #endif +#include + +#ifdef CONFIG_HDMI_TX_STRENGTH +#include +#endif + #include "s5p_tvout_common_lib.h" #include "hw_if/hw_if.h" @@ -1758,7 +1764,7 @@ static void s5p_sdo_ctrl_clock(bool on) #ifdef CONFIG_ARCH_EXYNOS4 s5p_tvout_pm_runtime_get(); #endif - // Restore sdo_base address + /* Restore sdo_base address */ s5p_sdo_init(s5p_sdo_ctrl_private.reg_mem.base); clk_enable(s5p_sdo_ctrl_private.clk[SDO_PCLK].ptr); @@ -1771,7 +1777,7 @@ static void s5p_sdo_ctrl_clock(bool on) clk_disable(s5p_sdo_ctrl_private.clk[SDO_MUX].ptr); - // Set sdo_base address to NULL + /* Set sdo_base address to NULL */ s5p_sdo_init(NULL); } @@ -2362,8 +2368,10 @@ static void s5p_hdmi_ctrl_internal_stop(void) #ifdef CONFIG_HDMI_HPD s5p_hpd_set_eint(); #endif - if (ctrl->hdcp_en) + if (ctrl->hdcp_en) { s5p_hdcp_stop(); + s5p_hdcp_flush_work(); + } s5p_hdmi_reg_enable(false); @@ -2376,10 +2384,16 @@ int s5p_hdmi_ctrl_phy_power(bool on) if (on) { /* on */ clk_enable(s5ptv_status.i2c_phy_clk); - // Restore i2c_hdmi_phy_base address + /* Restore i2c_hdmi_phy_base address */ s5p_hdmi_phy_init(s5p_hdmi_ctrl_private.reg_mem[HDMI_PHY].base); s5p_hdmi_phy_power(true); +#ifdef CONFIG_HDMI_TX_STRENGTH + if (s5p_tvif_ctrl_private.tx_val) + s5p_hdmi_phy_set_tx_strength( + s5p_tvif_ctrl_private.tx_ch, + s5p_tvif_ctrl_private.tx_val); +#endif } else { /* @@ -2398,7 +2412,7 @@ int s5p_hdmi_ctrl_phy_power(bool on) s5p_hdmi_phy_power(false); clk_disable(s5ptv_status.i2c_phy_clk); - // Set i2c_hdmi_phy_base to NULL + /* Set i2c_hdmi_phy_base to NULL */ s5p_hdmi_phy_init(NULL); } @@ -2419,7 +2433,7 @@ void s5p_hdmi_ctrl_clock(bool on) #endif clk_enable(clk[HDMI_PCLK].ptr); - // Restore hdmi_base address + /* Restore hdmi_base address */ s5p_hdmi_init(s5p_hdmi_ctrl_private.reg_mem[HDMI].base); } else { clk_disable(clk[HDMI_PCLK].ptr); @@ -2430,7 +2444,7 @@ void s5p_hdmi_ctrl_clock(bool on) clk_disable(clk[HDMI_MUX].ptr); - // Set hdmi_base to NULL + /* Set hdmi_base to NULL */ s5p_hdmi_init(NULL); } } @@ -2447,7 +2461,7 @@ void s5p_hdmi_ctrl_stop(void) tvout_dbg("running(%d)\n", ctrl->running); if (ctrl->running) { ctrl->running = false; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -2681,7 +2695,7 @@ static int s5p_tvif_ctrl_internal_stop(void) case TVOUT_HDMI: case TVOUT_HDMI_RGB: s5p_hdmi_ctrl_stop(); -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -2705,6 +2719,10 @@ static void s5p_tvif_ctrl_internal_start( enum s5p_tvout_o_mode inf) { tvout_dbg("\n"); +#ifdef __CONFIG_HDMI_SUPPORT_FULL_RANGE__ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_BYPASS; +#endif s5p_mixer_ctrl_set_int_enable(false); /* Clear All Interrupt Pending */ @@ -2724,6 +2742,47 @@ static void s5p_tvif_ctrl_internal_start( case TVOUT_HDMI: case TVOUT_HDMI_RGB: case TVOUT_DVI: +#ifdef __CONFIG_HDMI_SUPPORT_FULL_RANGE__ + switch (std) { + case TVOUT_480P_60_4_3: + if (inf == TVOUT_HDMI_RGB) /* full range */ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_BYPASS; + else if (s5p_tvif_get_q_range()) /* full range */ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_BYPASS; + else /* limited range */ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_YPBPR; + break; + case TVOUT_480P_60_16_9: + case TVOUT_480P_59: + case TVOUT_576P_50_16_9: + case TVOUT_576P_50_4_3: + case TVOUT_720P_60: + case TVOUT_720P_50: + case TVOUT_720P_59: + case TVOUT_1080I_60: + case TVOUT_1080I_59: + case TVOUT_1080I_50: + case TVOUT_1080P_60: + case TVOUT_1080P_30: + case TVOUT_1080P_59: + case TVOUT_1080P_50: + if (inf == TVOUT_HDMI_RGB) /* limited range */ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_RGB; + else if (s5p_tvif_get_q_range()) /* full range */ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_BYPASS; + else /* limited range */ + s5p_hdmi_output[inf].reg.pxl_limit = + S5P_HDMI_PX_LMT_CTRL_YPBPR; + break; + default: + break; + } +#endif s5p_hdmi_ctrl_phy_power(1); if (s5p_mixer_ctrl_start(std, inf) < 0) @@ -2854,7 +2913,7 @@ int s5p_tvif_ctrl_start( goto cannot_change; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -2889,6 +2948,16 @@ void s5p_tvif_ctrl_stop(void) int s5p_tvif_ctrl_constructor(struct platform_device *pdev) { +#ifdef CONFIG_HDMI_TX_STRENGTH + struct s5p_platform_tvout *pdata = to_tvout_plat(&pdev->dev); + s5p_tvif_ctrl_private.tx_ch = 0x00; + s5p_tvif_ctrl_private.tx_val = NULL; + if ((pdata) && (pdata->tx_tune)) { + s5p_tvif_ctrl_private.tx_ch = pdata->tx_tune->tx_ch; + s5p_tvif_ctrl_private.tx_val = pdata->tx_tune->tx_val; + } +#endif + #ifdef CONFIG_ANALOG_TVENC if (s5p_sdo_ctrl_constructor(pdev)) goto err; diff --git a/drivers/media/video/samsung/tvout/s5p_tvout.c b/drivers/media/video/samsung/tvout/s5p_tvout.c index 7407670..5f00ebc 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout.c +++ b/drivers/media/video/samsung/tvout/s5p_tvout.c @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(CONFIG_S5P_SYSMMU_TV) #include @@ -25,6 +26,10 @@ #include #endif +#if defined(CONFIG_HDMI_TX_STRENGTH) && !defined(CONFIG_USER_ALLOC_TVOUT) +#include +#endif + #include "s5p_tvout_common_lib.h" #include "s5p_tvout_ctrl.h" #include "s5p_tvout_fb.h" @@ -291,6 +296,12 @@ static int __devinit s5p_tvout_probe(struct platform_device *pdev) struct device *hdmi_audio_dev; #endif +#if defined(CONFIG_HDMI_TX_STRENGTH) && !defined(CONFIG_USER_ALLOC_TVOUT) + struct s5p_platform_tvout *pdata; + u8 tx_ch; + u8 *tx_val; +#endif + #ifdef CONFIG_TVOUT_DEBUG struct class *sec_tvout; tvout_dbg_flag = 1 << DBG_FLAG_HPD; @@ -339,6 +350,15 @@ static int __devinit s5p_tvout_probe(struct platform_device *pdev) s5p_hdmi_phy_power(true); if (s5p_tvif_ctrl_start(TVOUT_720P_60, TVOUT_HDMI) < 0) goto err_tvif_start; +#ifdef CONFIG_HDMI_TX_STRENGTH + pdata = to_tvout_plat(&pdev->dev); + if (pdata && pdata->tx_tune) { + tx_ch = pdata->tx_tune->tx_ch; + tx_val = pdata->tx_tune->tx_val; + } + if (tx_ch && tx_val) + s5p_hdmi_phy_set_tx_strength(tx_ch, tx_val); +#endif #endif /* prepare memory */ @@ -495,14 +515,19 @@ static int s5p_tvout_remove(struct platform_device *pdev) static void s5p_tvout_early_suspend(struct early_suspend *h) { tvout_dbg("\n"); +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND mutex_lock(&s5p_tvout_mutex); - s5p_mixer_ctrl_set_vsync_interrupt(false); + /* disable vsync interrupt during early suspend */ + s5p_mixer_ctrl_disable_vsync_interrupt(); s5p_vp_ctrl_suspend(); s5p_mixer_ctrl_suspend(); s5p_tvif_ctrl_suspend(); suspend_status = 1; tvout_dbg("suspend_status is true\n"); mutex_unlock(&s5p_tvout_mutex); +#else + suspend_status = 1; +#endif return; } @@ -511,6 +536,7 @@ static void s5p_tvout_late_resume(struct early_suspend *h) { tvout_dbg("\n"); +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND mutex_lock(&s5p_tvout_mutex); #if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) @@ -521,11 +547,17 @@ static void s5p_tvout_late_resume(struct early_suspend *h) #endif suspend_status = 0; tvout_dbg("suspend_status is false\n"); + s5p_tvif_ctrl_resume(); s5p_mixer_ctrl_resume(); s5p_vp_ctrl_resume(); - s5p_mixer_ctrl_set_vsync_interrupt(s5p_mixer_ctrl_get_vsync_interrupt()); + /* restore vsync interrupt setting */ + s5p_mixer_ctrl_set_vsync_interrupt( + s5p_mixer_ctrl_get_vsync_interrupt()); mutex_unlock(&s5p_tvout_mutex); +#else + suspend_status = 0; +#endif return; } @@ -562,8 +594,10 @@ static int s5p_tvout_suspend(struct device *dev) static int s5p_tvout_resume(struct device *dev) { tvout_dbg("\n"); +#if defined(CLOCK_GATING_ON_EARLY_SUSPEND) #if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) flag_after_resume = true; +#endif #else queue_work_on(0, tvout_resume_wq, &tvout_resume_work); #endif diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h b/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h index e43b9c7..467ab1d 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h +++ b/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h @@ -45,6 +45,12 @@ do { \ #endif #endif +/* +#if defined(CONFIG_MACH_T0) || defined(CONFIG_MACH_M3) +#define __CONFIG_HDMI_SUPPORT_FULL_RANGE__ +#endif +*/ + #define S5PTV_FB_CNT 2 #define S5PTV_VP_BUFF_CNT 4 #define S5PTV_VP_BUFF_SIZE (4*1024*1024) @@ -53,6 +59,10 @@ do { \ #define HDMI_START_NUM 0x1000 +#ifdef CONFIG_CPU_EXYNOS4210 +#define CLOCK_GATING_ON_EARLY_SUSPEND +#endif + enum s5p_tvout_disp_mode { TVOUT_NTSC_M = 0, TVOUT_PAL_BDGHI, diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h b/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h index 43043b4..b330a95 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h +++ b/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h @@ -29,7 +29,8 @@ extern void s5p_mixer_ctrl_init_fb_addr_phy(enum s5p_mixer_layer layer, dma_addr_t fb_addr); extern void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer); -extern int s5p_mixer_ctrl_set_pixel_format(enum s5p_mixer_layer layer, u32 bpp, u32 trans_len); +extern int s5p_mixer_ctrl_set_pixel_format( + enum s5p_mixer_layer layer, u32 bpp, u32 trans_len); extern int s5p_mixer_ctrl_enable_layer(enum s5p_mixer_layer layer); extern int s5p_mixer_ctrl_disable_layer(enum s5p_mixer_layer layer); extern int s5p_mixer_ctrl_set_priority(enum s5p_mixer_layer layer, u32 prio); @@ -52,6 +53,7 @@ extern int s5p_mixer_ctrl_mux_clk(struct clk *ptr); extern void s5p_mixer_ctrl_set_int_enable(bool en); extern void s5p_mixer_ctrl_set_vsync_interrupt(bool en); extern bool s5p_mixer_ctrl_get_vsync_interrupt(void); +extern void s5p_mixer_ctrl_disable_vsync_interrupt(void); extern void s5p_mixer_ctrl_clear_pend_all(void); extern void s5p_mixer_ctrl_stop(void); extern void s5p_mixer_ctrl_internal_start(void); diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_fb.c b/drivers/media/video/samsung/tvout/s5p_tvout_fb.c index 5a2ce5a..c0a3508 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_fb.c +++ b/drivers/media/video/samsung/tvout/s5p_tvout_fb.c @@ -303,7 +303,7 @@ static int s5p_tvout_fb_blank(int blank_mode, struct fb_info *fb) tvout_dbg("change blank mode\n"); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif switch (fb->node) { @@ -336,12 +336,12 @@ static int s5p_tvout_fb_blank(int blank_mode, struct fb_info *fb) goto err_fb_blank; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 1; err_fb_blank: -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return -1; @@ -356,7 +356,7 @@ static int s5p_tvout_fb_set_par(struct fb_info *fb) tvout_dbg("[fb%d] set_par\n", win->id); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif if (!fb->fix.smem_start) { @@ -390,7 +390,7 @@ static int s5p_tvout_fb_set_par(struct fb_info *fb) s5p_mixer_ctrl_set_src_win_pos(layer, src_x, src_y, w, h); s5p_mixer_ctrl_set_alpha_blending(layer, win->alpha.mode, win->alpha.value); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; @@ -472,7 +472,7 @@ static int s5p_tvout_fb_ioctl(struct fb_info *fb, unsigned int cmd, } p; tvout_dbg("\n"); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif switch (fb->node) { @@ -552,13 +552,13 @@ static int s5p_tvout_fb_ioctl(struct fb_info *fb, unsigned int cmd, s5p_mixer_ctrl_scaling(layer, p.user_scaling); break; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; err_fb_ioctl: -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return -1; diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c b/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c index 4f35a91..1c98453 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c +++ b/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c @@ -67,6 +67,12 @@ struct hpd_struct { #endif }; +#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC +static work_func_t ext_ic_control_func(void) ; +static DECLARE_DELAYED_WORK(ext_ic_control_dwork, + (work_func_t)ext_ic_control_func); +#endif + static struct hpd_struct hpd_struct; static int last_hpd_state; @@ -81,6 +87,10 @@ static ssize_t s5p_hpd_read(struct file *file, char __user *buffer, static unsigned int s5p_hpd_poll(struct file *file, poll_table *wait); static long s5p_hpd_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE +void mhl_hpd_handler(bool onoff); +bool (*is_mhl_power_state_on)(void); +#endif static const struct file_operations hpd_fops = { .owner = THIS_MODULE, @@ -139,6 +149,7 @@ static void s5p_hpd_kobject_uevent(void) if (hpd_state) { if (last_uevent_state == -1 || last_uevent_state == HPD_LO) { #ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC + HPDPRINTK("ext_ic power ON\n"); hpd_struct.ext_ic_control(true); msleep(20); #endif @@ -154,9 +165,13 @@ static void s5p_hpd_kobject_uevent(void) KOBJ_CHANGE, envp); #endif HPDPRINTK("[HDMI] HPD event -connect!!!\n"); - on_start_process = true; + if (atomic_read(&hdmi_status) == HDMI_OFF) { + on_start_process = true; + } else { + on_start_process = false; + } HPDIFPRINTK("%s() on_start_process(%d)\n", - __func__, on_start_process); + __func__, on_start_process); } last_uevent_state = HPD_HI; } else { @@ -176,10 +191,14 @@ static void s5p_hpd_kobject_uevent(void) KOBJ_CHANGE, envp); #endif HPDPRINTK("[HDMI] HPD event -disconnet!!!\n"); - on_stop_process = true; -#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC - hpd_struct.ext_ic_control(false); -#endif + if (atomic_read(&hdmi_status) == HDMI_ON) { + on_stop_process = true; + } else { + on_stop_process = false; + } + HPDIFPRINTK("%s() on_stop_process(%d)\n", + __func__, on_stop_process); + } last_uevent_state = HPD_LO; } @@ -233,9 +252,16 @@ static unsigned int s5p_hpd_poll(struct file *file, poll_table * wait) void hdmi_send_audio_ch_num( int supported_ch_num, struct switch_dev *p_audio_ch_switch) { - printk(KERN_INFO "%s() hdmi_send_audio_ch_num :: " - "HDMI Audio supported ch = %d", - __func__, supported_ch_num); + if (last_uevent_state == HPD_LO) { + printk(KERN_INFO "[WARNING] %s() " + "HDMI Audio ch = %d but not send\n", + __func__, supported_ch_num); + return; + } else + printk(KERN_INFO "%s() " + "HDMI Audio ch = %d\n", + __func__, supported_ch_num); + p_audio_ch_switch->state = 0; switch_set_state(p_audio_ch_switch, (int)supported_ch_num); } @@ -366,7 +392,16 @@ static int s5p_hpd_irq_eint(int irq) atomic_set(&poll_state, 1); last_hpd_state = HPD_LO; +#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE + if (is_mhl_power_state_on != NULL) + if (!is_mhl_power_state_on()) + mhl_hpd_handler(false); +#endif +#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC + schedule_delayed_work(&ext_ic_control_dwork , + msecs_to_jiffies(1000)); +#endif wake_up_interruptible(&hpd_struct.waitq); } schedule_work(&hpd_work); @@ -438,6 +473,15 @@ static int s5p_hpd_irq_hdmi(int irq) atomic_set(&poll_state, 1); last_hpd_state = HPD_LO; +#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE + if (is_mhl_power_state_on != NULL) + if (!is_mhl_power_state_on()) + mhl_hpd_handler(false); +#endif +#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC + schedule_delayed_work(&ext_ic_control_dwork , + msecs_to_jiffies(1000)); +#endif wake_up_interruptible(&hpd_struct.waitq); } @@ -474,6 +518,20 @@ static irqreturn_t s5p_hpd_irq_handler(int irq, void *dev_id) return ret; } +#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC +static work_func_t ext_ic_control_func(void) +{ + if (!hpd_struct.read_gpio()) { + hpd_struct.ext_ic_control(false); + HPDPRINTK("HDMI_EXT_IC Power Off\n"); + } else { + HPDPRINTK("HDMI_EXT_IC Delay work do nothing\n"); + } + return 0; +} +#endif + + #ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE static irqreturn_t s5p_hpd_irq_default_handler(int irq, void *dev_id) { @@ -566,6 +624,9 @@ static int __devinit s5p_hpd_probe(struct platform_device *pdev) if (hpd_struct.read_gpio()) { atomic_set(&hpd_struct.state, HPD_HI); last_hpd_state = HPD_HI; +#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC + hpd_struct.ext_ic_control(true); +#endif } else { atomic_set(&hpd_struct.state, HPD_LO); last_hpd_state = HPD_LO; @@ -575,6 +636,7 @@ static int __devinit s5p_hpd_probe(struct platform_device *pdev) hpd_struct.hpd_switch.name = "hdmi"; switch_dev_register(&hpd_struct.hpd_switch); #endif + switch_set_state(&hpd_struct.hpd_switch, last_hpd_state); irq_set_irq_type(hpd_struct.irq_n, IRQ_TYPE_EDGE_BOTH); ret = request_irq(hpd_struct.irq_n, (irq_handler_t) s5p_hpd_irq_handler, diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c index 68508e7..3fa6e55 100644 --- a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c +++ b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c @@ -369,7 +369,7 @@ static int s5p_tvout_tvif_s_std( int i; v4l2_std_id std_id = *norm; -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif for (i = 0; i < S5P_TVOUT_TVIF_NO_OF_STANDARD; i++) { @@ -379,7 +379,8 @@ static int s5p_tvout_tvif_s_std( if (i == S5P_TVOUT_TVIF_NO_OF_STANDARD) { tvout_err("There is no TV standard(0x%08Lx)\n", std_id); -#ifdef CONFIG_HAS_EARLYSUSPEND + +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return -EINVAL; @@ -390,7 +391,7 @@ static int s5p_tvout_tvif_s_std( tvout_dbg("standard id=0x%X, name=\"%s\"\n", (u32) std_id, s5p_tvout_tvif_standard[i].name); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif @@ -437,7 +438,7 @@ static int s5p_tvout_tvif_s_output( return -EINVAL; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) s5p_tvout_mutex_lock(); #endif on_start_process = true; @@ -582,12 +583,12 @@ static int s5p_tvout_tvif_s_output( s5p_tvif_ctrl_start(tv_std, tv_if); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; error_on_tvif_s_output: -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) s5p_tvout_mutex_unlock(); #endif return -1; @@ -749,7 +750,7 @@ long s5p_tvout_tvif_ioctl( void *argp = (void *) arg; int i = 0; -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif @@ -916,13 +917,13 @@ long s5p_tvout_tvif_ioctl( break; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return video_ioctl2(file, cmd, arg); end_tvif_ioctl: -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return ret; @@ -1035,7 +1036,7 @@ static int s5p_tvout_vo_s_fmt_type_private( (u32) vparam.base_y, (u32) vparam.base_c, pix_fmt->field); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif /* check progressive or not */ @@ -1133,52 +1134,72 @@ static int s5p_tvout_vo_s_fmt_type_private( pix_fmt->height, color, field); #else if (pix_fmt->priv) { - copy_buff_idx = s5ptv_vp_buff.copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx]; - - if ((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base == NULL) { - s5p_vp_ctrl_set_src_plane((u32) vparam.base_y, (u32) vparam.base_c, - pix_fmt->width, pix_fmt->height, color, field); + copy_buff_idx = + s5ptv_vp_buff. + copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx]; + + if ((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base + == NULL) { + s5p_vp_ctrl_set_src_plane( + (u32) vparam.base_y, (u32) vparam.base_c, + pix_fmt->width, pix_fmt->height, color, field); } else { - if (pix_fmt->pixelformat == V4L2_PIX_FMT_NV12T - || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) { - y_size = ALIGN(ALIGN(pix_fmt->width, 128) * ALIGN(pix_fmt->height, 32), SZ_8K); - cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) * ALIGN(pix_fmt->height >> 1, 32), SZ_8K); + if (pix_fmt->pixelformat == + V4L2_PIX_FMT_NV12T + || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) { + y_size = ALIGN(ALIGN(pix_fmt->width, 128) * + ALIGN(pix_fmt->height, 32), SZ_8K); + cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) * + ALIGN(pix_fmt->height >> 1, 32), SZ_8K); } else { y_size = pix_fmt->width * pix_fmt->height; - cbcr_size = pix_fmt->width * (pix_fmt->height >> 1); + cbcr_size = + pix_fmt->width * (pix_fmt->height >> 1); } - src_vir_y_addr = (unsigned int)phys_to_virt((unsigned long)vparam.base_y); - src_vir_cb_addr = (unsigned int)phys_to_virt((unsigned long)vparam.base_c); + src_vir_y_addr = (unsigned int)phys_to_virt( + (unsigned long)vparam.base_y); + src_vir_cb_addr = (unsigned int)phys_to_virt( + (unsigned long)vparam.base_c); - memcpy((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base, - (void *)src_vir_y_addr, y_size); - memcpy((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base + y_size, - (void *)src_vir_cb_addr, cbcr_size); + memcpy( + (void *) + s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base, + (void *)src_vir_y_addr, y_size); + memcpy( + (void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx]. + vir_base + y_size, + (void *)src_vir_cb_addr, cbcr_size); flush_all_cpu_caches(); outer_flush_all(); - s5p_vp_ctrl_set_src_plane((u32) s5ptv_vp_buff.vp_buffs[copy_buff_idx].phy_base, - (u32) s5ptv_vp_buff.vp_buffs[copy_buff_idx].phy_base + y_size, - pix_fmt->width, pix_fmt->height, color, field); + s5p_vp_ctrl_set_src_plane( + (u32) s5ptv_vp_buff. + vp_buffs[copy_buff_idx].phy_base, + (u32) s5ptv_vp_buff. + vp_buffs[copy_buff_idx].phy_base + + y_size, + pix_fmt->width, pix_fmt->height, color, field); s5ptv_vp_buff.curr_copy_idx++; - if (s5ptv_vp_buff.curr_copy_idx >= S5PTV_VP_BUFF_CNT - 1) + if (s5ptv_vp_buff.curr_copy_idx >= + S5PTV_VP_BUFF_CNT - 1) s5ptv_vp_buff.curr_copy_idx = 0; } } else { - s5p_vp_ctrl_set_src_plane((u32) vparam.base_y, (u32) vparam.base_c, - pix_fmt->width, pix_fmt->height, color, field); + s5p_vp_ctrl_set_src_plane( + (u32) vparam.base_y, (u32) vparam.base_c, + pix_fmt->width, pix_fmt->height, color, field); } #endif -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; error_on_s_fmt_type_private: -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return -1; @@ -1201,7 +1222,7 @@ static int s5p_tvout_vo_s_fmt_vid_overlay( rect->left, rect->top, rect->width, rect->height, a->fmt.win.global_alpha); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif s5p_tvout_v4l2_private.vo_dst_fmt = a->fmt.win; @@ -1211,7 +1232,7 @@ static int s5p_tvout_vo_s_fmt_vid_overlay( rect->left, rect->top, rect->width, rect->height); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; @@ -1237,7 +1258,7 @@ static int s5p_tvout_vo_s_crop( struct file *file, void *fh, struct v4l2_crop *a) { tvout_dbg("\n"); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif switch (a->type) { @@ -1260,7 +1281,7 @@ static int s5p_tvout_vo_s_crop( tvout_err("Invalid buf type(0x%08x)\n", a->type); break; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; @@ -1285,7 +1306,7 @@ static int s5p_tvout_vo_s_fbuf( (a->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) ? 1 : 0, a->fmt.priv); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif @@ -1294,7 +1315,7 @@ static int s5p_tvout_vo_s_fbuf( s5p_vp_ctrl_set_dest_win_priority(a->fmt.priv); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; @@ -1305,15 +1326,21 @@ static int s5p_tvout_vo_overlay( { tvout_dbg("%s\n", (i) ? "start" : "stop"); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_lock(); #endif - if (i) + if (i) { s5p_vp_ctrl_start(); - else + /* restore vsync interrupt setting */ + s5p_mixer_set_vsync_interrupt( + s5p_mixer_ctrl_get_vsync_interrupt()); + } else { + /* disable vsync interrupt when VP is disabled */ + s5p_mixer_ctrl_disable_vsync_interrupt(); s5p_vp_ctrl_stop(); + } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND) s5p_tvout_mutex_unlock(); #endif return 0; diff --git a/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c b/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c index d074da3..148e3e9 100644 --- a/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c +++ b/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c @@ -279,7 +279,7 @@ static int s5p_vp_ctrl_set_reg(void) struct s5p_vp_ctrl_pp_param *pp_param = &s5p_vp_ctrl_private.pp_param; struct s5p_vp_ctrl_op_mode *op_mode = &s5p_vp_ctrl_private.op_mode; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -362,7 +362,7 @@ static int s5p_vp_ctrl_set_reg(void) static void s5p_vp_ctrl_internal_stop(void) { -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -409,7 +409,7 @@ void s5p_vp_ctrl_set_src_plane( src_plane->w = width; src_plane->h = height; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -434,7 +434,7 @@ void s5p_vp_ctrl_set_src_win(u32 left, u32 top, u32 width, u32 height) src_win->w = width; src_win->h = height; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -466,7 +466,7 @@ void s5p_vp_ctrl_set_dest_win(u32 left, u32 top, u32 width, u32 height) dst_win->y = top; dst_win->w = width; dst_win->h = height; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -493,7 +493,7 @@ void s5p_vp_ctrl_set_dest_win(u32 left, u32 top, u32 width, u32 height) void s5p_vp_ctrl_set_dest_win_alpha_val(u32 alpha) { s5p_vp_ctrl_private.mixer_param.alpha = alpha; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -505,7 +505,7 @@ void s5p_vp_ctrl_set_dest_win_alpha_val(u32 alpha) void s5p_vp_ctrl_set_dest_win_blend(bool enable) { s5p_vp_ctrl_private.mixer_param.blend = enable; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -518,7 +518,7 @@ void s5p_vp_ctrl_set_dest_win_blend(bool enable) void s5p_vp_ctrl_set_dest_win_priority(u32 prio) { s5p_vp_ctrl_private.mixer_param.prio = prio; -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); return; @@ -531,7 +531,7 @@ void s5p_vp_ctrl_stop(void) { if (s5p_vp_ctrl_private.running) { s5p_vp_ctrl_internal_stop(); -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else @@ -647,7 +647,7 @@ int s5p_vp_ctrl_start(void) if (s5p_vp_ctrl_private.running) s5p_vp_ctrl_internal_stop(); else { -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CLOCK_GATING_ON_EARLY_SUSPEND if (suspend_status) { tvout_dbg("driver is suspend_status\n"); } else diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig index aaae26e..6304825 100644 --- a/drivers/media/video/samsung/ump/Kconfig +++ b/drivers/media/video/samsung/ump/Kconfig @@ -20,7 +20,7 @@ config UMP_VCM_ALLOC choice depends on VIDEO_UMP prompt "UMP MEMEMORY OPTION" -default UMP_OSMEM_ONLY +default UMP_OSMEM_ONLY config UMP_DED_ONLY bool "ump dedicated memory only" ---help--- @@ -37,7 +37,7 @@ config UMP_VCM_ONLY endchoice config UMP_MEM_SIZE int "UMP Memory Size" - depends on VIDEO_UMP + depends on VIDEO_UMP default "512" ---help--- This value is dedicated memory size of UMP (unit is MByte). @@ -48,4 +48,3 @@ config VIDEO_UMP_DEBUG default n help This enables UMP driver debug messages. - diff --git a/drivers/media/video/samsung/ump/Makefile b/drivers/media/video/samsung/ump/Makefile index f429c40..b3157a3 100644 --- a/drivers/media/video/samsung/ump/Makefile +++ b/drivers/media/video/samsung/ump/Makefile @@ -1,9 +1,9 @@ # # 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. # @@ -30,14 +30,13 @@ DEFINES += -DDEBUG endif # Set up our defines, which will be passed to gcc -DEFINES += -DKERNEL_BUILTIN=1 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 = +KBUILDROOT = # linux build system integration @@ -61,7 +60,7 @@ OSKFILES+=\ $(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 + $(KBUILDROOT)../mali/linux/mali_osk_misc.o ump-y := \ $(KBUILDROOT)linux/ump_kernel_linux.o \ @@ -83,12 +82,11 @@ ump-$(CONFIG_UMP_VCM_ALLOC) += \ $(KBUILDROOT)linux/ump_kernel_memory_backend_vcm.o \ EXTRA_CFLAGS += $(INCLUDES) \ - $(DEFINES) - - + $(DEFINES) + + # Get subversion revision number, fall back to 0000 if no svn info is available 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/Makefile.common b/drivers/media/video/samsung/ump/Makefile.common index 4b5db24..35527a2 100644 --- a/drivers/media/video/samsung/ump/Makefile.common +++ b/drivers/media/video/samsung/ump/Makefile.common @@ -1,17 +1,20 @@ # -# Copyright (C) 2010 ARM Limited. All rights reserved. -# +# Copyright (C) 2010-2012 ARM Limited. All rights reserved. +# # This program is free software and is provided to you under the terms of the GNU General Public License version 2 # as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -# +# # 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. # -UMP_FILE_PREFIX = ./drivers/video/samsung/ump +SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \ + $(UMP_FILE_PREFIX)common/ump_kernel_descriptor_mapping.c \ + $(UMP_FILE_PREFIX)common/ump_kernel_api.c \ + $(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c -SRC = $(UMP_FILE_PREFIX)/common/ump_kernel_common.c \ - $(UMP_FILE_PREFIX)/common/ump_kernel_descriptor_mapping.c \ - $(UMP_FILE_PREFIX)/common/ump_kernel_api.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 -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/Makefile_backup b/drivers/media/video/samsung/ump/Makefile_backup deleted file mode 100644 index 632cb0c..0000000 --- a/drivers/media/video/samsung/ump/Makefile_backup +++ /dev/null @@ -1,80 +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. -# -BUILD ?= debug -USING_MALI400 ?= 1 -USING_ZBT ?= 0 -USING_MMU ?= 1 -USING_UMP ?= 1 -CPU ?= vega1 -CONFIG ?= marcopolo-vega1-m400 - - -# Set up our defines, which will be passed to gcc -DEFINES += -DUSING_MALI400=$(USING_MALI400) -DEFINES += -DUSING_ZBT=$(USING_ZBT) -DEFINES += -DUSING_MMU=$(USING_MMU) -DEFINES += -DUSING_UMP=$(USING_UMP) -DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER -ifeq ($(BUILD), debug) -DEFINES += -DDEBUG -endif - - -UMP_FILE_PREFIX := drivers/video/samsung/ump -UDD_FILE_PREFIX := drivers/video/samsung/mali -KBUILDROOT = - -# linux build system integration - -obj-y += 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$(UMP_FILE_PREFIX)\ - -I$(UMP_FILE_PREFIX)/common\ - -I$(UMP_FILE_PREFIX)/linux\ - -I$(UMP_FILE_PREFIX)/include\ - -I$(UMP_FILE_PREFIX)/linux/license/proprietary/\ - -I$(UDD_FILE_PREFIX)/common\ - -I$(UDD_FILE_PREFIX)/linux - -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)../mali/linux/mali_osk_atomics.o \ - $(KBUILDROOT)../mali/linux/mali_osk_locks.o \ - $(KBUILDROOT)../mali/linux/mali_osk_memory.o \ - $(KBUILDROOT)../mali/linux/mali_osk_math.o \ - $(KBUILDROOT)../mali/linux/mali_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 - -EXTRA_CFLAGS += $(INCLUDES) \ - $(DEFINES) - - -# Get subversion revision number, fall back to 0000 if no svn info is available -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/Makefile_module b/drivers/media/video/samsung/ump/Makefile_module new file mode 100644 index 0000000..f0c3829 --- /dev/null +++ b/drivers/media/video/samsung/ump/Makefile_module @@ -0,0 +1,119 @@ +# +# 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. +# + +UMP_FILE_PREFIX = +UDD_FILE_PREFIX = ../mali/ + +ifneq ($(KBUILD_EXTMOD),) +include $(KBUILD_EXTMOD)/Makefile.common +else +include ./Makefile.common +endif + +# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH + +ARCH ?= arm +BUILD ?= debug + +EXTRA_CFLAGS += -DDEBUG -DMALI_STATE_TRACKING=0 +ifeq ($(BUILD), debug) +EXTRA_CFLAGS += -DDEBUG +endif + +# linux build system integration + +ifneq ($(KERNELRELEASE),) +# Inside the kernel build system + +EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/common -I$(KBUILD_EXTMOD)/linux -I$(KBUILD_EXTMOD)/../mali/common -I$(KBUILD_EXTMOD)/../mali/linux -I$(KBUILD_EXTMOD)/../../ump/include/ump + +# 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 $(KBUILD_EXTMOD)/linux/license/gpl/*),) +EXTRA_CFLAGS += -I$(KBUILD_EXTMOD)/linux/license/proprietary +else +EXTRA_CFLAGS += -I$(KBUILD_EXTMOD)/linux/license/gpl +endif + +SRC += $(UMP_FILE_PREFIX)linux/ump_kernel_linux.c \ + $(UMP_FILE_PREFIX)linux/ump_kernel_memory_backend_os.c \ + $(UMP_FILE_PREFIX)linux/ump_kernel_memory_backend_dedicated.c \ + $(UMP_FILE_PREFIX)linux/ump_memory_backend.c \ + $(UMP_FILE_PREFIX)linux/ump_ukk_wrappers.c \ + $(UMP_FILE_PREFIX)linux/ump_ukk_ref_wrappers.c \ + $(UMP_FILE_PREFIX)linux/ump_osk_atomics.c \ + $(UMP_FILE_PREFIX)linux/ump_osk_low_level_mem.c \ + $(UMP_FILE_PREFIX)linux/ump_osk_misc.c \ + $(UDD_FILE_PREFIX)linux/mali_osk_atomics.c \ + $(UDD_FILE_PREFIX)linux/mali_osk_locks.c \ + $(UDD_FILE_PREFIX)linux/mali_osk_memory.c \ + $(UDD_FILE_PREFIX)linux/mali_osk_math.c \ + $(UDD_FILE_PREFIX)linux/mali_osk_misc.c + +# Selecting files to compile by parsing the config file + +MODULE:=ump.ko + +obj-m := $(MODULE:.ko=.o) +$(MODULE:.ko=-y) := $(SRC:.c=.o) + +else +# Outside the kernel build system + +# 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- 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 ?= arm-none-linux-gnueabi- +endif + +# look up KDIR based om CPU selection +KDIR ?= $(KDIR-$(CPU)) + +ifeq ($(KDIR),) +$(error No KDIR found for platform $(CPU)) +endif + +# Validate selected config +ifneq ($(shell [ -d arch-$(CONFIG) ] && [ -f 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 arch ] && rm arch) +$(shell ln -sf arch-$(CONFIG) arch) +$(shell touch arch/config.h) +endif + +all: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules + +kernelrelease: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease + +clean: + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean + $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR)/../mali clean + +endif diff --git a/drivers/media/video/samsung/ump/arch b/drivers/media/video/samsung/ump/arch deleted file mode 120000 index a65a3fc..0000000 --- a/drivers/media/video/samsung/ump/arch +++ /dev/null @@ -1 +0,0 @@ -./arch-orion-m400 \ No newline at end of file diff --git a/drivers/media/video/samsung/ump/arch-debug/config.h b/drivers/media/video/samsung/ump/arch-debug/config.h new file mode 100644 index 0000000..688edc9 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-debug/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_UMP_H__ +#define __ARCH_CONFIG_UMP_H__ + +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#if (USING_MEMORY == 0) /* Dedicated Memory */ +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#else +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#endif + +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h b/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h deleted file mode 100644 index 014c4bb..0000000 --- a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h +++ /dev/null @@ -1,18 +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__ - -#define ARCH_UMP_BACKEND_DEFAULT 0 -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 -#define ARCH_UMP_MEMORY_SIZE_DEFAULT 0x04000000 - -#endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org b/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org deleted file mode 100755 index c92a32a..0000000 --- a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org +++ /dev/null @@ -1,87 +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 */ -#define MALI_BASE_ADDR 0xf0000000 -#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 PP_MMU_ADDR MALI_BASE_ADDR+0x4000 -#define PP_ADDR MALI_BASE_ADDR+0x8000 - -// See 3-11 page in trm. It describes control register address map. cglee - -static _mali_osk_resource_t arch_configuration [] = -{ - { - .type = MALI400GP, - .description = "Mali-400 GP", - .base = GP_ADDR, - .irq = 18+32, - .mmu_id = 1 - }, - { - .type = MALI400PP, - .base = PP_ADDR, - .irq = 16+32, - .description = "Mali-400 PP 0", - .mmu_id = 2 - }, -#if USING_MMU - { - .type = MMU, - .base = GP_MMU_ADDR, - .irq = 19+32, - .description = "Mali-400 MMU for GP", - .mmu_id = 1 - }, - { - .type = MMU, - .base = PP_MMU_ADDR, - .irq = 17+32, - .description = "Mali-400 MMU for PP 0", - .mmu_id = 2 - }, - { - .type = OS_MEMORY, - .description = "System Memory", - .size = 0x06000000, - .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE - }, - { - .type = MEM_VALIDATION, - .description = "memory validation", - .base = 0x204e0000, - .size = 0x7B20000, - .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 - { - .type = MEMORY, - .description = "Dedicated Memory", - .base = 0x2E000000, - .size = 0x02000000, - .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/ump/arch-orion-m400/config.h b/drivers/media/video/samsung/ump/arch-orion-m400/config.h index 117cc6e..688edc9 100644 --- a/drivers/media/video/samsung/ump/arch-orion-m400/config.h +++ b/drivers/media/video/samsung/ump/arch-orion-m400/config.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -11,12 +11,12 @@ #ifndef __ARCH_CONFIG_UMP_H__ #define __ARCH_CONFIG_UMP_H__ -#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY #if (USING_MEMORY == 0) /* Dedicated Memory */ -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 #else -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 #endif -#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 #endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h index 560eda9..38ae1ee 100644 --- a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h +++ b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 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. @@ -12,7 +12,7 @@ #define __ARCH_CONFIG_H__ #define ARCH_UMP_BACKEND_DEFAULT 0 -#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xC8000000 +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xCE000000 #define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL #endif /* __ARCH_CONFIG_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h b/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h new file mode 100644 index 0000000..688edc9 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_UMP_H__ +#define __ARCH_CONFIG_UMP_H__ + +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#if (USING_MEMORY == 0) /* Dedicated Memory */ +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#else +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#endif + +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch-release/config.h b/drivers/media/video/samsung/ump/arch-release/config.h new file mode 100644 index 0000000..688edc9 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch-release/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_UMP_H__ +#define __ARCH_CONFIG_UMP_H__ + +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#if (USING_MEMORY == 0) /* Dedicated Memory */ +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#else +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#endif + +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/arch/config.h b/drivers/media/video/samsung/ump/arch/config.h new file mode 100644 index 0000000..688edc9 --- /dev/null +++ b/drivers/media/video/samsung/ump/arch/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ARCH_CONFIG_UMP_H__ +#define __ARCH_CONFIG_UMP_H__ + +#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY +#if (USING_MEMORY == 0) /* Dedicated Memory */ +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000 +#else +#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0 +#endif + +#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024 +#endif /* __ARCH_CONFIG_UMP_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_api.c b/drivers/media/video/samsung/ump/common/ump_kernel_api.c index ddc9ef7..83f0d30 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_api.c +++ b/drivers/media/video/samsung/ump/common/ump_kernel_api.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -161,7 +161,7 @@ UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle memh) new_ref = _ump_osk_atomic_inc_and_read(&mem->ref_count); - DBG_MSG(4, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); + DBG_MSG(5, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); } @@ -181,7 +181,7 @@ UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle memh) new_ref = _ump_osk_atomic_dec_and_read(&mem->ref_count); - DBG_MSG(4, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); + DBG_MSG(5, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref)); if (0 == new_ref) { @@ -277,7 +277,7 @@ _mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info ) } _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); - DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id)); + DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id)); DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret)); return ret; @@ -313,15 +313,22 @@ _mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction ) void _ump_ukk_msync( _ump_uk_msync_s *args ) { ump_dd_mem * mem = NULL; + void *virtual = NULL; + u32 size = 0; + u32 offset = 0; + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); - _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); - if (NULL==mem) + if (NULL == mem) { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id)); return; } + /* Ensure the memory doesn't dissapear when we are flushing it. */ + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); /* Returns the cache settings back to Userspace */ args->is_cached=mem->is_cached; @@ -330,17 +337,215 @@ void _ump_ukk_msync( _ump_uk_msync_s *args ) if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op ) { DBG_MSG(3, ("_ump_ukk_msync READOUT ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached)); - return; + goto msync_release_and_return; } /* Nothing to do if the memory is not caches */ if ( 0==mem->is_cached ) { DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op)); - return ; + goto msync_release_and_return; + } + DBG_MSG(3, ("UMP[%02u] _ump_ukk_msync Flush OP: %d Address: 0x%08x Mapping: 0x%08x\n", + (ump_secure_id)args->secure_id, args->op, args->address, args->mapping)); + + if ( args->address ) + { + virtual = (void *)((u32)args->address); + offset = (u32)((args->address) - (args->mapping)); + } else { + /* Flush entire mapping when no address is specified. */ + virtual = args->mapping; + } + if ( args->size ) + { + size = args->size; + } else { + /* Flush entire mapping when no size is specified. */ + size = mem->size_bytes - offset; + } + + if ( (offset + size) > mem->size_bytes ) + { + DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes)); + goto msync_release_and_return; } - DBG_MSG(3, ("_ump_ukk_msync FLUSHING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op)); /* The actual cache flush - Implemented for each OS*/ - _ump_osk_msync( mem , args->op, (u32)args->mapping, (u32)args->address, args->size); + _ump_osk_msync( mem, virtual, offset, size, args->op, NULL); + +msync_release_and_return: + ump_dd_reference_release(mem); + return; +} + +void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args) +{ + ump_session_data * session_data; + ump_uk_cache_op_control op; + + DEBUG_ASSERT_POINTER( args ); + DEBUG_ASSERT_POINTER( args->ctx ); + + op = args->op; + session_data = (ump_session_data *)args->ctx; + + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + if ( op== _UMP_UK_CACHE_OP_START ) + { + session_data->cache_operations_ongoing++; + DBG_MSG(4, ("Cache ops start\n" )); + if ( session_data->cache_operations_ongoing != 1 ) + { + DBG_MSG(2, ("UMP: Number of simultanious cache control ops: %d\n", session_data->cache_operations_ongoing) ); + } + } + else if ( op== _UMP_UK_CACHE_OP_FINISH ) + { + DBG_MSG(4, ("Cache ops finish\n")); + session_data->cache_operations_ongoing--; + #if 0 + if ( session_data->has_pending_level1_cache_flush) + { + /* This function will set has_pending_level1_cache_flush=0 */ + _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data); + } + #endif + + /* to be on the safe side: always flush l1 cache when cache operations are done */ + _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data); + DBG_MSG(4, ("Cache ops finish end\n" )); + } + else + { + DBG_MSG(1, ("Illegal call to %s at line %d\n", __FUNCTION__, __LINE__)); + } + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + +} + +void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args ) +{ + ump_dd_mem * mem = NULL; + ump_uk_user old_user; + ump_uk_msync_op cache_op = _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE; + ump_session_data *session_data; + + DEBUG_ASSERT_POINTER( args ); + DEBUG_ASSERT_POINTER( args->ctx ); + + session_data = (ump_session_data *)args->ctx; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_switch_hw_usage(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + + old_user = mem->hw_device; + mem->hw_device = args->new_user; + + DBG_MSG(3, ("UMP[%02u] Switch usage Start New: %s Prev: %s.\n", (ump_secure_id)args->secure_id, args->new_user?"MALI":"CPU",old_user?"MALI":"CPU")); + + if ( ! mem->is_cached ) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(3, ("UMP[%02u] Changing owner of uncached memory. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); + return; + } + + if ( old_user == args->new_user) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(4, ("UMP[%02u] Setting the new_user equal to previous for. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); + return; + } + if ( + /* Previous AND new is both different from CPU */ + (old_user != _UMP_UK_USED_BY_CPU) && (args->new_user != _UMP_UK_USED_BY_CPU ) + ) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(4, ("UMP[%02u] Previous and new user is not CPU. Cache flushing not needed.\n", (ump_secure_id)args->secure_id)); + return; + } + + if ( (old_user != _UMP_UK_USED_BY_CPU ) && (args->new_user==_UMP_UK_USED_BY_CPU) ) + { + cache_op =_UMP_UK_MSYNC_INVALIDATE; + DBG_MSG(4, ("UMP[%02u] Cache invalidation needed\n", (ump_secure_id)args->secure_id)); +#ifdef UMP_SKIP_INVALIDATION +#error + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(4, ("UMP[%02u] Performing Cache invalidation SKIPPED\n", (ump_secure_id)args->secure_id)); + return; +#endif + } + /* Ensure the memory doesn't dissapear when we are flushing it. */ + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + /* Take lock to protect: session->cache_operations_ongoing and session->has_pending_level1_cache_flush */ + _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW); + /* Actual cache flush */ + _ump_osk_msync( mem, NULL, 0, mem->size_bytes, cache_op, session_data); + _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW); + + ump_dd_reference_release(mem); + DBG_MSG(4, ("UMP[%02u] Switch usage Finish\n", (ump_secure_id)args->secure_id)); + return; +} + +void _ump_ukk_lock(_ump_uk_lock_s *args ) +{ + ump_dd_mem * mem = NULL; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("UMP[%02u] Failed to look up mapping in _ump_ukk_lock(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + DBG_MSG(1, ("UMP[%02u] Lock. New lock flag: %d. Old Lock flag:\n", (u32)args->secure_id, (u32)args->lock_usage, (u32) mem->lock_usage )); + + mem->lock_usage = (ump_lock_usage) args->lock_usage; + + /** TODO: TAKE LOCK HERE */ + + ump_dd_reference_release(mem); +} + +void _ump_ukk_unlock(_ump_uk_unlock_s *args ) +{ + ump_dd_mem * mem = NULL; + + _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem); + + if (NULL == mem) + { + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_unlock(). ID: %u\n", (ump_secure_id)args->secure_id)); + return; + } + ump_dd_reference_add(mem); + _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); + + DBG_MSG(1, ("UMP[%02u] Unlocking. Old Lock flag:\n", (u32)args->secure_id, (u32) mem->lock_usage )); + + 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/media/video/samsung/ump/common/ump_kernel_common.c index e5ff198..1fa7c8a 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_common.c +++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -147,6 +147,9 @@ _mali_osk_errcode_t _ump_ukk_open( void** context ) *context = (void*)session_data; + session_data->cache_operations_ongoing = 0 ; + session_data->has_pending_level1_cache_flush = 0; + DBG_MSG(2, ("New session opened\n")); return _MALI_OSK_ERR_OK; @@ -225,19 +228,17 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args ) int map_id; session_data = (ump_session_data *)args->ctx; - if (NULL == session_data) + if(NULL == session_data) { MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n")); return _MALI_OSK_ERR_INVALID_ARGS; } - /* SEC kernel stability 2012-02-17 */ if (NULL == session_data->cookies_map) { MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n")); return _MALI_OSK_ERR_INVALID_ARGS; } - descriptor = (ump_memory_allocation*) _mali_osk_calloc( 1, sizeof(ump_memory_allocation)); if (NULL == descriptor) { @@ -370,14 +371,12 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ) MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n")); return; } - /* SEC kernel stability 2012-02-17 */ if (NULL == session_data->cookies_map) { MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n")); return; } - if (0 != ump_descriptor_mapping_get( session_data->cookies_map, (int)args->cookie, (void**)&descriptor) ) { MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie )); diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.h b/drivers/media/video/samsung/ump/common/ump_kernel_common.h index c8b5541..03d213d 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_common.h +++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.h @@ -1,15 +1,15 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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 __UMP_KERNEL_H__ -#define __UMP_KERNEL_H__ +#ifndef __UMP_KERNEL_COMMON_H__ +#define __UMP_KERNEL_COMMON_H__ #include "ump_kernel_types.h" #include "ump_kernel_interface.h" @@ -77,6 +77,8 @@ typedef struct ump_session_data int api_version; _mali_osk_lock_t * lock; ump_descriptor_mapping * cookies_map; /**< Secure mapping of cookies from _ump_ukk_map_mem() */ + int cache_operations_ongoing; + int has_pending_level1_cache_flush; } ump_session_data; @@ -123,4 +125,4 @@ int map_errcode( _mali_osk_errcode_t err ); #define __user #endif -#endif /* __UMP_KERNEL_H__ */ +#endif /* __UMP_KERNEL_COMMON_H__ */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c index 5174839..cc7b8be 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c +++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * A copy of the licence is included with the program, and can also be obtained from Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -65,9 +65,9 @@ void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map) int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target) { - int descriptor = -1;/*-EFAULT;*/ - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); - descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); + int descriptor = -1;/*-EFAULT;*/ + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); + descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); if (descriptor == map->current_nr_mappings) { int nr_mappings_new; @@ -89,8 +89,8 @@ int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * goto unlock_and_exit; } - _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); - _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); + _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); + _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); map->table = new_table; map->current_nr_mappings = nr_mappings_new; descriptor_table_free(old_table); @@ -107,10 +107,10 @@ unlock_and_exit: int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target) { - int result = -1;/*-EFAULT;*/ - DEBUG_ASSERT(map); - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + int result = -1;/*-EFAULT;*/ + DEBUG_ASSERT(map); + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) { *target = map->table->mappings[descriptor]; result = 0; @@ -122,9 +122,9 @@ int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, voi int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target) { - int result = -1;/*-EFAULT;*/ - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + int result = -1;/*-EFAULT;*/ + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) { map->table->mappings[descriptor] = target; result = 0; @@ -135,8 +135,8 @@ int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, voi void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor) { - _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); - if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) + _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); + if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) ) { map->table->mappings[descriptor] = NULL; _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage); @@ -163,4 +163,3 @@ static void descriptor_table_free(ump_descriptor_table * table) { _mali_osk_free(table); } - diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h index 319cc3b..881d3d8 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h +++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * A copy of the licence is included with the program, and can also be obtained from Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h index d329bb5..73915ee 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h +++ b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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,4 +49,3 @@ ump_memory_backend * ump_memory_backend_create ( void ); void ump_memory_backend_destroy( void ); #endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */ - diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c index 4dcbe21..a5ccfeb 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c +++ b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -95,6 +95,8 @@ UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd mem->release_func = phys_blocks_release; /* For now UMP handles created by ump_dd_handle_create_from_phys_blocks() is forced to be Uncached */ mem->is_cached = 0; + mem->hw_device = _UMP_UK_USED_BY_CPU; + mem->lock_usage = UMP_NOT_LOCKED; _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW); DBG_MSG(3, ("UMP memory created. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes)); @@ -165,6 +167,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ) } new_allocation->size_bytes = UMP_SIZE_ALIGN(user_interaction->size); /* Page align the size */ + new_allocation->lock_usage = UMP_NOT_LOCKED; /* Now, ask the active memory backend to do the actual memory allocation */ if (!device.backend->allocate( device.backend->ctx, new_allocation ) ) @@ -176,7 +179,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ) _mali_osk_free(session_memory_element); return _MALI_OSK_ERR_INVALID_FUNC; } - + new_allocation->hw_device = _UMP_UK_USED_BY_CPU; new_allocation->ctx = device.backend->ctx; new_allocation->release_func = device.backend->release; @@ -195,6 +198,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction ) return _MALI_OSK_ERR_OK; } + UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args) { ump_dd_mem * mem; @@ -255,4 +259,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/media/video/samsung/ump/common/ump_kernel_types.h index ca03dec..fdacd86 100644 --- a/drivers/media/video/samsung/ump/common/ump_kernel_types.h +++ b/drivers/media/video/samsung/ump/common/ump_kernel_types.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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,6 +14,22 @@ #include "ump_kernel_interface.h" #include "mali_osk.h" + +typedef enum +{ + UMP_USED_BY_CPU = 0, + UMP_USED_BY_MALI = 1, + UMP_USED_BY_UNKNOWN_DEVICE= 100, +} ump_hw_usage; + +typedef enum +{ + UMP_NOT_LOCKED = 0, + UMP_READ = 1, + UMP_READ_WRITE = 3, +} ump_lock_usage; + + /* * This struct is what is "behind" a ump_dd_handle */ @@ -28,6 +44,8 @@ typedef struct ump_dd_mem void * ctx; void * backend_info; int is_cached; + ump_hw_usage hw_device; + ump_lock_usage lock_usage; } ump_dd_mem; diff --git a/drivers/media/video/samsung/ump/common/ump_osk.h b/drivers/media/video/samsung/ump/common/ump_osk.h index bd9254b..dabdc7f 100644 --- a/drivers/media/video/samsung/ump/common/ump_osk.h +++ b/drivers/media/video/samsung/ump/common/ump_osk.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -18,7 +18,8 @@ #include #include -#include +#include "ump_uk_types.h" +#include "ump_kernel_common.h" #ifdef __cplusplus extern "C" @@ -39,7 +40,7 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor ); -void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size); +void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data ); void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr); diff --git a/drivers/media/video/samsung/ump/common/ump_uk_types.h b/drivers/media/video/samsung/ump/common/ump_uk_types.h index 2bac454..4fd1ef7 100644 --- a/drivers/media/video/samsung/ump/common/ump_uk_types.h +++ b/drivers/media/video/samsung/ump/common/ump_uk_types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. @@ -45,12 +45,11 @@ typedef enum _UMP_IOC_MAP_MEM, /* not used in Linux */ _UMP_IOC_UNMAP_MEM, /* not used in Linux */ _UMP_IOC_MSYNC, -#ifdef CONFIG_ION_EXYNOS + _UMP_IOC_CACHE_OPERATIONS_CONTROL, + _UMP_IOC_SWITCH_HW_USAGE, + _UMP_IOC_LOCK, + _UMP_IOC_UNLOCK, _UMP_IOC_ION_IMPORT, -#endif -#ifdef CONFIG_DMA_SHARED_BUFFER - _UMP_IOC_DMABUF_IMPORT, -#endif }_ump_uk_functions; typedef enum @@ -64,9 +63,30 @@ typedef enum { _UMP_UK_MSYNC_CLEAN = 0, _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE = 1, + _UMP_UK_MSYNC_INVALIDATE = 2, + _UMP_UK_MSYNC_FLUSH_L1 = 3, _UMP_UK_MSYNC_READOUT_CACHE_ENABLED = 128, } ump_uk_msync_op; +typedef enum +{ + _UMP_UK_CACHE_OP_START = 0, + _UMP_UK_CACHE_OP_FINISH = 1, +} ump_uk_cache_op_control; + +typedef enum +{ + _UMP_UK_READ = 1, + _UMP_UK_READ_WRITE = 3, +} ump_uk_lock_usage; + +typedef enum +{ + _UMP_UK_USED_BY_CPU = 0, + _UMP_UK_USED_BY_MALI = 1, + _UMP_UK_USED_BY_UNKNOWN_DEVICE= 100, +} ump_uk_user; + /** * Get API version ([in,out] u32 api_version, [out] u32 compatible) */ @@ -88,25 +108,14 @@ 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) */ - int ion_fd; + int ion_fd; /**< ion_fd */ u32 secure_id; /**< Return value from DD to Userdriver */ 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 - -#ifdef CONFIG_DMA_SHARED_BUFFER -struct ump_uk_dmabuf { - void *ctx; - int fd; - size_t size; - uint32_t ump_handle; -}; -#endif /** * SIZE_GET ([in] u32 secure_id, [out]size ) @@ -156,10 +165,38 @@ typedef struct _ump_uk_msync_s u32 size; /**< [in] size to flush */ ump_uk_msync_op op; /**< [in] flush operation */ u32 cookie; /**< [in] cookie stored with reference to the kernel mapping internals */ - u32 secure_id; /**< [in] cookie stored with reference to the kernel mapping internals */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ u32 is_cached; /**< [out] caching of CPU mappings */ } _ump_uk_msync_s; +typedef struct _ump_uk_cache_operations_control_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + ump_uk_cache_op_control op; /**< [in] cache operations start/stop */ +} _ump_uk_cache_operations_control_s; + + +typedef struct _ump_uk_switch_hw_usage_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ + ump_uk_user new_user; /**< [in] cookie stored with reference to the kernel mapping internals */ + +} _ump_uk_switch_hw_usage_s; + +typedef struct _ump_uk_lock_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ + ump_uk_lock_usage lock_usage; +} _ump_uk_lock_s; + +typedef struct _ump_uk_unlock_s +{ + void *ctx; /**< [in,out] user-kernel context (trashed on output) */ + u32 secure_id; /**< [in] secure_id that identifies the ump buffer */ +} _ump_uk_unlock_s; + #ifdef __cplusplus } #endif diff --git a/drivers/media/video/samsung/ump/common/ump_ukk.h b/drivers/media/video/samsung/ump/common/ump_ukk.h index db48cd6..4e6bb86 100644 --- a/drivers/media/video/samsung/ump/common/ump_ukk.h +++ b/drivers/media/video/samsung/ump/common/ump_ukk.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -44,6 +44,14 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args ); void _ump_ukk_msync( _ump_uk_msync_s *args ); +void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args); + +void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args ); + +void _ump_ukk_lock(_ump_uk_lock_s *args ); + +void _ump_ukk_unlock(_ump_uk_unlock_s *args ); + u32 _ump_ukk_report_memory_usage( void ); #ifdef __cplusplus diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h index ba81a07..f84d237 100644 --- a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h +++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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_interface_ref_drv.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h index 3efe165..36c5c9d 100644 --- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h +++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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_interface_vcm.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h index a784241..5ff4155 100644 --- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h +++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/media/video/samsung/ump/include/ump_kernel_platform.h index 1b5af40..339e967 100644 --- a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h +++ b/drivers/media/video/samsung/ump/include/ump_kernel_platform.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010, 2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/license/gpl/ump_kernel_license.h b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h index 17b930d..50a021c 100644 --- a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h +++ b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/ump_ioctl.h b/drivers/media/video/samsung/ump/linux/ump_ioctl.h index 50ef9df..1d49b4d 100644 --- a/drivers/media/video/samsung/ump/linux/ump_ioctl.h +++ b/drivers/media/video/samsung/ump/linux/ump_ioctl.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * A copy of the licence is included with the program, and can also be obtained from Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ @@ -19,7 +19,7 @@ extern "C" #include #include -#include "../common/ump_uk_types.h" +#include #ifndef __user #define __user @@ -39,16 +39,20 @@ extern "C" #define UMP_IOC_ALLOCATE _IOWR(UMP_IOCTL_NR, _UMP_IOC_ALLOCATE, _ump_uk_allocate_s) #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_size_get_s) +#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_msync_s) #ifdef CONFIG_ION_EXYNOS #define UMP_IOC_ION_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s) #endif - #ifdef CONFIG_DMA_SHARED_BUFFER #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) +#define UMP_IOC_LOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_LOCK, _ump_uk_lock_s) +#define UMP_IOC_UNLOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_UNLOCK, _ump_uk_unlock_s) + #ifdef __cplusplus } #endif diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c index 69f55c5..58cef54 100644 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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,7 +42,7 @@ struct ion_client *ion_client_ump = NULL; #endif /* Module parameter to control log level */ -int ump_debug_level = 3; +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"); @@ -55,7 +55,9 @@ MODULE_PARM_DESC(ump_major, "Device major number"); static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */ +#if UMP_LICENSE_IS_GPL static struct dentry *ump_debugfs_dir = NULL; +#endif /* * The data which we attached to each virtual memory mapping request we get. @@ -90,7 +92,7 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c #endif static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma); -#ifdef CONFIG_VIDEO_MALI400MP_R2P3 +#if defined(CONFIG_VIDEO_MALI400MP) || defined(CONFIG_VIDEO_MALI400MP_R3P0) || defined(CONFIG_VIDEO_MALI400MP_R2P3) extern int map_errcode( _mali_osk_errcode_t err ); #endif @@ -171,6 +173,7 @@ int ump_kernel_device_initialize(void) { int err; dev_t dev = 0; +#if UMP_LICENSE_IS_GPL ump_debugfs_dir = debugfs_create_dir(ump_dev_name, NULL); if (ERR_PTR(-ENODEV) == ump_debugfs_dir) { @@ -180,6 +183,7 @@ int ump_kernel_device_initialize(void) { debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops); } +#endif if (0 == ump_major) { @@ -257,8 +261,10 @@ void ump_kernel_device_terminate(void) /* free major */ unregister_chrdev_region(dev, 1); +#if UMP_LICENSE_IS_GPL if(ump_debugfs_dir) debugfs_remove_recursive(ump_debugfs_dir); +#endif } /* @@ -369,6 +375,22 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c err = ump_msync_wrapper((u32 __user *)argument, session_data); break; + case UMP_IOC_CACHE_OPERATIONS_CONTROL: + err = ump_cache_operations_control_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_SWITCH_HW_USAGE: + err = ump_switch_hw_usage_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_LOCK: + err = ump_lock_wrapper((u32 __user *)argument, session_data); + break; + + case UMP_IOC_UNLOCK: + err = ump_unlock_wrapper((u32 __user *)argument, session_data); + break; + default: DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg)); err = -EFAULT; @@ -377,7 +399,6 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c return err; } - #ifndef CONFIG_VIDEO_MALI400MP_R2P3 #ifndef CONFIG_VIDEO_MALI400MP #ifndef CONFIG_VIDEO_MALI400MP_R3P0 @@ -399,7 +420,6 @@ int map_errcode( _mali_osk_errcode_t err ) #endif #endif #endif - /* * Handle from OS to map specified virtual memory to specified UMP memory. */ @@ -431,6 +451,8 @@ static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma) vma->vm_flags = vma->vm_flags | VM_SHARED | VM_MAYSHARE ; DBG_MSG(3, ("UMP Map function: Forcing the CPU to use cache\n")); } + /* By setting this flag, during a process fork; the child process will not have the parent UMP mappings */ + vma->vm_flags |= VM_DONTCOPY; DBG_MSG(4, ("UMP vma->flags: %x\n", vma->vm_flags )); diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h index b93c814e..ef68040 100644 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h @@ -1,18 +1,18 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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 __UMP_KERNEL_H__ -#define __UMP_KERNEL_H__ +#ifndef __UMP_KERNEL_LINUX_H__ +#define __UMP_KERNEL_LINUX_H__ int ump_kernel_device_initialize(void); void ump_kernel_device_terminate(void); -#endif /* __UMP_KERNEL_H__ */ +#endif /* __UMP_KERNEL_LINUX_H__ */ diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c index 4e6c9b5..82c16cc 100644 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -52,6 +52,7 @@ static void block_allocator_shutdown(ump_memory_backend * backend); static int block_allocator_allocate(void* ctx, ump_dd_mem * mem); static void block_allocator_release(void * ctx, ump_dd_mem * handle); static inline u32 get_phys(block_allocator * allocator, block_info * block); +static u32 block_allocator_stat(struct ump_memory_backend *backend); @@ -104,6 +105,7 @@ ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size) backend->allocate = block_allocator_allocate; backend->release = block_allocator_release; backend->shutdown = block_allocator_shutdown; + backend->stat = block_allocator_stat; backend->pre_allocate_physical_check = NULL; backend->adjust_to_mali_phys = NULL; backend->get = NULL; @@ -220,6 +222,7 @@ static int block_allocator_allocate(void* ctx, ump_dd_mem * mem) mem->backend_info = last_allocated; up(&allocator->mutex); + mem->is_cached=0; return 1; } @@ -272,3 +275,13 @@ static inline u32 get_phys(block_allocator * allocator, block_info * block) { return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE); } + +static u32 block_allocator_stat(struct ump_memory_backend *backend) +{ + block_allocator *allocator; + BUG_ON(!backend); + allocator = (block_allocator*)backend->ctx; + BUG_ON(!allocator); + + return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE; +} diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h index fa4bdcc..4f7180e 100644 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -20,4 +20,3 @@ ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size); #endif /* __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ */ - diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c index 07fbd3f..2d81546 100644 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -136,16 +136,16 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor) return 0; /* failure */ } - while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max)) + while (left > 0) { struct page * new_page; if (is_cached) { - new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN ); + new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN); } else { - new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN | __GFP_COLD); + new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD); } if (NULL == new_page) { @@ -182,9 +182,7 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor) if (left) { - MSG_ERR(("Failed to allocate needed pages\n")); - MSG_ERR(("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)); + DBG_MSG(1, ("Failed to allocate needed pages\n")); while(pages_allocated) { diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h index f924705..b638562d 100644 --- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h +++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -20,4 +20,3 @@ ump_memory_backend * ump_os_memory_backend_create(const int max_allocation); #endif /* __UMP_KERNEL_MEMORY_BACKEND_OS_H__ */ - 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 index de7f212..46797ea 100644 --- 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 @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -66,9 +66,9 @@ ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation) { return NULL; } - + info->num_vcm_blocks = 0; - + sema_init(&info->mutex, 1); @@ -85,7 +85,7 @@ ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation) 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; @@ -128,8 +128,8 @@ static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor) 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 */ + 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; @@ -137,7 +137,7 @@ static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor) 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); @@ -146,7 +146,7 @@ static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor) 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 */ @@ -168,7 +168,7 @@ static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor) 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); @@ -288,5 +288,3 @@ static void vcm_attr_set(ump_dd_mem *mem, void *args) 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 index 62f6d12..c1ead0d 100644 --- 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 @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/ump_memory_backend.c b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c index f2a6bd6..821ac27 100644 --- a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c +++ b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -17,7 +17,6 @@ #include "ump_kernel_common.h" #include "ump_kernel_memory_backend_os.h" #include "ump_kernel_memory_backend_dedicated.h" -#include "ump_kernel_memory_backend_vcm.h" /* Configure which dynamic memory allocator to use */ int ump_backend = ARCH_UMP_BACKEND_DEFAULT; diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c index ef1902e..77be0c9 100644 --- a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c +++ b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/ump_osk_low_level_mem.c b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c index 17af2bd..b38c714 100644 --- a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c +++ b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -27,6 +27,7 @@ #include #include +#include /* to verify pointers from user space */ #include #include @@ -301,108 +302,140 @@ static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 s return; } -void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size) +static void level1_cache_flush_all(void) +{ + DBG_MSG(4, ("UMP[xx] Flushing complete L1 cache\n")); + __cpuc_flush_kern_all(); +} + +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; - u32 start_p, end_p; - ump_dd_physical_block *block; + const void *start_v, *end_v; - DBG_MSG(3, - ("Flushing nr of blocks: %u. First: paddr: 0x%08x vaddr: 0x%08x size:%dB\n", - mem->nr_blocks, mem->block_array[0].addr, - phys_to_virt(mem->block_array[0].addr), - mem->block_array[0].size)); - -#ifndef USING_DMA_FLUSH - if (address) { - if ((address >= start) - && ((address + size) <= start + mem->size_bytes)) { - if (size >= SZ_64K) { - flush_all_cpu_caches(); - } else if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) - dmac_flush_range((void *)address, - (void *)(address + size - 1)); - else - dmac_map_area((void *)address, size, - DMA_TO_DEVICE); -#ifdef CONFIG_CACHE_L2X0 - if (size >= SZ_1M) - outer_clean_all(); + /* 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)) ) + { + start_v = (void *)virt; + end_v = (void *)(start_v + size - 1); + /* There is no dmac_clean_range, so the L1 is always flushed, + * also for UMP_MSYNC_CLEAN. */ + dmac_flush_range(start_v, end_v); + DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v)); + } + else + { + if (session_data) + { + if (op == _UMP_UK_MSYNC_FLUSH_L1 ) + { + DBG_MSG(4, ("UMP Pending L1 cache flushes: %d\n", session_data->has_pending_level1_cache_flush)); + session_data->has_pending_level1_cache_flush = 0; + level1_cache_flush_all(); + return; + } else - _ump_osk_msync_with_virt(mem, op, start, address, size); -#endif - return; + { + if (session_data->cache_operations_ongoing) + { + session_data->has_pending_level1_cache_flush++; + DBG_MSG(4, ("UMP[%02u] Defering the L1 flush. Nr pending:%d\n", mem->secure_id, session_data->has_pending_level1_cache_flush) ); + } + else + { + /* Flushing the L1 cache for each switch_user() if ump_cache_operations_control(START) is not called */ + level1_cache_flush_all(); + } + } + } + else + { + DBG_MSG(4, ("Unkown state %s %d\n", __FUNCTION__, __LINE__)); + level1_cache_flush_all(); } } - if ((op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)) { - if ((mem->size_bytes >= SZ_1M)) { - flush_all_cpu_caches(); -#ifdef CONFIG_CACHE_L2X0 - outer_flush_all(); -#endif - return; - } else if ((mem->size_bytes >= SZ_64K)) { - flush_all_cpu_caches(); -#ifdef CONFIG_CACHE_L2X0 - for (i = 0; i < mem->nr_blocks; i++) { - block = &mem->block_array[i]; - start_p = (u32) block->addr; - end_p = start_p + block->size - 1; - outer_flush_range(start_p, end_p); - } -#endif - return; + if ( NULL == mem ) return; + + if ( mem->size_bytes==size) + { + DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache\n",mem->secure_id)); + } + else + { + DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache. Blocks:%u, TotalSize:%u. FlushSize:%u Offset:0x%x FirstPaddr:0x%08x\n", + mem->secure_id, mem->nr_blocks, mem->size_bytes, size, offset, mem->block_array[0].addr)); + } + + + /* Flush L2 using physical addresses, block for block. */ + for (i=0 ; i < mem->nr_blocks; i++) + { + u32 start_p, end_p; + ump_dd_physical_block *block; + block = &mem->block_array[i]; + + if(offset >= block->size) + { + offset -= block->size; + continue; } - } else { - if ((mem->size_bytes >= SZ_1M)) { - flush_all_cpu_caches(); -#ifdef CONFIG_CACHE_L2X0 - outer_clean_all(); -#endif - return; - } else if ((mem->size_bytes >= SZ_64K)) { - flush_all_cpu_caches(); -#ifdef CONFIG_CACHE_L2X0 - for (i = 0; i < mem->nr_blocks; i++) { - block = &mem->block_array[i]; - start_p = (u32) block->addr; + + if(offset) + { + start_p = (u32)block->addr + offset; + /* We'll zero the offset later, after using it to calculate end_p. */ + } + else + { + start_p = (u32)block->addr; + } + + if(size < block->size - offset) + { + end_p = start_p + size - 1; + size = 0; + } + else + { + if(offset) + { + end_p = start_p + (block->size - offset - 1); + size -= block->size - offset; + offset = 0; + } + else + { end_p = start_p + block->size - 1; - outer_clean_range(start_p, end_p); + size -= block->size; } -#endif - return; } - } -#endif - for (i = 0; i < mem->nr_blocks; i++) { - /* TODO: Find out which flush method is best of 1)Dma OR 2)Normal flush functions */ - /*#define USING_DMA_FLUSH */ -#ifdef USING_DMA_FLUSH - DEBUG_ASSERT((PAGE_SIZE == mem->block_array[i].size)); - dma_map_page(NULL, - pfn_to_page(mem->block_array[i]. - addr >> PAGE_SHIFT), 0, PAGE_SIZE, - DMA_BIDIRECTIONAL); - /*dma_unmap_page(NULL, mem->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL); */ -#else - block = &mem->block_array[i]; - start_p = (u32) block->addr; - end_p = start_p + block->size - 1; - if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) { - dmac_flush_range(phys_to_virt(start_p), - phys_to_virt(end_p)); - outer_flush_range(start_p, end_p); - } else { - dmac_map_area(phys_to_virt(start_p), block->size, - DMA_TO_DEVICE); - outer_clean_range(start_p, end_p); + switch(op) + { + case _UMP_UK_MSYNC_CLEAN: + outer_clean_range(start_p, end_p); + break; + case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE: + outer_flush_range(start_p, end_p); + break; + case _UMP_UK_MSYNC_INVALIDATE: + outer_inv_range(start_p, end_p); + break; + default: + break; + } + + if(0 == size) + { + /* Nothing left to flush. */ + break; } -#endif } -} + return; +} void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr) { diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c index 12066eb..1f1118e 100644 --- a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c +++ b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/ump_ukk_ref_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c index 3e355c0..405bdca 100644 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/ump_ukk_ref_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h index 7bd4660..8e3c0fc 100644 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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/linux/ump_ukk_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c index 8b73ca8..e5c5903 100644 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -138,9 +138,9 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi } /* - * IOCTL operation; Return size for specified UMP memory. + * IOCTL operation; Do cache maintenance on specified UMP memory. */ - int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data) +int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data) { _ump_uk_msync_s user_interaction; @@ -171,3 +171,136 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi return 0; /* success */ } +int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_cache_operations_control_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_cache_operations_control()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_cache_operations_control((_ump_uk_cache_operations_control_s*) &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_cache_operations_control()\n")); + return -EFAULT; + } +#endif + return 0; /* success */ +} + +int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_switch_hw_usage_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_switch_hw_usage( &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } +#endif + return 0; /* success */ +} + +int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_lock_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_lock( &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } +#endif + + return 0; /* success */ +} + +int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data) +{ + _ump_uk_unlock_s user_interaction; + + /* Sanity check input parameters */ + if (NULL == argument || NULL == session_data) + { + MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n")); + return -ENOTTY; + } + + if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction))) + { + MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } + + user_interaction.ctx = (void *) session_data; + + _ump_ukk_unlock( &user_interaction ); + + user_interaction.ctx = NULL; + +#if 0 /* No data to copy back */ + if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction))) + { + MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n")); + return -EFAULT; + } +#endif + + return 0; /* success */ +} diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h index 4892c31..99b790d 100644 --- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h +++ b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h @@ -1,9 +1,9 @@ /* - * Copyright (C) 2010 ARM Limited. All rights reserved. - * + * Copyright (C) 2010-2012 ARM Limited. All rights reserved. + * * This program is free software and is provided to you under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. - * + * * 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. */ @@ -30,6 +30,10 @@ int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data); int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data); int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data); +int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data); #ifdef __cplusplus diff --git a/drivers/media/video/slp_db8131m.c b/drivers/media/video/slp_db8131m.c new file mode 100644 index 0000000..a42bfd4c --- /dev/null +++ b/drivers/media/video/slp_db8131m.c @@ -0,0 +1,796 @@ +/* + * linux/drivers/media/video/slp_db8131m.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_VIDEO_SAMSUNG_V4L2 +#include +#endif +#include + +#include "slp_db8131m.h" + +#ifdef DB8131M_USLEEP +#include +#endif + +#define CHECK_ERR(x) if (unlikely((x) < 0)) { \ + cam_err("i2c failed, err %d\n", x); \ + return x; \ + } + +#define NELEMS(array) (sizeof(array) / sizeof(array[0])) + +static inline int db8131m_read(struct i2c_client *client, + u16 subaddr, u16 *data) +{ + u8 buf[2]; + int err = 0; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = buf, + }; + + *(u16 *)buf = cpu_to_be16(subaddr); + + err = i2c_transfer(client->adapter, &msg, 1); + if (unlikely(err < 0)) + cam_err("ERR: %d register read fail\n", __LINE__); + + msg.flags = I2C_M_RD; + + err = i2c_transfer(client->adapter, &msg, 1); + if (unlikely(err < 0)) + cam_err("ERR: %d register read fail\n", __LINE__); + + *data = ((buf[0] << 8) | buf[1]); + + return err; +} + +/* + * s5k6aafx sensor i2c write routine + * --<2Byte Subaddr><2Byte Value>-- + */ +static inline int db8131m_write(struct i2c_client *client, + u32 packet) +{ + u8 buf[4]; + int err = 0, retry_count = 5; + + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .buf = buf, + .len = 4, + }; + + if (!client->adapter) { + cam_err("ERR - can't search i2c client adapter\n"); + return -EIO; + } + + while (retry_count--) { + *(u32 *)buf = cpu_to_be32(packet); + err = i2c_transfer(client->adapter, &msg, 1); + if (likely(err == 1)) + break; + mdelay(10); + } + + if (unlikely(err < 0)) { + cam_err("ERR - 0x%08x write failed err=%d\n", + (u32)packet, err); + return err; + } + + return (err != 1) ? -1 : 0; +} + +/* program multiple registers */ +static int db8131m_write_regs(struct v4l2_subdev *sd, + const u8 *packet, u32 num) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = -EAGAIN; + int retry_count = 5; + + u8 buf[2] = {0,}; + + struct i2c_msg msg = { + msg.addr = client->addr, + msg.flags = 0, + msg.len = 2, + msg.buf = buf, + }; + + while (num) { + buf[0] = *packet++; + buf[1] = *packet++; + + num -= 2; + + retry_count = 5; + + while (retry_count--) { + ret = i2c_transfer(client->adapter, &msg, 1); + if (likely(ret == 1)) + break; + mdelay(10); + } + + if (unlikely(ret < 0)) { + cam_err("ERR - 0x%08x write failed err=%d\n", + (u32)packet, ret); + break; + } + } + + if (unlikely(ret < 0)) { + cam_err("fail to write registers!!\n"); + return -EIO; + } + + return 0; +} + +static int db8131m_check_dataline(struct v4l2_subdev *sd, s32 val) +{ + return 0; +} + +static int db8131m_debug_sensor_status(struct v4l2_subdev *sd) +{ + return 0; +} + +static int db8131m_check_sensor_status(struct v4l2_subdev *sd) +{ + return 0; +} + +static inline int db8131m_check_esd(struct v4l2_subdev *sd) +{ + return 0; +} + +static int db8131m_set_preview_start(struct v4l2_subdev *sd) +{ + struct db8131m_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("reset preview\n"); + +#ifdef CONFIG_LOAD_FILE + err = db8131m_write_regs_from_sd(sd, "db8131m_preview"); +#else + err = db8131m_write_regs(sd, db8131m_preview, + sizeof(db8131m_preview) / sizeof(db8131m_preview[0])); +#endif + if (state->check_dataline) + err = db8131m_check_dataline(sd, 1); + if (unlikely(err)) { + cam_err("fail to make preview\n"); + return err; + } + + return 0; +} + +static int db8131m_set_preview_stop(struct v4l2_subdev *sd) +{ + return 0; +} + +static int db8131m_set_capture_start(struct v4l2_subdev *sd) +{ + return 0; +} + +static int db8131m_set_sensor_mode(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct db8131m_state *state = to_state(sd); + + if ((ctrl->value != SENSOR_CAMERA) && + (ctrl->value != SENSOR_MOVIE)) { + cam_err("ERR: Not support.(%d)\n", ctrl->value); + return -EINVAL; + } + + state->sensor_mode = ctrl->value; + + return 0; +} + +static int db8131m_enum_framesizes(struct v4l2_subdev *sd, \ + struct v4l2_frmsizeenum *fsize) +{ + return 0; +} + +static int db8131m_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *ffmt) +{ + struct db8131m_state *state = to_state(sd); + u32 *width = NULL, *height = NULL; + + cam_dbg("E\n"); + /* + * Just copying the requested format as of now. + * We need to check here what are the formats the camera support, and + * set the most appropriate one according to the request from FIMC + */ + + state->req_fmt.width = ffmt->width; + state->req_fmt.height = ffmt->height; + state->req_fmt.priv = ffmt->field; + + switch (state->req_fmt.priv) { + case V4L2_PIX_FMT_MODE_PREVIEW: + cam_dbg("V4L2_PIX_FMT_MODE_PREVIEW\n"); + width = &state->preview_frmsizes.width; + height = &state->preview_frmsizes.height; + break; + + case V4L2_PIX_FMT_MODE_CAPTURE: + cam_dbg("V4L2_PIX_FMT_MODE_CAPTURE\n"); + width = &state->capture_frmsizes.width; + height = &state->capture_frmsizes.height; + break; + + default: + cam_err("ERR(EINVAL)\n"); + return -EINVAL; + } + + if ((*width != state->req_fmt.width) || + (*height != state->req_fmt.height)) { + cam_err("ERR: Invalid size. width= %d, height= %d\n", + state->req_fmt.width, state->req_fmt.height); + } + + return 0; +} + +static int db8131m_set_frame_rate(struct v4l2_subdev *sd, u32 fps) +{ + int err = 0; + + cam_info("frame rate %d\n\n", fps); + + switch (fps) { + case 7: + err = db8131m_write_regs(sd, db8131m_vt_7fps, + sizeof(db8131m_vt_7fps) / \ + sizeof(db8131m_vt_7fps[0])); + break; + case 10: + err = db8131m_write_regs(sd, db8131m_vt_10fps, + sizeof(db8131m_vt_10fps) / \ + sizeof(db8131m_vt_10fps[0])); + + break; + case 12: + err = db8131m_write_regs(sd, db8131m_vt_12fps, + sizeof(db8131m_vt_12fps) / \ + sizeof(db8131m_vt_12fps[0])); + + break; + case 15: + err = db8131m_write_regs(sd, db8131m_vt_15fps, + sizeof(db8131m_vt_15fps) / \ + sizeof(db8131m_vt_15fps[0])); + break; + default: + cam_err("ERR: Invalid framerate\n"); + break; + } + + if (unlikely(err < 0)) { + cam_err("i2c_write for set framerate\n"); + return -EIO; + } + + return err; +} + +static int db8131m_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + int err = 0; + + cam_dbg("E\n"); + + return err; +} + +static int db8131m_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + int err = 0; + u32 fps = 0; + struct db8131m_state *state = to_state(sd); + + if (!state->vt_mode) + return 0; + + cam_dbg("E\n"); + + fps = parms->parm.capture.timeperframe.denominator / + parms->parm.capture.timeperframe.numerator; + + if (fps != state->set_fps) { + if (fps < 0 && fps > 30) { + cam_err("invalid frame rate %d\n", fps); + fps = 30; + } + state->req_fps = fps; + + if (state->initialized) { + err = db8131m_set_frame_rate(sd, state->req_fps); + if (err >= 0) + state->set_fps = state->req_fps; + } + + } + + return err; +} + +static int db8131m_control_stream(struct v4l2_subdev *sd, u32 cmd) +{ + int err = 0; + + switch (cmd) { + case 0: /* STREAM_STOP */ + cam_dbg("stream stop!!!\n"); + break; + + case 1: /* STREAM_START */ + cam_warn("WARN: do nothing\n"); + break; + + default: + cam_err("ERR: Invalid cmd\n"); + break; + } + + if (unlikely(err)) + cam_err("failed to stream start(stop)\n"); + + return err; +} + +static int db8131m_init(struct v4l2_subdev *sd, u32 val) +{ + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + struct db8131m_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + /* set initial regster value */ + if (state->sensor_mode == SENSOR_CAMERA) { + cam_info("load camera common setting\n"); + err = db8131m_write_regs(sd, db8131m_common_1, + sizeof(db8131m_common_1) / \ + sizeof(db8131m_common_1[0])); + + msleep(150); + + err |= db8131m_write_regs(sd, db8131m_common_2, + sizeof(db8131m_common_2) / \ + sizeof(db8131m_common_2[0])); + } else { + cam_info("load recording setting\n"); + err = db8131m_write_regs(sd, db8131m_common_1, + sizeof(db8131m_common_1) / \ + sizeof(db8131m_common_1[0])); + + msleep(150); + + err = db8131m_write_regs(sd, db8131m_common_2, + sizeof(db8131m_common_2) / \ + sizeof(db8131m_common_2[0])); + } + if (unlikely(err)) { + cam_err("failed to init\n"); + return err; + } + + /* We stop stream-output from sensor when starting camera. */ + err = db8131m_control_stream(sd, 0); + if (unlikely(err < 0)) + return err; + msleep(150); + + state->initialized = 1; + + return 0; +} + +static int db8131m_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct db8131m_state *state = to_state(sd); + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + int err = 0; + + cam_info("stream mode = %d\n", enable); + + switch (enable) { + case STREAM_MODE_CAM_OFF: + if (state->sensor_mode == SENSOR_CAMERA) { + if (state->check_dataline) + err = db8131m_check_dataline(sd, 0); + else + err = db8131m_control_stream(sd, 0); + } + break; + + case STREAM_MODE_CAM_ON: + /* The position of this code need to be adjusted later */ + if ((state->sensor_mode == SENSOR_CAMERA) + && (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE)) + err = db8131m_set_capture_start(sd); + else + err = db8131m_set_preview_start(sd); + break; + + case STREAM_MODE_MOVIE_ON: + cam_dbg("do nothing(movie on)!!\n"); + break; + + case STREAM_MODE_MOVIE_OFF: + cam_dbg("do nothing(movie off)!!\n"); + break; + + default: + cam_err("ERR: Invalid stream mode\n"); + break; + } + + if (unlikely(err < 0)) { + cam_err("ERR: faild\n"); + return err; + } + + return 0; +} + +static int db8131m_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct db8131m_state *state = to_state(sd); + int err = 0; + + cam_dbg("ctrl->id : %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE); + + switch (ctrl->id) { + case V4L2_CID_CAMERA_EXIF_TV: + ctrl->value = state->exif.shutter_speed; + break; + case V4L2_CID_CAMERA_EXIF_ISO: + ctrl->value = state->exif.iso; + break; + default: + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_PRIVATE_BASE); + break; + } + + return err; +} + +static int db8131m_set_brightness(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct db8131m_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + if (state->check_dataline) + return 0; + + switch (ctrl->value) { + case EV_MINUS_4: + err = db8131m_write_regs(sd, db8131m_bright_m4, \ + sizeof(db8131m_bright_m4) / \ + sizeof(db8131m_bright_m4[0])); + break; + case EV_MINUS_3: + err = db8131m_write_regs(sd, db8131m_bright_m3, \ + sizeof(db8131m_bright_m3) / \ + sizeof(db8131m_bright_m3[0])); + + break; + case EV_MINUS_2: + err = db8131m_write_regs(sd, db8131m_bright_m2, \ + sizeof(db8131m_bright_m2) / \ + sizeof(db8131m_bright_m2[0])); + break; + case EV_MINUS_1: + err = db8131m_write_regs(sd, db8131m_bright_m1, \ + sizeof(db8131m_bright_m1) / \ + sizeof(db8131m_bright_m1[0])); + break; + case EV_DEFAULT: + err = db8131m_write_regs(sd, db8131m_bright_default, \ + sizeof(db8131m_bright_default) / \ + sizeof(db8131m_bright_default[0])); + break; + case EV_PLUS_1: + err = db8131m_write_regs(sd, db8131m_bright_p1, \ + sizeof(db8131m_bright_p1) / \ + sizeof(db8131m_bright_p1[0])); + break; + case EV_PLUS_2: + err = db8131m_write_regs(sd, db8131m_bright_p2, \ + sizeof(db8131m_bright_p2) / \ + sizeof(db8131m_bright_p2[0])); + break; + case EV_PLUS_3: + err = db8131m_write_regs(sd, db8131m_bright_p3, \ + sizeof(db8131m_bright_p3) / \ + sizeof(db8131m_bright_p3[0])); + break; + case EV_PLUS_4: + err = db8131m_write_regs(sd, db8131m_bright_p4, \ + sizeof(db8131m_bright_p4) / \ + sizeof(db8131m_bright_p4[0])); + break; + default: + cam_err("ERR: invalid brightness(%d)\n", ctrl->value); + return err; + break; + } + + if (unlikely(err < 0)) { + cam_err("ERR: i2c_write for set brightness\n"); + return -EIO; + } + + return 0; +} + +static int db8131m_set_blur(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + return 0; +} + +static int db8131m_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + struct db8131m_state *state = to_state(sd); + int err = 0; + + cam_info("ctrl->id : %d, value=%d\n", ctrl->id - V4L2_CID_PRIVATE_BASE, + ctrl->value); + + if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE) + && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE) + && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE)) + && (!state->initialized)) { + cam_warn("camera isn't initialized\n"); + return 0; + } + + switch (ctrl->id) { + case V4L2_CID_CAM_PREVIEW_ONOFF: + if (ctrl->value) + err = db8131m_set_preview_start(sd); + else + err = db8131m_set_preview_stop(sd); + cam_dbg("V4L2_CID_CAM_PREVIEW_ONOFF [%d]\n", ctrl->value); + break; + + case V4L2_CID_CAM_CAPTURE: + err = db8131m_set_capture_start(sd); + cam_dbg("V4L2_CID_CAM_CAPTURE\n"); + break; + + case V4L2_CID_CAMERA_BRIGHTNESS: + err = db8131m_set_brightness(sd, ctrl); + cam_dbg("V4L2_CID_CAMERA_BRIGHTNESS [%d]\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_VGA_BLUR: + err = db8131m_set_blur(sd, ctrl); + cam_dbg("V4L2_CID_CAMERA_VGA_BLUR [%d]\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_VT_MODE: + state->vt_mode = ctrl->value; + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE: + state->check_dataline = ctrl->value; + cam_dbg("check_dataline = %d\n", state->check_dataline); + err = 0; + break; + + case V4L2_CID_CAMERA_SENSOR_MODE: + err = db8131m_set_sensor_mode(sd, ctrl); + cam_dbg("sensor_mode = %d\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE_STOP: + cam_dbg("do nothing\n"); + /*err = db8131m_check_dataline_stop(sd);*/ + break; + + case V4L2_CID_CAMERA_CHECK_ESD: + err = db8131m_check_esd(sd); + break; + + case V4L2_CID_CAMERA_FRAME_RATE: + cam_dbg("do nothing\n"); + break; + + case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS: + db8131m_debug_sensor_status(sd); + err = db8131m_check_sensor_status(sd); + break; + + default: + cam_err("ERR(ENOIOCTLCMD)\n"); + /* no errors return.*/ + break; + } + + cam_dbg("X\n"); + return err; +} + +static const struct v4l2_subdev_core_ops db8131m_core_ops = { + .init = db8131m_init, /* initializing API */ +#if 0 + .queryctrl = db8131m_queryctrl, + .querymenu = db8131m_querymenu, +#endif + .g_ctrl = db8131m_g_ctrl, + .s_ctrl = db8131m_s_ctrl, +}; + +static const struct v4l2_subdev_video_ops db8131m_video_ops = { + /*.s_crystal_freq = db8131m_s_crystal_freq,*/ + .s_mbus_fmt = db8131m_s_fmt, + .s_stream = db8131m_s_stream, + .enum_framesizes = db8131m_enum_framesizes, + /*.enum_frameintervals = db8131m_enum_frameintervals,*/ + /*.enum_fmt = db8131m_enum_fmt,*/ + .g_parm = db8131m_g_parm, + .s_parm = db8131m_s_parm, +}; + +static const struct v4l2_subdev_ops db8131m_ops = { + .core = &db8131m_core_ops, + .video = &db8131m_video_ops, +}; + +/* + * db8131m_probe + * Fetching platform data is being done with s_config subdev call. + * In probe routine, we just register subdev device + */ +static int db8131m_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct db8131m_state *state = NULL; + struct v4l2_subdev *sd = NULL; + struct db8131m_platform_data *pdata = NULL; + cam_dbg("E\n"); + + state = kzalloc(sizeof(struct db8131m_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + + sd = &state->sd; + strcpy(sd->name, DB8131M_DRIVER_NAME); + + state->initialized = 0; + state->req_fps = state->set_fps = 8; + state->sensor_mode = SENSOR_CAMERA; + + pdata = client->dev.platform_data; + + if (!pdata) { + cam_err("no platform data\n"); + return -ENODEV; + } + + /* Registering subdev */ + v4l2_i2c_subdev_init(sd, client, &db8131m_ops); + + /* + * Assign default format and resolution + * Use configured default information in platform data + * or without them, use default information in driver + */ + if (!(pdata->default_width && pdata->default_height)) { + state->preview_frmsizes.width = DEFAULT_PREVIEW_WIDTH; + state->preview_frmsizes.height = DEFAULT_PREVIEW_HEIGHT; + } else { + state->preview_frmsizes.width = pdata->default_width; + state->preview_frmsizes.height = pdata->default_height; + } + state->capture_frmsizes.width = DEFAULT_CAPTURE_WIDTH; + state->capture_frmsizes.height = DEFAULT_CAPTURE_HEIGHT; + + cam_dbg("preview_width: %d , preview_height: %d, " + "capture_width: %d, capture_height: %d", + state->preview_frmsizes.width, state->preview_frmsizes.height, + state->capture_frmsizes.width, state->capture_frmsizes.height); + + state->req_fmt.width = state->preview_frmsizes.width; + state->req_fmt.height = state->preview_frmsizes.height; + + if (!pdata->pixelformat) + state->req_fmt.pixelformat = VT_DEFAULT_FMT; + else + state->req_fmt.pixelformat = pdata->pixelformat; + + cam_dbg("probed!!\n"); + + return 0; +} + +static int db8131m_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct db8131m_state *state = to_state(sd); + + cam_dbg("E\n"); + + state->initialized = 0; + + v4l2_device_unregister_subdev(sd); + kfree(to_state(sd)); + + return 0; +} + +static const struct i2c_device_id db8131m_id[] = { + { DB8131M_DRIVER_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, db8131m_id); + +static struct i2c_driver db8131m_i2c_driver = { + .driver = { + .name = DB8131M_DRIVER_NAME, + }, + .probe = db8131m_probe, + .remove = db8131m_remove, + .id_table = db8131m_id, +}; + +static int __init db8131m_mod_init(void) +{ + cam_dbg("E\n"); + return i2c_add_driver(&db8131m_i2c_driver); +} + +static void __exit db8131m_mod_exit(void) +{ + cam_dbg("E\n"); + i2c_del_driver(&db8131m_i2c_driver); +} +module_init(db8131m_mod_init); +module_exit(db8131m_mod_exit); + +MODULE_DESCRIPTION("DB8131M CAM driver"); +MODULE_AUTHOR(" "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/slp_db8131m.h b/drivers/media/video/slp_db8131m.h new file mode 100644 index 0000000..3c594a2 --- /dev/null +++ b/drivers/media/video/slp_db8131m.h @@ -0,0 +1,100 @@ +/* + * linux/drivers/media/video/slp_db8131m.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __DB8131M_H +#define __DB8131M_H + +#include + +extern struct class *camera_class; + +#define DB8131M_DRIVER_NAME "DB8131M" + +struct db8131m_framesize { + u32 width; + u32 height; +}; + +struct db8131m_exif { + u32 shutter_speed; + u16 iso; +}; + + +/* + * Driver information + */ +struct db8131m_state { + struct v4l2_subdev sd; + struct device *db8131m_dev; + /* + * req_fmt is the requested format from the application. + * set_fmt is the output format of the camera. Finally FIMC + * converts the camera output(set_fmt) to the requested format + * with hardware scaler. + */ + struct v4l2_pix_format req_fmt; + struct db8131m_framesize preview_frmsizes; + struct db8131m_framesize capture_frmsizes; + struct db8131m_exif exif; + + enum v4l2_sensor_mode sensor_mode; + s32 vt_mode; + s32 check_dataline; + u32 req_fps; + u32 set_fps; + u32 initialized; +}; + +static inline struct db8131m_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct db8131m_state, sd); +} + +/*#define CONFIG_CAM_DEBUG */ +#define cam_warn(fmt, ...) \ + do { \ + printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_err(fmt, ...) \ + do { \ + printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_info(fmt, ...) \ + do { \ + printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#ifdef CONFIG_CAM_DEBUG +#define cam_dbg(fmt, ...) \ + do { \ + printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) +#else +#define cam_dbg(fmt, ...) +#endif /* CONFIG_CAM_DEBUG */ + + + +/*********** Sensor specific ************/ +#define DB8131M_DELAY 0xFFFF0000 +#define DB8131M_DEF_APEX_DEN 100 + +/* Register address */ +#define REG_PAGE_SHUTTER 0x7000 +#define REG_ADDR_SHUTTER 0x14D0 +#define REG_PAGE_ISO 0x7000 +#define REG_ADDR_ISO 0x14C8 + +#include "slp_db8131m_setfile.h" + +#endif /* __DB8131M_H */ diff --git a/drivers/media/video/slp_db8131m_setfile.h b/drivers/media/video/slp_db8131m_setfile.h new file mode 100644 index 0000000..ebbdbb0 --- /dev/null +++ b/drivers/media/video/slp_db8131m_setfile.h @@ -0,0 +1,2264 @@ +/* + * linux/drivers/media/video/slp_db8131m_setfile.h + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * 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. + */ +#ifndef __DB8131M_SETFILE_H +#define __DB8131M_SETFILE_H + +#include + +/* 1.3M mipi setting-common from PARTRON */ +/*******************************************************************/ +/* Name : DB8131M Initial Setfile*/ +/* PLL mode : MCLK=24MHz / PCLK=48MHz*/ +/* FPS : Preview 7.5~15fps / Capture 7.5fps / recording 25fps*/ +/* Date : 2011.12.06*/ +/*******************************************************************/ + + +static const u8 db8131m_common_1[] = { +/***************************************************/ +/* Command Preview 7.5~15fps*/ +/***************************************************/ +0xFF, 0xC0, /*Page mode*/ +0x10, 0x01, +}; +/*Wait 150*/ + +static const u8 db8131m_common_2[] = { +/***************************************************/ +/* Format*/ +/***************************************************/ +0xFF, 0xA1, /*Page mode*/ +0x70, 0x01, +0x71, 0x0D, + +/***************************************************/ +/* SensorCon*/ +/***************************************************/ +0xFF, 0xD0, /*Page mode*/ +0x0F, 0x0B, /*ABLK_Ctrl_1_Addr*/ +0x13, 0x00, /*Gain_Addr*/ +0x15, 0x01, /*IVREFT_REFB_Addr*/ +0x20, 0x0E, /*ABLK_Rsrv_Addr*/ +0x23, 0x01, /*IVREFT2_REFB2_Addr*/ +0x24, 0x01, /*IPPG_IVCM2_Addr*/ +0x39, 0x70, /*RiseSx_CDS_1_L_Addr*/ +0x51, 0x19, /*Fallcreset_1_L_Addr*/ +0x83, 0x2D, /*RiseTran_Sig_Even_L_Addr*/ +0x85, 0x2F, /*FallTran_Sig_Even_L_Addr*/ +0x87, 0x2D, /*RiseTran_Sig_Odd_L_Addr*/ +0x89, 0x2F, /*FallTran_Sig_Odd_L_Addr*/ +0x8B, 0x27, /*RiseCNT_EN_1_L_Addr*/ +0x8D, 0x6c, /*FallCNT_EN_1_L_Addr*/ +0xD7, 0x80, /*ABLK_Ctrl_12_Addr*/ +0xDB, 0xA2, /*FallScanTx15_1_L_Addr*/ +0xED, 0x01, /*PLL_P_Addr*/ +0xEE, 0x0F, /*PLL_M_Addr*/ +0xEF, 0x00, /*PLL_S_Addr*/ +0xF9, 0x00, /*ABLK_Ctrl_8*/ +0xF8, 0x00, /*Vblank Sleep Mode enable*/ +0xFB, 0x90, /*PostADC_Gain_Addr*/ + +/***************************************************/ +/* Analog ADF*/ +/***************************************************/ +0xFF, 0x85, /*Page mode*/ +0x89, 0x93, /*gAdf_u8APThreshold*/ +0x8A, 0x0C, /*u8APClmpThreshold*/ +0x8C, 0x07, /*gAdf_u8APMinVal_ThrClampH*/ +0x8D, 0x40, /*gAdf_u8APMinVal_ThrClampL*/ +0x8E, 0x03, /*gAdf_u8APMinVal_DOFFSET*/ +0x8F, 0x14, /*gAdf_u8APMinVal_AMP2_1_SDM*/ +0x91, 0x1A, /*gAdf_u8APMinVal_AMP4_3_SDM*/ +0x92, 0x0F, /*gAdf_u8APMinVal_FallIntTx15*/ +0x93, 0x47, /*gAdf_u8APMinVal_CDSxRange_CtrlPre*/ +0x95, 0x18, /*gAdf_u8APMinVal_REFB_IVCM*/ +0x96, 0x38, /*gAdf_u8APMinVal_ref_os_PB*/ +0x97, 0x0D, /*gAdf_u8APMinVal_NTx_Range*/ +0x98, 0x0D, /*gAdf_u8APMaxVal_Clmp_rst*/ +0x99, 0x06, /*gAdf_u8APMaxVal_ThrClampH*/ +0x9A, 0x9F, /*gAdf_u8APMaxVal_ThrClampL*/ +0x9B, 0x02, /*gAdf_u8APMaxVal_DOFFSET*/ +0x9C, 0x1C, /*gAdf_u8APMaxVal_AMP2_1_SDM*/ +0x9E, 0x11, /*gAdf_u8APMaxVal_AMP4_3_SDM*/ +0x9F, 0x5D, /*gAdf_u8APMaxVal_FallIntTx15*/ +0xA0, 0x78, /*gAdf_u8APMaxVal_CDSxRange_CtrlPre*/ +0xA2, 0x18, /*gAdf_u8APMaxVal_REFB_IVCM*/ +0xA3, 0x40, /*gAdf_u8APMaxVal_ref_os_PB*/ +0xA4, 0x0B, /*gAdf_u8APMaxVal_NTx_Range*/ + +0xFF, 0x86, /*Page mode*/ +0x15, 0x00, /*gPT_u8Adf_APThrHys*/ +0x16, 0xF7, /*gPT_u8Adf_APFallIntTxThrLevel*/ +0x17, 0x13, /*gPT_u8Adf_APMinVal_BP2_1_SDM*/ +0x18, 0x13, /*gPT_u8Adf_APMidVal_BP2_1_SDM*/ +0x19, 0x1C, /*gPT_u8Adf_APMaxVal_BP2_1_SDM*/ +0x1A, 0x06, /*gPT_u8Adf_APMidVal_ThrClampH*/ +0x1B, 0xF0, /*gPT_u8Adf_APMidVal_ThrClampL*/ +0x1C, 0x01, /*gPT_u8Adf_APMidVal_DOFFSET*/ +0x1D, 0x14, /*gPT_u8Adf_APMidVal_AMP2_1_SDM*/ +0x1F, 0x31, /*gPT_u8Adf_APMidVal_AMP4_3_SDM*/ +0x20, 0x68, /*gPT_u8Adf_APMidVal_CDSxRange_CtrlPre*/ +0x22, 0x18, /*gPT_u8Adf_APMidVal_REFB_IVCM*/ +0x23, 0x38, /*gPT_u8Adf_APMidVal_ref_os_PB*/ +0x24, 0x0F, /*gPT_u8Adf_APMidVal_NTx_Range*/ +0x25, 0x77, /*gPT_u8Adf_APVal_EnSiSoSht_EnSm*/ + +0xFF, 0x87, /*Page mode*/ +0xEA, 0x41, + +0xFF, 0xD0, /*Page mode*/ +0x20, 0x0D, /*ABLK_Rsrv_Addr*/ + +0xFF, 0x83, /*Page mode*/ +0x63, 0x28, /*Again Table*/ +0x64, 0x10, /*Again Table*/ +0x65, 0xA8, /*Again Table*/ +0x66, 0x50, /*Again Table*/ +0x67, 0x28, /*Again Table*/ +0x68, 0x14, /*Again Table*/ + + +/***************************************************/ +/* AE*/ +/***************************************************/ +0xFF, 0x82, /*Page mode*/ +0x95, 0x88, /* AE weight*/ +0x96, 0x88, +0x97, 0xF8, +0x98, 0x8F, +0x99, 0xF8, +0x9A, 0x8F, +0x9B, 0x88, +0x9C, 0x88, +0xA9, 0x40, /* OTarget*/ +0xAA, 0x40, /* ITarget*/ +0x9D, 0x66, /* AE Speed*/ +0x9F, 0x06, /* AE HoldBnd*/ +0xA8, 0x40, /* STarget*/ +0xB9, 0x04, /* RGain*/ +0xBB, 0x04, /* GGain*/ +0xBD, 0x04, /* BGain*/ +0xC5, 0x02, /* PeakMvStep*/ +0xC6, 0x38, /* PeakTgMin*/ +0xC7, 0x24, /* PeakRatioTh1*/ +0xC8, 0x10, /* PeakRatioTh0*/ +0xC9, 0x05, /* PeakLuTh*/ +0xD5, 0x60, /* LuxGainTB_2*/ +0xFF, 0x83, /*Page mode */ +0x2F, 0x04, /* TimeNum0*/ +0x30, 0x05, /* TimeNum1*/ +0x4F, 0x05, /* FrameOffset*/ +0xFF, 0x82, /*Page mode */ +0xA1, 0x0A, /* AnalogGainMax*/ +0xF3, 0x09, /* SCLK*/ +0xF4, 0x60, +0xF9, 0x00, /* GainMax*/ +0xFA, 0xC8, /* GainMax*/ +0xFB, 0x62, /* Gain3Lut*/ +0xFC, 0x39, /* Gain2Lut*/ +0xFD, 0x28, /* Gain1Lut*/ +0xFE, 0x12, /* GainMin*/ +0xFF, 0x83, /*Page mode */ +0x03, 0x0F, /* TimeMax60Hz : 8fps*/ +0x04, 0x0A, /* Time3Lux60Hz : 12fps*/ +0x05, 0x04, /* Time2Lut60Hz : 24fps*/ +0x06, 0x04, /* Time1Lut60Hz : 24fps*/ +0xFF, 0x82, /*Page mode */ +0xD3, 0x12, /* LuxTBGainStep0 */ +0xD4, 0x36, /* LuxTBGainStep1 */ +0xD5, 0x60, /* LuxTBGainStep2*/ +0xD6, 0x01, /* LuxTBTimeStep0H*/ +0xD7, 0x00, /* LuxTBTimeStep0L*/ +0xD8, 0x01, /* LuxTBTimeStep1H*/ +0xD9, 0xC0, /* LuxTBTimeStep1L*/ +0xDA, 0x06, /* LuxTBTimeStep2H*/ +0xDB, 0x00, /* LuxTBTimeStep2L*/ +0xFF, 0x83, /*Page mode */ +0x0B, 0x04, +0x0C, 0x4C, /* Frame Rate*/ +0xFF, 0x82, /*Page mode */ +0x92, 0x5D, + +/***************************************************/ +/* AWB*/ +/***************************************************/ +0xFF, 0x83, /*Page mode */ +0x79, 0x83, /* AWB SKIN ON*/ +0x86, 0x07, /* gAWB_u16MinGrayCnt_rw_0*/ +0x87, 0x00, /* gAWB_u16MinGrayCnt_rw_1*/ +0x90, 0x05, /* gAWB_u16FinalRGain_ro_0*/ +0x94, 0x05, /* gAWB_u16FinalBGain_ro_0*/ +0x98, 0xD4, /* SkinWinCntTh*/ +0xA2, 0x28, /* SkinYTh*/ +0xA3, 0x00, /* SkinHoldHitCnt*/ +0xA4, 0x0F, /* SkinHoldHitCnt*/ +0xAD, 0x65, /* u8SkinTop2*/ +0xAE, 0x80, /* gAwb_u8SkinTop2LS1Ratio_rw 5zone*/ +0xAF, 0x20, /* gAwb_u8SkinTop2LS2Ratio_rw 6zone */ +0xB4, 0x10, /* u8SkinTop2LSHys_rw*/ +0xB5, 0x54, /* gAwb_u8SkinLTx*/ +0xB6, 0xbd, /* gAwb_u8SkinLTy*/ +0xB7, 0x74, /* gAwb_u8SkinRBx*/ +0xB8, 0x9d, /* gAwb_u8SkinRBy*/ +0xBA, 0x4F, /* UniCThrY_rw*/ +0xBF, 0x0C, /* u16UniCGrayCntThr_rw_0*/ +0xC0, 0x80, /* u16UniCGrayCntThr_rw_1*/ +0xFF, 0x87, /*Page mode */ +0xC9, 0x22, /* gUR_u8AWBTrim_Addr*/ +0xFF, 0x84, /*Page mode */ +0x49, 0x02, /* Threshold_indoor*/ +0x4A, 0x00, +0x4B, 0x03, /* Threshold_outdoor*/ +0x4C, 0x80, +0xFF, 0x83, /*Page mode */ +0xCB, 0x03, /* R MinGain [Default 0X20] A Spec Pass */ +0xCC, 0xC0, /* R MinGain [Default 0X20] A Spec Pass */ +0x82, 0x00, /* lockratio*/ +0xFF, 0x84, /*Page mode */ +0x3D, 0x00, /* gAwb_u32LuxConst1_rw_0*/ +0x3E, 0x00, /* gAwb_u32LuxConst1_rw_1*/ +0x3F, 0x06, /* gAwb_u32LuxConst1_rw_2*/ +0x40, 0x20, /* gAwb_u32LuxConst1_rw_3*/ +0x41, 0x07, /* gAwb_u32LuxConst2_rw_0*/ +0x42, 0x53, /* gAwb_u32LuxConst2_rw_1*/ +0x43, 0x00, /* gAwb_u32LuxConst2_rw_2*/ +0x44, 0x00, /* gAwb_u32LuxConst2_rw_3*/ +0x55, 0x03, /* gAwb_u8Weight_Gen_rw_0 */ +0x56, 0x10, /* gAwb_u8Weight_Gen_rw_1 */ +0x57, 0x14, /* gAwb_u8Weight_Gen_rw_2 */ +0x58, 0x07, /* gAwb_u8Weight_Gen_rw_3 */ +0x59, 0x04, /* gAwb_u8Weight_Gen_rw_4 */ +0x5A, 0x03, /* gAwb_u8Weight_Gen_rw_5 */ +0x5B, 0x03, /* gAwb_u8Weight_Gen_rw_6 */ +0x5C, 0x15, /* gAwb_u8Weight_Gen_rw_7 */ +0x5D, 0x01, /* gAwb_u8Weight_Ind_rw_0 */ +0x5E, 0x0F, /* gAwb_u8Weight_Ind_rw_1 */ +0x5F, 0x07, /* gAwb_u8Weight_Ind_rw_2 */ +0x60, 0x14, /* gAwb_u8Weight_Ind_rw_3 */ +0x61, 0x14, /* gAwb_u8Weight_Ind_rw_4 */ +0x62, 0x12, /* gAwb_u8Weight_Ind_rw_5 */ +0x63, 0x11, /* gAwb_u8Weight_Ind_rw_6 */ +0x64, 0x14, /* gAwb_u8Weight_Ind_rw_7 */ +0x65, 0x03, /* gAwb_u8Weight_Outd_rw_0*/ +0x66, 0x05, /* gAwb_u8Weight_Outd_rw_1*/ +0x67, 0x15, /* gAwb_u8Weight_Outd_rw_2*/ +0x68, 0x04, /* gAwb_u8Weight_Outd_rw_3*/ +0x69, 0x01, /* gAwb_u8Weight_Outd_rw_4*/ +0x6A, 0x02, /* gAwb_u8Weight_Outd_rw_5*/ +0x6B, 0x03, /* gAwb_u8Weight_Outd_rw_6*/ +0x6C, 0x15, /* gAwb_u8Weight_Outd_rw_6*/ +0xFF, 0x85, /*Page mode */ +0xE2, 0x0C, /* gPT_u8Awb_UnicolorZone_rw */ +0xFF, 0x83, /*Page mode */ +0xCD, 0x06, /*Max Rgain*/ +0xCE, 0x80, +0xD1, 0x06, /*Max BGain*/ +0xd2, 0x80, + +/***************************************************/ +/* AWB STE*/ +/***************************************************/ +0xFF, 0xA1, /*Page mode */ +/*Flash*/ +0xA0, 0x5c, /*AWBZone0LTx*/ +0xA1, 0x7a, /*AWBZone0LTy*/ +0xA2, 0x69, /*AWBZone0RBx*/ +0xA3, 0x6f, /*AWBZone0RBy*/ +/*cloudy*/ +0xA4, 0x73, /*AWBZone1LTx*/ +0xA5, 0x55, /*AWBZone1LTy*/ +0xA6, 0x8C, /*AWBZone1RBx*/ +0xA7, 0x30, /*AWBZone1RBy */ +/*Daylight */ +0xA8, 0x69, /*AWBZone2LTx*/ +0xA9, 0x69, /*AWBZone2LTy*/ +0xAA, 0x83, /*AWBZone2RBx*/ +0xAB, 0x52, /*AWBZone2RBy */ +/*Fluorescent */ +0xAC, 0x57, /*AWBZone3LTx*/ +0xAD, 0x6e, /*AWBZone3LTy*/ +0xAE, 0x6f, /*AWBZone3RBx*/ +0xAF, 0x59, /*AWBZone3RBy*/ + +/*CWF */ +0xB0, 0x50, /*AWBZone4LTx*/ +0xB1, 0x74, /*AWBZone4LTy*/ +0xB2, 0x65, /*AWBZone4RBx*/ +0xB3, 0x5d, /*AWBZone4RBy*/ +/*TL84 */ +0xB4, 0x53, /*AWBZone5LTx*/ +0xB5, 0x7f, /*AWBZone5LTy*/ +0xB6, 0x62, /*AWBZone5RBx*/ +0xB7, 0x75, /*AWBZone5RBy */ +/*A */ +0xB8, 0x4a, /*AWBZone6LTx*/ +0xB9, 0x87, /*AWBZone6LTy*/ +0xBA, 0x59, /*AWBZone6RBx*/ +0xBB, 0x78, /*AWBZone6RBy*/ +/*Horizon */ +0xBC, 0x41, /*AWBZone7LTx*/ +0xBD, 0x91, /*AWBZone7LTy*/ +0xBE, 0x4b, /*AWBZone7RBx*/ +0xBF, 0x89, /*AWBZone7RBy*/ +/*Skin */ +0xC0, 0x5b, /*AWBZone8LTx*/ +0xC1, 0x85, /*AWBZone8LTy*/ +0xC2, 0x60, /*AWBZone8RBx*/ +0xC3, 0x7b, /*AWBZone8RBy*/ + +/***************************************************/ +/* UR*/ +/***************************************************/ +0xFF, 0x85, /*Page mode */ +0x06, 0x05, +0xFF, 0x86, /*Page mode */ +0x14, 0x1E, /* CCM sum 1*/ +0xFF, 0x85, /*Page mode */ +0x86, 0x42, /* 42 saturation level*/ +0x07, 0x00, /* sup hysteresis*/ + +/*DAY light */ +0xFF, 0x83, /*Page mode */ +0xEA, 0x00, /*gAwb_s16AdapCCMTbl_0*/ +0xEB, 0x53, /*gAwb_s16AdapCCMTbl_1*/ +0xEC, 0xFF, /*gAwb_s16AdapCCMTbl_2*/ +0xED, 0xE1, /*gAwb_s16AdapCCMTbl_3*/ +0xEE, 0x00, /*gAwb_s16AdapCCMTbl_4*/ +0xEF, 0x05, /*gAwb_s16AdapCCMTbl_5*/ +0xF0, 0xFF, /*gAwb_s16AdapCCMTbl_6*/ +0xF1, 0xF3, /*gAwb_s16AdapCCMTbl_7*/ +0xF2, 0x00, /*gAwb_s16AdapCCMTbl_8*/ +0xF3, 0x4B, /*gAwb_s16AdapCCMTbl_9*/ +0xF4, 0xFF, /*gAwb_s16AdapCCMTbl_10*/ +0xF5, 0xFA, /*gAwb_s16AdapCCMTbl_11*/ +0xF6, 0xFF, /*gAwb_s16AdapCCMTbl_12*/ +0xF7, 0xFa, /*gAwb_s16AdapCCMTbl_13*/ +0xF8, 0xFF, /*gAwb_s16AdapCCMTbl_14*/ +0xF9, 0xC3, /*gAwb_s16AdapCCMTbl_15*/ +0xFA, 0x00, /*gAwb_s16AdapCCMTbl_16*/ +0xFB, 0x80, /*gAwb_s16AdapCCMTbl_17*/ + +/*CWF lgiht */ +0xFF, 0x83, /*Page mode*/ +0xFC, 0x00, /* gAwb_s16AdapCCMTbl_18 */ +0xFD, 0x68, /* gAwb_s16AdapCCMTbl_19 */ +0xFF, 0x85, /*Page mode */ +0xE0, 0xFF, /* gAwb_s16AdapCCMTbl_20 */ +0xE1, 0xde, /* gAwb_s16AdapCCMTbl_21 */ +0xFF, 0x84, /*Page mode */ +0x00, 0xff, /* gAwb_s16AdapCCMTbl_22 */ +0x01, 0xfa, /* gAwb_s16AdapCCMTbl_23 */ +0x02, 0xFF, /* gAwb_s16AdapCCMTbl_24 */ +0x03, 0xf0, /* gAwb_s16AdapCCMTbl_25 */ +0x04, 0x00, /* gAwb_s16AdapCCMTbl_26 */ +0x05, 0x52, /* gAwb_s16AdapCCMTbl_27 */ +0x06, 0xFF, /* gAwb_s16AdapCCMTbl_28 */ +0x07, 0xFa, /* gAwb_s16AdapCCMTbl_29 */ +0x08, 0x00, /* gAwb_s16AdapCCMTbl_30 */ +0x09, 0x00, /* gAwb_s16AdapCCMTbl_31 */ +0x0A, 0xFF, /* gAwb_s16AdapCCMTbl_32 */ +0x0B, 0xdb, /* gAwb_s16AdapCCMTbl_33 */ +0x0C, 0x00, /* gAwb_s16AdapCCMTbl_34 */ +0x0D, 0x68, /* gAwb_s16AdapCCMTbl_35 */ + +/*A light */ + +0x0E, 0x00, /* gAwb_s16AdapCCMTbl_36 */ +0x0F, 0x6d, /* gAwb_s16AdapCCMTbl_37 */ +0x10, 0xFF, /* gAwb_s16AdapCCMTbl_38 */ +0x11, 0xd5, /* gAwb_s16AdapCCMTbl_39 */ +0x12, 0xff, /* gAwb_s16AdapCCMTbl_40 */ +0x13, 0xfe, /* gAwb_s16AdapCCMTbl_41 */ +0x14, 0xFF, /* gAwb_s16AdapCCMTbl_42 */ +0x15, 0xf4, /* gAwb_s16AdapCCMTbl_43 */ +0x16, 0x00, /* gAwb_s16AdapCCMTbl_44 */ +0x17, 0x5a, /* gAwb_s16AdapCCMTbl_45 */ +0x18, 0xff, /* gAwb_s16AdapCCMTbl_46 */ +0x19, 0xef, /* gAwb_s16AdapCCMTbl_47 */ +0x1A, 0xff, /* gAwb_s16AdapCCMTbl_48 */ +0x1B, 0xfa, /* gAwb_s16AdapCCMTbl_49 */ +0x1C, 0xFF, /* gAwb_s16AdapCCMTbl_50 */ +0x1D, 0xbe, /* gAwb_s16AdapCCMTbl_51 */ +0x1E, 0x00, /* gAwb_s16AdapCCMTbl_52 */ +0x1F, 0x86, /* gAwb_s16AdapCCMTbl_53 */ + + +/***************************************************/ +/* ADF*/ +/***************************************************/ + +/* ISP setting*/ +0xFF, 0xA0, /*Page mode */ +0x10, 0x80, /* BLC: ABLC db*/ +0x60, 0x73, /* CDC: Dark CDC ON */ +0x61, 0x1F, /* Six CDC_Edge En, Slash EN*/ +0x69, 0x0C, /* Slash direction Line threshold*/ +0x6A, 0x60, /* Slash direction Pixel threshold*/ +0xC2, 0x04, /* NSF: directional smoothing*/ +0xD0, 0x51, /* DEM: pattern detection*/ +0xFF, 0xA1, /*Page mode */ +0x30, 0x01, /* EDE: Luminane adaptation on*/ +0x32, 0x50, /* EDE: Adaptation slope */ +0x34, 0x00, /* EDE: x1 point */ +0x35, 0x0B, /* EDE: x1 point */ +0x36, 0x01, /* EDE: x2 point */ +0x37, 0x80, /* EDE: x2 point */ +0x3A, 0x00, /* EDE: Adaptation left margin*/ +0x3B, 0x30, /* EDE: Adaptation right margin*/ +0x3C, 0x08, /* EDE: rgb edge threshol*/ + +/* Adaptive Setting*/ +0xFF, 0x85, /*Page mode */ +/* LSC*/ +0x0F, 0x43, /* LVLSC lux level threshold*/ +0x10, 0x43, /* LSLSC Light source , threshold lux*/ + +/* BGT*/ +0x17, 0x30, /* BGT lux level threshold*/ +0x26, 0x20, /* MinVal */ +0x3c, 0x00, /* MaxVal */ + +/* CNT*/ +0x18, 0x43, /* CNT lux level threshold*/ +0x27, 0x00, /* MinVal */ +0x3d, 0x00, /* MaxVal */ + +/* NSF */ +0x12, 0xA5, /* NSF lux level threshold */ +0x22, 0x38, /* u8MinVal_NSF1*/ +0x23, 0x70, /* u8MinVal_NSF2*/ +0xFF, 0x86, /*Page mode */ +0x12, 0x00, /* u8MinVal_NSF3*/ +0xFF, 0x85, /*Page mode */ +0x38, 0x12, /* u8MaxVal_NSF1*/ +0x39, 0x30, /* u8MaxVal_NSF2*/ +0xFF, 0x86, /*Page mode */ +0x13, 0x08, /* u8MaxVal_NSF3*/ + +/* GDC*/ +0xFF, 0x85, /*Page mode */ +0x15, 0xF4, /* GDC lux level threshold */ +0x2D, 0x20, /* u8MinVal_GDC1*/ +0x2E, 0x30, /* u8MinVal_GDC2*/ +0x43, 0x40, /* u8MaxVal_GDC1*/ +0x44, 0x80, /* u8MaxVal_GDC2*/ + +/* ISP Edge*/ +0x04, 0xFB, /* EnEDE*/ +0x14, 0x54, /* u8ThrLevel_EDE*/ +0x28, 0x00, /* u8MinVal_EDE_CP*/ +0x29, 0x03, /* u8MinVal_EDE1*/ +0x2A, 0x20, /* u8MinVal_EDE2*/ +0x2B, 0x00, /* u8MinVal_EDE_OFS*/ +0x2C, 0x22, /* u8MinVal_SG*/ +0x3E, 0x00, /* u8MaxVal_EDE_CP*/ +0x3F, 0x09, /* u8MaxVal_EDE1*/ +0x40, 0x22, /* u8MaxVal_EDE2*/ +0x41, 0x02, /* u8MaxVal_EDE_OFS*/ +0x42, 0x33, /* u8MaxVal_SG*/ + +/* Gamma Adaptive*/ + +0x16, 0xA0, /* Gamma Threshold*/ +0x47, 0x00, /* Min_Gamma_0*/ +0x48, 0x03, /* Min_Gamma_1*/ +0x49, 0x10, /* Min_Gamma_2*/ +0x4A, 0x25, /* Min_Gamma_3*/ +0x4B, 0x3B, /* Min_Gamma_4*/ +0x4C, 0x4F, /* Min_Gamma_5*/ +0x4D, 0x6D, /* Min_Gamma_6*/ +0x4E, 0x86, /* Min_Gamma_7*/ +0x4F, 0x9B, /* Min_Gamma_8*/ +0x50, 0xAD, /* Min_Gamma_9*/ +0x51, 0xC2, /* Min_Gamma_10*/ +0x52, 0xD3, /* Min_Gamma_11*/ +0x53, 0xE1, /* Min_Gamma_12*/ +0x54, 0xE9, /* Min_Gamma_13*/ +0x55, 0xF2, /* Min_Gamma_14*/ +0x56, 0xFA, /* Min_Gamma_15*/ +0x57, 0xFF, /* Min_Gamma_16*/ +0x58, 0x00, /* Max_Gamma_0 */ +0x59, 0x06, /* Max_Gamma_1 */ +0x5a, 0x14, /* Max_Gamma_2 */ +0x5b, 0x30, /* Max_Gamma_3 */ +0x5c, 0x4A, /* Max_Gamma_4 */ +0x5d, 0x5D, /* Max_Gamma_5 */ +0x5e, 0x75, /* Max_Gamma_6 */ +0x5f, 0x89, /* Max_Gamma_7 */ +0x60, 0x9A, /* Max_Gamma_8 */ +0x61, 0xA7, /* Max_Gamma_9 */ +0x62, 0xBC, /* Max_Gamma_10 */ +0x63, 0xD0, /* Max_Gamma_11 */ +0x64, 0xE0, /* Max_Gamma_12 */ +0x65, 0xE7, /* Max_Gamma_13 */ +0x66, 0xEE, /* Max_Gamma_14 */ +0x67, 0xF7, /* Max_Gamma_15 */ +0x68, 0xFF, /* Max_Gamma_16 */ + +/* Initial edge, noise filter setting*/ +0xFF, 0xA0, /*Page mode */ +0xC0, 0x12, /*NSFTh1_Addr*/ +0xC1, 0x30, /*NSFTh2_Addr*/ +0xC2, 0x08, /*NSFTh3_Addr*/ +0xFF, 0xA1, /*Page mode */ +0x30, 0x01, /*EDEOption_Addr*/ +0x31, 0x33, /*EDESlopeGain_Addr*/ +0x32, 0x50, /*EDELuAdpCtrl_Addr*/ +0x33, 0x00, /*EDEPreCoringPt_Addr*/ +0x34, 0x00, /*EDETransFuncXp1_Addr1*/ +0x35, 0x0B, /*EDETransFuncXp1_Addr0*/ +0x36, 0x01, /*EDETransFuncXp2_Addr1*/ +0x37, 0x80, /*EDETransFuncXp2_Addr0*/ +0x38, 0x09, /*EDETransFuncSl1_Addr*/ +0x39, 0x22, /*EDETransFuncSl2_Addr*/ +0x3A, 0x00, /*EDELuAdpLOffset_Addr*/ +0x3B, 0x30, /*EDELuAdpROffset_Addr*/ +0x3C, 0x08, /*EDERBThrd_Addr*/ +0x3D, 0x02, /*EDESmallOffset_Addr*/ + + +/* CCM Saturation Level*/ +0xFF, 0x85, /*Page mode */ +0x1A, 0x64, /* SUP Threshold */ +0x30, 0x40, /* MinSUP */ + +0xFF, 0xA0, /*Page mode */ +/* Lens Shading*/ +0x43, 0x80, /* RH7 rrhrhh*/ +0x44, 0x80, /* RV*/ +0x45, 0x80, /* RH */ +0x46, 0x80, /* RV*/ +0x47, 0x80, /* GH*/ +0x48, 0x80, /* GV*/ +0x49, 0x80, /* GH*/ +0x4A, 0x80, /* GV */ +0x4B, 0x80, /* BH*/ +0x4C, 0x80, /* BV*/ +0x4D, 0x80, /* BH*/ +0x4E, 0x80, /* BV */ +0x52, 0x90, /* GGain*/ +0x53, 0x20, /* GGain*/ +0x54, 0x00, /* GGain*/ + +/*Max Shading*/ +0xFF, 0x85, /*Page mode */ +0x32, 0xC0, +0x33, 0x30, +0x34, 0x00, +0x35, 0x90, +0x36, 0x20, +0x37, 0x00, + +/*Min Shading*/ +0x1c, 0xC0, +0x1d, 0x30, +0x1e, 0x00, +0x1f, 0x90, +0x20, 0x18, +0x21, 0x00, + +/* LineLength */ +0xFF, 0x87, /*Page mode */ +0xDC, 0x05, /* by Yong In Han 091511*/ +0xDD, 0xB0, /* by Yong In Han 091511*/ +0xd5, 0x00, /* Flip*/ +/***************************************************/ +/* SensorCon */ +/***************************************************/ +0xFF, 0xD0, /*Page mode */ +0x20, 0x0E, /* ABLK_Rsrv_Addr*/ +0x20, 0x0D, /* ABLK_Rsrv_Addr*/ + +/***************************************************/ +/* MIPI */ +/***************************************************/ +0xFF, 0xB0, /*Page mode */ +0x54, 0x02, /* MIPI PHY_HS_TX_CTRL*/ +0x38, 0x05, /* MIPI DPHY_CTRL_SET*/ + + +/* SXGA PR*/ +0xFF, 0x85, /*Page mode */ +0xB8, 0x0A, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr0*/ +0xB9, 0x00, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr1*/ +0xBC, 0x04, /* gPT_u8PR_Active_SXGA_DPHY_CLK_TIME_Addr3*/ +0xFF, 0x87, /*Page mode */ +0x0C, 0x00, /* start Y*/ +0x0D, 0x20, /* start Y */ +0x10, 0x03, /* end Y*/ +0x11, 0xE0, /* end Y */ + +/* Recoding */ +0xFF, 0x86, /*Page mode */ +0x38, 0x05, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr0*/ +0x39, 0x00, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr1*/ +0x3C, 0x04, /* gPT_u8PR_Active_720P_DPHY_CLK_TIME_Addr3*/ + +0xFF, 0x87, +0x23, 0x02, /*gPR_Active_720P_u8SensorCtrl_Addr */ +0x25, 0x01, /*gPR_Active_720P_u8PLL_P_Addr */ +0x26, 0x0F, /*gPR_Active_720P_u8PLL_M_Addr */ +0x27, 0x00, /*gPR_Active_720P_u8PLL_S_Addr */ +0x28, 0x00, /*gPR_Active_720P_u8PLL_Ctrl_Addr */ +0x29, 0x01, /*gPR_Active_720P_u8src_clk_sel_Addr */ +0x2A, 0x00, /*gPR_Active_720P_u8output_pad_status_Addr */ +0x2B, 0x3F, /*gPR_Active_720P_u8ablk_ctrl_10_Addr */ +0x2C, 0xFF, /*gPR_Active_720P_u8BayerFunc_Addr */ +0x2D, 0xFF, /*gPR_Active_720P_u8RgbYcFunc_Addr */ +0x2E, 0x00, /*gPR_Active_720P_u8ISPMode_Addr */ +0x2F, 0x02, /*gPR_Active_720P_u8SCLCtrl_Addr */ +0x30, 0x01, /*gPR_Active_720P_u8SCLHorScale_Addr0 */ +0x31, 0xFF, /*gPR_Active_720P_u8SCLHorScale_Addr1 */ +0x32, 0x03, /*gPR_Active_720P_u8SCLVerScale_Addr0 */ +0x33, 0xFF, /*gPR_Active_720P_u8SCLVerScale_Addr1 */ +0x34, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr0 */ +0x35, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr1 */ +0x36, 0x00, /*gPR_Active_720P_u8SCLCropStartY_Addr0 */ +0x37, 0x10, /*gPR_Active_720P_u8SCLCropStartY_Addr1 */ +0x38, 0x02, /*gPR_Active_720P_u8SCLCropEndX_Addr0 */ +0x39, 0x80, /*gPR_Active_720P_u8SCLCropEndX_Addr1 */ +0x3A, 0x01, /*gPR_Active_720P_u8SCLCropEndY_Addr0 */ +0x3B, 0xF0, /*gPR_Active_720P_u8SCLCropEndY_Addr1 */ +0x3C, 0x01, /*gPR_Active_720P_u8OutForm_Addr */ +0x3D, 0x0C, /*gPR_Active_720P_u8OutCtrl_Addr */ +0x3E, 0x04, /*gPR_Active_720P_u8AEWinStartX_Addr */ +0x3F, 0x04, /*gPR_Active_720P_u8AEWinStartY_Addr */ +0x40, 0x66, /*gPR_Active_720P_u8MergedWinWidth_Addr */ +0x41, 0x5E, /*gPR_Active_720P_u8MergedWinHeight_Addr */ +0x42, 0x04, /*gPR_Active_720P_u8AEHistWinAx_Addr */ +0x43, 0x04, /*gPR_Active_720P_u8AEHistWinAy_Addr */ +0x44, 0x98, /*gPR_Active_720P_u8AEHistWinBx_Addr */ +0x45, 0x78, /*gPR_Active_720P_u8AEHistWinBy_Addr */ +0x46, 0x22, /*gPR_Active_720P_u8AWBTrim_Addr */ +0x47, 0x28, /*gPR_Active_720P_u8AWBCTWinAx_Addr */ +0x48, 0x20, /*gPR_Active_720P_u8AWBCTWinAy_Addr */ +0x49, 0x78, /*gPR_Active_720P_u8AWBCTWinBx_Addr */ +0x4A, 0x60, /*gPR_Active_720P_u8AWBCTWinBy_Addr */ +0x4B, 0x03, /*gPR_Active_720P_u16AFCFrameLength_0 */ +0x4C, 0x00, /*gPR_Active_720P_u16AFCFrameLength_1 */ + +/* VGA PR */ +0xFF, 0x86, /*Page mode */ +0x2F, 0x05, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr0*/ +0x30, 0x00, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr1*/ +0x33, 0x04, /* gPT_u8PR_Active_VGA_DPHY_CLK_TIME_Addr3*/ + +0xFF, 0x87, /*Page mode */ +0x4D, 0x00, /*gPR_Active_VGA_u8SensorCtrl_Addr*/ +0x4E, 0x72, /*gPR_Active_VGA_u8SensorMode_Addr*/ +0x4F, 0x01, /*gPR_Active_VGA_u8PLL_P_Addr*/ +0x50, 0x0F, /*gPR_Active_VGA_u8PLL_M_Addr*/ +0x51, 0x00, /*gPR_Active_VGA_u8PLL_S_Addr*/ +0x52, 0x00, /*gPR_Active_VGA_u8PLL_Ctrl_Addr*/ +0x53, 0x01, /*gPR_Active_VGA_u8src_clk_sel_Addr*/ +0x54, 0x00, /*gPR_Active_VGA_u8output_pad_status_Addr*/ +0x55, 0x3F, /*gPR_Active_VGA_u8ablk_ctrl_10_Addr*/ +0x56, 0xFF, /*gPR_Active_VGA_u8BayerFunc_Addr*/ +0x57, 0xFF, /*gPR_Active_VGA_u8RgbYcFunc_Addr*/ +0x58, 0x00, /*gPR_Active_VGA_u8ISPMode_Addr*/ +0x59, 0x02, /*gPR_Active_VGA_u8SCLCtrl_Addr*/ +0x5A, 0x01, /*gPR_Active_VGA_u8SCLHorScale_Addr0*/ +0x5B, 0xFF, /*gPR_Active_VGA_u8SCLHorScale_Addr1*/ +0x5C, 0x01, /*gPR_Active_VGA_u8SCLVerScale_Addr0*/ +0x5D, 0xFF, /*gPR_Active_VGA_u8SCLVerScale_Addr1*/ +0x5E, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr0*/ +0x5F, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr1*/ +0x60, 0x00, /*gPR_Active_VGA_u8SCLCropStartY_Addr0*/ +0x61, 0x20, /*gPR_Active_VGA_u8SCLCropStartY_Addr1*/ +0x62, 0x05, /*gPR_Active_VGA_u8SCLCropEndX_Addr0*/ +0x63, 0x00, /*gPR_Active_VGA_u8SCLCropEndX_Addr1*/ +0x64, 0x03, /*gPR_Active_VGA_u8SCLCropEndY_Addr0*/ +0x65, 0xE0, /*gPR_Active_VGA_u8SCLCropEndY_Addr1*/ + +0xFF, 0xd1, /*Page mode */ +0x07, 0x00, /* power off mask clear*/ +0x0b, 0x00, /* clock off mask clear*/ +0xFF, 0xC0, /*Page mode */ +0x10, 0x41, + +/* Self-Cam END of Initial */ +}; + +/* Set-data based on SKT VT standard ,when using 3G network*/ +/* VGA 8fps +*/ +static const u8 db8131m_vt_common_1[] = { +/***************************************************/ +/* Device : DB8131M fixed 8Fps */ +/* MIPI Interface for Noncontious Clock */ +/***************************************************/ +/***************************************************/ +/* Command */ +/***************************************************/ +0xFF, 0xC0, /*Page mode*/ +0x10, 0x01, +}; +/*wait 150*/ + +static const u8 db8131m_vt_common_2[] = { +/***************************************************/ +/* Format */ +/***************************************************/ +0xFF, 0xA1, /*Page mode */ +0x70, 0x01, +0x71, 0x0D, + +/***************************************************/ +/* SensorCon */ +/***************************************************/ +0xFF, 0xD0, /*Page mode */ +0x0F, 0x0B, /*ABLK_Ctrl_1_Addr*/ +0x13, 0x00, /*Gain_Addr*/ +0x15, 0x01, /*IVREFT_REFB_Addr*/ +0x20, 0x0E, /*ABLK_Rsrv_Addr*/ +0x23, 0x01, /*IVREFT2_REFB2_Addr*/ +0x24, 0x01, /*IPPG_IVCM2_Addr*/ +0x39, 0x70, /*RiseSx_CDS_1_L_Addr*/ +0x51, 0x19, /*Fallcreset_1_L_Addr*/ +0x83, 0x2D, /*RiseTran_Sig_Even_L_Addr*/ +0x85, 0x2F, /*FallTran_Sig_Even_L_Addr*/ +0x87, 0x2D, /*RiseTran_Sig_Odd_L_Addr*/ +0x89, 0x2F, /*FallTran_Sig_Odd_L_Addr*/ +0x8B, 0x27, /*RiseCNT_EN_1_L_Addr*/ +0x8D, 0x6c, /*FallCNT_EN_1_L_Addr*/ +0xD7, 0x80, /*ABLK_Ctrl_12_Addr*/ +0xDB, 0xA2, /*FallScanTx15_1_L_Addr*/ +0xED, 0x01, /*PLL_P_Addr*/ +0xEE, 0x0F, /*PLL_M_Addr*/ +0xEF, 0x00, /*PLL_S_Addr*/ +0xF9, 0x00, /*ABLK_Ctrl_8*/ +0xF8, 0x00, /*Vblank Sleep Mode enable*/ +0xFB, 0x90, /*PostADC_Gain_Addr*/ + +/***************************************************/ +/* Analog ADF */ +/***************************************************/ +0xFF, 0x85, /*Page mode */ +0x89, 0x93, /*gAdf_u8APThreshold*/ +0x8A, 0x0C, /*u8APClmpThreshold*/ +0x8C, 0x07, /*gAdf_u8APMinVal_ThrClampH*/ +0x8D, 0x40, /*gAdf_u8APMinVal_ThrClampL*/ +0x8E, 0x03, /*gAdf_u8APMinVal_DOFFSET*/ +0x8F, 0x14, /*gAdf_u8APMinVal_AMP2_1_SDM*/ +0x91, 0x1A, /*gAdf_u8APMinVal_AMP4_3_SDM*/ +0x92, 0x0F, /*gAdf_u8APMinVal_FallIntTx15*/ +0x93, 0x47, /*gAdf_u8APMinVal_CDSxRange_CtrlPre*/ +0x95, 0x18, /*gAdf_u8APMinVal_REFB_IVCM*/ +0x96, 0x38, /*gAdf_u8APMinVal_ref_os_PB*/ +0x97, 0x0D, /*gAdf_u8APMinVal_NTx_Range*/ +0x98, 0x0D, /*gAdf_u8APMaxVal_Clmp_rst*/ +0x99, 0x06, /*gAdf_u8APMaxVal_ThrClampH*/ +0x9A, 0x9F, /*gAdf_u8APMaxVal_ThrClampL*/ +0x9B, 0x02, /*gAdf_u8APMaxVal_DOFFSET*/ +0x9C, 0x1C, /*gAdf_u8APMaxVal_AMP2_1_SDM*/ +0x9E, 0x11, /*gAdf_u8APMaxVal_AMP4_3_SDM*/ +0x9F, 0x5D, /*gAdf_u8APMaxVal_FallIntTx15*/ +0xA0, 0x78, /*gAdf_u8APMaxVal_CDSxRange_CtrlPre*/ +0xA2, 0x18, /*gAdf_u8APMaxVal_REFB_IVCM*/ +0xA3, 0x40, /*gAdf_u8APMaxVal_ref_os_PB*/ +0xA4, 0x0B, /*gAdf_u8APMaxVal_NTx_Range*/ + +0xFF, 0x86, /*Page mode */ +0x15, 0x00, /*gPT_u8Adf_APThrHys*/ +0x16, 0xF7, /*gPT_u8Adf_APFallIntTxThrLevel*/ +0x17, 0x13, /*gPT_u8Adf_APMinVal_BP2_1_SDM*/ +0x18, 0x13, /*gPT_u8Adf_APMidVal_BP2_1_SDM*/ +0x19, 0x1C, /*gPT_u8Adf_APMaxVal_BP2_1_SDM*/ +0x1A, 0x06, /*gPT_u8Adf_APMidVal_ThrClampH*/ +0x1B, 0xF0, /*gPT_u8Adf_APMidVal_ThrClampL*/ +0x1C, 0x01, /*gPT_u8Adf_APMidVal_DOFFSET*/ +0x1D, 0x14, /*gPT_u8Adf_APMidVal_AMP2_1_SDM*/ +0x1F, 0x31, /*gPT_u8Adf_APMidVal_AMP4_3_SDM*/ +0x20, 0x68, /*gPT_u8Adf_APMidVal_CDSxRange_CtrlPre*/ +0x22, 0x18, /*gPT_u8Adf_APMidVal_REFB_IVCM*/ +0x23, 0x38, /*gPT_u8Adf_APMidVal_ref_os_PB*/ +0x24, 0x0F, /*gPT_u8Adf_APMidVal_NTx_Range*/ +0x25, 0x77, /*gPT_u8Adf_APVal_EnSiSoSht_EnSm*/ + +0xFF, 0x87, /*Page mode */ +0xEA, 0x41, + +0xFF, 0xD0, /*Page mode */ +0x20, 0x0D, /*ABLK_Rsrv_Addr*/ + +0xFF, 0x83, /*Page mode */ +0x63, 0x28, /*Again Table*/ +0x64, 0x10, /*Again Table*/ +0x65, 0xA8, /*Again Table*/ +0x66, 0x50, /*Again Table*/ +0x67, 0x28, /*Again Table*/ +0x68, 0x14, /*Again Table*/ + + +/***************************************************/ +/* AE */ +/***************************************************/ +0xFF, 0x82, /*Page mode */ +0x91, 0x02, /* AeMode*/ +0x95, 0x88, /* AE weight*/ +0x96, 0x88, +0x97, 0xF8, +0x98, 0x8F, +0x99, 0xF8, +0x9A, 0x8F, +0x9B, 0x88, +0x9C, 0x88, +0xA9, 0x40, /* OTarget*/ +0xAA, 0x40, /* ITarget*/ +0x9D, 0x66, /* AE Speed*/ +0x9F, 0x06, /* AE HoldBnd*/ +0xA8, 0x40, /* STarget*/ +0xB9, 0x04, /* RGain*/ +0xBB, 0x04, /* GGain*/ +0xBD, 0x04, /* BGain*/ +0xC5, 0x02, /* PeakMvStep*/ +0xC6, 0x38, /* PeakTgMin*/ +0xC7, 0x24, /* PeakRatioTh1*/ +0xC8, 0x10, /* PeakRatioTh0*/ +0xC9, 0x05, /* PeakLuTh*/ +0xD5, 0x60, /* LuxGainTB_2*/ +0xFF, 0x83, /*Page mode */ +0x2F, 0x04, /* TimeNum0*/ +0x30, 0x05, /* TimeNum1*/ +0x4F, 0x05, /* FrameOffset*/ +0xFF, 0x82, /*Page mode */ +0xA1, 0x0A, /* AnalogGainMax*/ +0xF3, 0x09, /* SCLK*/ +0xF4, 0x60, +0xF9, 0x00, /* GainMax*/ +0xFA, 0xC8, /* GainMax*/ +0xFB, 0x62, /* Gain3Lut*/ +0xFC, 0x39, /* Gain2Lut*/ +0xFD, 0x28, /* Gain1Lut*/ +0xFE, 0x12, /* GainMin*/ +0xFF, 0x83, /*Page mode */ +0x03, 0x0F, /* TimeMax60Hz : 8fps*/ +0x04, 0x0A, /* Time3Lux60Hz : 12fps*/ +0x05, 0x04, /* Time2Lut60Hz : 24fps*/ +0x06, 0x04, /* Time1Lut60Hz : 24fps*/ +0xFF, 0x82, /*Page mode */ +0xD3, 0x12, /* LuxTBGainStep0 */ +0xD4, 0x36, /* LuxTBGainStep1 */ +0xD5, 0x60, /* LuxTBGainStep2*/ +0xD6, 0x01, /* LuxTBTimeStep0H*/ +0xD7, 0x00, /* LuxTBTimeStep0L*/ +0xD8, 0x01, /* LuxTBTimeStep1H*/ +0xD9, 0xC0, /* LuxTBTimeStep1L*/ +0xDA, 0x06, /* LuxTBTimeStep2H*/ +0xDB, 0x00, /* LuxTBTimeStep2L*/ +0xFF, 0x83, /*Page mode */ +0x0B, 0x08, +0x0C, 0x0C, /* Frame Rate*/ +0xFF, 0x82, /*Page mode */ +0x92, 0x5D, + +/***************************************************/ +/* AWB */ +/***************************************************/ +0xFF, 0x83, /*Page mode */ +0x79, 0x83, /* AWB SKIN ON*/ +0x86, 0x07, /* gAWB_u16MinGrayCnt_rw_0*/ +0x87, 0x00, /* gAWB_u16MinGrayCnt_rw_1*/ +0x90, 0x05, /* gAWB_u16FinalRGain_ro_0*/ +0x94, 0x05, /* gAWB_u16FinalBGain_ro_0*/ +0x98, 0xD4, /* SkinWinCntTh*/ +0xA2, 0x28, /* SkinYTh*/ +0xA3, 0x00, /* SkinHoldHitCnt*/ +0xA4, 0x0F, /* SkinHoldHitCnt*/ +0xAD, 0x65, /* u8SkinTop2*/ +0xAE, 0x80, /* gAwb_u8SkinTop2LS1Ratio_rw 5zone */ +0xAF, 0x20, /* gAwb_u8SkinTop2LS2Ratio_rw 6zone */ +0xB4, 0x10, /* u8SkinTop2LSHys_rw */ +0xB5, 0x54, /* gAwb_u8SkinLTx */ +0xB6, 0xbd, /* gAwb_u8SkinLTy */ +0xB7, 0x74, /* gAwb_u8SkinRBx */ +0xB8, 0x9d, /* gAwb_u8SkinRBy */ +0xBA, 0x4F, /* UniCThrY_rw */ +0xBF, 0x0C, /* u16UniCGrayCntThr_rw_0 */ +0xC0, 0x80, /* u16UniCGrayCntThr_rw_1 */ +0xFF, 0x87, /*Page mode */ +0xC9, 0x22, /* gUR_u8AWBTrim_Addr */ +0xFF, 0x84, /*Page mode */ +0x49, 0x02, /* Threshold_indoor */ +0x4A, 0x00, +0x4B, 0x03, /* Threshold_outdoor */ +0x4C, 0x80, +0xFF, 0x83, /*Page mode */ +0xCB, 0x03, /* R MinGain [Default 0X20] A Spec Pass */ +0xCC, 0xC0, /* R MinGain [Default 0X20] A Spec Pass */ +0x82, 0x00, /* lockratio*/ +0xFF, 0x84, /*Page mode */ +0x3D, 0x00, /* gAwb_u32LuxConst1_rw_0*/ +0x3E, 0x00, /* gAwb_u32LuxConst1_rw_1*/ +0x3F, 0x06, /* gAwb_u32LuxConst1_rw_2*/ +0x40, 0x20, /* gAwb_u32LuxConst1_rw_3*/ +0x41, 0x07, /* gAwb_u32LuxConst2_rw_0*/ +0x42, 0x53, /* gAwb_u32LuxConst2_rw_1*/ +0x43, 0x00, /* gAwb_u32LuxConst2_rw_2*/ +0x44, 0x00, /* gAwb_u32LuxConst2_rw_3*/ +0x55, 0x03, /* gAwb_u8Weight_Gen_rw_0 */ +0x56, 0x10, /* gAwb_u8Weight_Gen_rw_1 */ +0x57, 0x14, /* gAwb_u8Weight_Gen_rw_2 */ +0x58, 0x07, /* gAwb_u8Weight_Gen_rw_3 */ +0x59, 0x04, /* gAwb_u8Weight_Gen_rw_4 */ +0x5A, 0x03, /* gAwb_u8Weight_Gen_rw_5 */ +0x5B, 0x03, /* gAwb_u8Weight_Gen_rw_6 */ +0x5C, 0x15, /* gAwb_u8Weight_Gen_rw_7 */ +0x5D, 0x01, /* gAwb_u8Weight_Ind_rw_0 */ +0x5E, 0x0F, /* gAwb_u8Weight_Ind_rw_1 */ +0x5F, 0x07, /* gAwb_u8Weight_Ind_rw_2 */ +0x60, 0x14, /* gAwb_u8Weight_Ind_rw_3 */ +0x61, 0x14, /* gAwb_u8Weight_Ind_rw_4 */ +0x62, 0x12, /* gAwb_u8Weight_Ind_rw_5 */ +0x63, 0x11, /* gAwb_u8Weight_Ind_rw_6 */ +0x64, 0x14, /* gAwb_u8Weight_Ind_rw_7 */ +0x65, 0x03, /* gAwb_u8Weight_Outd_rw_0*/ +0x66, 0x05, /* gAwb_u8Weight_Outd_rw_1*/ +0x67, 0x15, /* gAwb_u8Weight_Outd_rw_2*/ +0x68, 0x04, /* gAwb_u8Weight_Outd_rw_3*/ +0x69, 0x01, /* gAwb_u8Weight_Outd_rw_4*/ +0x6A, 0x02, /* gAwb_u8Weight_Outd_rw_5*/ +0x6B, 0x03, /* gAwb_u8Weight_Outd_rw_6*/ +0x6C, 0x15, /* gAwb_u8Weight_Outd_rw_6*/ +0xFF, 0x85, /*Page mode */ +0xE2, 0x0C, /* gPT_u8Awb_UnicolorZone_rw */ +0xFF, 0x83, /*Page mode */ +0xCD, 0x06, /*Max Rgain*/ +0xCE, 0x80, +0xD1, 0x06, /*Max BGain*/ +0xd2, 0x80, + +/***************************************************/ +/* AWB STE */ +/***************************************************/ +0xFF, 0xA1, /*Page mode */ +/* Flash */ +0xA0, 0x5c, /*AWBZone0LTx*/ +0xA1, 0x7a, /*AWBZone0LTy*/ +0xA2, 0x69, /*AWBZone0RBx*/ +0xA3, 0x6f, /*AWBZone0RBy*/ +/* cloudy */ +0xA4, 0x73, /*AWBZone1LTx*/ +0xA5, 0x55, /*AWBZone1LTy*/ +0xA6, 0x8C, /*AWBZone1RBx*/ +0xA7, 0x30, /*AWBZone1RBy */ +/* Daylight */ +0xA8, 0x69, /*AWBZone2LTx*/ +0xA9, 0x69, /*AWBZone2LTy*/ +0xAA, 0x83, /*AWBZone2RBx*/ +0xAB, 0x52, /*AWBZone2RBy */ +/* Fluorescent */ +0xAC, 0x57, /*AWBZone3LTx*/ +0xAD, 0x6e, /*AWBZone3LTy*/ +0xAE, 0x6f, /*AWBZone3RBx*/ +0xAF, 0x59, /*AWBZone3RBy*/ + +/*CWF */ +0xB0, 0x50, /*AWBZone4LTx*/ +0xB1, 0x74, /*AWBZone4LTy*/ +0xB2, 0x65, /*AWBZone4RBx*/ +0xB3, 0x5d, /*AWBZone4RBy*/ +/*TL84 */ +0xB4, 0x53, /*AWBZone5LTx*/ +0xB5, 0x7f, /*AWBZone5LTy*/ +0xB6, 0x62, /*AWBZone5RBx*/ +0xB7, 0x75, /*AWBZone5RBy */ +/*A */ +0xB8, 0x4a, /*AWBZone6LTx*/ +0xB9, 0x87, /*AWBZone6LTy*/ +0xBA, 0x59, /*AWBZone6RBx*/ +0xBB, 0x78, /*AWBZone6RBy*/ +/*Horizon */ +0xBC, 0x41, /*AWBZone7LTx*/ +0xBD, 0x91, /*AWBZone7LTy*/ +0xBE, 0x4b, /*AWBZone7RBx*/ +0xBF, 0x89, /*AWBZone7RBy*/ +/*Skin */ +0xC0, 0x5b, /*AWBZone8LTx*/ +0xC1, 0x85, /*AWBZone8LTy*/ +0xC2, 0x60, /*AWBZone8RBx*/ +0xC3, 0x7b, /*AWBZone8RBy*/ + +/***************************************************/ +/* UR */ +/***************************************************/ +0xFF, 0x85, /*Page mode */ +0x06, 0x05, +0xFF, 0x86, /*Page mode */ +0x14, 0x1E, /* CCM sum 1*/ +0xFF, 0x85, /*Page mode */ +0x86, 0x42, /* 42 saturation level*/ +0x07, 0x00, /* sup hysteresis*/ + +/*DAY light */ +0xFF, 0x83, /*Page mode */ +0xEA, 0x00, /*gAwb_s16AdapCCMTbl_0*/ +0xEB, 0x53, /*gAwb_s16AdapCCMTbl_1*/ +0xEC, 0xFF, /*gAwb_s16AdapCCMTbl_2*/ +0xED, 0xE1, /*gAwb_s16AdapCCMTbl_3*/ +0xEE, 0x00, /*gAwb_s16AdapCCMTbl_4*/ +0xEF, 0x05, /*gAwb_s16AdapCCMTbl_5*/ +0xF0, 0xFF, /*gAwb_s16AdapCCMTbl_6*/ +0xF1, 0xF3, /*gAwb_s16AdapCCMTbl_7*/ +0xF2, 0x00, /*gAwb_s16AdapCCMTbl_8*/ +0xF3, 0x4B, /*gAwb_s16AdapCCMTbl_9*/ +0xF4, 0xFF, /*gAwb_s16AdapCCMTbl_10*/ +0xF5, 0xFA, /*gAwb_s16AdapCCMTbl_11*/ +0xF6, 0xFF, /*gAwb_s16AdapCCMTbl_12*/ +0xF7, 0xFa, /*gAwb_s16AdapCCMTbl_13*/ +0xF8, 0xFF, /*gAwb_s16AdapCCMTbl_14*/ +0xF9, 0xC3, /*gAwb_s16AdapCCMTbl_15*/ +0xFA, 0x00, /*gAwb_s16AdapCCMTbl_16*/ +0xFB, 0x80, /*gAwb_s16AdapCCMTbl_17*/ + +/*CWF lgiht */ +0xFF, 0x83, /*Page mode */ +0xFC, 0x00, /* gAwb_s16AdapCCMTbl_18 */ +0xFD, 0x68, /* gAwb_s16AdapCCMTbl_19 */ +0xFF, 0x85, /*Page mode */ +0xE0, 0xFF, /* gAwb_s16AdapCCMTbl_20 */ +0xE1, 0xde, /* gAwb_s16AdapCCMTbl_21 */ +0xFF, 0x84, /*Page mode */ +0x00, 0xff, /* gAwb_s16AdapCCMTbl_22 */ +0x01, 0xfa, /* gAwb_s16AdapCCMTbl_23 */ +0x02, 0xFF, /* gAwb_s16AdapCCMTbl_24 */ +0x03, 0xf0, /* gAwb_s16AdapCCMTbl_25 */ +0x04, 0x00, /* gAwb_s16AdapCCMTbl_26 */ +0x05, 0x52, /* gAwb_s16AdapCCMTbl_27 */ +0x06, 0xFF, /* gAwb_s16AdapCCMTbl_28 */ +0x07, 0xFa, /* gAwb_s16AdapCCMTbl_29 */ +0x08, 0x00, /* gAwb_s16AdapCCMTbl_30 */ +0x09, 0x00, /* gAwb_s16AdapCCMTbl_31 */ +0x0A, 0xFF, /* gAwb_s16AdapCCMTbl_32 */ +0x0B, 0xdb, /* gAwb_s16AdapCCMTbl_33 */ +0x0C, 0x00, /* gAwb_s16AdapCCMTbl_34 */ +0x0D, 0x68, /* gAwb_s16AdapCCMTbl_35 */ + +/*A light */ + +0x0E, 0x00, /* gAwb_s16AdapCCMTbl_36 */ +0x0F, 0x6d, /* gAwb_s16AdapCCMTbl_37 */ +0x10, 0xFF, /* gAwb_s16AdapCCMTbl_38 */ +0x11, 0xd5, /* gAwb_s16AdapCCMTbl_39 */ +0x12, 0xff, /* gAwb_s16AdapCCMTbl_40 */ +0x13, 0xfe, /* gAwb_s16AdapCCMTbl_41 */ +0x14, 0xFF, /* gAwb_s16AdapCCMTbl_42 */ +0x15, 0xf4, /* gAwb_s16AdapCCMTbl_43 */ +0x16, 0x00, /* gAwb_s16AdapCCMTbl_44 */ +0x17, 0x5a, /* gAwb_s16AdapCCMTbl_45 */ +0x18, 0xff, /* gAwb_s16AdapCCMTbl_46 */ +0x19, 0xef, /* gAwb_s16AdapCCMTbl_47 */ +0x1A, 0xff, /* gAwb_s16AdapCCMTbl_48 */ +0x1B, 0xfa, /* gAwb_s16AdapCCMTbl_49 */ +0x1C, 0xFF, /* gAwb_s16AdapCCMTbl_50 */ +0x1D, 0xbe, /* gAwb_s16AdapCCMTbl_51 */ +0x1E, 0x00, /* gAwb_s16AdapCCMTbl_52 */ +0x1F, 0x86, /* gAwb_s16AdapCCMTbl_53 */ + + +/***************************************************/ +/* ADF */ +/***************************************************/ + +/* ISP setting*/ +0xFF, 0xA0, /*Page mode */ +0x10, 0x80, /* BLC: ABLC db*/ +0x60, 0x73, /* CDC: Dark CDC ON */ +0x61, 0x1F, /* Six CDC_Edge En, Slash EN*/ +0x69, 0x0C, /* Slash direction Line threshold*/ +0x6A, 0x60, /* Slash direction Pixel threshold*/ +0xC2, 0x04, /* NSF: directional smoothing*/ +0xD0, 0x51, /* DEM: pattern detection*/ +0xFF, 0xA1, /*Page mode */ +0x30, 0x01, /* EDE: Luminane adaptation on*/ +0x32, 0x50, /* EDE: Adaptation slope */ +0x34, 0x00, /* EDE: x1 point */ +0x35, 0x0B, /* EDE: x1 point */ +0x36, 0x01, /* EDE: x2 point */ +0x37, 0x80, /* EDE: x2 point */ +0x3A, 0x00, /* EDE: Adaptation left margin*/ +0x3B, 0x30, /* EDE: Adaptation right margin*/ +0x3C, 0x08, /* EDE: rgb edge threshol*/ + +/* Adaptive Setting*/ +0xFF, 0x85, /*Page mode */ +/* LSC*/ +0x0F, 0x43, /* LVLSC lux level threshold*/ +0x10, 0x43, /* LSLSC Light source , threshold lux*/ + +/* BGT*/ +0x17, 0x30, /* BGT lux level threshold*/ +0x26, 0x20, /* MinVal */ +0x3c, 0x00, /* MaxVal */ + +/* CNT*/ +0x18, 0x43, /* CNT lux level threshold*/ +0x27, 0x00, /* MinVal */ +0x3d, 0x00, /* MaxVal */ + +/* NSF */ +0x12, 0xA5, /* NSF lux level threshold */ +0x22, 0x38, /* u8MinVal_NSF1*/ +0x23, 0x70, /* u8MinVal_NSF2*/ +0xFF, 0x86, /*Page mode */ +0x12, 0x00, /* u8MinVal_NSF3*/ +0xFF, 0x85, /*Page mode */ +0x38, 0x12, /* u8MaxVal_NSF1*/ +0x39, 0x30, /* u8MaxVal_NSF2*/ +0xFF, 0x86, /*Page mode */ +0x13, 0x08, /* u8MaxVal_NSF3*/ + +/* GDC*/ +0xFF, 0x85, /*Page mode */ +0x15, 0xF4, /* GDC lux level threshold */ +0x2D, 0x20, /* u8MinVal_GDC1*/ +0x2E, 0x30, /* u8MinVal_GDC2*/ +0x43, 0x40, /* u8MaxVal_GDC1*/ +0x44, 0x80, /* u8MaxVal_GDC2*/ + +/* ISP Edge*/ +0x04, 0xFB, /* EnEDE*/ +0x14, 0x54, /* u8ThrLevel_EDE*/ +0x28, 0x00, /* u8MinVal_EDE_CP*/ +0x29, 0x03, /* u8MinVal_EDE1*/ +0x2A, 0x20, /* u8MinVal_EDE2*/ +0x2B, 0x00, /* u8MinVal_EDE_OFS*/ +0x2C, 0x22, /* u8MinVal_SG*/ +0x3E, 0x00, /* u8MaxVal_EDE_CP*/ +0x3F, 0x09, /* u8MaxVal_EDE1*/ +0x40, 0x22, /* u8MaxVal_EDE2*/ +0x41, 0x02, /* u8MaxVal_EDE_OFS*/ +0x42, 0x33, /* u8MaxVal_SG*/ + +/* Gamma Adaptive*/ + +0x16, 0xA0, /* Gamma Threshold*/ +0x47, 0x00, /* Min_Gamma_0*/ +0x48, 0x03, /* Min_Gamma_1*/ +0x49, 0x10, /* Min_Gamma_2*/ +0x4A, 0x25, /* Min_Gamma_3*/ +0x4B, 0x3B, /* Min_Gamma_4*/ +0x4C, 0x4F, /* Min_Gamma_5*/ +0x4D, 0x6D, /* Min_Gamma_6*/ +0x4E, 0x86, /* Min_Gamma_7*/ +0x4F, 0x9B, /* Min_Gamma_8*/ +0x50, 0xAD, /* Min_Gamma_9*/ +0x51, 0xC2, /* Min_Gamma_10*/ +0x52, 0xD3, /* Min_Gamma_11*/ +0x53, 0xE1, /* Min_Gamma_12*/ +0x54, 0xE9, /* Min_Gamma_13*/ +0x55, 0xF2, /* Min_Gamma_14*/ +0x56, 0xFA, /* Min_Gamma_15*/ +0x57, 0xFF, /* Min_Gamma_16*/ +0x58, 0x00, /* Max_Gamma_0 */ +0x59, 0x06, /* Max_Gamma_1 */ +0x5a, 0x14, /* Max_Gamma_2 */ +0x5b, 0x30, /* Max_Gamma_3 */ +0x5c, 0x4A, /* Max_Gamma_4 */ +0x5d, 0x5D, /* Max_Gamma_5 */ +0x5e, 0x75, /* Max_Gamma_6 */ +0x5f, 0x89, /* Max_Gamma_7 */ +0x60, 0x9A, /* Max_Gamma_8 */ +0x61, 0xA7, /* Max_Gamma_9 */ +0x62, 0xBC, /* Max_Gamma_10 */ +0x63, 0xD0, /* Max_Gamma_11 */ +0x64, 0xE0, /* Max_Gamma_12 */ +0x65, 0xE7, /* Max_Gamma_13 */ +0x66, 0xEE, /* Max_Gamma_14 */ +0x67, 0xF7, /* Max_Gamma_15 */ +0x68, 0xFF, /* Max_Gamma_16 */ + +/* Initial edge, noise filter setting*/ +0xFF, 0xA0, /*Page mode */ +0xC0, 0x12, /*NSFTh1_Addr*/ +0xC1, 0x30, /*NSFTh2_Addr*/ +0xC2, 0x08, /*NSFTh3_Addr*/ +0xFF, 0xA1, /*Page mode */ +0x30, 0x01, /*EDEOption_Addr*/ +0x31, 0x33, /*EDESlopeGain_Addr*/ +0x32, 0x50, /*EDELuAdpCtrl_Addr*/ +0x33, 0x00, /*EDEPreCoringPt_Addr*/ +0x34, 0x00, /*EDETransFuncXp1_Addr1*/ +0x35, 0x0B, /*EDETransFuncXp1_Addr0*/ +0x36, 0x01, /*EDETransFuncXp2_Addr1*/ +0x37, 0x80, /*EDETransFuncXp2_Addr0*/ +0x38, 0x09, /*EDETransFuncSl1_Addr*/ +0x39, 0x22, /*EDETransFuncSl2_Addr*/ +0x3A, 0x00, /*EDELuAdpLOffset_Addr*/ +0x3B, 0x30, /*EDELuAdpROffset_Addr*/ +0x3C, 0x08, /*EDERBThrd_Addr*/ +0x3D, 0x02, /*EDESmallOffset_Addr*/ + +/* CCM Saturation Level*/ +0xFF, 0x85, /*Page mode */ +0x1A, 0x64, /* SUP Threshold */ +0x30, 0x40, /* MinSUP */ + +0xFF, 0xA0, /*Page mode */ +/* Lens Shading*/ +0x43, 0x80, /* RH7 rrhrhh*/ +0x44, 0x80, /* RV*/ +0x45, 0x80, /* RH */ +0x46, 0x80, /* RV*/ +0x47, 0x80, /* GH*/ +0x48, 0x80, /* GV*/ +0x49, 0x80, /* GH*/ +0x4A, 0x80, /* GV */ +0x4B, 0x80, /* BH*/ +0x4C, 0x80, /* BV*/ +0x4D, 0x80, /* BH*/ +0x4E, 0x80, /* BV */ +0x52, 0x90, /* GGain*/ +0x53, 0x20, /* GGain*/ +0x54, 0x00, /* GGain*/ + +/*Max Shading*/ +0xFF, 0x85, /*Page mode */ +0x32, 0xC0, +0x33, 0x30, +0x34, 0x00, +0x35, 0x90, +0x36, 0x20, +0x37, 0x00, + +/*Min Shading*/ +0x1c, 0xC0, +0x1d, 0x30, +0x1e, 0x00, +0x1f, 0x90, +0x20, 0x18, +0x21, 0x00, + +/* LineLength */ +0xFF, 0x87, /*Page mode */ +0xDC, 0x05, /* by Yong In Han 091511*/ +0xDD, 0xB0, /* by Yong In Han 091511*/ +0xd5, 0x00, /* Flip*/ +/***************************************************/ +/* SensorCon */ +/***************************************************/ +0xFF, 0xD0, /*Page mode */ +0x20, 0x0E, /* ABLK_Rsrv_Addr*/ +0x20, 0x0D, /* ABLK_Rsrv_Addr*/ + +/***************************************************/ +/* MIPI */ +/***************************************************/ +0xFF, 0xB0, /*Page mode */ +0x54, 0x02, /* MIPI PHY_HS_TX_CTRL*/ +0x38, 0x05, /* MIPI DPHY_CTRL_SET*/ + + +/* SXGA PR*/ +0xFF, 0x85, /*Page mode */ +0xB8, 0x0A, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr0*/ +0xB9, 0x00, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr1*/ +0xBC, 0x04, /* gPT_u8PR_Active_SXGA_DPHY_CLK_TIME_Addr3*/ +0xFF, 0x87, /*Page mode */ +0x0C, 0x00, /* start Y*/ +0x0D, 0x20, /* start Y */ +0x10, 0x03, /* end Y*/ +0x11, 0xE0, /* end Y */ + +/* Recoding */ +0xFF, 0x86, /*Page mode */ +0x38, 0x05, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr0*/ +0x39, 0x00, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr1*/ +0x3C, 0x04, /* gPT_u8PR_Active_720P_DPHY_CLK_TIME_Addr3*/ + +0xFF, 0x87, +0x23, 0x02, /*gPR_Active_720P_u8SensorCtrl_Addr */ +0x25, 0x01, /*gPR_Active_720P_u8PLL_P_Addr */ +0x26, 0x0F, /*gPR_Active_720P_u8PLL_M_Addr */ +0x27, 0x00, /*gPR_Active_720P_u8PLL_S_Addr */ +0x28, 0x00, /*gPR_Active_720P_u8PLL_Ctrl_Addr */ +0x29, 0x01, /*gPR_Active_720P_u8src_clk_sel_Addr */ +0x2A, 0x00, /*gPR_Active_720P_u8output_pad_status_Addr */ +0x2B, 0x3F, /*gPR_Active_720P_u8ablk_ctrl_10_Addr */ +0x2C, 0xFF, /*gPR_Active_720P_u8BayerFunc_Addr */ +0x2D, 0xFF, /*gPR_Active_720P_u8RgbYcFunc_Addr */ +0x2E, 0x00, /*gPR_Active_720P_u8ISPMode_Addr */ +0x2F, 0x02, /*gPR_Active_720P_u8SCLCtrl_Addr */ +0x30, 0x01, /*gPR_Active_720P_u8SCLHorScale_Addr0 */ +0x31, 0xFF, /*gPR_Active_720P_u8SCLHorScale_Addr1 */ +0x32, 0x03, /*gPR_Active_720P_u8SCLVerScale_Addr0 */ +0x33, 0xFF, /*gPR_Active_720P_u8SCLVerScale_Addr1 */ +0x34, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr0 */ +0x35, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr1 */ +0x36, 0x00, /*gPR_Active_720P_u8SCLCropStartY_Addr0 */ +0x37, 0x10, /*gPR_Active_720P_u8SCLCropStartY_Addr1 */ +0x38, 0x02, /*gPR_Active_720P_u8SCLCropEndX_Addr0 */ +0x39, 0x80, /*gPR_Active_720P_u8SCLCropEndX_Addr1 */ +0x3A, 0x01, /*gPR_Active_720P_u8SCLCropEndY_Addr0 */ +0x3B, 0xF0, /*gPR_Active_720P_u8SCLCropEndY_Addr1 */ +0x3C, 0x01, /*gPR_Active_720P_u8OutForm_Addr */ +0x3D, 0x0C, /*gPR_Active_720P_u8OutCtrl_Addr */ +0x3E, 0x04, /*gPR_Active_720P_u8AEWinStartX_Addr */ +0x3F, 0x04, /*gPR_Active_720P_u8AEWinStartY_Addr */ +0x40, 0x66, /*gPR_Active_720P_u8MergedWinWidth_Addr */ +0x41, 0x5E, /*gPR_Active_720P_u8MergedWinHeight_Addr */ +0x42, 0x04, /*gPR_Active_720P_u8AEHistWinAx_Addr */ +0x43, 0x04, /*gPR_Active_720P_u8AEHistWinAy_Addr */ +0x44, 0x98, /*gPR_Active_720P_u8AEHistWinBx_Addr */ +0x45, 0x78, /*gPR_Active_720P_u8AEHistWinBy_Addr */ +0x46, 0x22, /*gPR_Active_720P_u8AWBTrim_Addr */ +0x47, 0x28, /*gPR_Active_720P_u8AWBCTWinAx_Addr */ +0x48, 0x20, /*gPR_Active_720P_u8AWBCTWinAy_Addr */ +0x49, 0x78, /*gPR_Active_720P_u8AWBCTWinBx_Addr */ +0x4A, 0x60, /*gPR_Active_720P_u8AWBCTWinBy_Addr */ +0x4B, 0x03, /*gPR_Active_720P_u16AFCFrameLength_0 */ +0x4C, 0x00, /*gPR_Active_720P_u16AFCFrameLength_1 */ + + +/* VGA PR */ +0xFF, 0x86, /*Page mode */ +0x2F, 0x05, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr0*/ +0x30, 0x00, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr1*/ +0x33, 0x04, /* gPT_u8PR_Active_VGA_DPHY_CLK_TIME_Addr3 */ + +0xFF, 0x87, /*Page mode */ +0x4D, 0x00, /*gPR_Active_VGA_u8SensorCtrl_Addr*/ +0x4E, 0x72, /*gPR_Active_VGA_u8SensorMode_Addr*/ +0x4F, 0x01, /*gPR_Active_VGA_u8PLL_P_Addr*/ +0x50, 0x0F, /*gPR_Active_VGA_u8PLL_M_Addr*/ +0x51, 0x00, /*gPR_Active_VGA_u8PLL_S_Addr*/ +0x52, 0x00, /*gPR_Active_VGA_u8PLL_Ctrl_Addr*/ +0x53, 0x01, /*gPR_Active_VGA_u8src_clk_sel_Addr*/ +0x54, 0x00, /*gPR_Active_VGA_u8output_pad_status_Addr*/ +0x55, 0x3F, /*gPR_Active_VGA_u8ablk_ctrl_10_Addr*/ +0x56, 0xFF, /*gPR_Active_VGA_u8BayerFunc_Addr*/ +0x57, 0xFF, /*gPR_Active_VGA_u8RgbYcFunc_Addr*/ +0x58, 0x00, /*gPR_Active_VGA_u8ISPMode_Addr*/ +0x59, 0x02, /*gPR_Active_VGA_u8SCLCtrl_Addr*/ +0x5A, 0x01, /*gPR_Active_VGA_u8SCLHorScale_Addr0*/ +0x5B, 0xFF, /*gPR_Active_VGA_u8SCLHorScale_Addr1*/ +0x5C, 0x01, /*gPR_Active_VGA_u8SCLVerScale_Addr0*/ +0x5D, 0xFF, /*gPR_Active_VGA_u8SCLVerScale_Addr1*/ +0x5E, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr0*/ +0x5F, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr1*/ +0x60, 0x00, /*gPR_Active_VGA_u8SCLCropStartY_Addr0*/ +0x61, 0x20, /*gPR_Active_VGA_u8SCLCropStartY_Addr1*/ +0x62, 0x05, /*gPR_Active_VGA_u8SCLCropEndX_Addr0*/ +0x63, 0x00, /*gPR_Active_VGA_u8SCLCropEndX_Addr1*/ +0x64, 0x03, /*gPR_Active_VGA_u8SCLCropEndY_Addr0*/ +0x65, 0xE0, /*gPR_Active_VGA_u8SCLCropEndY_Addr1*/ + +0xFF, 0xd1, /*Page mode */ +0x07, 0x00, /* power off mask clear*/ +0x0b, 0x00, /* clock off mask clear*/ +0xFF, 0xC0, /*Page mode */ +0x10, 0x41, + + +/* VT-Call END of Initial*/ +}; + + +/* Set-data based on Samsung Reliabilty Group standard +* ,when using WIFI. 15fps +*/ +static const u8 db8131m_vt_wifi_common_1[] = { +/***************************************************/ +/* Device : DB8131M Fixed 8fps */ +/* MIPI Interface for Noncontious Clock */ +/***************************************************/ +/***************************************************/ +/* Command */ +/***************************************************/ +0xFF, 0xC0, /*Page mode*/ +0x10, 0x01, +}; +/*wait 150*/ + +static const u8 db8131m_vt_wifi_common_2[] = { +/***************************************************/ +/* Format */ +/***************************************************/ +0xFF, 0xA1, /*Page mode */ +0x70, 0x01, +0x71, 0x0D, + +/***************************************************/ +/* SensorCon */ +/***************************************************/ +0xFF, 0xD0, /*Page mode */ +0x0F, 0x0B, /*ABLK_Ctrl_1_Addr*/ +0x13, 0x00, /*Gain_Addr*/ +0x15, 0x01, /*IVREFT_REFB_Addr*/ +0x20, 0x0E, /*ABLK_Rsrv_Addr*/ +0x23, 0x01, /*IVREFT2_REFB2_Addr*/ +0x24, 0x01, /*IPPG_IVCM2_Addr*/ +0x39, 0x70, /*RiseSx_CDS_1_L_Addr*/ +0x51, 0x19, /*Fallcreset_1_L_Addr*/ +0x83, 0x2D, /*RiseTran_Sig_Even_L_Addr*/ +0x85, 0x2F, /*FallTran_Sig_Even_L_Addr*/ +0x87, 0x2D, /*RiseTran_Sig_Odd_L_Addr*/ +0x89, 0x2F, /*FallTran_Sig_Odd_L_Addr*/ +0x8B, 0x27, /*RiseCNT_EN_1_L_Addr*/ +0x8D, 0x6c, /*FallCNT_EN_1_L_Addr*/ +0xD7, 0x80, /*ABLK_Ctrl_12_Addr*/ +0xDB, 0xA2, /*FallScanTx15_1_L_Addr*/ +0xED, 0x01, /*PLL_P_Addr*/ +0xEE, 0x0F, /*PLL_M_Addr*/ +0xEF, 0x00, /*PLL_S_Addr*/ +0xF9, 0x00, /*ABLK_Ctrl_8*/ +0xF8, 0x00, /*Vblank Sleep Mode enable*/ +0xFB, 0x90, /*PostADC_Gain_Addr*/ + +/***************************************************/ +/* Analog ADF */ +/***************************************************/ +0xFF, 0x85, /*Page mode */ +0x89, 0x93, /*gAdf_u8APThreshold*/ +0x8A, 0x0C, /*u8APClmpThreshold*/ +0x8C, 0x07, /*gAdf_u8APMinVal_ThrClampH*/ +0x8D, 0x40, /*gAdf_u8APMinVal_ThrClampL*/ +0x8E, 0x03, /*gAdf_u8APMinVal_DOFFSET*/ +0x8F, 0x14, /*gAdf_u8APMinVal_AMP2_1_SDM*/ +0x91, 0x1A, /*gAdf_u8APMinVal_AMP4_3_SDM*/ +0x92, 0x0F, /*gAdf_u8APMinVal_FallIntTx15*/ +0x93, 0x47, /*gAdf_u8APMinVal_CDSxRange_CtrlPre*/ +0x95, 0x18, /*gAdf_u8APMinVal_REFB_IVCM*/ +0x96, 0x38, /*gAdf_u8APMinVal_ref_os_PB*/ +0x97, 0x0D, /*gAdf_u8APMinVal_NTx_Range*/ +0x98, 0x0D, /*gAdf_u8APMaxVal_Clmp_rst*/ +0x99, 0x06, /*gAdf_u8APMaxVal_ThrClampH*/ +0x9A, 0x9F, /*gAdf_u8APMaxVal_ThrClampL*/ +0x9B, 0x02, /*gAdf_u8APMaxVal_DOFFSET*/ +0x9C, 0x1C, /*gAdf_u8APMaxVal_AMP2_1_SDM*/ +0x9E, 0x11, /*gAdf_u8APMaxVal_AMP4_3_SDM*/ +0x9F, 0x5D, /*gAdf_u8APMaxVal_FallIntTx15*/ +0xA0, 0x78, /*gAdf_u8APMaxVal_CDSxRange_CtrlPre*/ +0xA2, 0x18, /*gAdf_u8APMaxVal_REFB_IVCM*/ +0xA3, 0x40, /*gAdf_u8APMaxVal_ref_os_PB*/ +0xA4, 0x0B, /*gAdf_u8APMaxVal_NTx_Range*/ + +0xFF, 0x86, /*Page mode */ +0x15, 0x00, /*gPT_u8Adf_APThrHys*/ +0x16, 0xF7, /*gPT_u8Adf_APFallIntTxThrLevel*/ +0x17, 0x13, /*gPT_u8Adf_APMinVal_BP2_1_SDM*/ +0x18, 0x13, /*gPT_u8Adf_APMidVal_BP2_1_SDM*/ +0x19, 0x1C, /*gPT_u8Adf_APMaxVal_BP2_1_SDM*/ +0x1A, 0x06, /*gPT_u8Adf_APMidVal_ThrClampH*/ +0x1B, 0xF0, /*gPT_u8Adf_APMidVal_ThrClampL*/ +0x1C, 0x01, /*gPT_u8Adf_APMidVal_DOFFSET*/ +0x1D, 0x14, /*gPT_u8Adf_APMidVal_AMP2_1_SDM*/ +0x1F, 0x31, /*gPT_u8Adf_APMidVal_AMP4_3_SDM*/ +0x20, 0x68, /*gPT_u8Adf_APMidVal_CDSxRange_CtrlPre*/ +0x22, 0x18, /*gPT_u8Adf_APMidVal_REFB_IVCM*/ +0x23, 0x38, /*gPT_u8Adf_APMidVal_ref_os_PB*/ +0x24, 0x0F, /*gPT_u8Adf_APMidVal_NTx_Range*/ +0x25, 0x77, /*gPT_u8Adf_APVal_EnSiSoSht_EnSm*/ + +0xFF, 0x87, /*Page mode */ +0xEA, 0x41, + +0xFF, 0xD0, /*Page mode */ +0x20, 0x0D, /*ABLK_Rsrv_Addr*/ + +0xFF, 0x83, /*Page mode */ +0x63, 0x28, /*Again Table*/ +0x64, 0x10, /*Again Table*/ +0x65, 0xA8, /*Again Table*/ +0x66, 0x50, /*Again Table*/ +0x67, 0x28, /*Again Table*/ +0x68, 0x14, /*Again Table*/ + + +/***************************************************/ +/* AE */ +/***************************************************/ +0xFF, 0x82, /*Page mode */ +0x91, 0x02, /* AeMode*/ +0x95, 0x88, /* AE weight*/ +0x96, 0x88, +0x97, 0xF8, +0x98, 0x8F, +0x99, 0xF8, +0x9A, 0x8F, +0x9B, 0x88, +0x9C, 0x88, +0xA9, 0x40, /* OTarget*/ +0xAA, 0x40, /* ITarget*/ +0x9D, 0x66, /* AE Speed*/ +0x9F, 0x06, /* AE HoldBnd*/ +0xA8, 0x40, /* STarget*/ +0xB9, 0x04, /* RGain*/ +0xBB, 0x04, /* GGain*/ +0xBD, 0x04, /* BGain*/ +0xC5, 0x02, /* PeakMvStep*/ +0xC6, 0x38, /* PeakTgMin*/ +0xC7, 0x24, /* PeakRatioTh1*/ +0xC8, 0x10, /* PeakRatioTh0*/ +0xC9, 0x05, /* PeakLuTh*/ +0xD5, 0x60, /* LuxGainTB_2*/ +0xFF, 0x83, /*Page mode */ +0x2F, 0x04, /* TimeNum0*/ +0x30, 0x05, /* TimeNum1*/ +0x4F, 0x05, /* FrameOffset*/ +0xFF, 0x82, /*Page mode */ +0xA1, 0x0A, /* AnalogGainMax*/ +0xF3, 0x09, /* SCLK*/ +0xF4, 0x60, +0xF9, 0x00, /* GainMax*/ +0xFA, 0xC8, /* GainMax*/ +0xFB, 0x62, /* Gain3Lut*/ +0xFC, 0x39, /* Gain2Lut*/ +0xFD, 0x28, /* Gain1Lut*/ +0xFE, 0x12, /* GainMin*/ +0xFF, 0x83, /*Page mode */ +0x03, 0x0F, /* TimeMax60Hz : 8fps*/ +0x04, 0x0A, /* Time3Lux60Hz : 12fps*/ +0x05, 0x04, /* Time2Lut60Hz : 24fps*/ +0x06, 0x04, /* Time1Lut60Hz : 24fps*/ +0xFF, 0x82, /*Page mode */ +0xD3, 0x12, /* LuxTBGainStep0 */ +0xD4, 0x36, /* LuxTBGainStep1 */ +0xD5, 0x60, /* LuxTBGainStep2*/ +0xD6, 0x01, /* LuxTBTimeStep0H*/ +0xD7, 0x00, /* LuxTBTimeStep0L*/ +0xD8, 0x01, /* LuxTBTimeStep1H*/ +0xD9, 0xC0, /* LuxTBTimeStep1L*/ +0xDA, 0x06, /* LuxTBTimeStep2H*/ +0xDB, 0x00, /* LuxTBTimeStep2L*/ +0xFF, 0x83, /*Page mode */ +0x0B, 0x08, +0x0C, 0x0C, /* Frame Rate*/ +0xFF, 0x82, /*Page mode */ +0x92, 0x5D, + +/***************************************************/ +/* AWB */ +/***************************************************/ +0xFF, 0x83, /*Page mode */ +0x79, 0x83, /* AWB SKIN ON*/ +0x86, 0x07, /* gAWB_u16MinGrayCnt_rw_0*/ +0x87, 0x00, /* gAWB_u16MinGrayCnt_rw_1*/ +0x90, 0x05, /* gAWB_u16FinalRGain_ro_0*/ +0x94, 0x05, /* gAWB_u16FinalBGain_ro_0*/ +0x98, 0xD4, /* SkinWinCntTh*/ +0xA2, 0x28, /* SkinYTh*/ +0xA3, 0x00, /* SkinHoldHitCnt*/ +0xA4, 0x0F, /* SkinHoldHitCnt*/ +0xAD, 0x65, /* u8SkinTop2*/ +0xAE, 0x80, /* gAwb_u8SkinTop2LS1Ratio_rw 5zone */ +0xAF, 0x20, /* gAwb_u8SkinTop2LS2Ratio_rw 6zone */ +0xB4, 0x10, /* u8SkinTop2LSHys_rw */ +0xB5, 0x54, /* gAwb_u8SkinLTx */ +0xB6, 0xbd, /* gAwb_u8SkinLTy */ +0xB7, 0x74, /* gAwb_u8SkinRBx */ +0xB8, 0x9d, /* gAwb_u8SkinRBy */ +0xBA, 0x4F, /* UniCThrY_rw */ +0xBF, 0x0C, /* u16UniCGrayCntThr_rw_0*/ +0xC0, 0x80, /* u16UniCGrayCntThr_rw_1 */ +0xFF, 0x87, /*Page mode */ +0xC9, 0x22, /* gUR_u8AWBTrim_Addr */ +0xFF, 0x84, /*Page mode */ +0x49, 0x02, /* Threshold_indoor */ +0x4A, 0x00, +0x4B, 0x03, /* Threshold_outdoor */ +0x4C, 0x80, +0xFF, 0x83, /*Page mode */ +0xCB, 0x03, /* R MinGain [Default 0X20] A Spec Pass */ +0xCC, 0xC0, /* R MinGain [Default 0X20] A Spec Pass */ +0x82, 0x00, /* lockratio*/ +0xFF, 0x84, /*Page mode */ +0x3D, 0x00, /* gAwb_u32LuxConst1_rw_0*/ +0x3E, 0x00, /* gAwb_u32LuxConst1_rw_1*/ +0x3F, 0x06, /* gAwb_u32LuxConst1_rw_2*/ +0x40, 0x20, /* gAwb_u32LuxConst1_rw_3*/ +0x41, 0x07, /* gAwb_u32LuxConst2_rw_0*/ +0x42, 0x53, /* gAwb_u32LuxConst2_rw_1*/ +0x43, 0x00, /* gAwb_u32LuxConst2_rw_2*/ +0x44, 0x00, /* gAwb_u32LuxConst2_rw_3*/ +0x55, 0x03, /* gAwb_u8Weight_Gen_rw_0 */ +0x56, 0x10, /* gAwb_u8Weight_Gen_rw_1 */ +0x57, 0x14, /* gAwb_u8Weight_Gen_rw_2 */ +0x58, 0x07, /* gAwb_u8Weight_Gen_rw_3 */ +0x59, 0x04, /* gAwb_u8Weight_Gen_rw_4 */ +0x5A, 0x03, /* gAwb_u8Weight_Gen_rw_5 */ +0x5B, 0x03, /* gAwb_u8Weight_Gen_rw_6 */ +0x5C, 0x15, /* gAwb_u8Weight_Gen_rw_7 */ +0x5D, 0x01, /* gAwb_u8Weight_Ind_rw_0 */ +0x5E, 0x0F, /* gAwb_u8Weight_Ind_rw_1 */ +0x5F, 0x07, /* gAwb_u8Weight_Ind_rw_2 */ +0x60, 0x14, /* gAwb_u8Weight_Ind_rw_3 */ +0x61, 0x14, /* gAwb_u8Weight_Ind_rw_4 */ +0x62, 0x12, /* gAwb_u8Weight_Ind_rw_5 */ +0x63, 0x11, /* gAwb_u8Weight_Ind_rw_6 */ +0x64, 0x14, /* gAwb_u8Weight_Ind_rw_7 */ +0x65, 0x03, /* gAwb_u8Weight_Outd_rw_0*/ +0x66, 0x05, /* gAwb_u8Weight_Outd_rw_1*/ +0x67, 0x15, /* gAwb_u8Weight_Outd_rw_2*/ +0x68, 0x04, /* gAwb_u8Weight_Outd_rw_3*/ +0x69, 0x01, /* gAwb_u8Weight_Outd_rw_4*/ +0x6A, 0x02, /* gAwb_u8Weight_Outd_rw_5*/ +0x6B, 0x03, /* gAwb_u8Weight_Outd_rw_6*/ +0x6C, 0x15, /* gAwb_u8Weight_Outd_rw_6*/ +0xFF, 0x85, /*Page mode */ +0xE2, 0x0C, /* gPT_u8Awb_UnicolorZone_rw */ +0xFF, 0x83, /*Page mode */ +0xCD, 0x06, /*Max Rgain*/ +0xCE, 0x80, +0xD1, 0x06, /*Max BGain*/ +0xd2, 0x80, + +/***************************************************/ +/* AWB STE */ +/***************************************************/ +0xFF, 0xA1, /*Page mode */ +/*Flash*/ +0xA0, 0x5c, /*AWBZone0LTx*/ +0xA1, 0x7a, /*AWBZone0LTy*/ +0xA2, 0x69, /*AWBZone0RBx*/ +0xA3, 0x6f, /*AWBZone0RBy*/ +/*cloudy*/ +0xA4, 0x73, /*AWBZone1LTx*/ +0xA5, 0x55, /*AWBZone1LTy*/ +0xA6, 0x8C, /*AWBZone1RBx*/ +0xA7, 0x30, /*AWBZone1RBy */ +/*Daylight */ +0xA8, 0x69, /*AWBZone2LTx*/ +0xA9, 0x69, /*AWBZone2LTy*/ +0xAA, 0x83, /*AWBZone2RBx*/ +0xAB, 0x52, /*AWBZone2RBy */ +/*Fluorescent */ +0xAC, 0x57, /*AWBZone3LTx*/ +0xAD, 0x6e, /*AWBZone3LTy*/ +0xAE, 0x6f, /*AWBZone3RBx*/ +0xAF, 0x59, /*AWBZone3RBy*/ + +/*CWF */ +0xB0, 0x50, /*AWBZone4LTx*/ +0xB1, 0x74, /*AWBZone4LTy*/ +0xB2, 0x65, /*AWBZone4RBx*/ +0xB3, 0x5d, /*AWBZone4RBy*/ +/*TL84 */ +0xB4, 0x53, /*AWBZone5LTx*/ +0xB5, 0x7f, /*AWBZone5LTy*/ +0xB6, 0x62, /*AWBZone5RBx*/ +0xB7, 0x75, /*AWBZone5RBy */ +/*A */ +0xB8, 0x4a, /*AWBZone6LTx*/ +0xB9, 0x87, /*AWBZone6LTy*/ +0xBA, 0x59, /*AWBZone6RBx*/ +0xBB, 0x78, /*AWBZone6RBy*/ +/*Horizon */ +0xBC, 0x41, /*AWBZone7LTx*/ +0xBD, 0x91, /*AWBZone7LTy*/ +0xBE, 0x4b, /*AWBZone7RBx*/ +0xBF, 0x89, /*AWBZone7RBy*/ +/*Skin */ +0xC0, 0x5b, /*AWBZone8LTx*/ +0xC1, 0x85, /*AWBZone8LTy*/ +0xC2, 0x60, /*AWBZone8RBx*/ +0xC3, 0x7b, /*AWBZone8RBy*/ + +/***************************************************/ +/* UR */ +/***************************************************/ +0xFF, 0x85, /*Page mode */ +0x06, 0x05, +0xFF, 0x86, /*Page mode */ +0x14, 0x1E, /* CCM sum 1*/ +0xFF, 0x85, /*Page mode */ +0x86, 0x42, /* 42 saturation level*/ +0x07, 0x00, /* sup hysteresis*/ + +/*DAY light */ +0xFF, 0x83, /*Page mode */ +0xEA, 0x00, /*gAwb_s16AdapCCMTbl_0*/ +0xEB, 0x53, /*gAwb_s16AdapCCMTbl_1*/ +0xEC, 0xFF, /*gAwb_s16AdapCCMTbl_2*/ +0xED, 0xE1, /*gAwb_s16AdapCCMTbl_3*/ +0xEE, 0x00, /*gAwb_s16AdapCCMTbl_4*/ +0xEF, 0x05, /*gAwb_s16AdapCCMTbl_5*/ +0xF0, 0xFF, /*gAwb_s16AdapCCMTbl_6*/ +0xF1, 0xF3, /*gAwb_s16AdapCCMTbl_7*/ +0xF2, 0x00, /*gAwb_s16AdapCCMTbl_8*/ +0xF3, 0x4B, /*gAwb_s16AdapCCMTbl_9*/ +0xF4, 0xFF, /*gAwb_s16AdapCCMTbl_10*/ +0xF5, 0xFA, /*gAwb_s16AdapCCMTbl_11*/ +0xF6, 0xFF, /*gAwb_s16AdapCCMTbl_12*/ +0xF7, 0xFa, /*gAwb_s16AdapCCMTbl_13*/ +0xF8, 0xFF, /*gAwb_s16AdapCCMTbl_14*/ +0xF9, 0xC3, /*gAwb_s16AdapCCMTbl_15*/ +0xFA, 0x00, /*gAwb_s16AdapCCMTbl_16*/ +0xFB, 0x80, /*gAwb_s16AdapCCMTbl_17*/ + +/*CWF lgiht */ +0xFF, 0x83, /*Page mode */ +0xFC, 0x00, /* gAwb_s16AdapCCMTbl_18 */ +0xFD, 0x68, /* gAwb_s16AdapCCMTbl_19 */ +0xFF, 0x85, /*Page mode */ +0xE0, 0xFF, /* gAwb_s16AdapCCMTbl_20 */ +0xE1, 0xde, /* gAwb_s16AdapCCMTbl_21 */ +0xFF, 0x84, /*Page mode */ +0x00, 0xff, /* gAwb_s16AdapCCMTbl_22 */ +0x01, 0xfa, /* gAwb_s16AdapCCMTbl_23 */ +0x02, 0xFF, /* gAwb_s16AdapCCMTbl_24 */ +0x03, 0xf0, /* gAwb_s16AdapCCMTbl_25 */ +0x04, 0x00, /* gAwb_s16AdapCCMTbl_26 */ +0x05, 0x52, /* gAwb_s16AdapCCMTbl_27 */ +0x06, 0xFF, /* gAwb_s16AdapCCMTbl_28 */ +0x07, 0xFa, /* gAwb_s16AdapCCMTbl_29 */ +0x08, 0x00, /* gAwb_s16AdapCCMTbl_30 */ +0x09, 0x00, /* gAwb_s16AdapCCMTbl_31 */ +0x0A, 0xFF, /* gAwb_s16AdapCCMTbl_32 */ +0x0B, 0xdb, /* gAwb_s16AdapCCMTbl_33 */ +0x0C, 0x00, /* gAwb_s16AdapCCMTbl_34 */ +0x0D, 0x68, /* gAwb_s16AdapCCMTbl_35 */ + +/*A light */ + +0x0E, 0x00, /* gAwb_s16AdapCCMTbl_36 */ +0x0F, 0x6d, /* gAwb_s16AdapCCMTbl_37 */ +0x10, 0xFF, /* gAwb_s16AdapCCMTbl_38 */ +0x11, 0xd5, /* gAwb_s16AdapCCMTbl_39 */ +0x12, 0xff, /* gAwb_s16AdapCCMTbl_40 */ +0x13, 0xfe, /* gAwb_s16AdapCCMTbl_41 */ +0x14, 0xFF, /* gAwb_s16AdapCCMTbl_42 */ +0x15, 0xf4, /* gAwb_s16AdapCCMTbl_43 */ +0x16, 0x00, /* gAwb_s16AdapCCMTbl_44 */ +0x17, 0x5a, /* gAwb_s16AdapCCMTbl_45 */ +0x18, 0xff, /* gAwb_s16AdapCCMTbl_46 */ +0x19, 0xef, /* gAwb_s16AdapCCMTbl_47 */ +0x1A, 0xff, /* gAwb_s16AdapCCMTbl_48 */ +0x1B, 0xfa, /* gAwb_s16AdapCCMTbl_49 */ +0x1C, 0xFF, /* gAwb_s16AdapCCMTbl_50 */ +0x1D, 0xbe, /* gAwb_s16AdapCCMTbl_51 */ +0x1E, 0x00, /* gAwb_s16AdapCCMTbl_52 */ +0x1F, 0x86, /* gAwb_s16AdapCCMTbl_53 */ + + +/***************************************************/ +/* ADF */ +/***************************************************/ + +/* ISP setting*/ +0xFF, 0xA0, /*Page mode */ +0x10, 0x80, /* BLC: ABLC db*/ +0x60, 0x73, /* CDC: Dark CDC ON */ +0x61, 0x1F, /* Six CDC_Edge En, Slash EN*/ +0x69, 0x0C, /* Slash direction Line threshold*/ +0x6A, 0x60, /* Slash direction Pixel threshold*/ +0xC2, 0x04, /* NSF: directional smoothing*/ +0xD0, 0x51, /* DEM: pattern detection*/ +0xFF, 0xA1, /*Page mode */ +0x30, 0x01, /* EDE: Luminane adaptation on*/ +0x32, 0x50, /* EDE: Adaptation slope */ +0x34, 0x00, /* EDE: x1 point */ +0x35, 0x0B, /* EDE: x1 point */ +0x36, 0x01, /* EDE: x2 point */ +0x37, 0x80, /* EDE: x2 point */ +0x3A, 0x00, /* EDE: Adaptation left margin*/ +0x3B, 0x30, /* EDE: Adaptation right margin*/ +0x3C, 0x08, /* EDE: rgb edge threshol*/ + +/* Adaptive Setting*/ +0xFF, 0x85, /*Page mode */ +/* LSC*/ +0x0F, 0x43, /* LVLSC lux level threshold*/ +0x10, 0x43, /* LSLSC Light source , threshold lux*/ + +/* BGT*/ +0x17, 0x30, /* BGT lux level threshold*/ +0x26, 0x20, /* MinVal */ +0x3c, 0x00, /* MaxVal */ + +/* CNT*/ +0x18, 0x43, /* CNT lux level threshold*/ +0x27, 0x00, /* MinVal */ +0x3d, 0x00, /* MaxVal */ + +/* NSF */ +0x12, 0xA5, /* NSF lux level threshold */ +0x22, 0x38, /* u8MinVal_NSF1*/ +0x23, 0x70, /* u8MinVal_NSF2*/ +0xFF, 0x86, /*Page mode */ +0x12, 0x00, /* u8MinVal_NSF3*/ +0xFF, 0x85, /*Page mode */ +0x38, 0x12, /* u8MaxVal_NSF1*/ +0x39, 0x30, /* u8MaxVal_NSF2*/ +0xFF, 0x86, /*Page mode */ +0x13, 0x08, /* u8MaxVal_NSF3*/ + +/* GDC*/ +0xFF, 0x85, /*Page mode */ +0x15, 0xF4, /* GDC lux level threshold */ +0x2D, 0x20, /* u8MinVal_GDC1*/ +0x2E, 0x30, /* u8MinVal_GDC2*/ +0x43, 0x40, /* u8MaxVal_GDC1*/ +0x44, 0x80, /* u8MaxVal_GDC2*/ + +/* ISP Edge*/ +0x04, 0xFB, /* EnEDE*/ +0x14, 0x54, /* u8ThrLevel_EDE*/ +0x28, 0x00, /* u8MinVal_EDE_CP*/ +0x29, 0x03, /* u8MinVal_EDE1*/ +0x2A, 0x20, /* u8MinVal_EDE2*/ +0x2B, 0x00, /* u8MinVal_EDE_OFS*/ +0x2C, 0x22, /* u8MinVal_SG*/ +0x3E, 0x00, /* u8MaxVal_EDE_CP*/ +0x3F, 0x09, /* u8MaxVal_EDE1*/ +0x40, 0x22, /* u8MaxVal_EDE2*/ +0x41, 0x02, /* u8MaxVal_EDE_OFS*/ +0x42, 0x33, /* u8MaxVal_SG*/ + +/* Gamma Adaptive*/ + +0x16, 0xA0, /* Gamma Threshold*/ +0x47, 0x00, /* Min_Gamma_0*/ +0x48, 0x03, /* Min_Gamma_1*/ +0x49, 0x10, /* Min_Gamma_2*/ +0x4A, 0x25, /* Min_Gamma_3*/ +0x4B, 0x3B, /* Min_Gamma_4*/ +0x4C, 0x4F, /* Min_Gamma_5*/ +0x4D, 0x6D, /* Min_Gamma_6*/ +0x4E, 0x86, /* Min_Gamma_7*/ +0x4F, 0x9B, /* Min_Gamma_8*/ +0x50, 0xAD, /* Min_Gamma_9*/ +0x51, 0xC2, /* Min_Gamma_10*/ +0x52, 0xD3, /* Min_Gamma_11*/ +0x53, 0xE1, /* Min_Gamma_12*/ +0x54, 0xE9, /* Min_Gamma_13*/ +0x55, 0xF2, /* Min_Gamma_14*/ +0x56, 0xFA, /* Min_Gamma_15*/ +0x57, 0xFF, /* Min_Gamma_16*/ +0x58, 0x00, /* Max_Gamma_0 */ +0x59, 0x06, /* Max_Gamma_1 */ +0x5a, 0x14, /* Max_Gamma_2 */ +0x5b, 0x30, /* Max_Gamma_3 */ +0x5c, 0x4A, /* Max_Gamma_4 */ +0x5d, 0x5D, /* Max_Gamma_5 */ +0x5e, 0x75, /* Max_Gamma_6 */ +0x5f, 0x89, /* Max_Gamma_7 */ +0x60, 0x9A, /* Max_Gamma_8 */ +0x61, 0xA7, /* Max_Gamma_9 */ +0x62, 0xBC, /* Max_Gamma_10 */ +0x63, 0xD0, /* Max_Gamma_11 */ +0x64, 0xE0, /* Max_Gamma_12 */ +0x65, 0xE7, /* Max_Gamma_13 */ +0x66, 0xEE, /* Max_Gamma_14 */ +0x67, 0xF7, /* Max_Gamma_15 */ +0x68, 0xFF, /* Max_Gamma_16 */ + +/* Initial edge, noise filter setting*/ +0xFF, 0xA0, /*Page mode */ +0xC0, 0x12, /*NSFTh1_Addr*/ +0xC1, 0x30, /*NSFTh2_Addr*/ +0xC2, 0x08, /*NSFTh3_Addr*/ +0xFF, 0xA1, /*Page mode */ +0x30, 0x01, /*EDEOption_Addr*/ +0x31, 0x33, /*EDESlopeGain_Addr*/ +0x32, 0x50, /*EDELuAdpCtrl_Addr*/ +0x33, 0x00, /*EDEPreCoringPt_Addr*/ +0x34, 0x00, /*EDETransFuncXp1_Addr1*/ +0x35, 0x0B, /*EDETransFuncXp1_Addr0*/ +0x36, 0x01, /*EDETransFuncXp2_Addr1*/ +0x37, 0x80, /*EDETransFuncXp2_Addr0*/ +0x38, 0x09, /*EDETransFuncSl1_Addr*/ +0x39, 0x22, /*EDETransFuncSl2_Addr*/ +0x3A, 0x00, /*EDELuAdpLOffset_Addr*/ +0x3B, 0x30, /*EDELuAdpROffset_Addr*/ +0x3C, 0x08, /*EDERBThrd_Addr*/ +0x3D, 0x02, /*EDESmallOffset_Addr*/ + + +/* CCM Saturation Level*/ +0xFF, 0x85, /*Page mode */ +0x1A, 0x64, /* SUP Threshold */ +0x30, 0x40, /* MinSUP */ + +0xFF, 0xA0, /*Page mode */ +/* Lens Shading*/ +0x43, 0x80, /* RH7 rrhrhh*/ +0x44, 0x80, /* RV*/ +0x45, 0x80, /* RH */ +0x46, 0x80, /* RV*/ +0x47, 0x80, /* GH*/ +0x48, 0x80, /* GV*/ +0x49, 0x80, /* GH*/ +0x4A, 0x80, /* GV */ +0x4B, 0x80, /* BH*/ +0x4C, 0x80, /* BV*/ +0x4D, 0x80, /* BH*/ +0x4E, 0x80, /* BV */ +0x52, 0x90, /* GGain*/ +0x53, 0x20, /* GGain*/ +0x54, 0x00, /* GGain*/ + +/*Max Shading*/ +0xFF, 0x85, /*Page mode */ +0x32, 0xC0, +0x33, 0x30, +0x34, 0x00, +0x35, 0x90, +0x36, 0x20, +0x37, 0x00, + +/*Min Shading*/ +0x1c, 0xC0, +0x1d, 0x30, +0x1e, 0x00, +0x1f, 0x90, +0x20, 0x18, +0x21, 0x00, + +/* LineLength */ +0xFF, 0x87, /*Page mode */ +0xDC, 0x05, /* by Yong In Han 091511*/ +0xDD, 0xB0, /* by Yong In Han 091511*/ +0xd5, 0x00, /* Flip*/ +/***************************************************/ +/* SensorCon */ +/***************************************************/ +0xFF, 0xD0, /*Page mode */ +0x20, 0x0E, /* ABLK_Rsrv_Addr*/ +0x20, 0x0D, /* ABLK_Rsrv_Addr*/ + +/***************************************************/ +/* MIPI */ +/***************************************************/ +0xFF, 0xB0, /*Page mode */ +0x54, 0x02, /* MIPI PHY_HS_TX_CTRL*/ +0x38, 0x05, /* MIPI DPHY_CTRL_SET*/ + + +/* SXGA PR*/ +0xFF, 0x85, /*Page mode */ +0xB8, 0x0A, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr0*/ +0xB9, 0x00, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr1*/ +0xBC, 0x04, /* gPT_u8PR_Active_SXGA_DPHY_CLK_TIME_Addr3*/ +0xFF, 0x87, /*Page mode */ +0x0C, 0x00, /* start Y*/ +0x0D, 0x20, /* start Y */ +0x10, 0x03, /* end Y*/ +0x11, 0xE0, /* end Y */ + +/* Recoding */ +0xFF, 0x86, /*Page mode */ +0x38, 0x05, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr0*/ +0x39, 0x00, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr1*/ +0x3C, 0x04, /* gPT_u8PR_Active_720P_DPHY_CLK_TIME_Addr3*/ + +0xFF, 0x87, +0x23, 0x02, /*gPR_Active_720P_u8SensorCtrl_Addr */ +0x25, 0x01, /*gPR_Active_720P_u8PLL_P_Addr */ +0x26, 0x0F, /*gPR_Active_720P_u8PLL_M_Addr */ +0x27, 0x00, /*gPR_Active_720P_u8PLL_S_Addr */ +0x28, 0x00, /*gPR_Active_720P_u8PLL_Ctrl_Addr */ +0x29, 0x01, /*gPR_Active_720P_u8src_clk_sel_Addr */ +0x2A, 0x00, /*gPR_Active_720P_u8output_pad_status_Addr */ +0x2B, 0x3F, /*gPR_Active_720P_u8ablk_ctrl_10_Addr */ +0x2C, 0xFF, /*gPR_Active_720P_u8BayerFunc_Addr */ +0x2D, 0xFF, /*gPR_Active_720P_u8RgbYcFunc_Addr */ +0x2E, 0x00, /*gPR_Active_720P_u8ISPMode_Addr */ +0x2F, 0x02, /*gPR_Active_720P_u8SCLCtrl_Addr */ +0x30, 0x01, /*gPR_Active_720P_u8SCLHorScale_Addr0 */ +0x31, 0xFF, /*gPR_Active_720P_u8SCLHorScale_Addr1 */ +0x32, 0x03, /*gPR_Active_720P_u8SCLVerScale_Addr0 */ +0x33, 0xFF, /*gPR_Active_720P_u8SCLVerScale_Addr1 */ +0x34, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr0 */ +0x35, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr1 */ +0x36, 0x00, /*gPR_Active_720P_u8SCLCropStartY_Addr0 */ +0x37, 0x10, /*gPR_Active_720P_u8SCLCropStartY_Addr1 */ +0x38, 0x02, /*gPR_Active_720P_u8SCLCropEndX_Addr0 */ +0x39, 0x80, /*gPR_Active_720P_u8SCLCropEndX_Addr1 */ +0x3A, 0x01, /*gPR_Active_720P_u8SCLCropEndY_Addr0 */ +0x3B, 0xF0, /*gPR_Active_720P_u8SCLCropEndY_Addr1 */ +0x3C, 0x01, /*gPR_Active_720P_u8OutForm_Addr */ +0x3D, 0x0C, /*gPR_Active_720P_u8OutCtrl_Addr */ +0x3E, 0x04, /*gPR_Active_720P_u8AEWinStartX_Addr */ +0x3F, 0x04, /*gPR_Active_720P_u8AEWinStartY_Addr */ +0x40, 0x66, /*gPR_Active_720P_u8MergedWinWidth_Addr */ +0x41, 0x5E, /*gPR_Active_720P_u8MergedWinHeight_Addr */ +0x42, 0x04, /*gPR_Active_720P_u8AEHistWinAx_Addr */ +0x43, 0x04, /*gPR_Active_720P_u8AEHistWinAy_Addr */ +0x44, 0x98, /*gPR_Active_720P_u8AEHistWinBx_Addr */ +0x45, 0x78, /*gPR_Active_720P_u8AEHistWinBy_Addr */ +0x46, 0x22, /*gPR_Active_720P_u8AWBTrim_Addr */ +0x47, 0x28, /*gPR_Active_720P_u8AWBCTWinAx_Addr */ +0x48, 0x20, /*gPR_Active_720P_u8AWBCTWinAy_Addr */ +0x49, 0x78, /*gPR_Active_720P_u8AWBCTWinBx_Addr */ +0x4A, 0x60, /*gPR_Active_720P_u8AWBCTWinBy_Addr */ +0x4B, 0x03, /*gPR_Active_720P_u16AFCFrameLength_0 */ +0x4C, 0x00, /*gPR_Active_720P_u16AFCFrameLength_1 */ + + +/* VGA PR */ +0xFF, 0x86, /*Page mode */ +0x2F, 0x05, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr0*/ +0x30, 0x00, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr1*/ +0x33, 0x04, /* gPT_u8PR_Active_VGA_DPHY_CLK_TIME_Addr3*/ + +0xFF, 0x87, /*Page mode */ +0x4D, 0x00, /*gPR_Active_VGA_u8SensorCtrl_Addr*/ +0x4E, 0x72, /*gPR_Active_VGA_u8SensorMode_Addr*/ +0x4F, 0x01, /*gPR_Active_VGA_u8PLL_P_Addr*/ +0x50, 0x0F, /*gPR_Active_VGA_u8PLL_M_Addr*/ +0x51, 0x00, /*gPR_Active_VGA_u8PLL_S_Addr*/ +0x52, 0x00, /*gPR_Active_VGA_u8PLL_Ctrl_Addr*/ +0x53, 0x01, /*gPR_Active_VGA_u8src_clk_sel_Addr*/ +0x54, 0x00, /*gPR_Active_VGA_u8output_pad_status_Addr*/ +0x55, 0x3F, /*gPR_Active_VGA_u8ablk_ctrl_10_Addr*/ +0x56, 0xFF, /*gPR_Active_VGA_u8BayerFunc_Addr*/ +0x57, 0xFF, /*gPR_Active_VGA_u8RgbYcFunc_Addr*/ +0x58, 0x00, /*gPR_Active_VGA_u8ISPMode_Addr*/ +0x59, 0x02, /*gPR_Active_VGA_u8SCLCtrl_Addr*/ +0x5A, 0x01, /*gPR_Active_VGA_u8SCLHorScale_Addr0*/ +0x5B, 0xFF, /*gPR_Active_VGA_u8SCLHorScale_Addr1*/ +0x5C, 0x01, /*gPR_Active_VGA_u8SCLVerScale_Addr0*/ +0x5D, 0xFF, /*gPR_Active_VGA_u8SCLVerScale_Addr1*/ +0x5E, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr0*/ +0x5F, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr1*/ +0x60, 0x00, /*gPR_Active_VGA_u8SCLCropStartY_Addr0*/ +0x61, 0x20, /*gPR_Active_VGA_u8SCLCropStartY_Addr1*/ +0x62, 0x05, /*gPR_Active_VGA_u8SCLCropEndX_Addr0*/ +0x63, 0x00, /*gPR_Active_VGA_u8SCLCropEndX_Addr1*/ +0x64, 0x03, /*gPR_Active_VGA_u8SCLCropEndY_Addr0*/ +0x65, 0xE0, /*gPR_Active_VGA_u8SCLCropEndY_Addr1*/ + +0xFF, 0xd1, /*Page mode */ +0x07, 0x00, /* power off mask clear*/ +0x0b, 0x00, /* clock off mask clear*/ +0xFF, 0xC0, /*Page mode */ +0x10, 0x41, + +/* Wifi VT-Call END of Initial*/ +}; + +/***************************************************/ +/* CAMERA_PREVIEW - ÃÔ¿µ ÈÄ ÇÁ¸®ºä º¹±Í½Ã ¼ÂÆà */ +/***************************************************/ + +static const u8 db8131m_preview[] = { +0xff, 0x82, +0x7F, 0x35, +}; + +/***************************************************/ +/* CAMERA_SNAPSHOT - ÃÔ¿µ */ +/***************************************************/ +static const u8 db8131m_capture[] = { +0xff, 0x82, +0x7F, 0x34, +0xff, 0xC0, +0x10, 0x03, +}; +/*Wait 150ms*/ +/* capture ½ÇÇà*/ + +/***************************************************/ +/* CAMERA_RECORDING WITH 25fps */ +/***************************************************/ + +static const u8 db8131m_recording_60Hz_common[] = { +/***************************************************/ +/* Device : DB8131M */ +/* MIPI Interface for Noncontious Clock */ +/***************************************************/ + +/* Recording Anti-Flicker 60Hz END of Initial */ +0xFF, 0x87, +0xDE, 0x7A, /*gPR_Active_720P_u8SensorMode_Addr */ +0xFF, 0xC0, /* Page mode*/ +0x10, 0x42, /* Preview Command*/ + +/* Fixed 25fps Mode*/ +0xFF, 0x82, /* Page mode*/ +0x91, 0x02, /* AeMode*/ +0xFF, 0x83, /* Page mode*/ +0x0B, 0x02, /* Frame Rate*/ +0x0C, 0x94, /* Frame Rate*/ +0x03, 0x04, /* TimeMax60Hz*/ +0x04, 0x03, /* Time3Lux60Hz*/ +0x05, 0x02, /* Time2Lut60Hz*/ +0x06, 0x01, /* Time1Lut60Hz*/ +0xFF, 0x82, /* Page mode*/ +0x92, 0x5D, +}; + + +static const u8 db8131m_stream_stop[] = { + +}; + + +/***************************************************/ +/* CAMERA_BRIGHTNESS_1 (1/9) M4 */ +/***************************************************/ +static const u8 db8131m_bright_m4[] = { +/* Brightness -4 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0xE0, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_2 (2/9) M3 */ +/***************************************************/ + +static const u8 db8131m_bright_m3[] = { +/* Brightness -3 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0xE8, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_3 (3/9) M2 */ +/***************************************************/ +static const u8 db8131m_bright_m2[] = { +/* Brightness -2 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0xF0, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_4 (4/9) M1 */ +/***************************************************/ + +static const u8 db8131m_bright_m1[] = { +/* Brightness -1 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0xF8, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_5 (5/9) Default */ +/***************************************************/ +static const u8 db8131m_bright_default[] = { +/* Brightness 0 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0x00, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_6 (6/9) P1 */ +/***************************************************/ +static const u8 db8131m_bright_p1[] = { +/* Brightness +1 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0x08, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_7 (7/9) P2 */ +/***************************************************/ +static const u8 db8131m_bright_p2[] = { +/* Brightness +2 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0x10, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_8 (8/9) P3 */ +/***************************************************/ +static const u8 db8131m_bright_p3[] = { +/* Brightness +3 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0x18, /* Brightness*/ +}; + +/***************************************************/ +/* CAMERA_BRIGHTNESS_9 (9/9) P4 */ +/***************************************************/ +static const u8 db8131m_bright_p4[] = { +/* Brightness +4 */ +0xFF, 0x87, /* Page mode*/ +0xAE, 0x20, /* Brightness*/ +}; + + +static const u8 db8131m_vt_7fps[] = { +/* Fixed 7fps Mode*/ +0xFF, 0x82, /* Page mode*/ +0x91, 0x02, /* AeMode*/ +0xFF, 0x83, /* Page mode*/ +0x0B, 0x09, /* Frame Rate*/ +0x0C, 0x33, /* Frame Rate*/ +0x03, 0x0F, /* TimeMax60Hz*/ +0x04, 0x0A, /* Time3Lux60Hz*/ +0x05, 0x06, /* Time2Lut60Hz*/ +0x06, 0x04, /* Time1Lut60Hz*/ +0xFF, 0x82, /* Page mode*/ +0x92, 0x5D, +}; + +static const u8 db8131m_vt_10fps[] = { +/* Fixed 10fps Mode */ +0xFF, 0x82, /* Page mode*/ +0x91, 0x02, /* AeMode*/ +0xFF, 0x83, /* Page mode*/ +0x0B, 0x06, /* Frame Rate*/ +0x0C, 0x70, /* Frame Rate*/ +0x03, 0x0A, /* TimeMax60Hz*/ +0x04, 0x08, /* Time3Lux60Hz*/ +0x05, 0x06, /* Time2Lut60Hz*/ +0x06, 0x04, /* Time1Lut60Hz*/ +0xFF, 0x82, /* Page mode*/ +0x92, 0x5D, + +}; + +static const u8 db8131m_vt_12fps[] = { +/* Fixed 12fps Mode */ +0xFF, 0x82, /* Page mode*/ +0x91, 0x02, /* AeMode*/ +0xFF, 0x83, /* Page mode*/ +0x0B, 0x05, /* Frame Rate*/ +0x0C, 0x5E, /* Frame Rate*/ +0x03, 0x0C, /* TimeMax60Hz*/ +0x04, 0x0A, /* Time3Lux60Hz*/ +0x05, 0x06, /* Time2Lut60Hz*/ +0x06, 0x04, /* Time1Lut60Hz*/ +0xFF, 0x82, /* Page mode*/ +0x92, 0x5D, +}; + +static const u8 db8131m_vt_15fps[] = { +/* Fixed 15fps Mode */ +0xFF, 0x82, /* Page mode*/ +0x91, 0x02, /* AeMode*/ +0xFF, 0x83, /* Page mode*/ +0x0B, 0x04, /* Frame Rate*/ +0x0C, 0x4C, /* Frame Rate*/ +0x03, 0x08, /* TimeMax60Hz*/ +0x04, 0x06, /* Time3Lux60Hz*/ +0x05, 0x04, /* Time2Lut60Hz*/ +0x06, 0x04, /* Time1Lut60Hz*/ +0xFF, 0x82, /* Page mode*/ +0x92, 0x5D, + +}; + +/***************************************************/ +/* CAMERA_DTP_ON */ +/***************************************************/ +static const u8 db8131m_pattern_on[] = { +0xFF, 0x87, /* Page mode*/ +0xAB, 0x00, /* BayerFunc*/ +0xAC, 0x28, /* RGBYcFunc*/ +0xFF, 0xA0, /* Page mode*/ +0x02, 0x05, /* TPG ? Gamma*/ + +}; + +/***************************************************/ +/* CAMERA_DTP_OFF */ +/***************************************************/ +static const u8 db8131m_pattern_off[] = { +0xFF, 0x87, /* Page mode*/ +0xAB, 0xFF, /* BayerFunc*/ +0xAC, 0xFF, /* RGBYcFunc*/ +0xFF, 0xA0, /* Page mode*/ +0x02, 0x00, /* TPG Disable*/ + +}; +#endif /* __DB8131M_SETFILE_H */ diff --git a/drivers/media/video/slp_s5c73m3.c b/drivers/media/video/slp_s5c73m3.c new file mode 100644 index 0000000..08726d2 --- /dev/null +++ b/drivers/media/video/slp_s5c73m3.c @@ -0,0 +1,3415 @@ +/* + * driver for LSI S5C73M3 (ISP for 8MP Camera) + * + * Copyright (c) 2011, Samsung Electronics. All rights reserved + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_BUSFREQ_OPP +#include +#else +#include +#endif + +#ifdef CONFIG_VIDEO_SAMSUNG_V4L2 +#include +#include +#endif + +#include + +#include +#ifdef CONFIG_VIDEO_SLP_S5C73M3 +#include "slp_s5c73m3.h" +#else +#include "s5c73m3.h" +#endif + +#define S5C73M3_DRIVER_NAME "S5C73M3" + +extern struct class *camera_class; /*sys/class/camera*/ +struct device *s5c73m3_dev; /*sys/class/camera/rear*/ +struct v4l2_subdev *sd_internal; + +#ifdef CONFIG_BUSFREQ_OPP +struct device *bus_dev; +#else +static struct pm_qos_request_list entry = {}; +#endif + +/*#define S5C73M3_FROM_BOOTING*/ + +#ifdef CONFIG_VIDEO_SLP_S5C73M3 + +#define S5C73M3_FW_PATH "/lib/firmware/SlimISP.bin" +#define S5C73M3_FW_GC_PATH "/lib/firmware/SlimISP_GC.bin" +#define S5C73M3_FW_GD_PATH "/lib/firmware/SlimISP_GD.bin" +#define S5C73M3_FW_GE_PATH "/lib/firmware/SlimISP_GE.bin" +#define S5C73M3_FW_GF_PATH "/lib/firmware/SlimISP_GF.bin" +#define S5C73M3_FW_ZC_PATH "/lib/firmware/SlimISP_ZC.bin" +#define S5C73M3_FW_ZD_PATH "/lib/firmware/SlimISP_ZD.bin" +#define S5C73M3_FW_ZE_PATH "/lib/firmware/SlimISP_ZE.bin" +#define S5C73M3_FW_ZF_PATH "/lib/firmware/SlimISP_ZF.bin" +#define S5C73M3_FW_ZG_PATH "/lib/firmware/SlimISP_ZG.bin" + +#else /* CONFIG_VIDEO_SLP_S5C73M3 */ + +/* For Android */ +#define S5C73M3_FW_PATH "/sdcard/SlimISP.bin" + +#endif /* CONFIG_VIDEO_SLP_S5C73M3 */ + +#define S5C73M3_FW_VER_LEN 6 +#define S5C73M3_FW_VER_FILE_CUR 0x60 + +#define S5C73M3_FLASH_BASE_ADDR 0x10000000 +#define S5C73M3_INT_RAM_BASE_ADDR 0x68000000 + +#define S5C73M3_I2C_RETRY 5 +#define S5C73M3_I2C_VERIFY 100 +#define S5C73M3_ISP_TIMEOUT 3000 +#define S5C73M3_ISP_AFB_TIMEOUT 15000 /* FIXME */ +#define S5C73M3_ISP_ESD_TIMEOUT 1000 + +#define S5C73M3_JPEG_MAXSIZE 0x800000 +#define S5C73M3_YUV_MAXSIZE 0x3F4800 /*FHD*/ +#define S5C73M3_POINTER_MAXSIZE 0x10E0 /*FHD*/ + +#define S5C73M3_DEF_APEX_DEN 100 + +#define CHECK_ERR(x) if ((x) < 0) { \ + cam_err("i2c failed, err %d\n", x); \ + return x; \ + } +static const struct s5c73m3_frmsizeenum preview_frmsizes[] = { + { S5C73M3_PREVIEW_QVGA, 320, 240, 0x01 }, + { S5C73M3_PREVIEW_CIF, 352, 288, 0x0E }, + { S5C73M3_PREVIEW_VGA, 640, 480, 0x02 }, + { S5C73M3_PREVIEW_880X720, 880, 720, 0x03 }, + { S5C73M3_PREVIEW_960X720, 960, 720, 0x04 }, + { S5C73M3_PREVIEW_1008X672, 1008, 672, 0x0F }, + { S5C73M3_PREVIEW_1184X666, 1184, 666, 0x05 }, + { S5C73M3_PREVIEW_720P, 1280, 720, 0x06 }, + { S5C73M3_VDIS_720P, 1536, 864, 0x07 }, + { S5C73M3_PREVIEW_1080P, 1920, 1080, 0x0A}, + { S5C73M3_VDIS_1080P, 2304, 1296, 0x0C}, +}; + +static const struct s5c73m3_frmsizeenum capture_frmsizes[] = { + { S5C73M3_CAPTURE_VGA, 640, 480, 0x10 }, + { S5C73M3_CAPTURE_1024X768, 1024, 768, 0xD0 }, + { S5C73M3_CAPTURE_HD, 1280, 720, 0x40 }, + { S5C73M3_CAPTURE_2MP, 1600, 1200, 0x70 }, + { S5C73M3_CAPTURE_W2MP, 2048, 1152, 0x80 }, + { S5C73M3_CAPTURE_3MP, 2048, 1536, 0x90 }, + { S5C73M3_CAPTURE_W4MP, 2560, 1440, 0xA0 }, + { S5C73M3_CAPTURE_5MP, 2560, 1920, 0xB0 }, + { S5C73M3_CAPTURE_W6MP, 3264, 1836, 0xE0 }, + { S5C73M3_CAPTURE_3264X2176, 3264, 2176, 0xC0 }, + { S5C73M3_CAPTURE_8MP, 3264, 2448, 0xF0 }, +}; + +static struct s5c73m3_control s5c73m3_ctrls[] = { + /* Exposure & Scenemode stuff(ISO, Metering, Saturation, etc) */ + { + .id = V4L2_CID_CAMERA_ISO, + .minimum = ISO_AUTO, + .maximum = ISO_800, + .step = 1, + .value = ISO_AUTO, + .default_value = ISO_AUTO, + }, { + /* Capture */ + .id = V4L2_CID_CAM_JPEG_QUALITY, + .minimum = 1, + .maximum = 100, + .step = 1, + .value = 100, + .default_value = 100, + }, +#ifdef CONFIG_VIDEO_SLP_S5C73M3 + { + /* Flash */ + .id = V4L2_CID_CAMERA_FLASH_MODE, + .minimum = FLASH_MODE_OFF, + .maximum = FLASH_MODE_MAX - 1, + .step = 1, + .value = FLASH_MODE_OFF, + .default_value = FLASH_MODE_OFF, + }, { + .id = V4L2_CID_EXPOSURE, + .minimum = EV_MINUS_4, + .maximum = EV_MAX - 1, + .step = 1, + .value = EV_DEFAULT, + .default_value = EV_DEFAULT, + }, { + .id = V4L2_CID_SATURATION, + .minimum = SATURATION_MINUS_2, + .maximum = SATURATION_MAX - 1, + .step = 1, + .value = SATURATION_DEFAULT, + .default_value = SATURATION_DEFAULT, + }, { + .id = V4L2_CID_SHARPNESS, + .minimum = SHARPNESS_MINUS_2, + .maximum = SHARPNESS_MAX - 1, + .step = 1, + .value = SHARPNESS_DEFAULT, + .default_value = SHARPNESS_DEFAULT, + }, { + .id = V4L2_CID_CAMERA_METERING, + .minimum = METERING_MATRIX, + .maximum = METERING_MAX - 1, + .step = 1, + .value = METERING_MATRIX, + .default_value = METERING_MATRIX, + }, { + .id = V4L2_CID_WHITE_BALANCE_PRESET, + .minimum = WHITE_BALANCE_AUTO, + .maximum = WHITE_BALANCE_MAX - 1, + .step = 1, + .value = WHITE_BALANCE_AUTO, + .default_value = WHITE_BALANCE_AUTO, + }, { + .id = V4L2_CID_COLORFX, + .minimum = V4L2_COLORFX_NONE, + .maximum = V4L2_COLORFX_VIVID, + .step = 1, + .value = V4L2_COLORFX_NONE, + .default_value = V4L2_COLORFX_NONE, + }, { + .id = V4L2_CID_CAMERA_SCENE_MODE, + .minimum = SCENE_MODE_NONE, + .maximum = SCENE_MODE_MAX - 1, + .step = 1, + .value = SCENE_MODE_NONE, + .default_value = SCENE_MODE_MAX, + }, { + /* Zoom */ + .id = V4L2_CID_ZOOM_ABSOLUTE, + .minimum = ZOOM_LEVEL_0, + .maximum = ZOOM_LEVEL_MAX - 1, + .step = 1, + .value = ZOOM_LEVEL_0, + .default_value = ZOOM_LEVEL_0, + }, { + /* Focus */ + .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT, + .minimum = 0, + .maximum = 4000, /* FIXME */ + .step = 1, + .value = 0, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP, + .minimum = 0, + .maximum = 3000, /* FIXME */ + .step = 1, + .value = 0, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH, + .minimum = 0, + .maximum = 4000, /* FIXME */ + .step = 1, + .value = 0, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT, + .minimum = 0, + .maximum = 3000, /* FIXME */ + .step = 1, + .value = 0, + .default_value = 0, + }, { + .id = V4L2_CID_CAMERA_FOCUS_MODE, + .minimum = FOCUS_MODE_AUTO, + .maximum = FOCUS_MODE_MAX, + .step = 1, + .value = FOCUS_MODE_AUTO, + .default_value = FOCUS_MODE_AUTO, + }, { + .id = V4L2_CID_CAMERA_SET_AUTO_FOCUS, + .minimum = 0, + .maximum = 1, + .step = 1, + .value = 0, + .default_value = 0, + }, { + .id = V4L2_CID_PHYSICAL_ROTATION, + .minimum = IS_ROTATION_0, + .maximum = IS_ROTATION_MAX - 1, + .step = 1, + .value = IS_ROTATION_90, + .default_value = IS_ROTATION_90, + }, +#else + { + .id = V4L2_CID_CAMERA_BRIGHTNESS, + .minimum = EV_MINUS_4, + .maximum = EV_MAX - 1, + .step = 1, + .value = EV_DEFAULT, + .default_value = EV_DEFAULT, + }, { + .id = V4L2_CID_CAMERA_SATURATION, + .minimum = SATURATION_MINUS_2, + .maximum = SATURATION_MAX - 1, + .step = 1, + .value = SATURATION_DEFAULT, + .default_value = SATURATION_DEFAULT, + }, { + .id = V4L2_CID_CAMERA_SHARPNESS, + .minimum = SHARPNESS_MINUS_2, + .maximum = SHARPNESS_MAX - 1, + .step = 1, + .value = SHARPNESS_DEFAULT, + .default_value = SHARPNESS_DEFAULT, + }, { + /* Zoom */ + .id = V4L2_CID_CAMERA_ZOOM, + .minimum = ZOOM_LEVEL_0, + .maximum = ZOOM_LEVEL_MAX - 1, + .step = 1, + .value = ZOOM_LEVEL_0, + .default_value = ZOOM_LEVEL_0, + }, +#endif + +}; + +static u8 sysfs_sensor_fw[10] = {0,}; +static u8 sysfs_phone_fw[10] = {0,}; +static u8 sysfs_sensor_type[15] = {0,}; +static u8 sysfs_isp_core[10] = {0,}; + +static int s5c73m3_s_stream_sensor(struct v4l2_subdev *sd, int onoff); +static int s5c73m3_set_touch_auto_focus(struct v4l2_subdev *sd); +static int s5c73m3_SPI_booting(struct v4l2_subdev *sd); +static int s5c73m3_get_af_cal_version(struct v4l2_subdev *sd); + +static inline struct s5c73m3_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct s5c73m3_state, sd); +} + +static int s5c73m3_i2c_write(struct v4l2_subdev *sd, + unsigned short addr, unsigned short data) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_msg msg; + unsigned char buf[4]; + int i, err; + + if (!client->adapter) + return -ENODEV; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = sizeof(buf); + msg.buf = buf; + + buf[0] = addr >> 8; + buf[1] = addr & 0xff; + buf[2] = data >> 8; + buf[3] = data & 0xff; + + cam_i2c_dbg("addr %#x, data %#x\n", addr, data); + + for (i = S5C73M3_I2C_RETRY; i; i--) { + err = i2c_transfer(client->adapter, &msg, 1); + if (err == 1) + break; + msleep(20); + } + + return err; +} + +static int s5c73m3_i2c_write_block(struct v4l2_subdev *sd, + const u32 regs[], int size) +{ + int i, err = 0; + + for (i = 0; i < size; i++) { + err = s5c73m3_i2c_write(sd, (regs[i]>>16), regs[i]); + CHECK_ERR(err); + } + + return err; +} + +static int s5c73m3_i2c_read(struct v4l2_subdev *sd, + unsigned short addr, unsigned short *data) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_msg msg; + unsigned char buf[2]; + int i, err; + + if (!client->adapter) + return -ENODEV; + + msg.addr = client->addr; + msg.flags = 0; + msg.len = sizeof(buf); + msg.buf = buf; + + buf[0] = addr >> 8; + buf[1] = addr & 0xff; + + for (i = S5C73M3_I2C_RETRY; i; i--) { + err = i2c_transfer(client->adapter, &msg, 1); + if (err == 1) + break; + msleep(20); + } + + if (err != 1) { + cam_err("addr %#x\n", addr); + return err; + } + + msg.flags = I2C_M_RD; + + for (i = S5C73M3_I2C_RETRY; i; i--) { + err = i2c_transfer(client->adapter, &msg, 1); + if (err == 1) + break; + msleep(20); + } + + if (err != 1) { + cam_err("addr %#x\n", addr); + return err; + } + + *data = ((buf[0] << 8) | buf[1]); + + return err; +} + +static int s5c73m3_write(struct v4l2_subdev *sd, + unsigned short addr1, unsigned short addr2, unsigned short data) +{ + int err; + + err = s5c73m3_i2c_write(sd, 0x0050, addr1); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, addr2); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, data); + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_read(struct v4l2_subdev *sd, + unsigned short addr1, unsigned short addr2, unsigned short *data) +{ + int err; + + err = s5c73m3_i2c_write(sd, 0xfcfc, 0x3310); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0058, addr1); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x005C, addr2); + CHECK_ERR(err); + + err = s5c73m3_i2c_read(sd, 0x0F14, data); + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_i2c_check_status(struct v4l2_subdev *sd) +{ + int err = 0; + int index = 0; + u16 status = 0; + u16 i2c_status = 0; + + do { + err = s5c73m3_read(sd, 0x0009, 0x5080, &status); + if (status == 0xffff) + break; + err = s5c73m3_read(sd, 0x0009, 0x599E, &i2c_status); + if (i2c_status != 0) + cam_dbg("i2c_status = %#x\n", i2c_status); + + index++; + udelay(500); + } while (index < 2000); /* 1 sec */ + + cam_dbg("index : %d, status : %#x, i2c_stauts : %#x\n", + index, status, i2c_status); + + if (index >= 2000) + err = -1; + + return err; +} + +static int s5c73m3_writeb_no_check_status(struct v4l2_subdev *sd, + unsigned short addr, unsigned short data) +{ + int err; + + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5000); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, addr); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, data); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5080); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001); + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_writeb(struct v4l2_subdev *sd, + unsigned short addr, unsigned short data) +{ + int err; + err = s5c73m3_i2c_check_status(sd); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5000); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, addr); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, data); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5080); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001); + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_set_mode(struct v4l2_subdev *sd) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_trace("E\n"); + + if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { + if (state->hdr_mode) { + err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT, + S5C73M3_HDR_OUTPUT); + CHECK_ERR(err); + cam_dbg("hdr ouput mode\n"); + } else { + err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT, + S5C73M3_YUV_OUTPUT); + CHECK_ERR(err); + cam_dbg("yuv ouput mode\n"); + } + } else { + if (state->hybrid_mode) { + err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT, + S5C73M3_HYBRID_OUTPUT); + CHECK_ERR(err); + cam_dbg("hybrid ouput mode\n"); + } else { + err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT, + S5C73M3_INTERLEAVED_OUTPUT); + CHECK_ERR(err); + cam_dbg("interleaved ouput mode\n"); + } + } + + cam_trace("X\n"); + return 0; +} + +/* + * v4l2_subdev_core_ops + */ +static int s5c73m3_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s5c73m3_ctrls); i++) { + if (qc->id == s5c73m3_ctrls[i].id) { + qc->maximum = s5c73m3_ctrls[i].maximum; + qc->minimum = s5c73m3_ctrls[i].minimum; + qc->step = s5c73m3_ctrls[i].step; + qc->default_value = s5c73m3_ctrls[i].default_value; + return 0; + } + } + + return -EINVAL; +} + +#ifdef CONFIG_TARGET_LOCALE_KOR +static int s5c73m3_set_antibanding(struct v4l2_subdev *sd, int val) +{ + return 0; +} +#endif + +static int s5c73m3_set_af_softlanding(struct v4l2_subdev *sd) +{ + int err = 0; + + cam_trace("E\n"); + + err = s5c73m3_writeb(sd, S5C73M3_AF_SOFTLANDING, + S5C73M3_AF_SOFTLANDING_ON); + CHECK_ERR(err); + cam_trace("X\n"); + + return 0; +} + +static int s5c73m3_dump_fw(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5c73m3_get_sensor_fw_version(struct v4l2_subdev *sd) +{ + struct s5c73m3_state *state = to_state(sd); + u16 read_val; + u16 sensor_fw; + u16 sensor_type; + int i; + int err = 0; + + /*ARM go*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF); + CHECK_ERR(err); + + udelay(400); + + /*Check boot done*/ + for (i = 0; i < 3; i++) { + err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val); + CHECK_ERR(err); + + if (read_val == 0x0C) + break; + + udelay(100); + } + + if (read_val != 0x0C) { + cam_err("boot fail, read_val %#x\n", read_val); + return -1; + } + + /*P,M,S and Boot Mode*/ + err = s5c73m3_write(sd, 0x3010, 0x0014, 0x2146); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3010, 0x0010, 0x230C); + CHECK_ERR(err); + + udelay(200); + + /*Check SPI ready*/ + for (i = 0; i < 300; i++) { + err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val); + CHECK_ERR(err); + + if (read_val == 0x230E) + break; + + udelay(100); + } + + if (read_val != 0x230E) { + cam_err("SPI not ready, read_val %#x\n", read_val); + return -1; + } + + /*ARM reset*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFD); + CHECK_ERR(err); + + /*remap*/ + err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183); + CHECK_ERR(err); + + /*ARM go again*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF); + CHECK_ERR(err); + + for (i = 0; i < 3; i++) { + err = s5c73m3_read(sd, 0x0000, 0x0060+i*2, &sensor_fw); + CHECK_ERR(err); + state->sensor_fw[i*2] = sensor_fw&0x00ff; + state->sensor_fw[i*2+1] = (sensor_fw&0xff00)>>8; + } + state->sensor_fw[i*2+2] = ' '; + + for (i = 0; i < 6; i++) { + err = s5c73m3_read(sd, 0x0000, 0x0066+i*2, &sensor_type); + CHECK_ERR(err); + state->sensor_type[i*2] = sensor_type&0x00ff; + state->sensor_type[i*2+1] = (sensor_type&0xff00)>>8; + } + state->sensor_type[i*2+2] = ' '; + + memcpy(sysfs_sensor_fw, state->sensor_fw, + sizeof(state->sensor_fw)); + memcpy(sysfs_sensor_type, state->sensor_type, + sizeof(state->sensor_type)); + + cam_dbg("Sensor_version = %s, Sensor_Type = %s\n", + state->sensor_fw, state->sensor_type); + + if ((state->sensor_fw[0] < 'A') || state->sensor_fw[0] > 'Z') { + cam_dbg("Sensor Version is invalid data\n"); + err = -1; + } + return err; +} + + +static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd) +{ + struct device *dev = sd->v4l2_dev->dev; + struct s5c73m3_state *state = to_state(sd); + const struct firmware *fw = {0, }; + char fw_path[20] = {0,}; + u8 *buf = NULL; + int err = 0; + + struct file *fp; + mm_segment_t old_fs; + long nread; + int fw_requested = 1; + + buf = vmalloc(S5C73M3_FW_VER_LEN+1); + if (!buf) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + fp = filp_open(S5C73M3_FW_PATH, O_RDONLY, 0); + if (IS_ERR(fp)) { + cam_trace("failed to open %s, err %ld\n", + S5C73M3_FW_PATH, PTR_ERR(fp)); + goto request_fw; + } + + fw_requested = 0; + err = vfs_llseek(fp, S5C73M3_FW_VER_FILE_CUR, SEEK_SET); + if (err < 0) { + cam_warn("failed to fseek, %d\n", err); + goto out; + } + + nread = vfs_read(fp, (char __user *)buf, + S5C73M3_FW_VER_LEN, + &fp->f_pos); + + if (nread != S5C73M3_FW_VER_LEN) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } + +request_fw: + if (fw_requested) { + set_fs(old_fs); + + if (state->sensor_fw[0] == 'O') { + sprintf(fw_path, "SlimISP_G%c.bin", + state->sensor_fw[1]); + } else if (state->sensor_fw[0] == 'S') { + sprintf(fw_path, "SlimISP_Z%c.bin", + state->sensor_fw[1]); + } else { + sprintf(fw_path, "SlimISP_%c%c.bin", + state->sensor_fw[0], + state->sensor_fw[1]); + } + cam_dbg("file_name = %s\n", fw_path); + + err = request_firmware(&fw, fw_path, dev); + if (err != 0) { + cam_err("request_firmware falied\n"); + err = -EINVAL; + goto out; + } + + memcpy(buf, (u8 *)&fw->data[S5C73M3_FW_VER_FILE_CUR], + S5C73M3_FW_VER_LEN); + + } + + memcpy(state->phone_fw, buf, S5C73M3_FW_VER_LEN); + state->phone_fw[S5C73M3_FW_VER_LEN+1] = ' '; + + memcpy(sysfs_phone_fw, state->phone_fw, sizeof(state->phone_fw)); + cam_dbg("Phone_version = %s\n", state->phone_fw); + + cam_dbg("end\n"); + +out: + if (!fw_requested) { + vfree(buf); + + filp_close(fp, current->files); + set_fs(old_fs); + } else { + release_firmware(fw); + } + + return err; +} + +static int s5c73m3_update_camerafw_to_FROM(struct v4l2_subdev *sd) +{ + int err; + int index = 0; + u16 status = 0; + + do { + /* stauts 0 : not ready ISP */ + if (status == 0) { + err = s5c73m3_writeb(sd, 0x0906, 0x0000); + CHECK_ERR(err); + } + + err = s5c73m3_read(sd, 0x0009, 0x5906, &status); + /* Success : 0x05, Fail : 0x07 , Progressing : 0xFFFF*/ + if (status == 0x0005 || + status == 0x0007) + break; + + index++; + msleep(20); + } while (index < 500); /* 10 sec */ + + + if (status == 0x0007) + return -1; + else + return 0; +} + +static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + + if (download) { + err = state->pdata->is_isp_reset(); + CHECK_ERR(err); + } + + err = s5c73m3_get_sensor_fw_version(sd); + err = s5c73m3_get_phone_fw_version(sd); + + if (state->phone_fw[0] == 'Z' || state->phone_fw[0] == 'G' || + state->phone_fw[0] == 'S' || state->phone_fw[0] == 'O') { + err = state->pdata->is_isp_reset(); + CHECK_ERR(err); + + err = s5c73m3_SPI_booting(sd); + CHECK_ERR(err); + + if (download) { + err = s5c73m3_update_camerafw_to_FROM(sd); + CHECK_ERR(err); + } + } + s5c73m3_get_af_cal_version(sd); + return 0; +} + +static int s5c73m3_set_sensor_mode(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case SENSOR_CAMERA: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_AUTO_MODE_AE_SET); + CHECK_ERR(err); + break; + + case SENSOR_MOVIE: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_30FPS); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = SENSOR_CAMERA; + goto retry; + } + state->sensor_mode = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_flash(struct v4l2_subdev *sd, int val, int recording) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case FLASH_MODE_OFF: + err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE, + S5C73M3_FLASH_MODE_OFF); + CHECK_ERR(err); + err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH, + S5C73M3_FLASH_TORCH_OFF); + CHECK_ERR(err); + break; + + case FLASH_MODE_AUTO: + err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH, + S5C73M3_FLASH_TORCH_OFF); + CHECK_ERR(err); + err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE, + S5C73M3_FLASH_MODE_AUTO); + CHECK_ERR(err); + break; + + case FLASH_MODE_ON: + err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH, + S5C73M3_FLASH_TORCH_OFF); + CHECK_ERR(err); + err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE, + S5C73M3_FLASH_MODE_ON); + CHECK_ERR(err); + break; + + case FLASH_MODE_TORCH: + err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE, + S5C73M3_FLASH_MODE_OFF); + CHECK_ERR(err); + err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH, + S5C73M3_FLASH_TORCH_ON); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = FLASH_MODE_OFF; + goto retry; + } + state->flash_mode = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + int err; + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", ctrl->value); + +retry: + switch (ctrl->value) { + case ISO_AUTO: + err = s5c73m3_writeb(sd, S5C73M3_ISO, + S5C73M3_ISO_AUTO); + CHECK_ERR(err); + break; + + case ISO_50: + case ISO_100: + err = s5c73m3_writeb(sd, S5C73M3_ISO, + S5C73M3_ISO_100); + CHECK_ERR(err); + break; + + case ISO_200: + err = s5c73m3_writeb(sd, S5C73M3_ISO, + S5C73M3_ISO_200); + CHECK_ERR(err); + break; + + case ISO_400: + err = s5c73m3_writeb(sd, S5C73M3_ISO, + S5C73M3_ISO_400); + CHECK_ERR(err); + break; + + case ISO_800: + err = s5c73m3_writeb(sd, S5C73M3_ISO, + S5C73M3_ISO_800); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", ctrl->value); + ctrl->value = ISO_AUTO; + goto retry; + } + + state->exif.iso = ctrl->value; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_metering(struct v4l2_subdev *sd, int val) +{ + int err; + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case METERING_CENTER: + err = s5c73m3_writeb(sd, S5C73M3_METER, + S5C73M3_METER_CENTER); + CHECK_ERR(err); + break; + + case METERING_SPOT: + err = s5c73m3_writeb(sd, S5C73M3_METER, + S5C73M3_METER_SPOT); + CHECK_ERR(err); + break; + + case METERING_MATRIX: + err = s5c73m3_writeb(sd, S5C73M3_METER, + S5C73M3_METER_AVERAGE); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = METERING_CENTER; + goto retry; + } + + state->exif.metering = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_exposure(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int err; + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", ctrl->value); + + if (ctrl->value < -4 || ctrl->value > 4) { + cam_warn("invalid value, %d\n", ctrl->value); + ctrl->value = 0; + } + err = s5c73m3_writeb(sd, S5C73M3_EV, + ctrl->value + 4); + CHECK_ERR(err); + + state->exif.bv = ctrl->value; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_contrast(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int err; + int contrast = 0; + cam_dbg("E, value %d\n", ctrl->value); + + if (ctrl->value < -2 || ctrl->value > 2) { + cam_warn("invalid value, %d\n", ctrl->value); + ctrl->value = 0; + } + if (ctrl->value < 0) + contrast = (ctrl->value * (-1)) + 2; + else + contrast = ctrl->value; + err = s5c73m3_writeb(sd, S5C73M3_CONTRAST, + contrast); + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_whitebalance(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case WHITE_BALANCE_AUTO: + err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE, + S5C73M3_AWB_MODE_AUTO); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_SUNNY: + err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE, + S5C73M3_AWB_MODE_DAYLIGHT); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_CLOUDY: + err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE, + S5C73M3_AWB_MODE_CLOUDY); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_TUNGSTEN: + err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE, + S5C73M3_AWB_MODE_INCANDESCENT); + CHECK_ERR(err); + break; + + case WHITE_BALANCE_FLUORESCENT: + err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE, + S5C73M3_AWB_MODE_FLUORESCENT1); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = WHITE_BALANCE_AUTO; + goto retry; + } + + state->wb_mode = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_sharpness(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", ctrl->value); + + cam_err("Sharpness control is not supported\n"); + + state->exif.sharpness = ctrl->value; + + return 0; +} + +static int s5c73m3_set_saturation(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", ctrl->value); + + cam_err("Saturation control is not supported\n"); + + state->exif.saturation = ctrl->value; + + return 0; +} + +static int s5c73m3_set_scene_mode(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case SCENE_MODE_NONE: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_NONE); + CHECK_ERR(err); + break; + + case SCENE_MODE_PORTRAIT: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_PORTRAIT); + CHECK_ERR(err); + break; + + case SCENE_MODE_LANDSCAPE: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_LANDSCAPE); + CHECK_ERR(err); + break; + + case SCENE_MODE_SPORTS: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_SPORTS); + CHECK_ERR(err); + break; + + case SCENE_MODE_PARTY_INDOOR: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_INDOOR); + CHECK_ERR(err); + break; + + case SCENE_MODE_BEACH_SNOW: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_BEACH); + CHECK_ERR(err); + break; + + case SCENE_MODE_SUNSET: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_SUNSET); + CHECK_ERR(err); + break; + + case SCENE_MODE_DUSK_DAWN: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_DAWN); + CHECK_ERR(err); + break; + + case SCENE_MODE_FALL_COLOR: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_FALL); + CHECK_ERR(err); + break; + + case SCENE_MODE_NIGHTSHOT: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_NIGHT); + CHECK_ERR(err); + break; + + case SCENE_MODE_BACK_LIGHT: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_AGAINSTLIGHT); + CHECK_ERR(err); + break; + + case SCENE_MODE_FIREWORKS: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_FIRE); + CHECK_ERR(err); + break; + + case SCENE_MODE_TEXT: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_TEXT); + CHECK_ERR(err); + break; + + case SCENE_MODE_CANDLE_LIGHT: + err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE, + S5C73M3_SCENE_MODE_CANDLE); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = SCENE_MODE_NONE; + goto retry; + } + + state->scene_mode = val; + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_capture_firework(struct v4l2_subdev *sd) +{ + int err = 0; + + cam_dbg("E, capture_firework\n"); + + err = s5c73m3_writeb(sd, S5C73M3_FIREWORK_CAPTURE, 0x0001); + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_set_effect(struct v4l2_subdev *sd, int val) +{ + int err; + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case IMAGE_EFFECT_NONE: + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT, + S5C73M3_IMAGE_EFFECT_NONE); + CHECK_ERR(err); + break; + + case IMAGE_EFFECT_SEPIA: + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT, + S5C73M3_IMAGE_EFFECT_SEPIA); + CHECK_ERR(err); + break; + + case IMAGE_EFFECT_BNW: + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT, + S5C73M3_IMAGE_EFFECT_MONO); + CHECK_ERR(err); + break; + + case IMAGE_EFFECT_NEGATIVE: + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT, + S5C73M3_IMAGE_EFFECT_NEGATIVE); + CHECK_ERR(err); + break; + + case IMAGE_EFFECT_AQUA: + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT, + S5C73M3_IMAGE_EFFECT_AQUA); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = IMAGE_EFFECT_NONE; + goto retry; + } + + state->exif.effect = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_wdr(struct v4l2_subdev *sd, int val) +{ + int err; + struct s5c73m3_state *state = to_state(sd); + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case WDR_OFF: + err = s5c73m3_writeb(sd, S5C73M3_WDR, + S5C73M3_WDR_OFF); + CHECK_ERR(err); + break; + + case WDR_ON: + err = s5c73m3_writeb(sd, S5C73M3_WDR, + S5C73M3_WDR_ON); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = WDR_OFF; + goto retry; + } + state->exif.wdr = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_antishake(struct v4l2_subdev *sd, int val) +{ + int err = 0; + if (val) { + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_ANTI_SHAKE); + CHECK_ERR(err); + } else { + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_AUTO_MODE_AE_SET); + CHECK_ERR(err); + } + return err; +} + +static int s5c73m3_set_face_beauty(struct v4l2_subdev *sd, int val) +{ + return 0; +} + +static int s5c73m3_set_ae_lock(struct v4l2_subdev *sd, int val) +{ + int err; + + if (val) + err = s5c73m3_writeb(sd, S5C73M3_AE_CON, S5C73M3_AE_STOP); + else + err = s5c73m3_writeb(sd, S5C73M3_AE_CON, S5C73M3_AE_START); + + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_set_awb_lock(struct v4l2_subdev *sd, int val) +{ + int err; + + if (val) + err = s5c73m3_writeb(sd, S5C73M3_AWB_CON, S5C73M3_AWB_STOP); + else + err = s5c73m3_writeb(sd, S5C73M3_AWB_CON, S5C73M3_AWB_START); + + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_set_ae_awb_lock(struct v4l2_subdev *sd, int val) +{ + return 0; +} + +static int s5c73m3_get_af_cal_version(struct v4l2_subdev *sd) +{ + struct s5c73m3_state *state = to_state(sd); + u16 status = 0; + int err = 0; + + /* Calibration Device */ + err = s5c73m3_read(sd, 0x0009, 0x300C, &status); + CHECK_ERR(err); + state->cal_device = status; + + /* Calibration DLL Version */ + status = 0; + err = s5c73m3_read(sd, 0x0009, 0x4FF8, &status); + CHECK_ERR(err); + state->cal_dll = status; + + cam_dbg("Cal_Device = 0x%x, Cal_DLL = 0x%x\n", + state->cal_device, state->cal_dll); + + return 0; +} + +static int s5c73m3_stop_af_lens(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_dbg("E, value\n"); + + if (val == CAF_START) { + if (state->focus.mode == FOCUS_MODE_CONTINOUS_VIDEO) { + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_MOVIE_CAF_START); + + } else { + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_PREVIEW_CAF_START); + } + } else { + err = s5c73m3_writeb(sd, S5C73M3_AF_CON, + S5C73M3_AF_CON_STOP); + } + CHECK_ERR(err); + + cam_dbg("X\n"); + + return err; +} + +static int s5c73m3_set_af(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + + cam_info("%s, mode %#x\n", val ? "start" : "stop", state->focus.mode); + + state->focus.status = 0; + + if (val) { + state->isflash = S5C73M3_ISNEED_FLASH_ON; + + if (state->focus.mode == FOCUS_MODE_TOUCH) + err = s5c73m3_set_touch_auto_focus(sd); + else + err = s5c73m3_writeb(sd, S5C73M3_AF_CON, + S5C73M3_AF_CON_START); + } else { + err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH + , S5C73M3_STILL_MAIN_FLASH_CANCEL); + err = s5c73m3_writeb(sd, S5C73M3_AF_CON, + S5C73M3_AF_CON_STOP); + state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED; + } + + CHECK_ERR(err); + + cam_info("X\n"); + return err; +} + +static int s5c73m3_get_pre_flash(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int err = 0; + u16 pre_flash = false; + + s5c73m3_read(sd, 0x0009, S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash); + ctrl->value = pre_flash; + return err; +} + +static int s5c73m3_get_af_result(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + u16 af_status = S5C73M3_AF_STATUS_UNFOCUSED; + /*u16 temp_status = 0;*/ + + err = s5c73m3_read(sd, 0x0009, S5C73M3_AF_STATUS, &af_status); + + /*err = s5c73m3_read(sd, 0x0009, 0x5840, &temp_status);*/ + + switch (af_status) { + case S5C73M3_AF_STATUS_FOCUSING: + case S5C73M3_CAF_STATUS_FOCUSING: + case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR: + case S5C73M3_AF_STATUS_INVALID: + ctrl->value = CAMERA_AF_STATUS_IN_PROGRESS; + break; + + case S5C73M3_AF_STATUS_FOCUSED: + case S5C73M3_CAF_STATUS_FOCUSED: + ctrl->value = CAMERA_AF_STATUS_SUCCESS; + break; + + case S5C73M3_CAF_STATUS_UNFOCUSED: + case S5C73M3_AF_STATUS_UNFOCUSED: + default: + ctrl->value = CAMERA_AF_STATUS_FAIL; + break; + } + state->focus.status = af_status; + + /*cam_dbg("af_status = %d, frame_cnt = %d\n", + state->focus.status, temp_status);*/ + return err; +} + +static int s5c73m3_set_af_mode(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case FOCUS_MODE_AUTO: + case FOCUS_MODE_INFINITY: + if (state->focus.mode != FOCUS_MODE_CONTINOUS_PICTURE) { + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_NORMAL); + CHECK_ERR(err); + } else { + err = s5c73m3_writeb(sd, S5C73M3_AF_CON, + S5C73M3_AF_CON_STOP); + CHECK_ERR(err); + } + + state->focus.mode = val; + state->caf_mode = S5C73M3_AF_MODE_NORMAL; + break; + + case FOCUS_MODE_MACRO: + if (state->focus.mode != FOCUS_MODE_CONTINOUS_PICTURE_MACRO) { + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_MACRO); + CHECK_ERR(err); + } else { + err = s5c73m3_writeb(sd, S5C73M3_AF_CON, + S5C73M3_AF_CON_STOP); + CHECK_ERR(err); + } + + state->focus.mode = val; + state->caf_mode = S5C73M3_AF_MODE_MACRO; + break; + + case FOCUS_MODE_CONTINOUS_PICTURE: + state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED; + + if (val != state->focus.mode && + state->caf_mode != S5C73M3_AF_MODE_NORMAL) { + state->focus.mode = val; + + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_NORMAL); + CHECK_ERR(err); + state->caf_mode = S5C73M3_AF_MODE_NORMAL; + } + + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_PREVIEW_CAF_START); + CHECK_ERR(err); + break; + + case FOCUS_MODE_CONTINOUS_PICTURE_MACRO: + state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED; + if (val != state->focus.mode && + state->caf_mode != S5C73M3_AF_MODE_MACRO) { + state->focus.mode = val; + + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_MACRO); + state->caf_mode = S5C73M3_AF_MODE_MACRO; + CHECK_ERR(err); + } + + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_PREVIEW_CAF_START); + CHECK_ERR(err); + break; + + case FOCUS_MODE_CONTINOUS_VIDEO: + state->focus.mode = val; + + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_MOVIE_CAF_START); + CHECK_ERR(err); + break; + + case FOCUS_MODE_FACEDETECT: + state->focus.mode = val; + break; + + case FOCUS_MODE_TOUCH: + state->focus.mode = val; + break; + + default: + cam_warn("invalid value, %d\n", val); + val = FOCUS_MODE_AUTO; + goto retry; + } + + state->focus.mode = val; + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_touch_auto_focus(struct v4l2_subdev *sd) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + + cam_dbg("s5c73m3_set_touch_auto_focus\n"); + +#ifdef CONFIG_VIDEO_SLP_S5C73M3 + cam_dbg("Rectangle Position(%d,%d,%d,%d)\n", + state->focus.top, state->focus.left, + state->focus.width, state->focus.height); + state->focus.pos_x = state->focus.left + state->focus.width / 2; + state->focus.pos_y = state->focus.top + state->focus.height / 2; +#endif + cam_dbg("Touch Position(%d,%d)\n", + state->focus.pos_x, state->focus.pos_y); + cam_dbg("Preview Size(%d,%d)\n", + state->preview->width, state->preview->height); + + err = s5c73m3_i2c_write(sd, 0xfcfc, 0x3310); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, S5C73M3_AF_TOUCH_POSITION); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_x); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_y); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->width); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->height); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5000); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0E0A); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0000); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5080); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001); + CHECK_ERR(err); + + return 0; +} + +static int s5c73m3_set_zoom(struct v4l2_subdev *sd, int value) +{ + int err; + cam_dbg("E, value %d\n", value); + +retry: + if (value < 0 || value > 30) { + cam_warn("invalid value, %d\n", value); + value = 0; + goto retry; + } + err = s5c73m3_writeb_no_check_status(sd, S5C73M3_ZOOM_STEP, + value); + CHECK_ERR(err); + mdelay(10); + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_set_jpeg_quality(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + int val = ctrl->value, err; + cam_dbg("E, value %d\n", val); + + if (val <= 65) /* Normal */ + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_QUALITY, + S5C73M3_IMAGE_QUALITY_NORMAL); + else if (val <= 75) /* Fine */ + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_QUALITY, + S5C73M3_IMAGE_QUALITY_FINE); + else /* Superfine */ + err = s5c73m3_writeb(sd, S5C73M3_IMAGE_QUALITY, + S5C73M3_IMAGE_QUALITY_SUPERFINE); + + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_get_exif(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5c73m3_aeawb_lock_unlock(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + int ae_lock = val & 0x1; + int awb_lock = (val & 0x2) >> 1; + int ae_lock_changed = + ~(ae_lock & state->ae_lock) & (ae_lock | state->ae_lock); + int awb_lock_changed = + ~(awb_lock & state->awb_lock) & (awb_lock | state->awb_lock); + + if (ae_lock_changed) { + cam_dbg("ae lock - %s\n", ae_lock ? "true" : "false"); + err = s5c73m3_writeb(sd, S5C73M3_AE_CON, + ae_lock ? S5C73M3_AE_STOP : S5C73M3_AE_START); + CHECK_ERR(err); + state->ae_lock = ae_lock; + } + if (awb_lock_changed && + state->wb_mode == WHITE_BALANCE_AUTO) { + cam_dbg("awb lock - %s\n", awb_lock ? "true" : "false"); + err = s5c73m3_writeb(sd, S5C73M3_AWB_CON, + awb_lock ? S5C73M3_AWB_STOP : S5C73M3_AWB_START); + CHECK_ERR(err); + state->awb_lock = awb_lock; + } + + return 0; +} + +static int s5c73m3_start_capture(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + u16 isneed_flash = false; + u16 pre_flash = false; + + s5c73m3_read(sd, 0x0009, S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash); + + if (state->flash_mode == FLASH_MODE_ON) { + if (!pre_flash) { + err = s5c73m3_writeb(sd, S5C73M3_STILL_PRE_FLASH + , S5C73M3_STILL_PRE_FLASH_FIRE); + msleep(100); + } + err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH + , S5C73M3_STILL_MAIN_FLASH_FIRE); + } else if (state->flash_mode == FLASH_MODE_AUTO) { + if (pre_flash) { + err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH + , S5C73M3_STILL_MAIN_FLASH_FIRE); + } else if (state->isflash != S5C73M3_ISNEED_FLASH_ON) { + err = s5c73m3_read(sd, 0x0009, + S5C73M3_AE_ISNEEDFLASH | 0x5000, &isneed_flash); + if (isneed_flash) { + err = s5c73m3_writeb(sd, S5C73M3_STILL_PRE_FLASH + , S5C73M3_STILL_PRE_FLASH_FIRE); + msleep(100); + err = s5c73m3_writeb(sd, + S5C73M3_STILL_MAIN_FLASH, + S5C73M3_STILL_MAIN_FLASH_FIRE); + } + } + } + + state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED; + + return 0; +} + +static int s5c73m3_set_auto_bracket_mode(struct v4l2_subdev *sd) +{ + int err = 0; + + err = s5c73m3_writeb(sd, S5C73M3_AE_AUTO_BRAKET, + S5C73M3_AE_AUTO_BRAKET_EV20); + CHECK_ERR(err); + + return err; +} + +static int s5c73m3_check_dataline(struct v4l2_subdev *sd, int val) +{ + return 0; +} + +static int s5c73m3_check_esd(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5c73m3_set_frame_rate(struct v4l2_subdev *sd, int fps) +{ + int err = 0; + struct s5c73m3_state *state = to_state(sd); + + if (!state->stream_enable) { + state->fps = fps; + return 0; + } + + switch (fps) { + case 30: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_30FPS); /* 30fps */ + break; + case 20: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_20FPS); /* 20fps */ + break; + case 15: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_FIXED_15FPS); /* 15fps */ + break; + default: + err = s5c73m3_writeb(sd, S5C73M3_AE_MODE, + S5C73M3_AUTO_MODE_AE_SET); /* auto */ + break; + } + return err; +} + +static int s5c73m3_set_face_zoom(struct v4l2_subdev *sd, int val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + + cam_dbg("s5c73m3_set_face_zoom\n"); +#ifdef CONFIG_VIDEO_SLP_S5C73M3 + cam_dbg("Rectangle Position(%d,%d,%d,%d)\n", + state->focus.top, state->focus.left, + state->focus.width, state->focus.height); + state->focus.pos_x = state->focus.left + state->focus.width / 2; + state->focus.pos_y = state->focus.top + state->focus.height / 2; +#endif + cam_dbg("Touch Position(%d,%d)\n", + state->focus.pos_x, state->focus.pos_y); + cam_dbg("Preview Size(%d,%d)\n", + state->preview->width, state->preview->height); + + err = s5c73m3_i2c_write(sd, 0xfcfc, 0x3310); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, S5C73M3_AF_TOUCH_POSITION); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_x); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_y); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->width); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->height); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5000); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, S5C73M3_AF_FACE_ZOOM); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, val); /*0:reset, 1:Start*/ + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5080); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001); + CHECK_ERR(err); + + return 0; +} + + +static int s5c73m3_set_face_detection(struct v4l2_subdev *sd, int val) +{ + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case FACE_DETECTION_ON: + err = s5c73m3_writeb(sd, S5C73M3_FACE_DET, + S5C73M3_FACE_DET_ON); + CHECK_ERR(err); + + err = s5c73m3_writeb(sd, S5C73M3_AF_MODE, + S5C73M3_AF_MODE_PREVIEW_CAF_START); + CHECK_ERR(err); + + break; + + case FACE_DETECTION_OFF: + err = s5c73m3_writeb(sd, S5C73M3_FACE_DET, + S5C73M3_FACE_DET_OFF); + CHECK_ERR(err); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = FACE_DETECTION_OFF; + goto retry; + } + + cam_trace("X\n"); + return 0; + +} + +static int s5c73m3_set_hybrid_capture(struct v4l2_subdev *sd) +{ + int err; + cam_trace("E\n"); + + err = s5c73m3_writeb(sd, S5C73M3_HYBRID_CAPTURE, 1); + + CHECK_ERR(err); + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + + if (unlikely(state->isp.bad_fw && ctrl->id != V4L2_CID_CAM_UPDATE_FW)) { + cam_err("\"Unknown\" state, please update F/W"); + return -ENOSYS; + } + + switch (ctrl->id) { + case V4L2_CID_CAMERA_FRAME_RATE: + err = s5c73m3_set_frame_rate(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FACE_DETECTION: + err = s5c73m3_set_face_detection(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FACE_ZOOM: + err = s5c73m3_set_face_zoom(sd, ctrl->value); + break; + + case V4L2_CID_CAM_UPDATE_FW: + if (ctrl->value == FW_MODE_DUMP) + err = s5c73m3_dump_fw(sd); + else if (ctrl->value == FW_MODE_UPDATE) + err = s5c73m3_check_fw(sd, 1); + else + err = 0; + break; + + case V4L2_CID_CAMERA_SENSOR_MODE: + err = s5c73m3_set_sensor_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FLASH_MODE: + err = s5c73m3_set_flash(sd, ctrl->value, 0); + break; + + case V4L2_CID_CAMERA_ISO: + err = s5c73m3_set_iso(sd, ctrl); + break; + + case V4L2_CID_CAMERA_METERING: + if (state->sensor_mode == SENSOR_CAMERA) + err = s5c73m3_set_metering(sd, ctrl->value); + break; + + case V4L2_CID_EXPOSURE: + ctrl->value -= 4; + err = s5c73m3_set_exposure(sd, ctrl); + break; + + case V4L2_CID_CAMERA_BRIGHTNESS: + err = s5c73m3_set_exposure(sd, ctrl); + break; + + case V4L2_CID_CAMERA_CONTRAST: + err = s5c73m3_set_contrast(sd, ctrl); + break; + + case V4L2_CID_WHITE_BALANCE_PRESET: + err = s5c73m3_set_whitebalance(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_WHITE_BALANCE: + err = s5c73m3_set_whitebalance(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_SCENE_MODE: + err = s5c73m3_set_scene_mode(sd, ctrl->value); + break; + + case V4L2_CID_COLORFX: + err = s5c73m3_set_effect(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_EFFECT: + err = s5c73m3_set_effect(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_WDR: + err = s5c73m3_set_wdr(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_ANTI_SHAKE: + err = s5c73m3_set_antishake(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_BEAUTY_SHOT: + err = s5c73m3_set_face_beauty(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_DEFAULT_FOCUS_POSITION: + /*err = s5c73m3_set_af_mode(sd, state->focus.mode);*/ + err = 0; + break; + + case V4L2_CID_FOCUS_AUTO_MODE: + err = s5c73m3_set_af_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FOCUS_MODE: + err = s5c73m3_set_af_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_SET_AUTO_FOCUS: + err = s5c73m3_set_af(sd, ctrl->value); + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT: + state->focus.left = ctrl->value; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP: + state->focus.top = ctrl->value; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH: + state->focus.width = ctrl->value; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT: + state->focus.height = ctrl->value; + break; + + case V4L2_CID_CAMERA_OBJECT_POSITION_X: + state->focus.pos_x = ctrl->value; + break; + + case V4L2_CID_CAMERA_OBJECT_POSITION_Y: + state->focus.pos_y = ctrl->value; + break; + + case V4L2_CID_CAMERA_ZOOM: + err = s5c73m3_set_zoom(sd, ctrl->value); + break; + + case V4L2_CID_CAM_JPEG_QUALITY: + err = s5c73m3_set_jpeg_quality(sd, ctrl); + break; + + case V4L2_CID_CAMERA_CAPTURE: + err = s5c73m3_start_capture(sd, ctrl->value); + + if (state->scene_mode == SCENE_MODE_FIREWORKS) + err = s5c73m3_capture_firework(sd); + break; + + case V4L2_CID_CAMERA_HDR: + state->hdr_mode = ctrl->value; + err = 0; + break; + + case V4L2_CID_CAMERA_HYBRID: + state->hybrid_mode = ctrl->value; + err = 0; + break; + + case V4L2_CID_CAMERA_HYBRID_CAPTURE: + err = s5c73m3_set_hybrid_capture(sd); + break; + + case V4L2_CID_CAMERA_VT_MODE: + state->vt_mode = ctrl->value; + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE: + state->check_dataline = ctrl->value; + break; + + case V4L2_CID_CAMERA_CHECK_ESD: + err = s5c73m3_check_esd(sd); + break; + + case V4L2_CID_CAMERA_JPEG_RESOLUTION: + state->jpeg_width = (u32)ctrl->value >> 16; + state->jpeg_height = (u32)ctrl->value & 0x0FFFF; + break; + + case V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK: + err = s5c73m3_aeawb_lock_unlock(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_CAF_START_STOP: + err = s5c73m3_stop_af_lens(sd, ctrl->value); + break; + + case V4L2_CID_SATURATION: + err = s5c73m3_set_saturation(sd, ctrl); + break; + + case V4L2_CID_SHARPNESS: + err = s5c73m3_set_sharpness(sd, ctrl); + break; + + default: + if ((ctrl->id & 0xFFFF) <= 2000) { + cam_err("no such control id(PRIVATE_BASE) %d, value %d\n", + ctrl->id & 0xFFFF, ctrl->value); + /*err = -ENOIOCTLCMD;*/ + } else if ((ctrl->id - V4L2_CID_BASE) <= 10000) { + cam_err("no such control id(BASE_CID) %d\n", + ctrl->id - V4L2_CID_BASE); + } else { + cam_err("no such control id(CAMERA_CLASS_BASE CID) %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + } + err = 0; + break; + } + + if (err < 0 && err != -ENOIOCTLCMD) + cam_err("failed, id %d, value %d\n", + ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); + return err; +} + +static int s5c73m3_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + + switch (ctrl->id) { + case V4L2_CID_CAMERA_CAPTURE: + err = s5c73m3_get_pre_flash(sd, ctrl); + break; + case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT: + err = s5c73m3_get_af_result(sd, ctrl); + break; + + case V4L2_CID_CAM_JPEG_MEMSIZE: + ctrl->value = 0xA00000; + break; + + case V4L2_CID_CAM_JPEG_MAIN_SIZE: + ctrl->value = state->jpeg.main_size; + break; + + case V4L2_CID_CAM_JPEG_MAIN_OFFSET: + ctrl->value = state->jpeg.main_offset; + break; + + case V4L2_CID_CAM_JPEG_THUMB_SIZE: + ctrl->value = state->jpeg.thumb_size; + break; + + case V4L2_CID_CAM_JPEG_THUMB_OFFSET: + ctrl->value = state->jpeg.thumb_offset; + break; + + case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET: + ctrl->value = state->jpeg.postview_offset; + break; + + case V4L2_CID_CAMERA_EXIF_FLASH: + ctrl->value = state->exif.flash; + break; + + case V4L2_CID_CAMERA_ISO: + ctrl->value = state->exif.iso; + break; + + case V4L2_CID_CAMERA_EXIF_ISO: + ctrl->value = state->exif.iso; + break; + + case V4L2_CID_CAMERA_EXIF_TV: + ctrl->value = state->exif.tv; + break; + + case V4L2_CID_CAMERA_EXIF_BV: + ctrl->value = state->exif.bv; + break; + + case V4L2_CID_CAMERA_EXIF_EBV: + ctrl->value = state->exif.ebv; + break; + + case V4L2_CID_WHITE_BALANCE_PRESET: + ctrl->value = state->wb_mode; + break; + + case V4L2_CID_EXPOSURE: + ctrl->value = state->exif.bv; + break; + + case V4L2_CID_COLORFX: + ctrl->value = state->exif.effect; + break; + + case V4L2_CID_SATURATION: + ctrl->value = state->exif.saturation; + break; + + case V4L2_CID_SHARPNESS: + ctrl->value = state->exif.sharpness; + break; + + case V4L2_CID_CAMERA_METERING: + ctrl->value = state->exif.metering; + break; + + case V4L2_CID_CAMERA_WDR: + ctrl->value = state->exif.wdr; + break; + + case V4L2_CID_CAMERA_FLASH_MODE: + ctrl->value = state->flash_mode; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT: + ctrl->value = state->focus.left; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP: + ctrl->value = state->focus.top; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH: + ctrl->value = state->focus.width; + break; + + case V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT: + ctrl->value = state->focus.height; + break; + + case V4L2_CID_CAM_STABILIZE: + cam_err("V4L2_CID_CAM_STABILIZE is not supported\n"); + break; + + case V4L2_CID_PHYSICAL_ROTATION: + ctrl->value = IS_ROTATION_90; + break; + + default: + if ((ctrl->id & 0xFFFF) <= 2000) { + cam_err("no such control id(PRIVATE_BASE) %d, value %d\n", + ctrl->id & 0xFFFF, ctrl->value); + /*err = -ENOIOCTLCMD;*/ + } else if ((ctrl->id - V4L2_CID_BASE) <= 10000) { + cam_err("no such control id(BASE_CID) %d\n", + ctrl->id - V4L2_CID_BASE); + } else { + cam_err("no such control id(CAMERA_CLASS_BASE CID) %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + } + err = 0; + break; + } + + if (err < 0 && err != -ENOIOCTLCMD) + cam_err("failed, id %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE); + + return err; +} + + +static int s5c73m3_g_ext_ctrl(struct v4l2_subdev *sd, + struct v4l2_ext_control *ctrl) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + + switch (ctrl->id) { + case V4L2_CID_CAM_SENSOR_FW_VER: + strcpy(ctrl->string, state->phone_fw); + break; + + default: + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + /*err = -ENOIOCTLCMD*/ + err = 0; + break; + } + + if (err < 0 && err != -ENOIOCTLCMD) + cam_err("failed, id %d\n", + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE); + + return err; +} + +static int s5c73m3_g_ext_ctrls(struct v4l2_subdev *sd, + struct v4l2_ext_controls *ctrls) +{ + struct v4l2_ext_control *ctrl = ctrls->controls; + int i, err = 0; + + for (i = 0; i < ctrls->count; i++, ctrl++) { + err = s5c73m3_g_ext_ctrl(sd, ctrl); + if (err) { + ctrls->error_idx = i; + break; + } + } + return err; +} + + +static int s5c73m3_program_fw(struct v4l2_subdev *sd, + u8 *buf, u32 addr, u32 unit, u32 count, u8 id) +{ + return 0; +} + +#ifndef CONFIG_VIDEO_S5C73M3_SPI +int s5c73m3_spi_write(const u8 *addr, const int len, const int txSize) +{ return 0; } +#endif + +static int s5c73m3_load_fw(struct v4l2_subdev *sd) +{ + struct device *dev = sd->v4l2_dev->dev; + struct s5c73m3_state *state = to_state(sd); + const struct firmware *fw; + char fw_path[20] = {0,}; + u8 *buf = NULL; + int err, txSize; + + struct file *fp; + mm_segment_t old_fs; + long fsize, nread; + int fw_requested = 1; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'C')) + fp = filp_open(S5C73M3_FW_GC_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'D')) + fp = filp_open(S5C73M3_FW_GD_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'E')) + fp = filp_open(S5C73M3_FW_GE_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'F')) + fp = filp_open(S5C73M3_FW_GF_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'C')) + fp = filp_open(S5C73M3_FW_ZC_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'D')) + fp = filp_open(S5C73M3_FW_ZD_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'E')) + fp = filp_open(S5C73M3_FW_ZE_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'F')) + fp = filp_open(S5C73M3_FW_ZF_PATH, O_RDONLY, 0); + else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'G')) + fp = filp_open(S5C73M3_FW_ZG_PATH, O_RDONLY, 0); + else + fp = filp_open(S5C73M3_FW_PATH, O_RDONLY, 0); + + if (IS_ERR(fp)) { + cam_trace("failed to open %s, err %ld\n", + S5C73M3_FW_PATH, PTR_ERR(fp)); + goto request_fw; + } + + fw_requested = 0; + fsize = fp->f_path.dentry->d_inode->i_size; + + buf = vmalloc(fsize); + if (!buf) { + cam_err("failed to allocate memory\n"); + err = -ENOMEM; + goto out; + } + + nread = vfs_read(fp, (char __user *)buf, fsize, &fp->f_pos); + if (nread != fsize) { + cam_err("failed to read firmware file, %ld Bytes\n", nread); + err = -EIO; + goto out; + } + +request_fw: + if (fw_requested) { + set_fs(old_fs); + + if (state->sensor_fw[0] == 'O') { + sprintf(fw_path, "SlimISP_G%c.bin", + state->sensor_fw[1]); + } else if (state->sensor_fw[0] == 'S') { + sprintf(fw_path, "SlimISP_Z%c.bin", + state->sensor_fw[1]); + } else { + sprintf(fw_path, "SlimISP_%c%c.bin", + state->sensor_fw[0], + state->sensor_fw[1]); + } + cam_dbg("file_name = %s\n", fw_path); + + err = request_firmware(&fw, fw_path, dev); + if (err != 0) { + cam_err("request_firmware falied\n"); + err = -EINVAL; + goto out; + } + + cam_dbg("start, size %d Bytes\n", fw->size); + buf = (u8 *)fw->data; + fsize = fw->size; + } + + if (fw_requested) + txSize = 60*1024; /*60KB*/ + else + txSize = 64; /*64 byte for non-DMA mode*/ + + err = s5c73m3_spi_write(buf, fsize, txSize); + if (err < 0) { + cam_err("s5c73m3_spi_write falied\n"); + goto out; + } + + cam_dbg("end\n"); + +out: + if (!fw_requested) { + vfree(buf); + + filp_close(fp, current->files); + set_fs(old_fs); + } else { + release_firmware(fw); + } + + return err; +} + +/* + * v4l2_subdev_video_ops + */ +static const struct s5c73m3_frmsizeenum *s5c73m3_get_frmsize + (const struct s5c73m3_frmsizeenum *frmsizes, int num_entries, int index) +{ + int i; + + for (i = 0; i < num_entries; i++) { + if (frmsizes[i].index == index) + return &frmsizes[i]; + } + + return NULL; +} + +static int s5c73m3_set_frmsize(struct v4l2_subdev *sd) +{ + struct s5c73m3_state *state = to_state(sd); + int err ; + cam_trace("E\n"); + + if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) { + err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE, + S5C73M3_YUV_MODE | state->preview->reg_val | + (state->sensor_mode<<8)); + CHECK_ERR(err); + + cam_dbg("yuv frame size %dx%d\n", + state->preview->width, state->preview->height); + } else { + err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE, + S5C73M3_INTERLEAVED_MODE + | state->capture->reg_val | state->preview->reg_val + |(state->sensor_mode<<8)); + CHECK_ERR(err); + + cam_dbg("interleaved yuv size %dx%d\n", + state->preview->width, state->preview->height); + + cam_dbg("interleaved jpeg size %dx%d\n", + state->capture->width, state->capture->height); + } + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_s_fmt(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *ffmt) +{ + struct s5c73m3_state *state = to_state(sd); + const struct s5c73m3_frmsizeenum **frmsize; + const struct s5c73m3_frmsizeenum **capfrmsize; + + u32 width = ffmt->width; + u32 height = ffmt->height; + u32 tmp_width; + u32 old_index, old_index_cap; + int i, num_entries; + cam_trace("E\n"); + + if (unlikely(state->isp.bad_fw)) { + cam_err("\"Unknown\" state, please update F/W"); + return -ENOSYS; + } + if (ffmt->width < ffmt->height) { + tmp_width = ffmt->height; + height = ffmt->width; + width = tmp_width; + } + + if (ffmt->colorspace == V4L2_COLORSPACE_JPEG) + state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE; + else + state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; + + s5c73m3_set_mode(sd); + + /*set frame size for preview(yuv)*/ + frmsize = &state->preview; + old_index = *frmsize ? (*frmsize)->index : -1; + *frmsize = NULL; + + num_entries = ARRAY_SIZE(preview_frmsizes); + for (i = 0; i < num_entries; i++) { + if (width == preview_frmsizes[i].width && + height == preview_frmsizes[i].height) { + *frmsize = &preview_frmsizes[i]; + break; + } + } + + if (*frmsize == NULL) { + cam_warn("invalid yuv frame size %dx%d\n", width, height); + *frmsize = s5c73m3_get_frmsize(preview_frmsizes, + num_entries, + S5C73M3_PREVIEW_960X720); + } + + /*set frame size for capture(jpeg)*/ + /*it's meaningful for interleaved mode*/ + capfrmsize = &state->capture; + old_index_cap = *capfrmsize ? (*capfrmsize)->index : -1; + *capfrmsize = NULL; + + width = state->jpeg_width; + height = state->jpeg_height; + + num_entries = ARRAY_SIZE(capture_frmsizes); + for (i = 0; i < num_entries; i++) { + if (width == capture_frmsizes[i].width && + height == capture_frmsizes[i].height) { + *capfrmsize = &capture_frmsizes[i]; + break; + } + } + + if (*capfrmsize == NULL) { + cam_warn("invalid jpeg frame size %dx%d\n", width, height); + *capfrmsize = s5c73m3_get_frmsize(capture_frmsizes, num_entries, + S5C73M3_CAPTURE_VGA); + } + + cam_dbg("yuv %dx%d\n", (*frmsize)->width, (*frmsize)->height); + cam_dbg("jpeg %dx%d\n", (*capfrmsize)->width, (*capfrmsize)->height); + if (state->stream_enable) { + if (ffmt->colorspace == V4L2_COLORSPACE_JPEG) { + if ((old_index != (*frmsize)->index) + || (old_index_cap != (*capfrmsize)->index)) + s5c73m3_set_frmsize(sd); + } else { + if (old_index != (*frmsize)->index) + s5c73m3_set_frmsize(sd); + } + } else + s5c73m3_set_frmsize(sd); + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) +{ + struct s5c73m3_state *state = to_state(sd); + + cam_info("g_parm: FPS %d\n", state->fps); + if (state->fps == 0) { + a->parm.capture.timeperframe.numerator = state->fps; + a->parm.capture.timeperframe.denominator = 1; + } else { + a->parm.capture.timeperframe.numerator = 1; + a->parm.capture.timeperframe.denominator = state->fps; + } + + return 0; +} + +static int s5c73m3_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) +{ + struct s5c73m3_state *state = to_state(sd); + u32 denom = a->parm.capture.timeperframe.denominator; + u32 numer = a->parm.capture.timeperframe.numerator; + u32 err = 0; + u32 fps; + + if (unlikely(state->isp.bad_fw)) { + cam_err("\"Unknown\" state, please update F/W"); + return -ENOSYS; + } + + if (numer == 0) { + fps = 0; + } else { + fps = denom / numer; + if (fps != state->fps) { + if (fps < 0 || fps > 30) { + cam_err("invalid frame rate %d\n", fps); + fps = 30; + } + } + } + + state->fps = fps; + + cam_err("Frame rate = %d(%d)\n", fps, state->fps); + + err = s5c73m3_set_frame_rate(sd, state->fps); + CHECK_ERR(err); + + return 0; +} + +static int s5c73m3_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize) +{ + struct s5c73m3_state *state = to_state(sd); + unsigned int i; + int index = fsize->index; + + /* + * Compatible with current fimc code, we have added this condition. + * Fimc use this subdev call for getting width and height of current + * state. + */ + if (index != -1) { + if (index < ARRAY_SIZE(preview_frmsizes)) { + for (i = 0; i < ARRAY_SIZE(preview_frmsizes); ++i) { + /* + * If we need to check pixelformat, please add + * condition at this line. + */ + if (index == i) { + fsize->type = + V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = + preview_frmsizes[i].width; + fsize->discrete.height = + preview_frmsizes[i].height; + return 0; + } + } + } + return -EINVAL; + } + + /* + * The camera interface should read this value, this is the resolution + * at which the sensor would provide framedata to the camera i/f + * In case of image capture, + * this returns the default camera resolution (VGA) + */ + if (state->preview == NULL) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + if (state->hdr_mode) { + fsize->discrete.width = state->capture->width; + fsize->discrete.height = state->capture->height; + } else { + fsize->discrete.width = state->preview->width; + fsize->discrete.height = state->preview->height; + } + return 0; +} + +static int s5c73m3_s_stream_sensor(struct v4l2_subdev *sd, int onoff) +{ + int err = 0; + int index = 0; + u16 stream_status = 0; + + cam_info("%s::::onoff=%d\n", __func__, onoff); + err = s5c73m3_writeb(sd, S5C73M3_SENSOR_STREAMING, + onoff ? S5C73M3_SENSOR_STREAMING_ON : + S5C73M3_SENSOR_STREAMING_OFF); + CHECK_ERR(err); + + do { + err = s5c73m3_read(sd, 0x0009, 0x5080, &stream_status); + if (stream_status == 0xffff) + break; + + index++; + msleep(20); + } while (index < 30); + + if (index >= 30) { + cam_info("%s::::TimeOut!! index = %d, status = 0x%x", + __func__, index, stream_status); + err = -1; + } + + return err; +} + +static int s5c73m3_s_stream_hdr(struct v4l2_subdev *sd, int enable) +{ + struct s5c73m3_state *state = to_state(sd); + int err = 0; + cam_info("s_stream_hdr\n"); + + if (enable) { + err = s5c73m3_i2c_write(sd, 0x0050, 0x0009); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5000); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0902); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0008); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x091A); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0002); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0B10); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x8000 | + state->capture->reg_val | + state->preview->reg_val); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0054, 0x5080); + CHECK_ERR(err); + + err = s5c73m3_i2c_write(sd, 0x0F14, 0x0003); + CHECK_ERR(err); + + err = s5c73m3_s_stream_sensor(sd, enable); + err = s5c73m3_set_auto_bracket_mode(sd); + } else { + err = s5c73m3_s_stream_sensor(sd, enable); + } + + return 0; +} + +static int s5c73m3_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + + cam_trace("E\n"); + + if (unlikely(state->isp.bad_fw)) { + cam_err("\"Unknown\" state, please update F/W"); + return -ENOSYS; + } + + switch (enable) { + case STREAM_MODE_CAM_ON: + case STREAM_MODE_CAM_OFF: + switch (state->format_mode) { + case V4L2_PIX_FMT_MODE_CAPTURE: + cam_info("capture %s", + enable == STREAM_MODE_CAM_ON ? "on" : "off"); + + s5c73m3_s_stream_sensor(sd, enable); + if (enable == STREAM_MODE_CAM_ON && + state->focus.mode == + FOCUS_MODE_CONTINOUS_VIDEO) { + s5c73m3_set_af_mode(sd, + FOCUS_MODE_CONTINOUS_VIDEO); + } + break; + + default: + cam_info("preview %s", + enable == STREAM_MODE_CAM_ON ? "on" : "off"); + + if (state->hdr_mode) { + err = s5c73m3_set_flash(sd, FLASH_MODE_OFF, 0); + err = s5c73m3_s_stream_hdr(sd, enable); + } else { + err = s5c73m3_s_stream_sensor(sd, enable); + if (enable == STREAM_MODE_CAM_ON && + state->focus.mode == + FOCUS_MODE_CONTINOUS_VIDEO) { + s5c73m3_set_af_mode(sd, + FOCUS_MODE_CONTINOUS_VIDEO); + } + } + break; + } + break; + + case STREAM_MODE_MOVIE_ON: + if (state->flash_mode != FLASH_MODE_OFF) + err = s5c73m3_set_flash(sd, state->flash_mode, 1); + + if (state->preview->index == S5C73M3_PREVIEW_720P || + state->preview->index == S5C73M3_PREVIEW_1080P) + err = s5c73m3_set_af(sd, 1); + break; + + case STREAM_MODE_MOVIE_OFF: + if (state->preview->index == S5C73M3_PREVIEW_720P || + state->preview->index == S5C73M3_PREVIEW_1080P) + err = s5c73m3_set_af(sd, 0); + + s5c73m3_set_flash(sd, FLASH_MODE_OFF, 1); + break; + + default: + cam_err("invalid stream option, %d\n", enable); + break; + } + +#if 0 + err = s5c73m3_writeb(sd, S5C73M3_AF_CAL, 0); + CHECK_ERR(err); +#endif + state->stream_enable = enable; + if (state->stream_enable && state->hdr_mode == 0) { + if (state->fps) + s5c73m3_set_frame_rate(sd, state->fps); + } + + cam_trace("X\n"); + return 0; +} + +static int s5c73m3_check_version(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5c73m3_init_param(struct v4l2_subdev *sd) +{ + s5c73m3_set_flash(sd, FLASH_MODE_OFF, 0); + return 0; +} + +static int s5c73m3_FROM_booting(struct v4l2_subdev *sd) +{ + u16 read_val; + int i, err; + + cam_trace("E\n"); + + /*ARM go*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF); + CHECK_ERR(err); + + udelay(400); + + /*Check boot done*/ + for (i = 0; i < 4; i++) { + err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val); + CHECK_ERR(err); + + if (read_val == 0x0C) + break; + + udelay(100); + } + + if (read_val != 0x0C) { + cam_err("boot fail, read_val %#x\n", read_val); + return -1; + } + + /*P,M,S and Boot Mode*/ + err = s5c73m3_write(sd, 0x3100, 0x010C, 0x0044); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3100, 0x0108, 0x000D); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3100, 0x0304, 0x0001); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x0001, 0x0000, 0x5800); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x0001, 0x0002, 0x0002); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3100, 0x0000, 0x0001); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3010, 0x0014, 0x1B85); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3010, 0x0010, 0x230C); + CHECK_ERR(err); + + mdelay(300); + + /*Check binary read done*/ + for (i = 0; i < 3; i++) { + err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val); + CHECK_ERR(err); + + if (read_val == 0x230E) + break; + + udelay(100); + } + + if (read_val != 0x230E) { + cam_err("binary read fail, read_val %#x\n", read_val); + return -1; + } + + /*ARM reset*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFD); + CHECK_ERR(err); + + /*remap*/ + err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183); + CHECK_ERR(err); + + /*ARM go again*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF); + CHECK_ERR(err); + + cam_trace("X\n"); + + return 0; +} + +static int s5c73m3_SPI_booting(struct v4l2_subdev *sd) +{ + u16 read_val; + int i, err; + + cam_trace("E\n"); + + /*ARM go*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF); + CHECK_ERR(err); + + udelay(400); + + /*Check boot done*/ + for (i = 0; i < 3; i++) { + err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val); + CHECK_ERR(err); + + if (read_val == 0x0C) + break; + + udelay(100); + } + + if (read_val != 0x0C) { + cam_err("boot fail, read_val %#x\n", read_val); + return -1; + } + + /*P,M,S and Boot Mode*/ + err = s5c73m3_write(sd, 0x3010, 0x0014, 0x2146); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3010, 0x0010, 0x210C); + CHECK_ERR(err); + + udelay(200); + + /*Check SPI ready*/ + for (i = 0; i < 3; i++) { + err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val); + CHECK_ERR(err); + + if (read_val == 0x210D) + break; + + udelay(100); + } + + if (read_val != 0x210D) { + cam_err("SPI not ready, read_val %#x\n", read_val); + return -1; + } + + /*download fw by SPI*/ + s5c73m3_load_fw(sd); + + /*ARM reset*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFD); + CHECK_ERR(err); + + /*remap*/ + err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183); + CHECK_ERR(err); + + /*ARM go again*/ + err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF); + CHECK_ERR(err); + + cam_trace("X\n"); + + return 0; +} + +static int s5c73m3_read_vdd_core(struct v4l2_subdev *sd) +{ + struct s5c73m3_state *state = to_state(sd); + u16 read_val; + int err; + + cam_trace("E\n"); + + /*Initialize OTP Controller*/ + err = s5c73m3_write(sd, 0x3800, 0xA004, 0x0000); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0004); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0D8, 0x0000); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0DC, 0x0004); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4000); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0D4, 0x0015); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0001); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0B4, 0x9F90); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA09C, 0x9A95); + CHECK_ERR(err); + + /*Page Select*/ + err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4800); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4400); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4200); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA004, 0x00C0); + CHECK_ERR(err); + err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0001); + CHECK_ERR(err); + +#if 0 /*read_val should be 0x7383*/ + err = s5c73m3_read(sd, 0x0000, 0x131C, &read_val); + CHECK_ERR(err); + + cam_dbg("read_val %#x\n", read_val); +#endif + + /*Read Data*/ + err = s5c73m3_read(sd, 0x3800, 0xA034, &read_val); + CHECK_ERR(err); + + cam_dbg("read_val %#x\n", read_val); + + /*Read Data End*/ + err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0000); + CHECK_ERR(err); + + if (read_val & 0x200) { + state->pdata->set_vdd_core(1150000); + strcpy(sysfs_isp_core, "1.15V"); + } else if (read_val & 0x800) { + state->pdata->set_vdd_core(1100000); + strcpy(sysfs_isp_core, "1.10V"); + } else if (read_val & 0x2000) { + state->pdata->set_vdd_core(1050000); + strcpy(sysfs_isp_core, "1.05V"); + } else if (read_val & 0x8000) { + state->pdata->set_vdd_core(1000000); + strcpy(sysfs_isp_core, "1.00V"); + } else { + state->pdata->set_vdd_core(1150000); + strcpy(sysfs_isp_core, "1.15V"); + } + + cam_trace("X\n"); + + return 0; +} + + +static int s5c73m3_init(struct v4l2_subdev *sd, u32 val) +{ + struct s5c73m3_state *state = to_state(sd); + int err; + + sd_internal = sd; + + /* Default state values */ + state->isp.bad_fw = 0; + + state->preview = NULL; + state->capture = NULL; + + state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW; + state->sensor_mode = SENSOR_CAMERA; + state->flash_mode = FLASH_MODE_OFF; + state->beauty_mode = 0; + state->focus.mode = FOCUS_MODE_CONTINOUS_PICTURE; + state->focus.touch = 0; + + state->fps = 0; /* auto */ + + memset(&state->focus, 0, sizeof(state->focus)); + + if (!state->pdata->is_vdd_core_set()) + s5c73m3_read_vdd_core(sd); + +#ifdef S5C73M3_FROM_BOOTING + err = s5c73m3_FROM_booting(sd); +#else + err = s5c73m3_check_fw(sd, 0); + if (err < 0) { + cam_dbg("isp.bad_fw is true\n"); + state->isp.bad_fw = 1; + } +#endif + CHECK_ERR(err); + + s5c73m3_init_param(sd); + + return 0; +} + +static const struct v4l2_subdev_core_ops s5c73m3_core_ops = { + .init = s5c73m3_init, /* initializing API */ + .load_fw = s5c73m3_load_fw, + .queryctrl = s5c73m3_queryctrl, + .g_ctrl = s5c73m3_g_ctrl, + .s_ctrl = s5c73m3_s_ctrl, + .g_ext_ctrls = s5c73m3_g_ext_ctrls, +}; + +static const struct v4l2_subdev_video_ops s5c73m3_video_ops = { + .s_mbus_fmt = s5c73m3_s_fmt, + .g_parm = s5c73m3_g_parm, + .s_parm = s5c73m3_s_parm, + .enum_framesizes = s5c73m3_enum_framesizes, + .s_stream = s5c73m3_s_stream, +}; + +static const struct v4l2_subdev_ops s5c73m3_ops = { + .core = &s5c73m3_core_ops, + .video = &s5c73m3_video_ops, +}; + +static ssize_t s5c73m3_camera_rear_camtype_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char type[25]; + + strcpy(type, sysfs_sensor_type); + return sprintf(buf, "%s\n", type); +} + +static ssize_t s5c73m3_camera_rear_camfw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s %s\n", sysfs_sensor_fw, sysfs_phone_fw); +} + +static ssize_t s5c73m3_camera_rear_flash(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int err; + + if (buf[0] == '0') + err = s5c73m3_writeb(sd_internal, S5C73M3_FLASH_TORCH, + S5C73M3_FLASH_TORCH_OFF); + else + err = s5c73m3_writeb(sd_internal, S5C73M3_FLASH_TORCH, + S5C73M3_FLASH_TORCH_ON); + + CHECK_ERR(err); + + return count; +} + +static ssize_t s5c73m3_camera_isp_core_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + char core[10]; + + strcpy(core, sysfs_isp_core); + return sprintf(buf, "%s\n", core); +} + +static DEVICE_ATTR(rear_camtype, S_IRUGO, + s5c73m3_camera_rear_camtype_show, NULL); +static DEVICE_ATTR(rear_camfw, S_IRUGO, s5c73m3_camera_rear_camfw_show, NULL); +static DEVICE_ATTR(rear_flash, S_IWUSR | S_IWGRP, NULL, + s5c73m3_camera_rear_flash); +static DEVICE_ATTR(isp_core, S_IRUGO, s5c73m3_camera_isp_core_show, NULL); + +/* + * s5c73m3_probe + * Fetching platform data is being done with s_config subdev call. + * In probe routine, we just register subdev device + */ +static int __devinit s5c73m3_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct s5c73m3_state *state; + struct v4l2_subdev *sd; + + state = kzalloc(sizeof(struct s5c73m3_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + + sd = &state->sd; + strcpy(sd->name, S5C73M3_DRIVER_NAME); + + state->pdata = client->dev.platform_data; + + /* Registering subdev */ + v4l2_i2c_subdev_init(sd, client, &s5c73m3_ops); + +#ifdef CAM_DEBUG + state->dbg_level = CAM_DEBUG; +#endif + +#ifdef CONFIG_BUSFREQ_OPP + /* lock bus frequency */ + dev_lock(bus_dev, s5c73m3_dev, 400200); +#else + pm_qos_update_request(&entry, 400200); +#endif + + if (s5c73m3_dev) + dev_set_drvdata(s5c73m3_dev, state); + + printk(KERN_DEBUG "%s\n", __func__); + + return 0; +} + +static int __devexit s5c73m3_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct s5c73m3_state *state = to_state(sd); + + if (unlikely(state->isp.bad_fw)) { + cam_err("camera is not ready!!\n"); + } else { + if (s5c73m3_set_af_softlanding(sd) < 0) + cam_err("failed to set soft landing\n"); + } + v4l2_device_unregister_subdev(sd); + +#ifdef CONFIG_BUSFREQ_OPP + /* Unlock bus frequency */ + dev_unlock(bus_dev, s5c73m3_dev); +#else + pm_qos_update_request(&entry, 0); +#endif + + kfree(state->fw_version); + kfree(state); + + return 0; +} + +static const struct i2c_device_id s5c73m3_id[] = { + { S5C73M3_DRIVER_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, s5c73m3_id); + +static struct i2c_driver s5c73m3_i2c_driver = { + .driver = { + .name = S5C73M3_DRIVER_NAME, + }, + .probe = s5c73m3_probe, + .remove = __devexit_p(s5c73m3_remove), + .id_table = s5c73m3_id, +}; + +static int __init s5c73m3_mod_init(void) +{ +#ifdef CONFIG_BUSFREQ_OPP + /* To lock bus frequency in OPP mode */ + bus_dev = dev_get("exynos-busfreq"); +#else + pm_qos_add_request(&entry, PM_QOS_BUS_DMA_THROUGHPUT, 0); +#endif + + if (!s5c73m3_dev) { + s5c73m3_dev = device_create(camera_class, + NULL, 0, NULL, "rear"); + if (IS_ERR(s5c73m3_dev)) { + cam_warn("failed to create device!\n"); + return 0; + } + + if (device_create_file(s5c73m3_dev, &dev_attr_rear_camtype) + < 0) { + cam_warn("failed to create device file, %s\n", + dev_attr_rear_camtype.attr.name); + } + + if (device_create_file(s5c73m3_dev, &dev_attr_rear_camfw) < 0) { + cam_warn("failed to create device file, %s\n", + dev_attr_rear_camfw.attr.name); + } + + if (device_create_file(s5c73m3_dev, &dev_attr_rear_flash) < 0) { + cam_warn("failed to create device file, %s\n", + dev_attr_rear_flash.attr.name); + } + + if (device_create_file(s5c73m3_dev, &dev_attr_isp_core) < 0) { + cam_warn("failed to create device file, %s\n", + dev_attr_isp_core.attr.name); + } + } + + return i2c_add_driver(&s5c73m3_i2c_driver); +} + +static void __exit s5c73m3_mod_exit(void) +{ + i2c_del_driver(&s5c73m3_i2c_driver); +} +module_init(s5c73m3_mod_init); +module_exit(s5c73m3_mod_exit); + + +MODULE_DESCRIPTION("driver for LSI S5C73M3"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/slp_s5c73m3.h b/drivers/media/video/slp_s5c73m3.h new file mode 100644 index 0000000..314c65f --- /dev/null +++ b/drivers/media/video/slp_s5c73m3.h @@ -0,0 +1,516 @@ +/* + * Driver for LSI S5C73M3 (ISP for 8MP Camera) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __SLP_S5C73M3_H +#define __SLP_S5C73M3_H + +#define CONFIG_CAM_DEBUG 1 + +#define cam_warn(fmt, ...) \ + do { \ + printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_err(fmt, ...) \ + do { \ + printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_info(fmt, ...) \ + do { \ + printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#ifdef CONFIG_CAM_DEBUG +#define CAM_DEBUG (1 << 0) +#define CAM_TRACE (1 << 1) +#define CAM_I2C (1 << 2) + +#define cam_dbg(fmt, ...) \ + do { \ + if (to_state(sd)->dbg_level & CAM_DEBUG) \ + printk(KERN_DEBUG "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_trace(fmt, ...) \ + do { \ + if (to_state(sd)->dbg_level & CAM_TRACE) \ + printk(KERN_DEBUG "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_i2c_dbg(fmt, ...) \ + do { \ + if (to_state(sd)->dbg_level & CAM_I2C) \ + printk(KERN_DEBUG "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } while (0) +#else +#define cam_dbg(fmt, ...) +#define cam_trace(fmt, ...) +#define cam_i2c_dbg(fmt, ...) +#endif + +enum s5c73m3_prev_frmsize { + S5C73M3_PREVIEW_QCIF, + S5C73M3_PREVIEW_QCIF2, + S5C73M3_PREVIEW_QVGA, + S5C73M3_PREVIEW_CIF, + S5C73M3_PREVIEW_VGA, + S5C73M3_PREVIEW_D1, + S5C73M3_PREVIEW_WVGA, + S5C73M3_PREVIEW_880X720, + S5C73M3_PREVIEW_960X720, + S5C73M3_PREVIEW_1008X672, + S5C73M3_PREVIEW_1056X704, + S5C73M3_PREVIEW_1184X666, + S5C73M3_PREVIEW_720P, + S5C73M3_VDIS_720P, + S5C73M3_PREVIEW_1080P, + S5C73M3_VDIS_1080P, + S5C73M3_PREVIEW_HDR, +}; + +enum s5c73m3_cap_frmsize { + S5C73M3_CAPTURE_VGA, /* 640 x 480 */ + S5C73M3_CAPTURE_WVGA, /* 800 x 480 */ + S5C73M3_CAPTURE_1024X768, /* 1024 x 768 */ + S5C73M3_CAPTURE_HD, /* 1280 x 720 */ + S5C73M3_CAPTURE_W1MP, /* 1600 x 960 */ + S5C73M3_CAPTURE_2MP, /* UXGA - 1600 x 1200 */ + S5C73M3_CAPTURE_W2MP, /* 2048 x 1232 */ + S5C73M3_CAPTURE_3MP, /* QXGA - 2048 x 1536 */ + S5C73M3_CAPTURE_W4MP, /* WQXGA - 2560 x 1440 */ + S5C73M3_CAPTURE_5MP, /* 2560 x 1920 */ + S5C73M3_CAPTURE_W6MP, /* 3072 x 1856 */ + S5C73M3_CAPTURE_7MP, /* 3072 x 2304 */ + S5C73M3_CAPTURE_W7MP, /* WQXGA - 2560 x 1536 */ + S5C73M3_CAPTURE_3264X2176, /* 3264 x 2176 */ + S5C73M3_CAPTURE_8MP, /* 3264 x 2448 */ +}; + +enum s5c73m3_isneed_flash_tristate { + S5C73M3_ISNEED_FLASH_OFF = 0x00, + S5C73M3_ISNEED_FLASH_ON = 0x01, + S5C73M3_ISNEED_FLASH_UNDEFINED = 0x02, +}; + +struct s5c73m3_control { + u32 id; + s32 value; + s32 minimum; /* Note signedness */ + s32 maximum; + s32 step; + s32 default_value; +}; + +struct s5c73m3_frmsizeenum { + unsigned int index; + unsigned int width; + unsigned int height; + u8 reg_val; /* a value for category parameter */ +}; + +struct s5c73m3_isp { + wait_queue_head_t wait; + unsigned int irq; /* irq issued by ISP */ + unsigned int issued; + unsigned int int_factor; + unsigned int bad_fw:1; +}; + +struct s5c73m3_jpeg { + int quality; + unsigned int main_size; /* Main JPEG file size */ + unsigned int thumb_size; /* Thumbnail file size */ + unsigned int main_offset; + unsigned int thumb_offset; + unsigned int postview_offset; +}; + +struct s5c73m3_focus { + unsigned int mode; + unsigned int lock; + unsigned int status; + unsigned int touch; + unsigned int pos_x; + unsigned int pos_y; + + /* rectangle type values */ + unsigned int left; + unsigned int top; + unsigned int width; + unsigned int height; +}; + +struct s5c73m3_exif { + char unique_id[7]; + u32 exptime; /* us */ + u16 flash; + u16 iso; + int tv; /* shutter speed */ + int bv; /* brightness */ + int ebv; /* exposure bias */ + int effect; /* effect(colorfx) */ + int saturation; + int sharpness; + int metering; + int wdr; +}; + +struct s5c73m3_state { + struct s5c73m3_platform_data *pdata; + struct v4l2_subdev sd; + + struct s5c73m3_isp isp; + + const struct s5c73m3_frmsizeenum *preview; + const struct s5c73m3_frmsizeenum *capture; + + enum v4l2_pix_format_mode format_mode; + enum v4l2_sensor_mode sensor_mode; + enum v4l2_flash_mode flash_mode; + enum v4l2_wb_mode wb_mode; + enum v4l2_scene_mode scene_mode; + int vt_mode; + int beauty_mode; + int hdr_mode; + int hybrid_mode; + int zoom; + int stream_enable; + int ae_lock; + int awb_lock; + + int cal_device; + int cal_dll; + + unsigned int fps; + struct s5c73m3_focus focus; + int caf_mode; + char isflash; + + struct s5c73m3_jpeg jpeg; + struct s5c73m3_exif exif; + + int check_dataline; + char *fw_version; + + u32 jpeg_width; + u32 jpeg_height; + + u8 sensor_fw[10]; + u8 phone_fw[10]; + + u8 sensor_type[15]; + +#ifdef CONFIG_CAM_DEBUG + u8 dbg_level; +#endif +}; + +#define S5C73M3_IMG_OUTPUT 0x0902 +#define S5C73M3_HDR_OUTPUT 0x0008 +#define S5C73M3_YUV_OUTPUT 0x0009 +#define S5C73M3_INTERLEAVED_OUTPUT 0x000D +#define S5C73M3_HYBRID_OUTPUT 0x0016 + +#define S5C73M3_STILL_PRE_FLASH 0x0A00 +#define S5C73M3_STILL_PRE_FLASH_FIRE 0x0000 +#define S5C73M3_STILL_PRE_FLASH_NON_FIRED 0x0000 +#define S5C73M3_STILL_PRE_FLASH_FIRED 0x0001 + +#define S5C73M3_STILL_MAIN_FLASH 0x0A02 +#define S5C73M3_STILL_MAIN_FLASH_CANCEL 0x0001 +#define S5C73M3_STILL_MAIN_FLASH_FIRE 0x0002 + + +#define S5C73M3_ZOOM_STEP 0x0B00 + + +#define S5C73M3_IMAGE_EFFECT 0x0B0A +#define S5C73M3_IMAGE_EFFECT_NONE 0x0001 +#define S5C73M3_IMAGE_EFFECT_NEGATIVE 0x0002 +#define S5C73M3_IMAGE_EFFECT_AQUA 0x0003 +#define S5C73M3_IMAGE_EFFECT_SEPIA 0x0004 +#define S5C73M3_IMAGE_EFFECT_MONO 0x0005 + +#define S5C73M3_IMAGE_QUALITY 0x0B0C +#define S5C73M3_IMAGE_QUALITY_SUPERFINE 0x0000 +#define S5C73M3_IMAGE_QUALITY_FINE 0x0001 +#define S5C73M3_IMAGE_QUALITY_NORMAL 0x0002 + + +#define S5C73M3_FLASH_MODE 0x0B0E +#define S5C73M3_FLASH_MODE_OFF 0x0000 +#define S5C73M3_FLASH_MODE_ON 0x0001 +#define S5C73M3_FLASH_MODE_AUTO 0x0002 + +#define S5C73M3_FLASH_TORCH 0x0B12 +#define S5C73M3_FLASH_TORCH_OFF 0x0000 +#define S5C73M3_FLASH_TORCH_ON 0x0001 + +#define S5C73M3_AE_ISNEEDFLASH 0x0CBA +#define S5C73M3_AE_ISNEEDFLASH_OFF 0x0000 +#define S5C73M3_AE_ISNEEDFLASH_ON 0x0001 + + +#define S5C73M3_CHG_MODE 0x0B10 +#define S5C73M3_YUV_MODE 0x8000 +#define S5C73M3_INTERLEAVED_MODE 0x8000 +#define S5C73M3_CHG_MODE_YUV_320_240 0x8001 +#define S5C73M3_CHG_MODE_YUV_400_300 0x8002 +#define S5C73M3_CHG_MODE_YUV_640_480 0x8003 +#define S5C73M3_CHG_MODE_YUV_800_600 0x8004 +#define S5C73M3_CHG_MODE_YUV_960_720 0x8005 +#define S5C73M3_CHG_MODE_YUV_1280_720 0x8006 +#define S5C73M3_CHG_MODE_YUV_1280_960 0x8007 +#define S5C73M3_CHG_MODE_YUV_1600_1200 0x8008 +#define S5C73M3_CHG_MODE_YUV_1632_1224 0x8009 +#define S5C73M3_CHG_MODE_YUV_1920_1080 0x800A +#define S5C73M3_CHG_MODE_YUV_1920_1440 0x800B +#define S5C73M3_CHG_MODE_YUV_2304_1296 0x800C +#define S5C73M3_CHG_MODE_YUV_2304_1728 0x800D +#define S5C73M3_CHG_MODE_JPEG_640_480 0x0010 +#define S5C73M3_CHG_MODE_JPEG_800_450 0x0020 +#define S5C73M3_CHG_MODE_JPEG_800_600 0x0030 +#define S5C73M3_CHG_MODE_JPEG_1600_960 0x0040 +#define S5C73M3_CHG_MODE_JPEG_1600_1200 0x0050 +#define S5C73M3_CHG_MODE_JPEG_2048_1152 0x0060 +#define S5C73M3_CHG_MODE_JPEG_2048_1536 0x0070 +#define S5C73M3_CHG_MODE_JPEG_2560_1440 0x0080 +#define S5C73M3_CHG_MODE_JPEG_2560_1920 0x0090 +#define S5C73M3_CHG_MODE_JPEG_3072_1728 0x00A0 +#define S5C73M3_CHG_MODE_JPEG_3264_2304 0x00B0 +#define S5C73M3_CHG_MODE_JPEG_3264_1836 0x00C0 +#define S5C73M3_CHG_MODE_JPEG_3264_2448 0x00D0 + + +#define S5C73M3_AF_CON 0x0E00 +#define S5C73M3_AF_CON_STOP 0x0000 +#define S5C73M3_AF_CON_SCAN 0x0001/*AF_SCAN:Full Search*/ +#define S5C73M3_AF_CON_START 0x0002/*AF_START:Fast Search*/ + +#define S5C73M3_AF_STATUS 0x5E80 + +#define S5C73M3_AF_TOUCH_AF 0x0E0A + +#define S5C73M3_AF_CAL 0x0E06 + +#define S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR 0x0001 +#define S5C73M3_CAF_STATUS_FOCUSING 0x0002 +#define S5C73M3_CAF_STATUS_FOCUSED 0x0003 +#define S5C73M3_CAF_STATUS_UNFOCUSED 0x0004 + +#define S5C73M3_AF_STATUS_INVALID 0x0010 +#define S5C73M3_AF_STATUS_FOCUSING 0x0020 +#define S5C73M3_AF_STATUS_FOCUSED 0x0030/*SUCCESS*/ +#define S5C73M3_AF_STATUS_UNFOCUSED 0x0040/*FAIL*/ + +#define S5C73M3_AF_TOUCH_POSITION 0x5E8E + +#define S5C73M3_AF_FACE_ZOOM 0x0E10 + +#define S5C73M3_AF_MODE 0x0E02 +#define S5C73M3_AF_MODE_NORMAL 0x0000 +#define S5C73M3_AF_MODE_MACRO 0x0001 +#define S5C73M3_AF_MODE_MOVIE_CAF_START 0x0002 +#define S5C73M3_AF_MODE_MOVIE_CAF_STOP 0x0003 +#define S5C73M3_AF_MODE_PREVIEW_CAF_START 0x0004 +#define S5C73M3_AF_MODE_PREVIEW_CAF_STOP 0x0005 + +#define S5C73M3_AF_SOFTLANDING 0x0E16 +#define S5C73M3_AF_SOFTLANDING_ON 0x0000 + +#define S5C73M3_FACE_DET 0x0E0C +#define S5C73M3_FACE_DET_OFF 0x0000 +#define S5C73M3_FACE_DET_ON 0x0001 + +#define S5C73M3_FACE_DET_OSD 0x0E0E +#define S5C73M3_FACE_DET_OSD_OFF 0x0000 +#define S5C73M3_FACE_DET_OSD_ON 0x0001 + +#define S5C73M3_AE_CON 0x0C00 +#define S5C73M3_AE_STOP 0x0000/*LOCK*/ +#define S5C73M3_AE_START 0x0001/*UNLOCK*/ + +#define S5C73M3_ISO 0x0C02 +#define S5C73M3_ISO_AUTO 0x0000 +#define S5C73M3_ISO_100 0x0001 +#define S5C73M3_ISO_200 0x0002 +#define S5C73M3_ISO_400 0x0003 +#define S5C73M3_ISO_800 0x0004 +#define S5C73M3_ISO_SPORTS 0x0005 +#define S5C73M3_ISO_NIGHT 0x0006 +#define S5C73M3_ISO_INDOOR 0x0007 + +#define S5C73M3_EV 0x0C04 +#define S5C73M3_EV_M20 0x0000 +#define S5C73M3_EV_M15 0x0001 +#define S5C73M3_EV_M10 0x0002 +#define S5C73M3_EV_M05 0x0003 +#define S5C73M3_EV_ZERO 0x0004 +#define S5C73M3_EV_P05 0x0005 +#define S5C73M3_EV_P10 0x0006 +#define S5C73M3_EV_P15 0x0007 +#define S5C73M3_EV_P20 0x0008 + +#define S5C73M3_METER 0x0C06 +#define S5C73M3_METER_CENTER 0x0000 +#define S5C73M3_METER_SPOT 0x0001 +#define S5C73M3_METER_AVERAGE 0x0002 +#define S5C73M3_METER_SMART 0x0003 + +#define S5C73M3_WDR 0x0C08 +#define S5C73M3_WDR_OFF 0x0000 +#define S5C73M3_WDR_ON 0x0001 + +#define S5C73M3_AE_MODE 0x0C1E +#define S5C73M3_AUTO_MODE_AE_SET 0x0000 +#define S5C73M3_FIXED_30FPS 0x0002 +#define S5C73M3_FIXED_20FPS 0x0003 +#define S5C73M3_FIXED_15FPS 0x0004 +#define S5C73M3_FIXED_120FPS 0x0008 +#define S5C73M3_FIXED_7FPS 0x0009 +#define S5C73M3_ANTI_SHAKE 0x0013 + +#define S5C73M3_SHARPNESS 0x0C14 +#define S5C73M3_SHARPNESS_0 0x0000 +#define S5C73M3_SHARPNESS_1 0x0001 +#define S5C73M3_SHARPNESS_2 0x0002 +#define S5C73M3_SHARPNESS_M1 0x0003 +#define S5C73M3_SHARPNESS_M2 0x0004 + +#define S5C73M3_SATURATION 0x0C16 +#define S5C73M3_SATURATION_0 0x0000 +#define S5C73M3_SATURATION_1 0x0001 +#define S5C73M3_SATURATION_2 0x0002 +#define S5C73M3_SATURATION_M1 0x0003 +#define S5C73M3_SATURATION_M2 0x0004 + +#define S5C73M3_CONTRAST 0x0C18 +#define S5C73M3_CONTRAST_0 0x0000 +#define S5C73M3_CONTRAST_1 0x0001 +#define S5C73M3_CONTRAST_2 0x0002 +#define S5C73M3_CONTRAST_M1 0x0003 +#define S5C73M3_CONTRAST_M2 0x0004 + +#define S5C73M3_SCENE_MODE 0x0C1A +#define S5C73M3_SCENE_MODE_NONE 0x0000 +#define S5C73M3_SCENE_MODE_PORTRAIT 0x0001 +#define S5C73M3_SCENE_MODE_LANDSCAPE 0x0002 +#define S5C73M3_SCENE_MODE_SPORTS 0x0003 +#define S5C73M3_SCENE_MODE_INDOOR 0x0004 +#define S5C73M3_SCENE_MODE_BEACH 0x0005 +#define S5C73M3_SCENE_MODE_SUNSET 0x0006 +#define S5C73M3_SCENE_MODE_DAWN 0x0007 +#define S5C73M3_SCENE_MODE_FALL 0x0008 +#define S5C73M3_SCENE_MODE_NIGHT 0x0009 +#define S5C73M3_SCENE_MODE_AGAINSTLIGHT 0x000A +#define S5C73M3_SCENE_MODE_FIRE 0x000B +#define S5C73M3_SCENE_MODE_TEXT 0x000C +#define S5C73M3_SCENE_MODE_CANDLE 0x000D + +#define S5C73M3_FIREWORK_CAPTURE 0x0C20 + +#define S5C73M3_AE_AUTO_BRAKET 0x0B14 +#define S5C73M3_AE_AUTO_BRAKET_EV05 0x0080 +#define S5C73M3_AE_AUTO_BRAKET_EV10 0x0100 +#define S5C73M3_AE_AUTO_BRAKET_EV15 0x0180 +#define S5C73M3_AE_AUTO_BRAKET_EV20 0x0200 + +#define S5C73M3_SENSOR_STREAMING 0x090A +#define S5C73M3_SENSOR_STREAMING_OFF 0x0000 +#define S5C73M3_SENSOR_STREAMING_ON 0x0001 + +#define S5C73M3_AWB_MODE 0x0D02 +#define S5C73M3_AWB_MODE_INCANDESCENT 0x0000 +#define S5C73M3_AWB_MODE_FLUORESCENT1 0x0001 +#define S5C73M3_AWB_MODE_FLUORESCENT2 0x0002 +#define S5C73M3_AWB_MODE_DAYLIGHT 0x0003 +#define S5C73M3_AWB_MODE_CLOUDY 0x0004 +#define S5C73M3_AWB_MODE_AUTO 0x0005 + +#define S5C73M3_AWB_CON 0x0D00 +#define S5C73M3_AWB_STOP 0x0000/*LOCK*/ +#define S5C73M3_AWB_START 0x0001/*UNLOCK*/ + +#define S5C73M3_HYBRID_CAPTURE 0x0996 + +/* S5C73M3 Sensor Mode */ +#define S5C73M3_SYSINIT_MODE 0x0 +#define S5C73M3_PARMSET_MODE 0x1 +#define S5C73M3_MONITOR_MODE 0x2 +#define S5C73M3_STILLCAP_MODE 0x3 + +/* Interrupt Factor */ +#define S5C73M3_INT_SOUND (1 << 7) +#define S5C73M3_INT_LENS_INIT (1 << 6) +#define S5C73M3_INT_FD (1 << 5) +#define S5C73M3_INT_FRAME_SYNC (1 << 4) +#define S5C73M3_INT_CAPTURE (1 << 3) +#define S5C73M3_INT_ZOOM (1 << 2) +#define S5C73M3_INT_AF (1 << 1) +#define S5C73M3_INT_MODE (1 << 0) + +/* ESD Interrupt */ +#define S5C73M3_INT_ESD (1 << 0) + +static const u32 S5C73M3_INIT[] = { +0x00500009, +0x00545000, +0x0F140B08, +0x0F140000, +0x0F140900, +0x0F140403, /*640MHz*/ +0x00545080, +0x0F140002 +}; + +static u32 S5C73M3_OTP_CONTROL[] = { +0xFCFC3310, +0x00503800, +0x0054A004, +0x0F140000, +0x0054A000, +0x0F140004, +0x0054A0D8, +0x0F140000, +0x0054A0DC, +0x0F140004, +0x0054A0C4, +0x0F144000, +0x0054A0D4, +0x0F140015, +0x0054A000, +0x0F140001, +0x0054A0B4, +0x0F149F90, +0x0054A09C, +0x0F149A95, +}; + +static u32 S5C73M3_OTP_PAGE[] = { +0x0054A0C4, +0x0F144800, +0x0054A0C4, +0x0F144400, +0x0054A0C4, +0x0F144200, +0x0054A004, +0x0F1400C0, +0x0054A000, +0x0F140001, +}; + +#ifdef CONFIG_VIDEO_S5C73M3_SPI +extern int s5c73m3_spi_write(const u8 *addr, const int len, const int txSize); +#endif + +#endif /* __SLP_S5C73M3_H */ diff --git a/drivers/media/video/slp_s5k4ecgx.c b/drivers/media/video/slp_s5k4ecgx.c new file mode 100644 index 0000000..c78ca71 --- /dev/null +++ b/drivers/media/video/slp_s5k4ecgx.c @@ -0,0 +1,2335 @@ +/* + * Driver for S5K4ECGX from Samsung Electronics + * + * 5Mp CMOS Image Sensor SoC with an Embedded Image Processor + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_VIDEO_SAMSUNG_V4L2 +#include +#include +#endif +#include + +#include "slp_s5k4ecgx.h" + +#ifdef S5K4ECGX_USLEEP +#include +#endif + +#define S5K4ECGX_BURST_MODE +#ifdef S5K4ECGX_BURST_MODE + static u16 addr, value; + + static int len; + static u8 buf[SZ_4K] = {0,}; +#else + static u8 buf[4] = {0,}; +#endif + +/* 5M mem size */ +#define S5K4ECGX_INTLV_DATA_MAXSIZE (5 << 20) + +static const struct s5k4ecgx_framesize preview_frmsizes[] = { + { S5K4ECGX_PREVIEW_640, 640, 480 }, + { S5K4ECGX_PREVIEW_176, 640, 480 }, + { S5K4ECGX_PREVIEW_320, 320, 240 }, + { S5K4ECGX_PREVIEW_720, 720, 480 }, + { S5K4ECGX_PREVIEW_800, 800, 480 }, + { S5K4ECGX_PREVIEW_1280, 1280, 720 }, +}; + +static const struct s5k4ecgx_framesize capture_frmsizes[] = { + { S5K4ECGX_CAPTURE_5MP, 2560, 1920 }, + { S5K4ECGX_CAPTURE_3MP, 2048, 1536 }, + { S5K4ECGX_CAPTURE_2MP, 1600, 1200 }, + { S5K4ECGX_CAPTURE_1MP, 1280, 960 }, + { S5K4ECGX_CAPTURE_XGA, 1024, 768 }, + { S5K4ECGX_CAPTURE_VGA, 640, 480 }, +}; + +#define CHECK_ERR(x) if (unlikely((x) < 0)) { \ + cam_err("i2c failed, err %d\n", x); \ + return x; \ + } + +#define NELEMS(array) (sizeof(array) / sizeof(array[0])) + +#ifdef S5K4ECGX_USLEEP +/* + * Use msleep() if the sleep time is over 1000 us. +*/ +static void s5k4ecgx_usleep(u32 usecs) +{ + ktime_t expires; + u64 add_time = (u64)usecs * 1000; + + if (unlikely(!usecs)) + return; + + expires = ktime_add_ns(ktime_get(), add_time); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_hrtimeout(&expires, HRTIMER_MODE_ABS); +} +#endif + +static void s5k4ecgx_cam_delay(struct v4l2_subdev *sd) +{ + struct s5k4ecgx_state *state = to_state(sd); + + if (state->scene_mode == SCENE_MODE_NIGHTSHOT || + state->scene_mode == SCENE_MODE_FIREWORKS) + msleep(250); + else + msleep(200); +} + +static inline int s5k4ecgx_read(struct i2c_client *client, + u16 subaddr, u16 *data) +{ + u8 buf[2]; + int err = 0; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = buf, + }; + + *(u16 *)buf = cpu_to_be16(subaddr); + + err = i2c_transfer(client->adapter, &msg, 1); + if (unlikely(err < 0)) + cam_err("ERR: %d register read fail\n", __LINE__); + + msg.flags = I2C_M_RD; + + err = i2c_transfer(client->adapter, &msg, 1); + if (unlikely(err < 0)) + cam_err("ERR: %d register read fail\n", __LINE__); + + *data = ((buf[0] << 8) | buf[1]); + + return err; +} + +static inline int s5k4ecgx_write(struct i2c_client *client, + u32 packet) +{ + u8 buf[4]; + int err = 0, retry_count = 5; + + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .buf = buf, + .len = 4, + }; + + if (!client->adapter) { + cam_err("ERR - can't search i2c client adapter\n"); + return -EIO; + } + + while (retry_count--) { + *(u32 *)buf = cpu_to_be32(packet); + err = i2c_transfer(client->adapter, &msg, 1); + if (likely(err == 1)) + break; + mdelay(10); + } + + if (unlikely(err < 0)) { + cam_err("ERR - 0x%08x write failed err=%d\n", + (u32)packet, err); + return err; + } + + return (err != 1) ? -1 : 0; +} + +/* +* Read a register. +*/ +static int s5k4ecgx_read_reg(struct v4l2_subdev *sd, + u16 page, u16 addr, u16 *val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + u32 page_cmd = (0x002C << 16) | page; + u32 addr_cmd = (0x002E << 16) | addr; + int err = 0; + + cam_dbg("page_cmd=0x%X, addr_cmd=0x%X\n", page_cmd, addr_cmd); + + err = s5k4ecgx_write(client, page_cmd); + CHECK_ERR(err); + err = s5k4ecgx_write(client, addr_cmd); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, val); + CHECK_ERR(err); + + return 0; +} + +/* program multiple registers */ +static int s5k4ecgx_write_regs(struct v4l2_subdev *sd, + const u32 *packet, u32 num) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = -EAGAIN; + u32 temp = 0; + u16 delay = 0; + int retry_count = 5; + + struct i2c_msg msg = { + msg.addr = client->addr, + msg.flags = 0, + msg.len = 4, + msg.buf = buf, + }; + + while (num--) { + temp = *packet++; + + if ((temp & S5K4ECGX_DELAY) == S5K4ECGX_DELAY) { + delay = temp & 0xFFFF; + cam_dbg("line(%d):delay(0x%x):delay(%d)\n", + __LINE__, delay, delay); + msleep(delay); + continue; + } + +#ifdef S5K4ECGX_BURST_MODE + addr = temp >> 16; + value = temp & 0xFFFF; + + switch (addr) { + case 0x0F12: + if (len == 0) { + buf[len++] = addr >> 8; + buf[len++] = addr & 0xFF; + } + buf[len++] = value >> 8; + buf[len++] = value & 0xFF; + + if ((*packet >> 16) != addr) { + msg.len = len; + goto s5k4ecgx_burst_write; + } + break; + + case 0xFFFF: + break; + + default: + msg.len = 4; + *(u32 *)buf = cpu_to_be32(temp); + goto s5k4ecgx_burst_write; + } + + continue; +#else + *(u32 *)buf = cpu_to_be32(temp); +#endif + +#ifdef S5K4ECGX_BURST_MODE +s5k4ecgx_burst_write: + len = 0; +#endif + retry_count = 5; + + while (retry_count--) { + ret = i2c_transfer(client->adapter, &msg, 1); + if (likely(ret == 1)) + break; + mdelay(10); + } + + if (unlikely(ret < 0)) { + cam_err("ERR - 0x%08x write failed err=%d\n", \ + (u32)packet, ret); + break; + } + } + + if (unlikely(ret < 0)) { + cam_err("fail to write registers!!\n"); + return -EIO; + } + + return 0; +} + +static int camera_flash_manual_ctrl(struct v4l2_subdev *sd, int mode) +{ + struct s5k4ecgx_state *state = to_state(sd); + int ret = 0; + cam_dbg(" E\n"); + if (mode == CAM_FLASH_ON) { + /* FLASH mode */ + ret = state->pdata->flash_ctrl(CAM_FLASH_ON); + state->preflash = PREFLASH_ON; + } else if (mode == CAM_FLASH_TORCH) { + /* TORCH mode */ + ret = state->pdata->flash_ctrl(CAM_FLASH_TORCH); + state->preflash = PREFLASH_ON; + } else { + ret = state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + } + return ret; +} + +static int s5k4ecgx_get_exif(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5k4ecgx_get_lux(struct v4l2_subdev *sd) +{ + struct s5k4ecgx_state *state = to_state(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int msb = 0; + int lsb = 0; + int cur_lux = 0; + bool lowlight = false; + int err = 0; + cam_dbg(" E\n"); + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E2C18); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&lsb); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&msb); + CHECK_ERR(err); + + cur_lux = (msb << 16) | lsb; + + if (cur_lux >= 0x32) + lowlight = false; + else + lowlight = true; + + state->lowlight = lowlight; + + cam_info("%s, s5k4ecgx_status.lowlight is %d\n", __func__, + state->lowlight); + /*this value is under 0x0032 in low light condition */ + return err; +} + +static int s5k4ecgx_ae_stable(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct s5k4ecgx_state *state = to_state(sd); + int val = 0; + int err = 0; + int cnt; + do { + if (state->focus.start == AUTO_FOCUS_OFF) { + cam_info("af_start_preflash: AF is cancelled!\n"); + state->focus.status = CAMERA_AF_STATUS_MAX; + break; + } + + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E2C74); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&val); + CHECK_ERR(err); + + if (val == 0x1) + break; + + s5k4ecgx_usleep(10*1000); + + } while (cnt < 40); + cam_info("%s, ret value is %d\n", __func__, + val); + + return err; +} + +static int s5k4ecgx_set_awb_lock(struct v4l2_subdev *sd, int val) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + cam_info(" E\n"); + + if (val == state->awb_lock) + return 0; + + if (val) + err = s5k4ecgx_write_regs(sd, s5k4ecgx_awb_lock_EVT1,\ + sizeof(s5k4ecgx_awb_lock_EVT1) / \ + sizeof(s5k4ecgx_awb_lock_EVT1[0])); + else + err = s5k4ecgx_write_regs(sd, s5k4ecgx_awb_unlock_EVT1,\ + sizeof(s5k4ecgx_awb_unlock_EVT1) / \ + sizeof(s5k4ecgx_awb_unlock_EVT1[0])); + + CHECK_ERR(err); + state->awb_lock = val; + cam_info("awb %s\n", val ? "lock" : "unlock"); + return err; +} + +static int s5k4ecgx_set_ae_lock(struct v4l2_subdev *sd, int val) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + cam_info(" E\n"); + + if (val == state->ae_lock) + return 0; + + if (val) + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ae_lock_EVT1,\ + sizeof(s5k4ecgx_ae_lock_EVT1) / \ + sizeof(s5k4ecgx_ae_lock_EVT1[0])); + else + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ae_unlock_EVT1,\ + sizeof(s5k4ecgx_ae_unlock_EVT1) / \ + sizeof(s5k4ecgx_ae_unlock_EVT1[0])); + + CHECK_ERR(err); + state->ae_lock = val; + cam_info("ae %s\n", val ? "lock" : "unlock"); + return err; +} + +static int s5k4ecgx_check_dataline(struct v4l2_subdev *sd, s32 val) +{ + cam_info("DTP %s\n", val ? "ON" : "OFF"); + return 0; +} + +static int s5k4ecgx_debug_sensor_status(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5k4ecgx_check_sensor_status(struct v4l2_subdev *sd) +{ + return 0; +} + +static inline int s5k4ecgx_check_esd(struct v4l2_subdev *sd) +{ + return 0; +} + +static int s5k4ecgx_set_preview_start(struct v4l2_subdev *sd) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_info(" E\n"); + + if ((state->runmode == RUNMODE_NOTREADY) || + (state->runmode == RUNMODE_CAPTURING)) { + cam_err("%s: ERROR - Invalid runmode\n", __func__); + return -EPERM; + } + + state->focus.status = CAMERA_AF_STATUS_MAX; + + if (state->runmode == RUNMODE_CAPTURE_STOP) { + if (state->preflash != PREFLASH_OFF) { + err = state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + } + /* AE/AWB unlock */ + err = s5k4ecgx_set_ae_lock(sd, false); + err = s5k4ecgx_set_awb_lock(sd, false); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Preview_Return_EVT1,\ + sizeof(s5k4ecgx_Preview_Return_EVT1) / \ + sizeof(s5k4ecgx_Preview_Return_EVT1[0])); + } else { + switch (state->preview_frmsizes->index) { + case S5K4ECGX_PREVIEW_1280: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_1280_Preview_EVT1,\ + sizeof(s5k4ecgx_1280_Preview_EVT1) / \ + sizeof(s5k4ecgx_1280_Preview_EVT1[0])); + cam_info("S5K4ECGX_PREVIEW_1280\n"); + break; + case S5K4ECGX_PREVIEW_800: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_800_Preview_EVT1,\ + sizeof(s5k4ecgx_800_Preview_EVT1) / \ + sizeof(s5k4ecgx_800_Preview_EVT1[0])); + cam_info("S5K4ECGX_PREVIEW_800\n"); + break; + case S5K4ECGX_PREVIEW_720: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_720_Preview_EVT1,\ + sizeof(s5k4ecgx_720_Preview_EVT1) / \ + sizeof(s5k4ecgx_720_Preview_EVT1[0])); + cam_info("S5K4ECGX_PREVIEW_720\n"); + break; + case S5K4ECGX_PREVIEW_320: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_320_Preview_EVT1,\ + sizeof(s5k4ecgx_320_Preview_EVT1) / \ + sizeof(s5k4ecgx_320_Preview_EVT1[0])); + cam_info("S5K4ECGX_PREVIEW_320\n"); + break; + case S5K4ECGX_PREVIEW_176: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_176_Preview_EVT1,\ + sizeof(s5k4ecgx_176_Preview_EVT1) / \ + sizeof(s5k4ecgx_176_Preview_EVT1[0])); + cam_info("S5K4ECGX_PREVIEW_640\n"); + break; + case S5K4ECGX_PREVIEW_640: + default: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_640_Preview_EVT1,\ + sizeof(s5k4ecgx_640_Preview_EVT1) / \ + sizeof(s5k4ecgx_640_Preview_EVT1[0])); + cam_info("S5K4ECGX_PREVIEW_640\n"); + break; + } + + if (state->check_dataline) + err = s5k4ecgx_check_dataline(sd, 1); + } + + if (unlikely(err)) { + cam_err("fail to make preview\n"); + return err; + } + + state->runmode = RUNMODE_RUNNING; + + return 0; +} + +static int s5k4ecgx_set_preview_stop(struct v4l2_subdev *sd) +{ + int err = 0; + cam_info("do nothing.\n"); + + return err; +} + +static int s5k4ecgx_check_capture_status(struct v4l2_subdev *sd) +{ + int cnt = 0; + int status = 0; + int err = 0; + struct i2c_client *client = v4l2_get_subdevdata(sd); + + msleep(20); + while (cnt < 150) { + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E0244); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, (unsigned short *) + &status); + CHECK_ERR(err); + + if (!status) + break; + msleep(20); + cnt++; + } + if (cnt) + pr_info("[s5k4ecgx] wait time for capture frame : %dms\n", + cnt * 10); + if (status) + pr_info("[s5k4ecgx] take picture failed.\n"); + + return 0; +} + +static int s5k4ecgx_set_capture_start(struct v4l2_subdev *sd) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = -EINVAL; + cam_info(" E\n"); + /* check lowlight */ + if (state->lowlight) { + /* check scene mode */ + if (state->scene_mode != SCENE_MODE_NIGHTSHOT && + state->scene_mode != SCENE_MODE_FIREWORKS) { + /*low light capture start */ + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_Low_Cap_On_EVT1, \ + sizeof(s5k4ecgx_Low_Cap_On_EVT1) / \ + sizeof(s5k4ecgx_Low_Cap_On_EVT1[0])); + cam_info("s5k4ecgx_set_capture_start : s5k4ecgx_Low_Cap_On_EVT1\n"); + + /* check flash on */ + if (state->flash_mode == FLASH_MODE_AUTO || + state->flash_mode == FLASH_MODE_ON) { + /* AE/AWB unlock */ + err = s5k4ecgx_set_ae_lock(sd, false); + CHECK_ERR(err); + err = s5k4ecgx_set_awb_lock(sd, false); + CHECK_ERR(err); + /* Main flash on */ + state->pdata->flash_ctrl(CAM_FLASH_ON); + state->preflash = PREFLASH_ON; + /* 200ms AE delay */ + msleep(200); + } else + s5k4ecgx_cam_delay(sd); + } + } else { + /* check flash on */ + if (state->flash_mode == FLASH_MODE_ON) { + /* AE/AWB unlock */ + err = s5k4ecgx_set_ae_lock(sd, false); + CHECK_ERR(err); + err = s5k4ecgx_set_awb_lock(sd, false); + CHECK_ERR(err); + /* Main flash on */ + state->pdata->flash_ctrl(CAM_FLASH_ON); + state->preflash = PREFLASH_ON; + /* 200ms AE delay */ + msleep(200); + } + } + + /*capture start*/ + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Capture_Start_EVT1, \ + sizeof(s5k4ecgx_Capture_Start_EVT1) / \ + sizeof(s5k4ecgx_Capture_Start_EVT1[0])); + cam_info("s5k4ecgx_set_capture_start : s5k4ecgx_Capture_Start_EVT1\n"); + + state->runmode = RUNMODE_CAPTURING; + + /*capture delay*/ + err = s5k4ecgx_check_capture_status(sd); + + /* FIX later - temp code*/ + state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + + if (unlikely(err)) { + cam_err("failed to make capture\n"); + return err; + } + + s5k4ecgx_get_exif(sd); + + return err; +} + +static int s5k4ecgx_set_sensor_mode(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5k4ecgx_state *state = to_state(sd); + + if ((ctrl->value != SENSOR_CAMERA) && + (ctrl->value != SENSOR_MOVIE)) { + cam_err("ERR: Not support.(%d)\n", ctrl->value); + return -EINVAL; + } + + state->sensor_mode = ctrl->value; + + return 0; +} + +static int s5k4ecgx_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + cam_dbg("E\n"); + return 0; +} + +static int s5k4ecgx_enum_framesizes(struct v4l2_subdev *sd, \ + struct v4l2_frmsizeenum *fsize) +{ + struct s5k4ecgx_state *state = to_state(sd); + + cam_dbg("s5k4ecgx_enum_framesizes E\n"); + + /* + * Return the actual output settings programmed to the camera + * + * The camera interface should read this value, this is the resolution + * at which the sensor would provide framedata to the camera i/f + * In case of image capture, + * this returns the default camera resolution (VGA) + */ + if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) { + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = state->capture_frmsizes->width; + fsize->discrete.height = state->capture_frmsizes->height; + } else { + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = state->preview_frmsizes->width; + fsize->discrete.height = state->preview_frmsizes->height; + } + + cam_info("width - %d , height - %d\n", + fsize->discrete.width, fsize->discrete.height); + + return 0; +} + +static int s5k4ecgx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + int err = 0; + + cam_dbg("E\n"); + + return err; +} + +static int s5k4ecgx_set_fmt_size(struct v4l2_subdev *sd) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + cam_info("s5k4ecgx_set_fmt_size E\n"); + + if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) { + switch (state->capture_frmsizes->index) { + case S5K4ECGX_CAPTURE_5MP: + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_5M_Capture_EVT1,\ + sizeof(s5k4ecgx_5M_Capture_EVT1) / + sizeof(s5k4ecgx_5M_Capture_EVT1[0])); + cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_5MP\n"); + break; + case S5K4ECGX_CAPTURE_3MP: + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_3M_Capture_EVT1, + sizeof(s5k4ecgx_3M_Capture_EVT1) / + sizeof(s5k4ecgx_3M_Capture_EVT1[0])); + cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_3MP\n"); + break; + case S5K4ECGX_CAPTURE_2MP: + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_2M_Capture_EVT1, + sizeof(s5k4ecgx_2M_Capture_EVT1) / + sizeof(s5k4ecgx_2M_Capture_EVT1[0])); + cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_2MP\n"); + break; + case S5K4ECGX_CAPTURE_1MP: + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_1M_Capture_EVT1, + sizeof(s5k4ecgx_1M_Capture_EVT1) / + sizeof(s5k4ecgx_1M_Capture_EVT1[0])); + cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_1MP\n"); + break; + case S5K4ECGX_CAPTURE_XGA: + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_XGA_Capture_EVT1, + sizeof(s5k4ecgx_XGA_Capture_EVT1) / + sizeof(s5k4ecgx_XGA_Capture_EVT1[0])); + cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_XGA\n"); + break; + case S5K4ECGX_CAPTURE_VGA: + err = s5k4ecgx_write_regs(sd, + s5k4ecgx_VGA_Capture_EVT1, + sizeof(s5k4ecgx_VGA_Capture_EVT1) / + sizeof(s5k4ecgx_VGA_Capture_EVT1[0])); + cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_VGA\n"); + break; + default: + cam_err("ERR: Invalid capture size\n"); + break; + } + } + + if (unlikely(err < 0)) { + cam_err("i2c_write for set framerate\n"); + return -EIO; + } + + return err; +} + +static int s5k4ecgx_s_fmt(struct v4l2_subdev *sd, \ + struct v4l2_mbus_framefmt *ffmt) +{ + struct s5k4ecgx_state *state = to_state(sd); + u32 num_entries = 0; + u32 i; + u32 err = 0; + u32 width, height = 0; + + cam_info("s5k4ecgx_s_fmt E\n"); + /* + * Just copying the requested format as of now. + * We need to check here what are the formats the camera support, and + * set the most appropriate one according to the request from FIMC + */ + + width = state->req_fmt.width = ffmt->width; + height = state->req_fmt.height = ffmt->height; + + if (ffmt->colorspace == V4L2_COLORSPACE_JPEG) + state->req_fmt.priv = V4L2_PIX_FMT_MODE_CAPTURE; + else + state->req_fmt.priv = V4L2_PIX_FMT_MODE_PREVIEW; + + switch (state->req_fmt.priv) { + case V4L2_PIX_FMT_MODE_PREVIEW: + cam_info("V4L2_PIX_FMT_MODE_PREVIEW\n"); + num_entries = ARRAY_SIZE(preview_frmsizes); + for (i = 0; i < num_entries; i++) { + if (width == preview_frmsizes[i].width && + height == preview_frmsizes[i].height) { + state->preview_frmsizes = &preview_frmsizes[i]; + break; + } + if (i == (num_entries - 1)) + state->preview_frmsizes = &preview_frmsizes[0]; + } + break; + + case V4L2_PIX_FMT_MODE_CAPTURE: + cam_info("V4L2_PIX_FMT_MODE_CAPTURE\n"); + num_entries = ARRAY_SIZE(capture_frmsizes); + for (i = 0; i < num_entries; i++) { + if (width == capture_frmsizes[i].width && \ + height == capture_frmsizes[i].height) { + state->capture_frmsizes = &capture_frmsizes[i]; + break; + } + } + break; + + default: + cam_err + ("ERR(EINVAL) : Invalid capture size width(%d), height(%d)\n",\ + ffmt->width, ffmt->height); + return -EINVAL; + } + + /*set frame size of preview or capture*/ + err = s5k4ecgx_set_fmt_size(sd); + + return err; +} + +static int s5k4ecgx_set_frame_rate(struct v4l2_subdev *sd, u32 fps) +{ + int err = 0; + + cam_info("frame rate %d\n\n", fps); + + switch (fps) { + case 7: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_7_EVT1, + sizeof(s5k4ecgx_FPS_7_EVT1) / \ + sizeof(s5k4ecgx_FPS_7_EVT1[0])); + break; + case 15: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_15_EVT1, + sizeof(s5k4ecgx_FPS_15_EVT1) / \ + sizeof(s5k4ecgx_FPS_15_EVT1[0])); + + break; + case 20: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_20_EVT1, + sizeof(s5k4ecgx_FPS_20_EVT1) / \ + sizeof(s5k4ecgx_FPS_20_EVT1[0])); + + break; + case 24: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_24_EVT1, + sizeof(s5k4ecgx_FPS_24_EVT1) / \ + sizeof(s5k4ecgx_FPS_24_EVT1[0])); + break; + case 30: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_30_EVT1, + sizeof(s5k4ecgx_FPS_30_EVT1) / \ + sizeof(s5k4ecgx_FPS_30_EVT1[0])); + break; + default: + cam_err("ERR: Invalid framerate\n"); + break; + } + + if (unlikely(err < 0)) { + cam_err("i2c_write for set framerate\n"); + return -EIO; + } + + return err; +} + +static int s5k4ecgx_g_parm(struct v4l2_subdev *sd,\ + struct v4l2_streamparm *parms) +{ + int err = 0; + + cam_dbg("E\n"); + + return err; +} + +static int s5k4ecgx_s_parm(struct v4l2_subdev *sd, \ + struct v4l2_streamparm *parms) +{ + int err = 0; + u32 fps = 0; + u32 denom = parms->parm.capture.timeperframe.denominator; + u32 numer = parms->parm.capture.timeperframe.numerator; + struct s5k4ecgx_state *state = to_state(sd); + + cam_dbg("E\n"); + + if (denom >= 1 && numer == 1) + fps = denom / numer; + else if (denom == 1 && numer == 0) + fps = 0; + + if (fps != state->set_fps) { + if (fps < 0 && fps > 30) { + cam_err("invalid frame rate %d\n", fps); + fps = 30; + } + state->req_fps = fps; + + if (state->initialized) { + err = s5k4ecgx_set_frame_rate(sd, state->req_fps); + if (err >= 0) + state->set_fps = state->req_fps; + } + + } + + return err; +} + +static int s5k4ecgx_control_stream(struct v4l2_subdev *sd, int cmd) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + + switch (cmd) { + case STREAM_START: + cam_warn("WARN: do nothing\n"); + break; + + case STREAM_STOP: + cam_dbg("stream stop!!!\n"); + if (state->runmode == RUNMODE_CAPTURING) + state->runmode = RUNMODE_CAPTURE_STOP; + + break; + + default: + cam_err("ERR: Invalid cmd\n"); + break; + } + + if (unlikely(err)) + cam_err("failed to stream start(stop)\n"); + + return err; +} + +static int s5k4ecgx_init(struct v4l2_subdev *sd, u32 val) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + /* set initial regster value */ + if (state->sensor_mode == SENSOR_CAMERA) { + cam_info("load camera common setting\n"); + err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg1_EVT1, + sizeof(s5k4ecgx_init_reg1_EVT1) / \ + sizeof(s5k4ecgx_init_reg1_EVT1[0])); + + msleep(20); + + err |= s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg2_EVT1, + sizeof(s5k4ecgx_init_reg2_EVT1) / \ + sizeof(s5k4ecgx_init_reg2_EVT1[0])); + } else { + cam_info("load recording setting\n"); + err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg1_EVT1, + sizeof(s5k4ecgx_init_reg1_EVT1) / \ + sizeof(s5k4ecgx_init_reg1_EVT1[0])); + + msleep(20); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg2_EVT1, + sizeof(s5k4ecgx_init_reg2_EVT1) / \ + sizeof(s5k4ecgx_init_reg2_EVT1[0])); + } + + if (unlikely(err)) { + cam_err("failed to init\n"); + return err; + } + + state->runmode = RUNMODE_INIT; + + /* We stop stream-output from sensor when starting camera. */ + err = s5k4ecgx_control_stream(sd, STREAM_STOP); + if (unlikely(err < 0)) + return err; + msleep(150); + + state->initialized = 1; + + return 0; +} + +static int s5k4ecgx_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + + cam_info("stream mode = %d\n", enable); + + switch (enable) { + case STREAM_MODE_CAM_OFF: + if (state->sensor_mode == SENSOR_CAMERA) { + if (state->check_dataline) + err = s5k4ecgx_check_dataline(sd, 0); + else + err = s5k4ecgx_control_stream(sd, STREAM_STOP); + } + break; + + case STREAM_MODE_CAM_ON: + /* The position of this code need to be adjusted later */ + if ((state->sensor_mode == SENSOR_CAMERA) + && (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE)) + err = s5k4ecgx_set_capture_start(sd); + else + err = s5k4ecgx_set_preview_start(sd); + break; + + case STREAM_MODE_MOVIE_ON: + cam_dbg("do nothing(movie on)!!\n"); + break; + + case STREAM_MODE_MOVIE_OFF: + cam_dbg("do nothing(movie off)!!\n"); + break; + + default: + cam_err("ERR: Invalid stream mode\n"); + break; + } + + if (unlikely(err < 0)) { + cam_err("ERR: faild\n"); + return err; + } + + return 0; +} + +static int s5k4ecgx_get_af_1stsearch(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int af_status = -1; + int err = 0; + int ret = 0; + cam_info("- Start\n"); + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E2EEE); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&af_status); + CHECK_ERR(err); + + switch (af_status & 0xff) { + case AF_PROGRESS_1ST: + ret = CAMERA_AF_STATUS_IN_PROGRESS; + break; + + case AF_SUCCESS_1ST: + ret = CAMERA_AF_STATUS_SUCCESS; + break; + + case AF_FAIL_1ST: + default: + ret = CAMERA_AF_STATUS_FAIL; + break; + } + + ctrl->value = ret; + cam_info("- END%d\n", ret); + return ret; +} + +static int s5k4ecgx_get_af_2ndsearch(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int af_status = -1; + int err = 0; + int ret = 0; + cam_info(" E\n"); + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E2207); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&af_status); + CHECK_ERR(err); + + switch (af_status & 0xff) { + case AF_SUCCESS_2ND: + ret = CAMERA_AF_STATUS_SUCCESS; + break; + + case AF_PROGRESS_2ND: + default: + ret = CAMERA_AF_STATUS_IN_PROGRESS; + break; + } + + ctrl->value = ret; + cam_info(" - END%d\n", ret); + return ret; +} + +static int s5k4ecgx_get_af_result(struct v4l2_subdev *sd, + struct v4l2_control *ctrl) +{ + struct s5k4ecgx_state *state = to_state(sd); + int status = 0; + cam_info(" - START\n"); + if (state->focus.first == true) { + state->focus.first = false; + s5k4ecgx_cam_delay(sd); + } + + /* 1st search af */ + s5k4ecgx_cam_delay(sd); + + status = s5k4ecgx_get_af_1stsearch(sd, ctrl); + + if (status != CAMERA_AF_STATUS_SUCCESS) { + state->focus.status = status; + if (status == CAMERA_AF_STATUS_FAIL) + state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + return status; + } + + /* 2nd search af */ + s5k4ecgx_cam_delay(sd); + + status = s5k4ecgx_get_af_2ndsearch(sd, ctrl); + + state->focus.status = status; + state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + + cam_info("af_status = %d\n", status); + cam_info(" - END\n"); + return 0; +} + + +static int s5k4ecgx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + + /* V4L2_CID_PRIVATE_BASE==0x08000000 */ + /* V4L2_CID_CAMERA_CLASS_BASE==0x009a0900 */ + /* V4L2_CID_BASE==0x00980900 */ + + if (ctrl->id > V4L2_CID_PRIVATE_BASE) + cam_dbg("ctrl->id:%d, value=%d V4L2_CID_PRIVATE_BASE\n",\ + ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); + else if (ctrl->id > V4L2_CID_CAMERA_CLASS_BASE) + cam_dbg("ctrl->id:%d, value=%d V4L2_CID_CAMERA_CLASS_BASE\n",\ + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE, ctrl->value); + else + cam_dbg("ctrl->id:%d, value=%d V4L2_CID_BASE\n", \ + ctrl->id - V4L2_CID_BASE, ctrl->value); + + mutex_lock(&state->ctrl_lock); + + switch (ctrl->id) { + case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT: + ctrl->value = state->focus.status; + break; + + case V4L2_CID_CAM_JPEG_MEMSIZE: + ctrl->value = S5K4ECGX_INTLV_DATA_MAXSIZE; + break; + + case V4L2_CID_CAM_JPEG_MAIN_SIZE: + ctrl->value = S5K4ECGX_INTLV_DATA_MAXSIZE; + break; + + case V4L2_CID_CAM_JPEG_MAIN_OFFSET: + ctrl->value = 0; + break; + + case V4L2_CID_CAM_JPEG_THUMB_SIZE: + ctrl->value = 0; + break; + + case V4L2_CID_CAM_JPEG_THUMB_OFFSET: + ctrl->value = 0; + break; + + case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET: + ctrl->value = 0; + break; + + case V4L2_CID_CAMERA_EXIF_FLASH: + ctrl->value = state->exif.flash; + break; + + case V4L2_CID_CAMERA_ISO: + ctrl->value = state->exif.iso; + break; + + case V4L2_CID_CAMERA_EXIF_ISO: + ctrl->value = state->exif.iso; + break; + + case V4L2_CID_CAMERA_EXIF_TV: + ctrl->value = state->exif.tv; + break; + + case V4L2_CID_CAMERA_EXIF_BV: + ctrl->value = state->exif.bv; + break; + + case V4L2_CID_CAMERA_EXIF_EBV: + ctrl->value = state->exif.ebv; + break; + + case V4L2_CID_WHITE_BALANCE_PRESET: + ctrl->value = state->wb_mode; + break; + + default: + cam_err("no such control id %d\n", + ctrl->id - V4L2_CID_PRIVATE_BASE); + break; + } + + mutex_unlock(&state->ctrl_lock); + + return err; +} + +static int s5k4ecgx_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + int err; + struct s5k4ecgx_state *state = to_state(sd); + cam_dbg("E, value %d\n", ctrl->value); + +retry: + switch (ctrl->value) { + case ISO_AUTO: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_Auto_EVT1, \ + sizeof(s5k4ecgx_ISO_Auto_EVT1) / \ + sizeof(s5k4ecgx_ISO_Auto_EVT1[0])); + break; + + case ISO_50: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_50_EVT1, \ + sizeof(s5k4ecgx_ISO_50_EVT1) / \ + sizeof(s5k4ecgx_ISO_50_EVT1[0])); + break; + + case ISO_100: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_100_EVT1, \ + sizeof(s5k4ecgx_ISO_100_EVT1) / \ + sizeof(s5k4ecgx_ISO_100_EVT1[0])); + break; + + case ISO_200: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_200_EVT1, \ + sizeof(s5k4ecgx_ISO_200_EVT1) / \ + sizeof(s5k4ecgx_ISO_200_EVT1[0])); + break; + + case ISO_400: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_400_EVT1, \ + sizeof(s5k4ecgx_ISO_400_EVT1) / \ + sizeof(s5k4ecgx_ISO_400_EVT1[0])); + break; + + default: + cam_warn("invalid value, %d\n", ctrl->value); + ctrl->value = ISO_AUTO; + goto retry; + } + + state->exif.iso = ctrl->value; + + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_set_metering(struct v4l2_subdev *sd, int val) +{ + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case METERING_CENTER: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Center_EVT1, \ + sizeof(s5k4ecgx_Metering_Center_EVT1) / \ + sizeof(s5k4ecgx_Metering_Center_EVT1[0])); + break; + + case METERING_SPOT: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Spot_EVT1, \ + sizeof(s5k4ecgx_Metering_Spot_EVT1) / \ + sizeof(s5k4ecgx_Metering_Spot_EVT1[0])); + break; + + case METERING_MATRIX: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Matrix_EVT1, \ + sizeof(s5k4ecgx_Metering_Matrix_EVT1) / \ + sizeof(s5k4ecgx_Metering_Matrix_EVT1[0])); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = METERING_CENTER; + goto retry; + } + + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_set_exposure(struct v4l2_subdev *sd, \ + struct v4l2_control *ctrl) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_dbg("E\n"); + + if (state->check_dataline) + return 0; + + switch (ctrl->value) { + case 0: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_4_EVT1, \ + sizeof(s5k4ecgx_EV_Minus_4_EVT1) / \ + sizeof(s5k4ecgx_EV_Minus_4_EVT1[0])); + break; + case 1: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_3_EVT1, \ + sizeof(s5k4ecgx_EV_Minus_3_EVT1) / \ + sizeof(s5k4ecgx_EV_Minus_3_EVT1[0])); + + break; + case 2: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_2_EVT1, \ + sizeof(s5k4ecgx_EV_Minus_2_EVT1) / \ + sizeof(s5k4ecgx_EV_Minus_2_EVT1[0])); + break; + case 3: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_1_EVT1, \ + sizeof(s5k4ecgx_EV_Minus_1_EVT1) / \ + sizeof(s5k4ecgx_EV_Minus_1_EVT1[0])); + break; + case 4: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Default_EVT1, \ + sizeof(s5k4ecgx_EV_Default_EVT1) / \ + sizeof(s5k4ecgx_EV_Default_EVT1[0])); + break; + case 5: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_1_EVT1, \ + sizeof(s5k4ecgx_EV_Plus_1_EVT1) / \ + sizeof(s5k4ecgx_EV_Plus_1_EVT1[0])); + break; + case 6: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_2_EVT1, \ + sizeof(s5k4ecgx_EV_Plus_2_EVT1) / \ + sizeof(s5k4ecgx_EV_Plus_2_EVT1[0])); + break; + case 7: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_3_EVT1, \ + sizeof(s5k4ecgx_EV_Plus_3_EVT1) / \ + sizeof(s5k4ecgx_EV_Plus_3_EVT1[0])); + break; + case 8: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_4_EVT1, \ + sizeof(s5k4ecgx_EV_Plus_4_EVT1) / \ + sizeof(s5k4ecgx_EV_Plus_4_EVT1[0])); + break; + default: + cam_err("ERR: invalid brightness(%d)\n", ctrl->value); + return err; + break; + } + + if (unlikely(err < 0)) { + cam_err("ERR: i2c_write for set brightness\n"); + return -EIO; + } + + return 0; +} + +static int s5k4ecgx_set_whitebalance(struct v4l2_subdev *sd, int val) +{ + int err; + struct s5k4ecgx_state *state = to_state(sd); + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case WHITE_BALANCE_AUTO: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Auto_EVT1, \ + sizeof(s5k4ecgx_WB_Auto_EVT1) / \ + sizeof(s5k4ecgx_WB_Auto_EVT1[0])); + break; + + case WHITE_BALANCE_SUNNY: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Sunny_EVT1, \ + sizeof(s5k4ecgx_WB_Sunny_EVT1) / \ + sizeof(s5k4ecgx_WB_Sunny_EVT1[0])); + break; + + case WHITE_BALANCE_CLOUDY: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Cloudy_EVT1, \ + sizeof(s5k4ecgx_WB_Cloudy_EVT1) / \ + sizeof(s5k4ecgx_WB_Cloudy_EVT1[0])); + break; + + case WHITE_BALANCE_TUNGSTEN: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Tungsten_EVT1, \ + sizeof(s5k4ecgx_WB_Tungsten_EVT1) / \ + sizeof(s5k4ecgx_WB_Tungsten_EVT1[0])); + break; + + case WHITE_BALANCE_FLUORESCENT: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Fluorescent_EVT1, \ + sizeof(s5k4ecgx_WB_Fluorescent_EVT1) / \ + sizeof(s5k4ecgx_WB_Fluorescent_EVT1[0])); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = WHITE_BALANCE_AUTO; + goto retry; + } + + state->wb_mode = val; + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_set_scene_mode(struct v4l2_subdev *sd, int val) +{ + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case SCENE_MODE_NONE: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Default_EVT1, \ + sizeof(s5k4ecgx_Scene_Default_EVT1) / \ + sizeof(s5k4ecgx_Scene_Default_EVT1[0])); + break; + + case SCENE_MODE_PORTRAIT: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Portrait_EVT1, \ + sizeof(s5k4ecgx_Scene_Portrait_EVT1) / \ + sizeof(s5k4ecgx_Scene_Portrait_EVT1[0])); + break; + + case SCENE_MODE_LANDSCAPE: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Landscape_EVT1, \ + sizeof(s5k4ecgx_Scene_Landscape_EVT1) / \ + sizeof(s5k4ecgx_Scene_Landscape_EVT1[0])); + break; + + case SCENE_MODE_SPORTS: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Sports_EVT1, \ + sizeof(s5k4ecgx_Scene_Sports_EVT1) / \ + sizeof(s5k4ecgx_Scene_Sports_EVT1[0])); + break; + + case SCENE_MODE_PARTY_INDOOR: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Party_Indoor_EVT1,\ + sizeof(s5k4ecgx_Scene_Party_Indoor_EVT1) / \ + sizeof(s5k4ecgx_Scene_Party_Indoor_EVT1[0])); + break; + + case SCENE_MODE_BEACH_SNOW: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Beach_Snow_EVT1, \ + sizeof(s5k4ecgx_Scene_Beach_Snow_EVT1) / \ + sizeof(s5k4ecgx_Scene_Beach_Snow_EVT1[0])); + break; + + case SCENE_MODE_SUNSET: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Sunset_EVT1, \ + sizeof(s5k4ecgx_Scene_Sunset_EVT1) / \ + sizeof(s5k4ecgx_Scene_Sunset_EVT1[0])); + break; + + case SCENE_MODE_DUSK_DAWN: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Duskdawn_EVT1, \ + sizeof(s5k4ecgx_Scene_Duskdawn_EVT1) / \ + sizeof(s5k4ecgx_Scene_Duskdawn_EVT1[0])); + break; + + case SCENE_MODE_FALL_COLOR: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Fall_Color_EVT1, \ + sizeof(s5k4ecgx_Scene_Fall_Color_EVT1) / \ + sizeof(s5k4ecgx_Scene_Fall_Color_EVT1[0])); + break; + + case SCENE_MODE_NIGHTSHOT: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Nightshot_EVT1, \ + sizeof(s5k4ecgx_Scene_Nightshot_EVT1) / \ + sizeof(s5k4ecgx_Scene_Nightshot_EVT1[0])); + break; + + case SCENE_MODE_BACK_LIGHT: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Backlight_EVT1, \ + sizeof(s5k4ecgx_Scene_Backlight_EVT1) / \ + sizeof(s5k4ecgx_Scene_Backlight_EVT1[0])); + break; + + case SCENE_MODE_FIREWORKS: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Fireworks_EVT1, \ + sizeof(s5k4ecgx_Scene_Fireworks_EVT1) / \ + sizeof(s5k4ecgx_Scene_Fireworks_EVT1[0])); + break; + + case SCENE_MODE_TEXT: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Text_EVT1, \ + sizeof(s5k4ecgx_Scene_Text_EVT1) / \ + sizeof(s5k4ecgx_Scene_Text_EVT1[0])); + break; + + case SCENE_MODE_CANDLE_LIGHT: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_Scene_Candle_Light_EVT1, \ + sizeof(s5k4ecgx_Scene_Candle_Light_EVT1) / \ + sizeof(s5k4ecgx_Scene_Candle_Light_EVT1[0])); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = SCENE_MODE_NONE; + goto retry; + } + + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_set_effect(struct v4l2_subdev *sd, int val) +{ + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case IMAGE_EFFECT_NONE: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Normal_EVT1, \ + sizeof(s5k4ecgx_Effect_Normal_EVT1) / \ + sizeof(s5k4ecgx_Effect_Normal_EVT1[0])); + break; + + case IMAGE_EFFECT_SEPIA: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Sepia_EVT1, \ + sizeof(s5k4ecgx_Effect_Sepia_EVT1) / \ + sizeof(s5k4ecgx_Effect_Sepia_EVT1[0])); + break; + + case IMAGE_EFFECT_BNW: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_Effect_Black_White_EVT1, \ + sizeof(s5k4ecgx_Effect_Black_White_EVT1) / \ + sizeof(s5k4ecgx_Effect_Black_White_EVT1[0])); + break; + + case IMAGE_EFFECT_NEGATIVE: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Negative_EVT1, \ + sizeof(s5k4ecgx_Effect_Negative_EVT1) / \ + sizeof(s5k4ecgx_Effect_Negative_EVT1[0])); + break; + + case IMAGE_EFFECT_AQUA: + err = s5k4ecgx_write_regs(sd, \ + s5k4ecgx_Effect_Solarization_EVT1, \ + sizeof(s5k4ecgx_Effect_Solarization_EVT1) / \ + sizeof(s5k4ecgx_Effect_Solarization_EVT1[0])); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = IMAGE_EFFECT_NONE; + goto retry; + } + + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_set_wdr(struct v4l2_subdev *sd, int val) +{ + int err; + cam_dbg("E, value %d\n", val); + +retry: + switch (val) { + case WDR_OFF: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WDR_off_EVT1, \ + sizeof(s5k4ecgx_WDR_off_EVT1) / \ + sizeof(s5k4ecgx_WDR_off_EVT1[0])); + break; + + case WDR_ON: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_WDR_on_EVT1, \ + sizeof(s5k4ecgx_WDR_on_EVT1) / \ + sizeof(s5k4ecgx_WDR_on_EVT1[0])); + break; + + default: + cam_warn("invalid value, %d\n", val); + val = WDR_OFF; + goto retry; + } + + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_set_jpeg_quality(struct v4l2_subdev *sd, int val) +{ + int err = -1; + cam_dbg("E, value %d\n", val); + + if (val <= 65) /* Normal */ + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Jpeg_Quality_Low_EVT1,\ + sizeof(s5k4ecgx_Jpeg_Quality_Low_EVT1) / \ + sizeof(s5k4ecgx_Jpeg_Quality_Low_EVT1[0])); + else if (val <= 75) /* Fine */ + err = s5k4ecgx_write_regs + (sd, s5k4ecgx_Jpeg_Quality_Normal_EVT1,\ + sizeof(s5k4ecgx_Jpeg_Quality_Normal_EVT1) / \ + sizeof(s5k4ecgx_Jpeg_Quality_Normal_EVT1[0])); + else /* Superfine */ + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Jpeg_Quality_High_EVT1,\ + sizeof(s5k4ecgx_Jpeg_Quality_High_EVT1) / \ + sizeof(s5k4ecgx_Jpeg_Quality_High_EVT1[0])); + + CHECK_ERR(err); + + cam_dbg("X\n"); + return 0; +} + +static int s5k4ecgx_return_focus(struct v4l2_subdev *sd) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("E\n"); + + switch (state->focus.mode) { + case FOCUS_MODE_MACRO: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_1_EVT1,\ + sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1) / \ + sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_2_EVT1,\ + sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1) / \ + sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_3_EVT1,\ + sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1) / \ + sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1[0])); + + break; + + default: + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_1_EVT1,\ + sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1) / \ + sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_2_EVT1,\ + sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1) / \ + sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_3_EVT1,\ + sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1) / \ + sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1[0])); + + break; + } + + CHECK_ERR(err); + return 0; +} + +/* PX: Stop AF */ +static int s5k4ecgx_stop_af(struct v4l2_subdev *sd, s32 touch) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + + cam_info("E\n"); + mutex_lock(&state->af_lock); + + switch (state->focus.status) { + case CAMERA_AF_STATUS_FAIL: + case CAMERA_AF_STATUS_SUCCESS: + cam_dbg("Stop AF, focus mode %d, AF result %d\n", + state->focus.mode, state->focus.status); + + err = s5k4ecgx_set_ae_lock(sd, false); + err = s5k4ecgx_set_awb_lock(sd, false); + if (unlikely(err)) { + cam_err("%s: ERROR, fail to set lock\n", __func__); + goto err_out; + } + state->focus.status = CAMERA_AF_STATUS_MAX; + state->preflash = PREFLASH_NONE; + break; + + case CAMERA_AF_STATUS_MAX: + break; + + default: + cam_err("%s: WARNING, unnecessary calling. AF status=%d\n", + __func__, state->focus.status); + /* Return 0. */ + goto err_out; + break; + } + + if (!touch) { + /* We move lens to default position if af is cancelled.*/ + err = s5k4ecgx_return_focus(sd); + if (unlikely(err)) { + cam_err("%s: ERROR, fail to af_norma_mode (%d)\n", + __func__, err); + goto err_out; + } + } + + mutex_unlock(&state->af_lock); + cam_info("X\n"); + return 0; + +err_out: + mutex_unlock(&state->af_lock); + return err; +} + +static int s5k4ecgx_set_af_mode(struct v4l2_subdev *sd, int val) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = -1; + u32 af_cancel = 0; + cam_info(" - value %d\n", val); + + mutex_lock(&state->af_lock); + +retry: + af_cancel = (u32)val & FOCUS_MODE_DEFAULT; + switch (val) { + case FOCUS_MODE_AUTO: + case FOCUS_MODE_INFINITY: + state->focus.mode = val; + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_1_EVT1,\ + sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1) / \ + sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_2_EVT1,\ + sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1) / \ + sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_3_EVT1,\ + sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1) / \ + sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1[0])); + + break; + + case FOCUS_MODE_MACRO: + state->focus.mode = val; + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_1_EVT1,\ + sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1) / \ + sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_2_EVT1,\ + sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1) / \ + sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1[0])); + + s5k4ecgx_cam_delay(sd); + + err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_3_EVT1,\ + sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1) / \ + sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1[0])); + + break; + + default: + cam_warn("invalid value, %d\n", val); + val = FOCUS_MODE_AUTO; + goto retry; + } + + state->focus.mode = val; + mutex_unlock(&state->af_lock); + + if (af_cancel) + s5k4ecgx_stop_af(sd, 0); + + return 0; + + CHECK_ERR(err); + return 0; +} + +/* PX: Do AF */ +static int s5k4ecgx_do_af(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct s5k4ecgx_state *state = to_state(sd); + u16 read_value = 0; + u32 count = 0; + int err = 0; + + cam_info("E\n"); + + /* AE, AWB Lock */ + err = s5k4ecgx_set_ae_lock(sd, true); + CHECK_ERR(err); + err = s5k4ecgx_set_awb_lock(sd, true); + CHECK_ERR(err); + + /* AF start */ + err = s5k4ecgx_write_regs(sd, s5k4ecgx_Single_AF_Start_EVT1,\ + sizeof(s5k4ecgx_Single_AF_Start_EVT1) / \ + sizeof(s5k4ecgx_Single_AF_Start_EVT1[0])); + CHECK_ERR(err); + + /* 1 frame delay */ + s5k4ecgx_cam_delay(sd); + + /* AF Searching */ + cam_dbg("AF 1st search\n"); + + /*1st search*/ + for (count = 0; count < FIRST_AF_SEARCH_COUNT; count++) { + if (state->focus.start == AUTO_FOCUS_OFF) { + cam_dbg("do_af: AF is cancelled while doing(1st)\n"); + state->focus.status = CAMERA_AF_STATUS_MAX; + goto check_done; + } + + /* 1 frame delay */ + s5k4ecgx_cam_delay(sd); + + read_value = 0x0; + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E2EEE); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, &read_value); + CHECK_ERR(err); + cam_info("1st AF status(%02d) = 0x%04X\n", + count, read_value); + + if ((read_value & 0xff) != AF_PROGRESS_1ST) + break; + } + + if ((read_value & 0xff) != AF_SUCCESS_1ST) { + cam_err("%s: ERROR, 1st AF failed. count=%d, read_val=0x%X\n\n", + __func__, count, read_value); + state->focus.status = CAMERA_AF_STATUS_FAIL; + goto check_done; + } + + /*2nd search*/ + cam_dbg("AF 2nd search\n"); + for (count = 0; count < SECOND_AF_SEARCH_COUNT; count++) { + if (state->focus.start == AUTO_FOCUS_OFF) { + cam_dbg("do_af: AF is cancelled while doing(2nd)\n"); + state->focus.status = CAMERA_AF_STATUS_MAX; + goto check_done; + } + + read_value = 0x0; + err = s5k4ecgx_write(client, 0x002C7000); + CHECK_ERR(err); + err = s5k4ecgx_write(client, 0x002E2207); + CHECK_ERR(err); + err = s5k4ecgx_read(client, 0x0F12, &read_value); + CHECK_ERR(err); + cam_info("2nd AF status(%02d) = 0x%04X\n", + count, read_value); + if ((read_value & 0xff) == AF_SUCCESS_2ND) + break; + } + + if (count >= SECOND_AF_SEARCH_COUNT) { + /* 0x01XX means "Not Finish". */ + cam_err("%s: ERROR, 2nd AF failed. read_val=0x%X\n\n", + __func__, read_value & 0xff); + state->focus.status = CAMERA_AF_STATUS_FAIL; + goto check_done; + } + + cam_info("AF Success!\n"); + state->focus.status = CAMERA_AF_STATUS_SUCCESS; + +check_done: + /* restore write mode */ + + /* We only unlocked AE,AWB in case of being cancelled. + * But we now unlock it unconditionally if AF is started, + */ + if (state->focus.status == CAMERA_AF_STATUS_MAX) { + cam_dbg("%s: Single AF cancelled.\n", __func__); + /* AE, AWB Lock */ + err = s5k4ecgx_set_ae_lock(sd, false); + CHECK_ERR(err); + err = s5k4ecgx_set_awb_lock(sd, false); + CHECK_ERR(err); + } else { + state->focus.start = AUTO_FOCUS_OFF; + cam_dbg("%s: Single AF finished\n", __func__); + } + + if ((state->preflash == PREFLASH_ON) && + (state->sensor_mode == SENSOR_CAMERA)) { + state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + if (state->focus.status == CAMERA_AF_STATUS_MAX) + state->preflash = PREFLASH_NONE; + } + + /* Notice: we here turn touch flag off set previously + * when doing Touch AF. */ + + return 0; +} + +static void s5k4ecgx_af_worker(struct work_struct *work) +{ + struct s5k4ecgx_state *state = container_of(work, \ + struct s5k4ecgx_state, af_work); + struct v4l2_subdev *sd = &state->sd; + int err = -EINVAL; + + cam_info("E\n"); + + mutex_lock(&state->af_lock); + + /* 1. Check Low Light */ + err = s5k4ecgx_get_lux(sd); + + /* 2. Turn on Pre Flash */ + switch (state->flash_mode) { + case FLASH_MODE_AUTO: + if (!state->lowlight) { + /* flash not needed */ + break; + } + + case FLASH_MODE_ON: + state->pdata->flash_ctrl(CAM_FLASH_TORCH); + state->preflash = PREFLASH_ON; + break; + + case FLASH_MODE_OFF: + default: + break; + } + + if (state->preflash == PREFLASH_ON) { + /* 3. Waiting until AE Stable */ + err = s5k4ecgx_ae_stable(sd); + } else if (state->focus.start == AUTO_FOCUS_OFF) { + cam_info("af_start_preflash: AF is cancelled!\n"); + state->focus.status = CAMERA_AF_STATUS_MAX; + } + + if (state->focus.status == CAMERA_AF_STATUS_MAX) { + if (state->preflash == PREFLASH_ON) { + state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + } + goto out; + } + + s5k4ecgx_do_af(sd); + +out: + mutex_unlock(&state->af_lock); + cam_info("X\n"); + return; +} + +static int s5k4ecgx_set_af(struct v4l2_subdev *sd, s32 val) +{ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + + cam_info("%s: %s, focus mode %d\n", __func__, + val ? "start" : "stop", state->focus.mode); + + if (unlikely((u32)val >= AUTO_FOCUS_MAX)) { + cam_err("%s: ERROR, invalid value(%d)\n", __func__, val); + return -EINVAL; + } + +/* need to check the AF scenario with SLP team - temp code */ +/* + if (state->focus.start == val) + return 0; +*/ + state->focus.start = val; + + if (val == AUTO_FOCUS_ON) { + err = queue_work(state->workqueue, &state->af_work); + if (likely(err)) + state->focus.status = CAMERA_AF_STATUS_IN_PROGRESS; + else + cam_warn("WARNING, AF is still processing. So new AF cannot start\n"); + } else { + /* Cancel AF */ + /* 1. AE/AWB UnLock */ + err = s5k4ecgx_set_ae_lock(sd, false); + CHECK_ERR(err); + err = s5k4ecgx_set_awb_lock(sd, false); + CHECK_ERR(err); + /* 2. Turn off on pre flash */ + state->pdata->flash_ctrl(CAM_FLASH_OFF); + state->preflash = PREFLASH_OFF; + /* 3. Cancel AF mode */ + err = s5k4ecgx_set_af_mode(sd, state->focus.mode); + cam_info("set_af: AF cancel requested!\n"); + } + + cam_info("X\n"); + return 0; +} + +static int s5k4ecgx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + /* struct i2c_client *client = v4l2_get_subdevdata(sd); */ + struct s5k4ecgx_state *state = to_state(sd); + int err = 0; + + /* V4L2_CID_PRIVATE_BASE == 0x08000000 */ + /* V4L2_CID_CAMERA_CLASS_BASE == 0x009a0900 */ + /* V4L2_CID_BASE == 0x00980900 */ + + if (ctrl->id > V4L2_CID_PRIVATE_BASE) + cam_dbg("ctrl->id:%d, value=%d V4L2_CID_PRIVATE_BASE\n", \ + ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value); + else if (ctrl->id > V4L2_CID_CAMERA_CLASS_BASE) + cam_dbg("ctrl->id:%d, value=%d V4L2_CID_CAMERA_CLASS_BASE\n",\ + ctrl->id - V4L2_CID_CAMERA_CLASS_BASE, ctrl->value); + else + cam_dbg("ctrl->id:%d, value=%d V4L2_CID_BASE\n", \ + ctrl->id - V4L2_CID_BASE, ctrl->value); + + if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE) + && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE) + && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE)) + && (!state->initialized)) { + cam_warn("camera isn't initialized\n"); + return 0; + } + + if (ctrl->id != V4L2_CID_CAMERA_SET_AUTO_FOCUS) + mutex_lock(&state->ctrl_lock); + + switch (ctrl->id) { + case V4L2_CID_CAM_JPEG_QUALITY: + err = s5k4ecgx_set_jpeg_quality(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_ISO: + err = s5k4ecgx_set_iso(sd, ctrl); + break; + + case V4L2_CID_CAMERA_METERING: + if (state->sensor_mode == SENSOR_CAMERA) + err = s5k4ecgx_set_metering(sd, ctrl->value); + break; + + case V4L2_CID_EXPOSURE: + err = s5k4ecgx_set_exposure(sd, ctrl); + cam_dbg("V4L2_CID_EXPOSURE [%d]\n", ctrl->value); + break; + + case V4L2_CID_WHITE_BALANCE_PRESET: + case V4L2_CID_CAMERA_WHITE_BALANCE: + err = s5k4ecgx_set_whitebalance(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_SCENE_MODE: + state->scene_mode = ctrl->value; + err = s5k4ecgx_set_scene_mode(sd, ctrl->value); + break; + + case V4L2_CID_COLORFX: + err = s5k4ecgx_set_effect(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_WDR: + err = s5k4ecgx_set_wdr(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_FLASH_MODE: + state->flash_mode = ctrl->value; + break; + + case V4L2_CID_FOCUS_AUTO_MODE: + case V4L2_CID_CAMERA_FOCUS_MODE: + err = s5k4ecgx_set_af_mode(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_SET_AUTO_FOCUS: + err = s5k4ecgx_set_af(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE: + state->check_dataline = ctrl->value; + cam_dbg("check_dataline = %d\n", state->check_dataline); + err = 0; + break; + + case V4L2_CID_CAMERA_SENSOR_MODE: + err = s5k4ecgx_set_sensor_mode(sd, ctrl); + cam_dbg("sensor_mode = %d\n", ctrl->value); + break; + + case V4L2_CID_CAMERA_CHECK_DATALINE_STOP: + cam_dbg("do nothing\n"); + break; + + case V4L2_CID_CAMERA_CHECK_ESD: + err = s5k4ecgx_check_esd(sd); + break; + + case V4L2_CID_CAMERA_FRAME_RATE: + err = s5k4ecgx_set_frame_rate(sd, ctrl->value); + break; + + case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS: + s5k4ecgx_debug_sensor_status(sd); + err = s5k4ecgx_check_sensor_status(sd); + break; + + default: + cam_err("ERR(ENOIOCTLCMD)\n"); + /* no errors return.*/ + break; + } + + if (ctrl->id != V4L2_CID_CAMERA_SET_AUTO_FOCUS) + mutex_unlock(&state->ctrl_lock); + + cam_dbg("X\n"); + return err; +} + +static const struct v4l2_subdev_core_ops s5k4ecgx_core_ops = { + .init = s5k4ecgx_init, /* initializing API */ + .g_ctrl = s5k4ecgx_g_ctrl, + .s_ctrl = s5k4ecgx_s_ctrl, +}; + +static const struct v4l2_subdev_video_ops s5k4ecgx_video_ops = { + .s_mbus_fmt = s5k4ecgx_s_fmt, + .s_stream = s5k4ecgx_s_stream, + .enum_framesizes = s5k4ecgx_enum_framesizes, + .g_parm = s5k4ecgx_g_parm, + .s_parm = s5k4ecgx_s_parm, +}; + +static const struct v4l2_subdev_ops s5k4ecgx_ops = { + .core = &s5k4ecgx_core_ops, + .video = &s5k4ecgx_video_ops, +}; + +/* + * s5k4ecgx_probe + * Fetching platform data is being done with s_config subdev call. + * In probe routine, we just register subdev device + */ +static int s5k4ecgx_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct s5k4ecgx_state *state = NULL; + struct v4l2_subdev *sd = NULL; + struct s5k4ecgx_platform_data *pdata = NULL; + cam_dbg("E\n"); + + state = kzalloc(sizeof(struct s5k4ecgx_state), GFP_KERNEL); + if (state == NULL) + return -ENOMEM; + + sd = &state->sd; + strcpy(sd->name, S5K4ECGX_DRIVER_NAME); + + state->runmode = RUNMODE_NOTREADY; + state->initialized = 0; + state->req_fps = state->set_fps = 0; + state->sensor_mode = SENSOR_CAMERA; + state->zoom = 0; + state->flash_mode = FLASH_MODE_BASE; + state->lowlight = 0; + state->awb_lock = 0; + state->ae_lock = 0; + state->preflash = PREFLASH_NONE; + + pdata = client->dev.platform_data; + + if (!pdata) { + cam_err("no platform data\n"); + return -ENODEV; + } + + /* Registering subdev */ + v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops); + + mutex_init(&state->ctrl_lock); + mutex_init(&state->af_lock); + + state->workqueue = create_workqueue("cam_workqueue"); + if (unlikely(!state->workqueue)) { + dev_err(&client->dev, "probe, fail to create workqueue\n"); + goto err_out; + } + INIT_WORK(&state->af_work, s5k4ecgx_af_worker); + + /* + * Assign default format and resolution + * Use configured default information in platform data + * or without them, use default information in driver + */ + + /*S5K4ECGX_PREVIEW_VGA*/ + state->preview_frmsizes = &preview_frmsizes[0]; + /*S5K4ECGX_CAPTURE_5MP */ + state->capture_frmsizes = &capture_frmsizes[0]; + cam_dbg("preview_width: %d , preview_height: %d, " + "capture_width: %d, capture_height: %d", + state->preview_frmsizes->width, state->preview_frmsizes->height, + state->capture_frmsizes->width, state->capture_frmsizes->height); + + state->req_fmt.width = state->preview_frmsizes->width; + state->req_fmt.height = state->preview_frmsizes->height; + + state->pdata = pdata; + + if (!pdata->pixelformat) + state->req_fmt.pixelformat = DEFAULT_FMT; + else + state->req_fmt.pixelformat = pdata->pixelformat; + + cam_dbg("probed!!\n"); + + return 0; + +err_out: + kfree(state); + return -ENOMEM; +} + +static int s5k4ecgx_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct s5k4ecgx_state *state = to_state(sd); + + cam_dbg("E\n"); + + destroy_workqueue(state->workqueue); + + state->initialized = 0; + + v4l2_device_unregister_subdev(sd); + + mutex_destroy(&state->ctrl_lock); + mutex_destroy(&state->af_lock); + + kfree(to_state(sd)); + + return 0; +} + +static const struct i2c_device_id s5k4ecgx_id[] = { + { S5K4ECGX_DRIVER_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, s5k4ecgx_id); + +static struct i2c_driver s5k4ecgx_i2c_driver = { + .driver = { + .name = S5K4ECGX_DRIVER_NAME, + }, + .probe = s5k4ecgx_probe, + .remove = s5k4ecgx_remove, + .id_table = s5k4ecgx_id, +}; + +static int __init s5k4ecgx_mod_init(void) +{ + cam_dbg("E\n"); + return i2c_add_driver(&s5k4ecgx_i2c_driver); +} + +static void __exit s5k4ecgx_mod_exit(void) +{ + cam_dbg("E\n"); + i2c_del_driver(&s5k4ecgx_i2c_driver); +} +module_init(s5k4ecgx_mod_init); +module_exit(s5k4ecgx_mod_exit); + +MODULE_DESCRIPTION("S5K4ECGX MIPI sensor driver"); +MODULE_AUTHOR("seungwoolee"); +MODULE_AUTHOR("jinsookim"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/slp_s5k4ecgx.h b/drivers/media/video/slp_s5k4ecgx.h new file mode 100644 index 0000000..400581f --- /dev/null +++ b/drivers/media/video/slp_s5k4ecgx.h @@ -0,0 +1,195 @@ +/* + * Driver for S5K4ECGX 5M ISP from Samsung + * Copyright (C) 2012 Samsung Electronics Co., Ltd. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __S5K4ECGX_H +#define __S5K4ECGX_H + +#include + +#define S5K4ECGX_DRIVER_NAME "S5K4ECGX" +#define is_focus(__mode) (state->focus.mode == __mode) + +#define FIRST_AF_SEARCH_COUNT 80 +#define SECOND_AF_SEARCH_COUNT 80 + +extern struct class *camera_class; + +enum stream_cmd { + STREAM_STOP, + STREAM_START, +}; + +struct s5k4ecgx_framesize { + u32 index; + u32 width; + u32 height; +}; + +struct s5k4ecgx_exif { + u32 exptime; /* us */ + u16 flash; + u16 iso; + int tv; /* shutter speed */ + int bv; /* brightness */ + int ebv; /* exposure bias */ +}; + +struct s5k4ecgx_focus { + unsigned int mode; + unsigned int lock; + unsigned int status; + unsigned int touch; + unsigned int pos_x; + unsigned int pos_y; + unsigned int width; + unsigned int height; + unsigned int start; + bool focusing; + bool needed; + bool first; +}; + +enum preflash_status { + PREFLASH_NONE = 0, + PREFLASH_OFF, + PREFLASH_ON, +}; + +enum s5k4ecgx_runmode { + RUNMODE_NOTREADY, + RUNMODE_INIT, + RUNMODE_RUNNING, /* previewing */ + RUNMODE_RUNNING_STOP, + RUNMODE_CAPTURING, + RUNMODE_CAPTURE_STOP, +}; + +/* + * Driver information + */ +struct s5k4ecgx_state { + struct v4l2_subdev sd; + struct device *s5k4ecgx_dev; + struct s5k4ecgx_platform_data *pdata; + /* + * req_fmt is the requested format from the application. + * set_fmt is the output format of the camera. Finally FIMC + * converts the camera output(set_fmt) to the requested format + * with hardware scaler. + */ + struct v4l2_pix_format req_fmt; + const struct s5k4ecgx_framesize *preview_frmsizes; + const struct s5k4ecgx_framesize *capture_frmsizes; + struct s5k4ecgx_exif exif; + struct s5k4ecgx_focus focus; + + enum v4l2_flash_mode flash_mode; + enum preflash_status preflash; + enum v4l2_sensor_mode sensor_mode; + enum v4l2_scene_mode scene_mode; + enum v4l2_wb_mode wb_mode; + enum s5k4ecgx_runmode runmode; + + struct mutex ctrl_lock; /* Mutex */ + struct mutex af_lock; /* Mutex */ + struct work_struct af_work; /* workque for AF */ + struct work_struct af_win_work; /* workque for AF */ + struct workqueue_struct *workqueue; /* workque for AF */ + + s32 vt_mode; + s32 check_dataline; + u32 req_fps; + u32 set_fps; + u32 initialized; + u32 zoom; + bool lowlight; + bool ae_lock; + bool awb_lock; +}; + +enum AF_1ST_STATUS { + AF_PROGRESS_1ST = 1, + AF_SUCCESS_1ST , + AF_FAIL_1ST, +}; + +enum AF_2ND_STATUS { + AF_SUCCESS_2ND = 0, + AF_PROGRESS_2ND = 1, +}; + +enum s5k4ecgx_prev_frmsize { + S5K4ECGX_PREVIEW_176, /* 176 x 144 */ + S5K4ECGX_PREVIEW_320, /* 320 x 240 */ + S5K4ECGX_PREVIEW_640, /* 640 x 480 */ + S5K4ECGX_PREVIEW_720, /* 720 x 480 */ + S5K4ECGX_PREVIEW_800, /* 800 x 480 */ + S5K4ECGX_PREVIEW_1280, /* 1280 x 720 */ +}; + +enum s5k4ecgx_cap_frmsize { + S5K4ECGX_CAPTURE_VGA, /* 640 x 480 */ + S5K4ECGX_CAPTURE_XGA, /* 1024 x 768 */ + S5K4ECGX_CAPTURE_1MP, /* 1280 x 960 */ + S5K4ECGX_CAPTURE_2MP, /* UXGA - 1600 x 1200 */ + S5K4ECGX_CAPTURE_3MP, /* QXGA - 2048 x 1536 */ + S5K4ECGX_CAPTURE_5MP, /* 2560 x 1920 */ +}; + +static inline struct s5k4ecgx_state *to_state(struct v4l2_subdev *sd) +{ + return container_of(sd, struct s5k4ecgx_state, sd); +} + +/*#define CONFIG_CAM_DEBUG */ +#define cam_warn(fmt, ...) \ + do { \ + printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_err(fmt, ...) \ + do { \ + printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#define cam_info(fmt, ...) \ + do { \ + printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) + +#ifdef CONFIG_CAM_DEBUG +#define cam_dbg(fmt, ...) \ + do { \ + printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__); \ + } while (0) +#else +#define cam_dbg(fmt, ...) +#endif /* CONFIG_CAM_DEBUG */ + + +/************ driver feature ************/ +#define S5K4ECGX_USLEEP +/* #define CONFIG_LOAD_FILE */ + + +/*********** Sensor specific ************/ +/* #define S5K4ECGX_100MS_DELAY 0xAA55AA5F */ +/* #define S5K4ECGX_10MS_DELAY 0xAA55AA5E */ +#define S5K4ECGX_DELAY 0xFFFF0000 +#define S5K4ECGX_DEF_APEX_DEN 100 + +/* Register address */ +#define REG_PAGE_SHUTTER 0x7000 +#define REG_ADDR_SHUTTER 0x14D0 +#define REG_PAGE_ISO 0x7000 +#define REG_ADDR_ISO 0x14C8 + +#include "slp_s5k4ecgx_setfile.h" + +#endif /* __S5K4ECGX_H */ diff --git a/drivers/media/video/slp_s5k4ecgx_setfile.h b/drivers/media/video/slp_s5k4ecgx_setfile.h new file mode 100644 index 0000000..2c84c7b --- /dev/null +++ b/drivers/media/video/slp_s5k4ecgx_setfile.h @@ -0,0 +1,7308 @@ +/* + * Driver for S5K4ECGX 5M ISP from Samsung + * + * Copyright (C) 2011, + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __S5K4ECGX_SETFILE_H +#define __S5K4ECGX_SETFILE_H + +#include + +/* + * s5k4ecgx register configuration for combinations of initialization + */ +/* FOR 4EC EVT1.1*/ + +/*//////////////////////////FOR EVT1.1//////////////////////////*/ +/* 20110706 SEMCO Base setting*/ +/* ARM Initiation */ +static const u32 s5k4ecgx_init_reg1_EVT1[] = { +/*================================================================== +// 01.Start Setting +//==================================================================*/ + 0xFCFCD000, + 0x00100001, /*S/W Reset */ + 0x10300000, /*contint_host_int */ + 0x00140001, /*sw_load_complete-Release CORE(Arm)from reset state*/ +}; + +/* Delay 10ms*/ + +static const u32 s5k4ecgx_init_reg2_EVT1[] = { +/*=============================================================== +//02.ETC Setting +//==============================================================*/ + + 0x0028D000, + 0x002A1082, /*Driving current Setting */ + 0x0F1202AA, /*d0_d4_cd10 d0_d4_cd10 9:0 */ + 0x0F1202AA, /*d5_d9_cd10 d5_d9_cd10 9:0 */ + 0x0F1200AA, /*gpio_cd10 gpio_cd10 */ + 0x0F120AAA, /*clks_output_cd10 clks_output_cd10 11:0 */ + 0x002A100E, + 0x0F120000, /*pclk_delay_r */ + + 0x002A007A, + 0x0F120000, + +/*This register is for FACTORY ONLY. +If you change it without prior notification*/ +/* YOU are RESPONSIBLE for the FAILURE that will happen in the future.*/ + + /*ISP FE(ADLC) */ + 0x002AE406, + 0x0F120092, + 0x002AE410, + 0x0F123804, + 0x002AE41A, + 0x0F120010, /*101022 ADD adlcptune_total */ + 0x002AE420, + 0x0F120003, + 0x0F120060, + 0x002AE42E, + 0x0F120004, + 0x002AF400, + 0x0F125A3C, + 0x0F120023, + 0x0F128080, + 0x0F1203AF, + 0x0F12000A, + 0x0F12AA54, + 0x0F120040, + 0x0F12464E, + 0x0F120240, + 0x0F120240, + 0x0F120040, + 0x0F121000, + 0x0F1255FF, /*555C -> 55FF */ + 0x0F12D000, + 0x0F120010, + 0x0F120202, + 0x0F120401, + 0x0F120022, + 0x0F120088, + 0x0F12009F, + 0x0F120000, + 0x0F121800, + 0x0F120088, + 0x0F120000, + 0x0F122428, + 0x0F120000, + 0x0F1203EE, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x002AF552, + 0x0F120708, + 0x0F12080C, + + 0x00287000, /*For subsampling Size */ + 0x002A18BC, + 0x0F120004, + 0x0F1205B6, + 0x0F120000, + 0x0F120000, + 0x0F120001, + 0x0F1205BA, + 0x0F120000, + 0x0F120000, + 0x0F120007, + 0x0F1205BA, + 0x0F120000, + 0x0F120000, + 0x0F1201F4, + 0x0F12024E, + 0x0F120000, + 0x0F120000, + 0x0F1201F4, + 0x0F1205B6, + 0x0F120000, + 0x0F120000, + 0x0F1201F4, + 0x0F1205BA, + 0x0F120000, + 0x0F120000, + 0x0F1201F4, + 0x0F12024F, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120075, + 0x0F1200CF, + 0x0F120000, + 0x0F120000, + 0x0F120075, + 0x0F1200D6, + 0x0F120000, + 0x0F120000, + 0x0F120004, + 0x0F1201F4, + 0x0F120000, + 0x0F120000, + 0x0F1200F0, + 0x0F1201F4, + 0x0F12029E, + 0x0F1205B2, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F1201F8, + 0x0F120228, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120208, + 0x0F120238, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120218, + 0x0F120238, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120001, + 0x0F120009, + 0x0F1200DE, + 0x0F1205C0, + 0x0F120000, + 0x0F120000, + 0x0F1200DF, + 0x0F1200E4, + 0x0F1201F8, + 0x0F1201FD, + 0x0F1205B6, + 0x0F1205BB, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F1201F8, + 0x0F120000, + 0x0F120000, + 0x0F120077, + 0x0F12007E, + 0x0F12024F, + 0x0F12025E, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120004, + 0x0F1209D1, + 0x0F120000, + 0x0F120000, + 0x0F120001, + 0x0F1209D5, + 0x0F120000, + 0x0F120000, + 0x0F120008, + 0x0F1209D5, + 0x0F120000, + 0x0F120000, + 0x0F1202AA, + 0x0F120326, + 0x0F120000, + 0x0F120000, + 0x0F1202AA, + 0x0F1209D1, + 0x0F120000, + 0x0F120000, + 0x0F1202AA, + 0x0F1209D5, + 0x0F120000, + 0x0F120000, + 0x0F1202AA, + 0x0F120327, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120008, + 0x0F120084, + 0x0F120000, + 0x0F120000, + 0x0F120008, + 0x0F12008D, + 0x0F120000, + 0x0F120000, + 0x0F120008, + 0x0F1202AA, + 0x0F120000, + 0x0F120000, + 0x0F1200AA, + 0x0F1202AA, + 0x0F1203AD, + 0x0F1209CD, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F1202AE, + 0x0F1202DE, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F1202BE, + 0x0F1202EE, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F1202CE, + 0x0F1202EE, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120001, + 0x0F120009, + 0x0F120095, + 0x0F1209DB, + 0x0F120000, + 0x0F120000, + 0x0F120096, + 0x0F12009B, + 0x0F1202AE, + 0x0F1202B3, + 0x0F1209D1, + 0x0F1209D6, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F1202AE, + 0x0F120000, + 0x0F120000, + 0x0F120009, + 0x0F120010, + 0x0F120327, + 0x0F120336, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x002A1AF8, + 0x0F125A3C, /*senHal_TuneStr_AngTuneData1_2_D000F400 register */ + 0x002A1896, + 0x0F120002, /*senHal_SamplingType 0002 03EE: PLA*/ + 0x0F120000, /*senHal_SamplingMode 0 : 2 PLA / 1 : 4PLA*/ + 0x0F120003, /*senHal_PLAOption [0] VPLA enable [1] H*/ + + 0x002A189E, + 0x0F120FB0, /*senHal_ExpMinPixels*/ + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin*/ + 0x0F120060, /*senHal_uAddColsNoBin*/ + 0x0F1205C0, /*senHal_uMinColsBin*/ + 0x0F1205C0, /*senHal_uMinColsNoBin*/ + + 0x002A1AEA, + 0x0F128080, /*senHal_SubF404Tune*/ + 0x0F120080, /*senHal_FullF404Tune*/ + 0x002A1AE0, + 0x0F120000, /*senHal_bSenAAC*/ + + 0x002A1A72, + 0x0F120000, /*senHal_bSRX SRX off*/ + 0x002A18A2, + 0x0F120004, /*senHal_NExpLinesCheckFine extend For*/ + 0x002A1A6A, + 0x0F12009A, /*senHal_usForbiddenRightOfs*/ + 0x002A385E, + 0x0F12024C, /*Mon_Sen_uExpPixelsOfs*/ + + 0x002A0EE6, + 0x0F120000, /*setot_bUseDigitalHbin*/ + 0x002A1B2A, + 0x0F120300, /*senHal_TuneStr2_usAngTuneGainTh 2 */ + 0x0F1200D6, /*senHal_TuneStr2_AngTuneF4CA_0_ 2 70001B2*/ + 0x0F12008D, /*senHal_TuneStr2_AngTuneF4CA_1_ 2 70001B2*/ + 0x0F1200CF, /*senHal_TuneStr2_AngTuneF4C2_0_ 2 70001B3*/ + 0x0F120084, /*senHal_TuneStr2_AngTuneF4C2_1_ 2 70001B3*/ + + /* OTP setting*/ + 0x002A0722, + 0x0F120100, /*skl_OTP_usWaitTime This register sho*/ + 0x002A0726, + 0x0F120001, /*skl_bUseOTPfunc//OTP on/off function*/ + 0x002A08D6, + 0x0F120001, /*ash_bUseOTPData*/ + 0x002A146E, + 0x0F120000, /*awbb_otp_disable*/ + 0x002A08DC, + 0x0F120000, /*ash_bUseGasAlphaOTP*/ + +/*==================================================== +// 05.Trap and Patch +====================================================*/ +/* Start of Patch data*/ + 0x00287000, + 0x002A3AF8, + 0x0F12B570, /*70003AF8 */ + 0x0F124B39, /*70003AFA */ + 0x0F124939, /*70003AFC */ + 0x0F12483A, /*70003AFE */ + 0x0F122200, /*70003B00 */ + 0x0F12C008, /*70003B02 */ + 0x0F126001, /*70003B04 */ + 0x0F124939, /*70003B06 */ + 0x0F124839, /*70003B08 */ + 0x0F122401, /*70003B0A */ + 0x0F12F000, /*70003B0C */ + 0x0F12FBD4, /*70003B0E */ + 0x0F124938, /*70003B10 */ + 0x0F124839, /*70003B12 */ + 0x0F122502, /*70003B14 */ + 0x0F120022, /*70003B16 */ + 0x0F12F000, /*70003B18 */ + 0x0F12FBCE, /*70003B1A */ + 0x0F124837, /*70003B1C */ + 0x0F120261, /*70003B1E */ + 0x0F128001, /*70003B20 */ + 0x0F122100, /*70003B22 */ + 0x0F128041, /*70003B24 */ + 0x0F124936, /*70003B26 */ + 0x0F124836, /*70003B28 */ + 0x0F126041, /*70003B2A */ + 0x0F124936, /*70003B2C */ + 0x0F124837, /*70003B2E */ + 0x0F122403, /*70003B30 */ + 0x0F12002A, /*70003B32 */ + 0x0F12F000, /*70003B34 */ + 0x0F12FBC0, /*70003B36 */ + 0x0F124832, /*70003B38 */ + 0x0F124935, /*70003B3A */ + 0x0F1230C0, /*70003B3C */ + 0x0F1263C1, /*70003B3E */ + 0x0F124930, /*70003B40 */ + 0x0F124834, /*70003B42 */ + 0x0F123980, /*70003B44 */ + 0x0F126408, /*70003B46 */ + 0x0F124833, /*70003B48 */ + 0x0F124934, /*70003B4A */ + 0x0F126388, /*70003B4C */ + 0x0F124934, /*70003B4E */ + 0x0F124834, /*70003B50 */ + 0x0F120022, /*70003B52 */ + 0x0F122504, /*70003B54 */ + 0x0F12F000, /*70003B56 */ + 0x0F12FBAF, /*70003B58 */ + 0x0F124933, /*70003B5A */ + 0x0F124833, /*70003B5C */ + 0x0F122405, /*70003B5E */ + 0x0F12002A, /*70003B60 */ + 0x0F12F000, /*70003B62 */ + 0x0F12F881, /*70003B64 */ + 0x0F12491F, /*70003B66 */ + 0x0F124830, /*70003B68 */ + 0x0F120022, /*70003B6A */ + 0x0F122506, /*70003B6C */ + 0x0F1239B6, /*70003B6E */ + 0x0F121D80, /*70003B70 */ + 0x0F12F000, /*70003B72 */ + 0x0F12F879, /*70003B74 */ + 0x0F12482D, /*70003B76 */ + 0x0F12492D, /*70003B78 */ + 0x0F122407, /*70003B7A */ + 0x0F12002A, /*70003B7C */ + 0x0F12300C, /*70003B7E */ + 0x0F12F000, /*70003B80 */ + 0x0F12F872, /*70003B82 */ + 0x0F124829, /*70003B84 */ + 0x0F12492B, /*70003B86 */ + 0x0F120022, /*70003B88 */ + 0x0F122508, /*70003B8A */ + 0x0F123010, /*70003B8C */ + 0x0F12F000, /*70003B8E */ + 0x0F12F86B, /*70003B90 */ + 0x0F124929, /*70003B92 */ + 0x0F124829, /*70003B94 */ + 0x0F122409, /*70003B96 */ + 0x0F12002A, /*70003B98 */ + 0x0F12F000, /*70003B9A */ + 0x0F12FB8D, /*70003B9C */ + 0x0F124928, /*70003B9E */ + 0x0F124828, /*70003BA0 */ + 0x0F120022, /*70003BA2 */ + 0x0F12250A, /*70003BA4 */ + 0x0F12F000, /*70003BA6 */ + 0x0F12FB87, /*70003BA8 */ + 0x0F124927, /*70003BAA */ + 0x0F124827, /*70003BAC */ + 0x0F12240B, /*70003BAE */ + 0x0F12002A, /*70003BB0 */ + 0x0F12F000, /*70003BB2 */ + 0x0F12FB81, /*70003BB4 */ + 0x0F124926, /*70003BB6 */ + 0x0F124826, /*70003BB8 */ + 0x0F120022, /*70003BBA */ + 0x0F12250C, /*70003BBC */ + 0x0F12F000, /*70003BBE */ + 0x0F12FB7B, /*70003BC0 */ + 0x0F124925, /*70003BC2 */ + 0x0F124825, /*70003BC4 */ + 0x0F12240D, /*70003BC6 */ + 0x0F12002A, /*70003BC8 */ + 0x0F12F000, /*70003BCA */ + 0x0F12FB75, /*70003BCC */ + 0x0F124924, /*70003BCE */ + 0x0F124824, /*70003BD0 */ + 0x0F120022, /*70003BD2 */ + 0x0F12F000, /*70003BD4 */ + 0x0F12FB70, /*70003BD6 */ + 0x0F12BC70, /*70003BD8 */ + 0x0F12BC08, /*70003BDA */ + 0x0F124718, /*70003BDC */ + 0x0F120000, /*70003BDE */ + 0x0F12018F, /*70003BE0 */ + 0x0F124EC2, /*70003BE2 */ + 0x0F12037F, /*70003BE4 */ + 0x0F120000, /*70003BE6 */ + 0x0F121F90, /*70003BE8 */ + 0x0F127000, /*70003BEA */ + 0x0F123C81, /*70003BEC */ + 0x0F127000, /*70003BEE */ + 0x0F12E38B, /*70003BF0 */ + 0x0F120000, /*70003BF2 */ + 0x0F123CB9, /*70003BF4 */ + 0x0F127000, /*70003BF6 */ + 0x0F12C3B1, /*70003BF8 */ + 0x0F120000, /*70003BFA */ + 0x0F124780, /*70003BFC */ + 0x0F127000, /*70003BFE */ + 0x0F123D17, /*70003C00 */ + 0x0F127000, /*70003C02 */ + 0x0F120080, /*70003C04 */ + 0x0F127000, /*70003C06 */ + 0x0F123D53, /*70003C08 */ + 0x0F127000, /*70003C0A */ + 0x0F12B49D, /*70003C0C */ + 0x0F120000, /*70003C0E */ + 0x0F123DFF, /*70003C10 */ + 0x0F127000, /*70003C12 */ + 0x0F123DB3, /*70003C14 */ + 0x0F127000, /*70003C16 */ + 0x0F12FFFF, /*70003C18 */ + 0x0F1200FF, /*70003C1A */ + 0x0F1217E0, /*70003C1C */ + 0x0F127000, /*70003C1E */ + 0x0F123F7B, /*70003C20 */ + 0x0F127000, /*70003C22 */ + 0x0F12053D, /*70003C24 */ + 0x0F120000, /*70003C26 */ + 0x0F120000, /*70003C28 */ + 0x0F120A89, /*70003C2A */ + 0x0F126CD2, /*70003C2C */ + 0x0F120000, /*70003C2E */ + 0x0F120000, /*70003C30 */ + 0x0F120A9A, /*70003C32 */ + 0x0F120000, /*70003C34 */ + 0x0F1202D2, /*70003C36 */ + 0x0F123FC9, /*70003C38 */ + 0x0F127000, /*70003C3A */ + 0x0F129E65, /*70003C3C */ + 0x0F120000, /*70003C3E */ + 0x0F12403D, /*70003C40 */ + 0x0F127000, /*70003C42 */ + 0x0F127C49, /*70003C44 */ + 0x0F120000, /*70003C46 */ + 0x0F1240B1, /*70003C48 */ + 0x0F127000, /*70003C4A */ + 0x0F127C63, /*70003C4C */ + 0x0F120000, /*70003C4E */ + 0x0F1240CD, /*70003C50 */ + 0x0F127000, /*70003C52 */ + 0x0F128F01, /*70003C54 */ + 0x0F120000, /*70003C56 */ + 0x0F12416F, /*70003C58 */ + 0x0F127000, /*70003C5A */ + 0x0F127F3F, /*70003C5C */ + 0x0F120000, /*70003C5E */ + 0x0F1241FD, /*70003C60 */ + 0x0F127000, /*70003C62 */ + 0x0F1298C5, /*70003C64 */ + 0x0F120000, /*70003C66 */ + 0x0F12B570, /*70003C68 */ + 0x0F12000C, /*70003C6A */ + 0x0F120015, /*70003C6C */ + 0x0F120029, /*70003C6E */ + 0x0F12F000, /*70003C70 */ + 0x0F12FB2A, /*70003C72 */ + 0x0F1249F8, /*70003C74 */ + 0x0F1200A8, /*70003C76 */ + 0x0F12500C, /*70003C78 */ + 0x0F12BC70, /*70003C7A */ + 0x0F12BC08, /*70003C7C */ + 0x0F124718, /*70003C7E */ + 0x0F126808, /*70003C80 */ + 0x0F120400, /*70003C82 */ + 0x0F120C00, /*70003C84 */ + 0x0F126849, /*70003C86 */ + 0x0F120409, /*70003C88 */ + 0x0F120C09, /*70003C8A */ + 0x0F124AF3, /*70003C8C */ + 0x0F128992, /*70003C8E */ + 0x0F122A00, /*70003C90 */ + 0x0F12D00D, /*70003C92 */ + 0x0F122300, /*70003C94 */ + 0x0F121A89, /*70003C96 */ + 0x0F12D400, /*70003C98 */ + 0x0F12000B, /*70003C9A */ + 0x0F120419, /*70003C9C */ + 0x0F120C09, /*70003C9E */ + 0x0F1223FF, /*70003CA0 */ + 0x0F1233C1, /*70003CA2 */ + 0x0F121810, /*70003CA4 */ + 0x0F124298, /*70003CA6 */ + 0x0F12D800, /*70003CA8 */ + 0x0F120003, /*70003CAA */ + 0x0F120418, /*70003CAC */ + 0x0F120C00, /*70003CAE */ + 0x0F124AEB, /*70003CB0 */ + 0x0F128150, /*70003CB2 */ + 0x0F128191, /*70003CB4 */ + 0x0F124770, /*70003CB6 */ + 0x0F12B5F3, /*70003CB8 */ + 0x0F120004, /*70003CBA */ + 0x0F12B081, /*70003CBC */ + 0x0F129802, /*70003CBE */ + 0x0F126800, /*70003CC0 */ + 0x0F120600, /*70003CC2 */ + 0x0F120E00, /*70003CC4 */ + 0x0F122201, /*70003CC6 */ + 0x0F120015, /*70003CC8 */ + 0x0F120021, /*70003CCA */ + 0x0F123910, /*70003CCC */ + 0x0F12408A, /*70003CCE */ + 0x0F1240A5, /*70003CD0 */ + 0x0F124FE4, /*70003CD2 */ + 0x0F120016, /*70003CD4 */ + 0x0F122C10, /*70003CD6 */ + 0x0F12DA03, /*70003CD8 */ + 0x0F128839, /*70003CDA */ + 0x0F1243A9, /*70003CDC */ + 0x0F128039, /*70003CDE */ + 0x0F12E002, /*70003CE0 */ + 0x0F128879, /*70003CE2 */ + 0x0F1243B1, /*70003CE4 */ + 0x0F128079, /*70003CE6 */ + 0x0F12F000, /*70003CE8 */ + 0x0F12FAF6, /*70003CEA */ + 0x0F122C10, /*70003CEC */ + 0x0F12DA03, /*70003CEE */ + 0x0F128839, /*70003CF0 */ + 0x0F124329, /*70003CF2 */ + 0x0F128039, /*70003CF4 */ + 0x0F12E002, /*70003CF6 */ + 0x0F128879, /*70003CF8 */ + 0x0F124331, /*70003CFA */ + 0x0F128079, /*70003CFC */ + 0x0F1249DA, /*70003CFE */ + 0x0F128809, /*70003D00 */ + 0x0F122900, /*70003D02 */ + 0x0F12D102, /*70003D04 */ + 0x0F12F000, /*70003D06 */ + 0x0F12FAEF, /*70003D08 */ + 0x0F122000, /*70003D0A */ + 0x0F129902, /*70003D0C */ + 0x0F126008, /*70003D0E */ + 0x0F12BCFE, /*70003D10 */ + 0x0F12BC08, /*70003D12 */ + 0x0F124718, /*70003D14 */ + 0x0F12B538, /*70003D16 */ + 0x0F129C04, /*70003D18 */ + 0x0F120015, /*70003D1A */ + 0x0F12002A, /*70003D1C */ + 0x0F129400, /*70003D1E */ + 0x0F12F000, /*70003D20 */ + 0x0F12FAEA, /*70003D22 */ + 0x0F124AD1, /*70003D24 */ + 0x0F128811, /*70003D26 */ + 0x0F122900, /*70003D28 */ + 0x0F12D00F, /*70003D2A */ + 0x0F128820, /*70003D2C */ + 0x0F124281, /*70003D2E */ + 0x0F12D20C, /*70003D30 */ + 0x0F128861, /*70003D32 */ + 0x0F128853, /*70003D34 */ + 0x0F124299, /*70003D36 */ + 0x0F12D200, /*70003D38 */ + 0x0F121E40, /*70003D3A */ + 0x0F120400, /*70003D3C */ + 0x0F120C00, /*70003D3E */ + 0x0F128020, /*70003D40 */ + 0x0F128851, /*70003D42 */ + 0x0F128061, /*70003D44 */ + 0x0F124368, /*70003D46 */ + 0x0F121840, /*70003D48 */ + 0x0F126060, /*70003D4A */ + 0x0F12BC38, /*70003D4C */ + 0x0F12BC08, /*70003D4E */ + 0x0F124718, /*70003D50 */ + 0x0F12B5F8, /*70003D52 */ + 0x0F120004, /*70003D54 */ + 0x0F126808, /*70003D56 */ + 0x0F120400, /*70003D58 */ + 0x0F120C00, /*70003D5A */ + 0x0F122201, /*70003D5C */ + 0x0F120015, /*70003D5E */ + 0x0F120021, /*70003D60 */ + 0x0F123910, /*70003D62 */ + 0x0F12408A, /*70003D64 */ + 0x0F1240A5, /*70003D66 */ + 0x0F124FBE, /*70003D68 */ + 0x0F120016, /*70003D6A */ + 0x0F122C10, /*70003D6C */ + 0x0F12DA03, /*70003D6E */ + 0x0F128839, /*70003D70 */ + 0x0F1243A9, /*70003D72 */ + 0x0F128039, /*70003D74 */ + 0x0F12E002, /*70003D76 */ + 0x0F128879, /*70003D78 */ + 0x0F1243B1, /*70003D7A */ + 0x0F128079, /*70003D7C */ + 0x0F12F000, /*70003D7E */ + 0x0F12FAC3, /*70003D80 */ + 0x0F122C10, /*70003D82 */ + 0x0F12DA03, /*70003D84 */ + 0x0F128838, /*70003D86 */ + 0x0F124328, /*70003D88 */ + 0x0F128038, /*70003D8A */ + 0x0F12E002, /*70003D8C */ + 0x0F128878, /*70003D8E */ + 0x0F124330, /*70003D90 */ + 0x0F128078, /*70003D92 */ + 0x0F1248B6, /*70003D94 */ + 0x0F128800, /*70003D96 */ + 0x0F120400, /*70003D98 */ + 0x0F12D507, /*70003D9A */ + 0x0F124BB5, /*70003D9C */ + 0x0F127819, /*70003D9E */ + 0x0F124AB5, /*70003DA0 */ + 0x0F127810, /*70003DA2 */ + 0x0F127018, /*70003DA4 */ + 0x0F127011, /*70003DA6 */ + 0x0F1249B4, /*70003DA8 */ + 0x0F128188, /*70003DAA */ + 0x0F12BCF8, /*70003DAC */ + 0x0F12BC08, /*70003DAE */ + 0x0F124718, /*70003DB0 */ + 0x0F12B538, /*70003DB2 */ + 0x0F1248B2, /*70003DB4 */ + 0x0F124669, /*70003DB6 */ + 0x0F12F000, /*70003DB8 */ + 0x0F12FAAE, /*70003DBA */ + 0x0F1248B1, /*70003DBC */ + 0x0F1249B0, /*70003DBE */ + 0x0F1269C2, /*70003DC0 */ + 0x0F122400, /*70003DC2 */ + 0x0F1231A8, /*70003DC4 */ + 0x0F122A00, /*70003DC6 */ + 0x0F12D008, /*70003DC8 */ + 0x0F1261C4, /*70003DCA */ + 0x0F12684A, /*70003DCC */ + 0x0F126242, /*70003DCE */ + 0x0F126282, /*70003DD0 */ + 0x0F12466B, /*70003DD2 */ + 0x0F12881A, /*70003DD4 */ + 0x0F126302, /*70003DD6 */ + 0x0F12885A, /*70003DD8 */ + 0x0F126342, /*70003DDA */ + 0x0F126A02, /*70003DDC */ + 0x0F122A00, /*70003DDE */ + 0x0F12D00A, /*70003DE0 */ + 0x0F126204, /*70003DE2 */ + 0x0F126849, /*70003DE4 */ + 0x0F126281, /*70003DE6 */ + 0x0F12466B, /*70003DE8 */ + 0x0F128819, /*70003DEA */ + 0x0F126301, /*70003DEC */ + 0x0F128859, /*70003DEE */ + 0x0F126341, /*70003DF0 */ + 0x0F1249A5, /*70003DF2 */ + 0x0F1288C9, /*70003DF4 */ + 0x0F1263C1, /*70003DF6 */ + 0x0F12F000, /*70003DF8 */ + 0x0F12FA96, /*70003DFA */ + 0x0F12E7A6, /*70003DFC */ + 0x0F12B5F0, /*70003DFE */ + 0x0F12B08B, /*70003E00 */ + 0x0F1220FF, /*70003E02 */ + 0x0F121C40, /*70003E04 */ + 0x0F1249A1, /*70003E06 */ + 0x0F1289CC, /*70003E08 */ + 0x0F124E9E, /*70003E0A */ + 0x0F126AB1, /*70003E0C */ + 0x0F124284, /*70003E0E */ + 0x0F12D101, /*70003E10 */ + 0x0F12489F, /*70003E12 */ + 0x0F126081, /*70003E14 */ + 0x0F126A70, /*70003E16 */ + 0x0F120200, /*70003E18 */ + 0x0F12F000, /*70003E1A */ + 0x0F12FA8D, /*70003E1C */ + 0x0F120400, /*70003E1E */ + 0x0F120C00, /*70003E20 */ + 0x0F124A96, /*70003E22 */ + 0x0F128A11, /*70003E24 */ + 0x0F129109, /*70003E26 */ + 0x0F122101, /*70003E28 */ + 0x0F120349, /*70003E2A */ + 0x0F124288, /*70003E2C */ + 0x0F12D200, /*70003E2E */ + 0x0F120001, /*70003E30 */ + 0x0F124A92, /*70003E32 */ + 0x0F128211, /*70003E34 */ + 0x0F124D97, /*70003E36 */ + 0x0F128829, /*70003E38 */ + 0x0F129108, /*70003E3A */ + 0x0F124A8B, /*70003E3C */ + 0x0F122303, /*70003E3E */ + 0x0F123222, /*70003E40 */ + 0x0F121F91, /*70003E42 */ + 0x0F12F000, /*70003E44 */ + 0x0F12FA7E, /*70003E46 */ + 0x0F128028, /*70003E48 */ + 0x0F12488E, /*70003E4A */ + 0x0F124987, /*70003E4C */ + 0x0F126BC2, /*70003E4E */ + 0x0F126AC0, /*70003E50 */ + 0x0F124282, /*70003E52 */ + 0x0F12D201, /*70003E54 */ + 0x0F128CC8, /*70003E56 */ + 0x0F128028, /*70003E58 */ + 0x0F1288E8, /*70003E5A */ + 0x0F129007, /*70003E5C */ + 0x0F122240, /*70003E5E */ + 0x0F124310, /*70003E60 */ + 0x0F1280E8, /*70003E62 */ + 0x0F122000, /*70003E64 */ + 0x0F120041, /*70003E66 */ + 0x0F12194B, /*70003E68 */ + 0x0F12001E, /*70003E6A */ + 0x0F123680, /*70003E6C */ + 0x0F128BB2, /*70003E6E */ + 0x0F12AF04, /*70003E70 */ + 0x0F12527A, /*70003E72 */ + 0x0F124A7D, /*70003E74 */ + 0x0F12188A, /*70003E76 */ + 0x0F128897, /*70003E78 */ + 0x0F1283B7, /*70003E7A */ + 0x0F1233A0, /*70003E7C */ + 0x0F12891F, /*70003E7E */ + 0x0F12AE01, /*70003E80 */ + 0x0F125277, /*70003E82 */ + 0x0F128A11, /*70003E84 */ + 0x0F128119, /*70003E86 */ + 0x0F121C40, /*70003E88 */ + 0x0F120400, /*70003E8A */ + 0x0F120C00, /*70003E8C */ + 0x0F122806, /*70003E8E */ + 0x0F12D3E9, /*70003E90 */ + 0x0F12F000, /*70003E92 */ + 0x0F12FA5F, /*70003E94 */ + 0x0F12F000, /*70003E96 */ + 0x0F12FA65, /*70003E98 */ + 0x0F124F79, /*70003E9A */ + 0x0F1237A8, /*70003E9C */ + 0x0F122800, /*70003E9E */ + 0x0F12D10A, /*70003EA0 */ + 0x0F121FE0, /*70003EA2 */ + 0x0F1238FD, /*70003EA4 */ + 0x0F12D001, /*70003EA6 */ + 0x0F121CC0, /*70003EA8 */ + 0x0F12D105, /*70003EAA */ + 0x0F124874, /*70003EAC */ + 0x0F128829, /*70003EAE */ + 0x0F123818, /*70003EB0 */ + 0x0F126840, /*70003EB2 */ + 0x0F124348, /*70003EB4 */ + 0x0F126078, /*70003EB6 */ + 0x0F124972, /*70003EB8 */ + 0x0F126878, /*70003EBA */ + 0x0F126B89, /*70003EBC */ + 0x0F124288, /*70003EBE */ + 0x0F12D300, /*70003EC0 */ + 0x0F120008, /*70003EC2 */ + 0x0F126078, /*70003EC4 */ + 0x0F122000, /*70003EC6 */ + 0x0F120041, /*70003EC8 */ + 0x0F12AA04, /*70003ECA */ + 0x0F125A53, /*70003ECC */ + 0x0F12194A, /*70003ECE */ + 0x0F12269C, /*70003ED0 */ + 0x0F1252B3, /*70003ED2 */ + 0x0F12AB01, /*70003ED4 */ + 0x0F125A59, /*70003ED6 */ + 0x0F1232A0, /*70003ED8 */ + 0x0F128111, /*70003EDA */ + 0x0F121C40, /*70003EDC */ + 0x0F120400, /*70003EDE */ + 0x0F120C00, /*70003EE0 */ + 0x0F122806, /*70003EE2 */ + 0x0F12D3F0, /*70003EE4 */ + 0x0F124965, /*70003EE6 */ + 0x0F129809, /*70003EE8 */ + 0x0F128208, /*70003EEA */ + 0x0F129808, /*70003EEC */ + 0x0F128028, /*70003EEE */ + 0x0F129807, /*70003EF0 */ + 0x0F1280E8, /*70003EF2 */ + 0x0F121FE0, /*70003EF4 */ + 0x0F1238FD, /*70003EF6 */ + 0x0F12D13B, /*70003EF8 */ + 0x0F124D64, /*70003EFA */ + 0x0F1289E8, /*70003EFC */ + 0x0F121FC1, /*70003EFE */ + 0x0F1239FF, /*70003F00 */ + 0x0F12D136, /*70003F02 */ + 0x0F124C5F, /*70003F04 */ + 0x0F128AE0, /*70003F06 */ + 0x0F12F000, /*70003F08 */ + 0x0F12FA34, /*70003F0A */ + 0x0F120006, /*70003F0C */ + 0x0F128B20, /*70003F0E */ + 0x0F12F000, /*70003F10 */ + 0x0F12FA38, /*70003F12 */ + 0x0F129000, /*70003F14 */ + 0x0F126AA1, /*70003F16 */ + 0x0F126878, /*70003F18 */ + 0x0F121809, /*70003F1A */ + 0x0F120200, /*70003F1C */ + 0x0F12F000, /*70003F1E */ + 0x0F12FA0B, /*70003F20 */ + 0x0F120400, /*70003F22 */ + 0x0F120C00, /*70003F24 */ + 0x0F120022, /*70003F26 */ + 0x0F123246, /*70003F28 */ + 0x0F120011, /*70003F2A */ + 0x0F12310A, /*70003F2C */ + 0x0F122305, /*70003F2E */ + 0x0F12F000, /*70003F30 */ + 0x0F12FA08, /*70003F32 */ + 0x0F1266E8, /*70003F34 */ + 0x0F126B23, /*70003F36 */ + 0x0F120002, /*70003F38 */ + 0x0F120031, /*70003F3A */ + 0x0F120018, /*70003F3C */ + 0x0F12F000, /*70003F3E */ + 0x0F12FA29, /*70003F40 */ + 0x0F12466B, /*70003F42 */ + 0x0F128518, /*70003F44 */ + 0x0F126EEA, /*70003F46 */ + 0x0F126B60, /*70003F48 */ + 0x0F129900, /*70003F4A */ + 0x0F12F000, /*70003F4C */ + 0x0F12FA22, /*70003F4E */ + 0x0F12466B, /*70003F50 */ + 0x0F128558, /*70003F52 */ + 0x0F120029, /*70003F54 */ + 0x0F12980A, /*70003F56 */ + 0x0F123170, /*70003F58 */ + 0x0F12F000, /*70003F5A */ + 0x0F12FA23, /*70003F5C */ + 0x0F120028, /*70003F5E */ + 0x0F123060, /*70003F60 */ + 0x0F128A02, /*70003F62 */ + 0x0F124946, /*70003F64 */ + 0x0F123128, /*70003F66 */ + 0x0F12808A, /*70003F68 */ + 0x0F128A42, /*70003F6A */ + 0x0F1280CA, /*70003F6C */ + 0x0F128A80, /*70003F6E */ + 0x0F128108, /*70003F70 */ + 0x0F12B00B, /*70003F72 */ + 0x0F12BCF0, /*70003F74 */ + 0x0F12BC08, /*70003F76 */ + 0x0F124718, /*70003F78 */ + 0x0F12B570, /*70003F7A */ + 0x0F122400, /*70003F7C */ + 0x0F124D46, /*70003F7E */ + 0x0F124846, /*70003F80 */ + 0x0F128881, /*70003F82 */ + 0x0F124846, /*70003F84 */ + 0x0F128041, /*70003F86 */ + 0x0F122101, /*70003F88 */ + 0x0F128001, /*70003F8A */ + 0x0F12F000, /*70003F8C */ + 0x0F12FA12, /*70003F8E */ + 0x0F124842, /*70003F90 */ + 0x0F123820, /*70003F92 */ + 0x0F128BC0, /*70003F94 */ + 0x0F12F000, /*70003F96 */ + 0x0F12FA15, /*70003F98 */ + 0x0F124B42, /*70003F9A */ + 0x0F12220D, /*70003F9C */ + 0x0F120712, /*70003F9E */ + 0x0F1218A8, /*70003FA0 */ + 0x0F128806, /*70003FA2 */ + 0x0F1200E1, /*70003FA4 */ + 0x0F1218C9, /*70003FA6 */ + 0x0F1281CE, /*70003FA8 */ + 0x0F128846, /*70003FAA */ + 0x0F12818E, /*70003FAC */ + 0x0F128886, /*70003FAE */ + 0x0F12824E, /*70003FB0 */ + 0x0F1288C0, /*70003FB2 */ + 0x0F128208, /*70003FB4 */ + 0x0F123508, /*70003FB6 */ + 0x0F12042D, /*70003FB8 */ + 0x0F120C2D, /*70003FBA */ + 0x0F121C64, /*70003FBC */ + 0x0F120424, /*70003FBE */ + 0x0F120C24, /*70003FC0 */ + 0x0F122C07, /*70003FC2 */ + 0x0F12D3EC, /*70003FC4 */ + 0x0F12E658, /*70003FC6 */ + 0x0F12B510, /*70003FC8 */ + 0x0F124834, /*70003FCA */ + 0x0F124C34, /*70003FCC */ + 0x0F1288C0, /*70003FCE */ + 0x0F128060, /*70003FD0 */ + 0x0F122001, /*70003FD2 */ + 0x0F128020, /*70003FD4 */ + 0x0F124831, /*70003FD6 */ + 0x0F123820, /*70003FD8 */ + 0x0F128BC0, /*70003FDA */ + 0x0F12F000, /*70003FDC */ + 0x0F12F9F2, /*70003FDE */ + 0x0F1288E0, /*70003FE0 */ + 0x0F124A31, /*70003FE2 */ + 0x0F122800, /*70003FE4 */ + 0x0F12D003, /*70003FE6 */ + 0x0F124930, /*70003FE8 */ + 0x0F128849, /*70003FEA */ + 0x0F122900, /*70003FEC */ + 0x0F12D009, /*70003FEE */ + 0x0F122001, /*70003FF0 */ + 0x0F1203C0, /*70003FF2 */ + 0x0F128050, /*70003FF4 */ + 0x0F1280D0, /*70003FF6 */ + 0x0F122000, /*70003FF8 */ + 0x0F128090, /*70003FFA */ + 0x0F128110, /*70003FFC */ + 0x0F12BC10, /*70003FFE */ + 0x0F12BC08, /*70004000 */ + 0x0F124718, /*70004002 */ + 0x0F128050, /*70004004 */ + 0x0F128920, /*70004006 */ + 0x0F1280D0, /*70004008 */ + 0x0F128960, /*7000400A */ + 0x0F120400, /*7000400C */ + 0x0F121400, /*7000400E */ + 0x0F128090, /*70004010 */ + 0x0F1289A1, /*70004012 */ + 0x0F120409, /*70004014 */ + 0x0F121409, /*70004016 */ + 0x0F128111, /*70004018 */ + 0x0F1289E3, /*7000401A */ + 0x0F128A24, /*7000401C */ + 0x0F122B00, /*7000401E */ + 0x0F12D104, /*70004020 */ + 0x0F1217C3, /*70004022 */ + 0x0F120F5B, /*70004024 */ + 0x0F121818, /*70004026 */ + 0x0F1210C0, /*70004028 */ + 0x0F128090, /*7000402A */ + 0x0F122C00, /*7000402C */ + 0x0F12D1E6, /*7000402E */ + 0x0F1217C8, /*70004030 */ + 0x0F120F40, /*70004032 */ + 0x0F121840, /*70004034 */ + 0x0F1210C0, /*70004036 */ + 0x0F128110, /*70004038 */ + 0x0F12E7E0, /*7000403A */ + 0x0F12B510, /*7000403C */ + 0x0F12000C, /*7000403E */ + 0x0F124919, /*70004040 */ + 0x0F122204, /*70004042 */ + 0x0F126820, /*70004044 */ + 0x0F125E8A, /*70004046 */ + 0x0F120140, /*70004048 */ + 0x0F121A80, /*7000404A */ + 0x0F120280, /*7000404C */ + 0x0F128849, /*7000404E */ + 0x0F12F000, /*70004050 */ + 0x0F12F9C0, /*70004052 */ + 0x0F126020, /*70004054 */ + 0x0F12E7D2, /*70004056 */ + 0x0F1238D4, /*70004058 */ + 0x0F127000, /*7000405A */ + 0x0F1217D0, /*7000405C */ + 0x0F127000, /*7000405E */ + 0x0F125000, /*70004060 */ + 0x0F12D000, /*70004062 */ + 0x0F121100, /*70004064 */ + 0x0F12D000, /*70004066 */ + 0x0F12171A, /*70004068 */ + 0x0F127000, /*7000406A */ + 0x0F124780, /*7000406C */ + 0x0F127000, /*7000406E */ + 0x0F122FCA, /*70004070 */ + 0x0F127000, /*70004072 */ + 0x0F122FC5, /*70004074 */ + 0x0F127000, /*70004076 */ + 0x0F122FC6, /*70004078 */ + 0x0F127000, /*7000407A */ + 0x0F122ED8, /*7000407C */ + 0x0F127000, /*7000407E */ + 0x0F122BD0, /*70004080 */ + 0x0F127000, /*70004082 */ + 0x0F1217E0, /*70004084 */ + 0x0F127000, /*70004086 */ + 0x0F122DE8, /*70004088 */ + 0x0F127000, /*7000408A */ + 0x0F1237E0, /*7000408C */ + 0x0F127000, /*7000408E */ + 0x0F12210C, /*70004090 */ + 0x0F127000, /*70004092 */ + 0x0F121484, /*70004094 */ + 0x0F127000, /*70004096 */ + 0x0F12A006, /*70004098 */ + 0x0F120000, /*7000409A */ + 0x0F120724, /*7000409C */ + 0x0F127000, /*7000409E */ + 0x0F12A000, /*700040A0 */ + 0x0F12D000, /*700040A2 */ + 0x0F122270, /*700040A4 */ + 0x0F127000, /*700040A6 */ + 0x0F122558, /*700040A8 */ + 0x0F127000, /*700040AA */ + 0x0F12146C, /*700040AC */ + 0x0F127000, /*700040AE */ + 0x0F12B510, /*700040B0 */ + 0x0F12000C, /*700040B2 */ + 0x0F124979, /*700040B4 */ + 0x0F122208, /*700040B6 */ + 0x0F126820, /*700040B8 */ + 0x0F125E8A, /*700040BA */ + 0x0F120140, /*700040BC */ + 0x0F121A80, /*700040BE */ + 0x0F120280, /*700040C0 */ + 0x0F1288C9, /*700040C2 */ + 0x0F12F000, /*700040C4 */ + 0x0F12F986, /*700040C6 */ + 0x0F126020, /*700040C8 */ + 0x0F12E798, /*700040CA */ + 0x0F12B5FE, /*700040CC */ + 0x0F12000C, /*700040CE */ + 0x0F126825, /*700040D0 */ + 0x0F126866, /*700040D2 */ + 0x0F1268A0, /*700040D4 */ + 0x0F129001, /*700040D6 */ + 0x0F1268E7, /*700040D8 */ + 0x0F121BA8, /*700040DA */ + 0x0F1242B5, /*700040DC */ + 0x0F12DA00, /*700040DE */ + 0x0F121B70, /*700040E0 */ + 0x0F129000, /*700040E2 */ + 0x0F12496D, /*700040E4 */ + 0x0F12486E, /*700040E6 */ + 0x0F12884A, /*700040E8 */ + 0x0F128843, /*700040EA */ + 0x0F12435A, /*700040EC */ + 0x0F122304, /*700040EE */ + 0x0F125ECB, /*700040F0 */ + 0x0F120A92, /*700040F2 */ + 0x0F1218D2, /*700040F4 */ + 0x0F1202D2, /*700040F6 */ + 0x0F120C12, /*700040F8 */ + 0x0F1288CB, /*700040FA */ + 0x0F128880, /*700040FC */ + 0x0F124343, /*700040FE */ + 0x0F120A98, /*70004100 */ + 0x0F122308, /*70004102 */ + 0x0F125ECB, /*70004104 */ + 0x0F1218C0, /*70004106 */ + 0x0F1202C0, /*70004108 */ + 0x0F120C00, /*7000410A */ + 0x0F120411, /*7000410C */ + 0x0F120400, /*7000410E */ + 0x0F121409, /*70004110 */ + 0x0F121400, /*70004112 */ + 0x0F121A08, /*70004114 */ + 0x0F124962, /*70004116 */ + 0x0F1239E0, /*70004118 */ + 0x0F126148, /*7000411A */ + 0x0F129801, /*7000411C */ + 0x0F123040, /*7000411E */ + 0x0F127880, /*70004120 */ + 0x0F122800, /*70004122 */ + 0x0F12D103, /*70004124 */ + 0x0F129801, /*70004126 */ + 0x0F120029, /*70004128 */ + 0x0F12F000, /*7000412A */ + 0x0F12F959, /*7000412C */ + 0x0F128839, /*7000412E */ + 0x0F129800, /*70004130 */ + 0x0F124281, /*70004132 */ + 0x0F12D814, /*70004134 */ + 0x0F128879, /*70004136 */ + 0x0F129800, /*70004138 */ + 0x0F124281, /*7000413A */ + 0x0F12D20C, /*7000413C */ + 0x0F129801, /*7000413E */ + 0x0F120029, /*70004140 */ + 0x0F12F000, /*70004142 */ + 0x0F12F955, /*70004144 */ + 0x0F129801, /*70004146 */ + 0x0F120029, /*70004148 */ + 0x0F12F000, /*7000414A */ + 0x0F12F951, /*7000414C */ + 0x0F129801, /*7000414E */ + 0x0F120029, /*70004150 */ + 0x0F12F000, /*70004152 */ + 0x0F12F94D, /*70004154 */ + 0x0F12E003, /*70004156 */ + 0x0F129801, /*70004158 */ + 0x0F120029, /*7000415A */ + 0x0F12F000, /*7000415C */ + 0x0F12F948, /*7000415E */ + 0x0F129801, /*70004160 */ + 0x0F120032, /*70004162 */ + 0x0F120039, /*70004164 */ + 0x0F12F000, /*70004166 */ + 0x0F12F94B, /*70004168 */ + 0x0F126020, /*7000416A */ + 0x0F12E5D0, /*7000416C */ + 0x0F12B57C, /*7000416E */ + 0x0F12484C, /*70004170 */ + 0x0F12A901, /*70004172 */ + 0x0F120004, /*70004174 */ + 0x0F12F000, /*70004176 */ + 0x0F12F8CF, /*70004178 */ + 0x0F12466B, /*7000417A */ + 0x0F1288D9, /*7000417C */ + 0x0F128898, /*7000417E */ + 0x0F124B47, /*70004180 */ + 0x0F123346, /*70004182 */ + 0x0F121E9A, /*70004184 */ + 0x0F12F000, /*70004186 */ + 0x0F12F943, /*70004188 */ + 0x0F124846, /*7000418A */ + 0x0F124944, /*7000418C */ + 0x0F123812, /*7000418E */ + 0x0F123140, /*70004190 */ + 0x0F128A42, /*70004192 */ + 0x0F12888B, /*70004194 */ + 0x0F1218D2, /*70004196 */ + 0x0F128242, /*70004198 */ + 0x0F128AC2, /*7000419A */ + 0x0F1288C9, /*7000419C */ + 0x0F121851, /*7000419E */ + 0x0F1282C1, /*700041A0 */ + 0x0F120020, /*700041A2 */ + 0x0F124669, /*700041A4 */ + 0x0F12F000, /*700041A6 */ + 0x0F12F8B7, /*700041A8 */ + 0x0F12483F, /*700041AA */ + 0x0F12214D, /*700041AC */ + 0x0F128301, /*700041AE */ + 0x0F122196, /*700041B0 */ + 0x0F128381, /*700041B2 */ + 0x0F12211D, /*700041B4 */ + 0x0F123020, /*700041B6 */ + 0x0F128001, /*700041B8 */ + 0x0F12F000, /*700041BA */ + 0x0F12F931, /*700041BC */ + 0x0F12F000, /*700041BE */ + 0x0F12F937, /*700041C0 */ + 0x0F12483A, /*700041C2 */ + 0x0F124C3A, /*700041C4 */ + 0x0F126E00, /*700041C6 */ + 0x0F1260E0, /*700041C8 */ + 0x0F12466B, /*700041CA */ + 0x0F128818, /*700041CC */ + 0x0F128859, /*700041CE */ + 0x0F120025, /*700041D0 */ + 0x0F121A40, /*700041D2 */ + 0x0F123540, /*700041D4 */ + 0x0F1261A8, /*700041D6 */ + 0x0F124831, /*700041D8 */ + 0x0F129900, /*700041DA */ + 0x0F123060, /*700041DC */ + 0x0F12F000, /*700041DE */ + 0x0F12F92F, /*700041E0 */ + 0x0F12466B, /*700041E2 */ + 0x0F128819, /*700041E4 */ + 0x0F121DE0, /*700041E6 */ + 0x0F1230F9, /*700041E8 */ + 0x0F128741, /*700041EA */ + 0x0F128859, /*700041EC */ + 0x0F128781, /*700041EE */ + 0x0F122000, /*700041F0 */ + 0x0F1271A0, /*700041F2 */ + 0x0F1274A8, /*700041F4 */ + 0x0F12BC7C, /*700041F6 */ + 0x0F12BC08, /*700041F8 */ + 0x0F124718, /*700041FA */ + 0x0F12B5F8, /*700041FC */ + 0x0F120005, /*700041FE */ + 0x0F126808, /*70004200 */ + 0x0F120400, /*70004202 */ + 0x0F120C00, /*70004204 */ + 0x0F12684A, /*70004206 */ + 0x0F120412, /*70004208 */ + 0x0F120C12, /*7000420A */ + 0x0F12688E, /*7000420C */ + 0x0F1268CC, /*7000420E */ + 0x0F124922, /*70004210 */ + 0x0F12884B, /*70004212 */ + 0x0F124343, /*70004214 */ + 0x0F120A98, /*70004216 */ + 0x0F122304, /*70004218 */ + 0x0F125ECB, /*7000421A */ + 0x0F1218C0, /*7000421C */ + 0x0F1202C0, /*7000421E */ + 0x0F120C00, /*70004220 */ + 0x0F1288CB, /*70004222 */ + 0x0F124353, /*70004224 */ + 0x0F120A9A, /*70004226 */ + 0x0F122308, /*70004228 */ + 0x0F125ECB, /*7000422A */ + 0x0F1218D1, /*7000422C */ + 0x0F1202C9, /*7000422E */ + 0x0F120C09, /*70004230 */ + 0x0F122701, /*70004232 */ + 0x0F12003A, /*70004234 */ + 0x0F1240AA, /*70004236 */ + 0x0F129200, /*70004238 */ + 0x0F12002A, /*7000423A */ + 0x0F123A10, /*7000423C */ + 0x0F124097, /*7000423E */ + 0x0F122D10, /*70004240 */ + 0x0F12DA06, /*70004242 */ + 0x0F124A1B, /*70004244 */ + 0x0F129B00, /*70004246 */ + 0x0F128812, /*70004248 */ + 0x0F12439A, /*7000424A */ + 0x0F124B19, /*7000424C */ + 0x0F12801A, /*7000424E */ + 0x0F12E003, /*70004250 */ + 0x0F124B18, /*70004252 */ + 0x0F12885A, /*70004254 */ + 0x0F1243BA, /*70004256 */ + 0x0F12805A, /*70004258 */ + 0x0F120023, /*7000425A */ + 0x0F120032, /*7000425C */ + 0x0F12F000, /*7000425E */ + 0x0F12F8D7, /*70004260 */ + 0x0F122D10, /*70004262 */ + 0x0F12DA05, /*70004264 */ + 0x0F124913, /*70004266 */ + 0x0F129A00, /*70004268 */ + 0x0F128808, /*7000426A */ + 0x0F124310, /*7000426C */ + 0x0F128008, /*7000426E */ + 0x0F12E003, /*70004270 */ + 0x0F124810, /*70004272 */ + 0x0F128841, /*70004274 */ + 0x0F124339, /*70004276 */ + 0x0F128041, /*70004278 */ + 0x0F124D0D, /*7000427A */ + 0x0F122000, /*7000427C */ + 0x0F123580, /*7000427E */ + 0x0F1288AA, /*70004280 */ + 0x0F125E30, /*70004282 */ + 0x0F122100, /*70004284 */ + 0x0F12F000, /*70004286 */ + 0x0F12F8E3, /*70004288 */ + 0x0F128030, /*7000428A */ + 0x0F122000, /*7000428C */ + 0x0F1288AA, /*7000428E */ + 0x0F125E20, /*70004290 */ + 0x0F122100, /*70004292 */ + 0x0F12F000, /*70004294 */ + 0x0F12F8DC, /*70004296 */ + 0x0F128020, /*70004298 */ + 0x0F12E587, /*7000429A */ + 0x0F122558, /*7000429C */ + 0x0F127000, /*7000429E */ + 0x0F122AB8, /*700042A0 */ + 0x0F127000, /*700042A2 */ + 0x0F12145E, /*700042A4 */ + 0x0F127000, /*700042A6 */ + 0x0F122698, /*700042A8 */ + 0x0F127000, /*700042AA */ + 0x0F122BB8, /*700042AC */ + 0x0F127000, /*700042AE */ + 0x0F122998, /*700042B0 */ + 0x0F127000, /*700042B2 */ + 0x0F121100, /*700042B4 */ + 0x0F12D000, /*700042B6 */ + 0x0F124778, /*700042B8 */ + 0x0F1246C0, /*700042BA */ + 0x0F12C000, /*700042BC */ + 0x0F12E59F, /*700042BE */ + 0x0F12FF1C, /*700042C0 */ + 0x0F12E12F, /*700042C2 */ + 0x0F121789, /*700042C4 */ + 0x0F120001, /*700042C6 */ + 0x0F124778, /*700042C8 */ + 0x0F1246C0, /*700042CA */ + 0x0F12C000, /*700042CC */ + 0x0F12E59F, /*700042CE */ + 0x0F12FF1C, /*700042D0 */ + 0x0F12E12F, /*700042D2 */ + 0x0F1216F1, /*700042D4 */ + 0x0F120001, /*700042D6 */ + 0x0F124778, /*700042D8 */ + 0x0F1246C0, /*700042DA */ + 0x0F12C000, /*700042DC */ + 0x0F12E59F, /*700042DE */ + 0x0F12FF1C, /*700042E0 */ + 0x0F12E12F, /*700042E2 */ + 0x0F12C3B1, /*700042E4 */ + 0x0F120000, /*700042E6 */ + 0x0F124778, /*700042E8 */ + 0x0F1246C0, /*700042EA */ + 0x0F12C000, /*700042EC */ + 0x0F12E59F, /*700042EE */ + 0x0F12FF1C, /*700042F0 */ + 0x0F12E12F, /*700042F2 */ + 0x0F12C36D, /*700042F4 */ + 0x0F120000, /*700042F6 */ + 0x0F124778, /*700042F8 */ + 0x0F1246C0, /*700042FA */ + 0x0F12C000, /*700042FC */ + 0x0F12E59F, /*700042FE */ + 0x0F12FF1C, /*70004300 */ + 0x0F12E12F, /*70004302 */ + 0x0F12F6D7, /*70004304 */ + 0x0F120000, /*70004306 */ + 0x0F124778, /*70004308 */ + 0x0F1246C0, /*7000430A */ + 0x0F12C000, /*7000430C */ + 0x0F12E59F, /*7000430E */ + 0x0F12FF1C, /*70004310 */ + 0x0F12E12F, /*70004312 */ + 0x0F12B49D, /*70004314 */ + 0x0F120000, /*70004316 */ + 0x0F124778, /*70004318 */ + 0x0F1246C0, /*7000431A */ + 0x0F12C000, /*7000431C */ + 0x0F12E59F, /*7000431E */ + 0x0F12FF1C, /*70004320 */ + 0x0F12E12F, /*70004322 */ + 0x0F127EDF, /*70004324 */ + 0x0F120000, /*70004326 */ + 0x0F124778, /*70004328 */ + 0x0F1246C0, /*7000432A */ + 0x0F12C000, /*7000432C */ + 0x0F12E59F, /*7000432E */ + 0x0F12FF1C, /*70004330 */ + 0x0F12E12F, /*70004332 */ + 0x0F12448D, /*70004334 */ + 0x0F120000, /*70004336 */ + 0x0F124778, /*70004338 */ + 0x0F1246C0, /*7000433A */ + 0x0F12F004, /*7000433C */ + 0x0F12E51F, /*7000433E */ + 0x0F1229EC, /*70004340 */ + 0x0F120001, /*70004342 */ + 0x0F124778, /*70004344 */ + 0x0F1246C0, /*70004346 */ + 0x0F12C000, /*70004348 */ + 0x0F12E59F, /*7000434A */ + 0x0F12FF1C, /*7000434C */ + 0x0F12E12F, /*7000434E */ + 0x0F122EF1, /*70004350 */ + 0x0F120000, /*70004352 */ + 0x0F124778, /*70004354 */ + 0x0F1246C0, /*70004356 */ + 0x0F12C000, /*70004358 */ + 0x0F12E59F, /*7000435A */ + 0x0F12FF1C, /*7000435C */ + 0x0F12E12F, /*7000435E */ + 0x0F12EE03, /*70004360 */ + 0x0F120000, /*70004362 */ + 0x0F124778, /*70004364 */ + 0x0F1246C0, /*70004366 */ + 0x0F12C000, /*70004368 */ + 0x0F12E59F, /*7000436A */ + 0x0F12FF1C, /*7000436C */ + 0x0F12E12F, /*7000436E */ + 0x0F12A58B, /*70004370 */ + 0x0F120000, /*70004372 */ + 0x0F124778, /*70004374 */ + 0x0F1246C0, /*70004376 */ + 0x0F12C000, /*70004378 */ + 0x0F12E59F, /*7000437A */ + 0x0F12FF1C, /*7000437C */ + 0x0F12E12F, /*7000437E */ + 0x0F127C49, /*70004380 */ + 0x0F120000, /*70004382 */ + 0x0F124778, /*70004384 */ + 0x0F1246C0, /*70004386 */ + 0x0F12C000, /*70004388 */ + 0x0F12E59F, /*7000438A */ + 0x0F12FF1C, /*7000438C */ + 0x0F12E12F, /*7000438E */ + 0x0F127C63, /*70004390 */ + 0x0F120000, /*70004392 */ + 0x0F124778, /*70004394 */ + 0x0F1246C0, /*70004396 */ + 0x0F12C000, /*70004398 */ + 0x0F12E59F, /*7000439A */ + 0x0F12FF1C, /*7000439C */ + 0x0F12E12F, /*7000439E */ + 0x0F122DB7, /*700043A0 */ + 0x0F120000, /*700043A2 */ + 0x0F124778, /*700043A4 */ + 0x0F1246C0, /*700043A6 */ + 0x0F12C000, /*700043A8 */ + 0x0F12E59F, /*700043AA */ + 0x0F12FF1C, /*700043AC */ + 0x0F12E12F, /*700043AE */ + 0x0F12EB3D, /*700043B0 */ + 0x0F120000, /*700043B2 */ + 0x0F124778, /*700043B4 */ + 0x0F1246C0, /*700043B6 */ + 0x0F12C000, /*700043B8 */ + 0x0F12E59F, /*700043BA */ + 0x0F12FF1C, /*700043BC */ + 0x0F12E12F, /*700043BE */ + 0x0F12F061, /*700043C0 */ + 0x0F120000, /*700043C2 */ + 0x0F124778, /*700043C4 */ + 0x0F1246C0, /*700043C6 */ + 0x0F12C000, /*700043C8 */ + 0x0F12E59F, /*700043CA */ + 0x0F12FF1C, /*700043CC */ + 0x0F12E12F, /*700043CE */ + 0x0F12F0EF, /*700043D0 */ + 0x0F120000, /*700043D2 */ + 0x0F124778, /*700043D4 */ + 0x0F1246C0, /*700043D6 */ + 0x0F12F004, /*700043D8 */ + 0x0F12E51F, /*700043DA */ + 0x0F122824, /*700043DC */ + 0x0F120001, /*700043DE */ + 0x0F124778, /*700043E0 */ + 0x0F1246C0, /*700043E2 */ + 0x0F12C000, /*700043E4 */ + 0x0F12E59F, /*700043E6 */ + 0x0F12FF1C, /*700043E8 */ + 0x0F12E12F, /*700043EA */ + 0x0F128EDD, /*700043EC */ + 0x0F120000, /*700043EE */ + 0x0F124778, /*700043F0 */ + 0x0F1246C0, /*700043F2 */ + 0x0F12C000, /*700043F4 */ + 0x0F12E59F, /*700043F6 */ + 0x0F12FF1C, /*700043F8 */ + 0x0F12E12F, /*700043FA */ + 0x0F128DCB, /*700043FC */ + 0x0F120000, /*700043FE */ + 0x0F124778, /*70004400 */ + 0x0F1246C0, /*70004402 */ + 0x0F12C000, /*70004404 */ + 0x0F12E59F, /*70004406 */ + 0x0F12FF1C, /*70004408 */ + 0x0F12E12F, /*7000440A */ + 0x0F128E17, /*7000440C */ + 0x0F120000, /*7000440E */ + 0x0F124778, /*70004410 */ + 0x0F1246C0, /*70004412 */ + 0x0F12C000, /*70004414 */ + 0x0F12E59F, /*70004416 */ + 0x0F12FF1C, /*70004418 */ + 0x0F12E12F, /*7000441A */ + 0x0F1298C5, /*7000441C */ + 0x0F120000, /*7000441E */ + 0x0F124778, /*70004420 */ + 0x0F1246C0, /*70004422 */ + 0x0F12C000, /*70004424 */ + 0x0F12E59F, /*70004426 */ + 0x0F12FF1C, /*70004428 */ + 0x0F12E12F, /*7000442A */ + 0x0F127C7D, /*7000442C */ + 0x0F120000, /*7000442E */ + 0x0F124778, /*70004430 */ + 0x0F1246C0, /*70004432 */ + 0x0F12C000, /*70004434 */ + 0x0F12E59F, /*70004436 */ + 0x0F12FF1C, /*70004438 */ + 0x0F12E12F, /*7000443A */ + 0x0F127E31, /*7000443C */ + 0x0F120000, /*7000443E */ + 0x0F124778, /*70004440 */ + 0x0F1246C0, /*70004442 */ + 0x0F12C000, /*70004444 */ + 0x0F12E59F, /*70004446 */ + 0x0F12FF1C, /*70004448 */ + 0x0F12E12F, /*7000444A */ + 0x0F127EAB, /*7000444C */ + 0x0F120000, /*7000444E */ + 0x0F124778, /*70004450 */ + 0x0F1246C0, /*70004452 */ + 0x0F12C000, /*70004454 */ + 0x0F12E59F, /*70004456 */ + 0x0F12FF1C, /*70004458 */ + 0x0F12E12F, /*7000445A */ + 0x0F127501, /*7000445C */ + 0x0F120000, /*7000445E */ +/* End of Patch Data(Last : 7000445Eh) +// Total Size 2408 (0x0968) +// Addr : 3AF8 , Size : 2406(966h) + +//TNP_USER_MBCV_CONTROL +//TNP_4EC_MBR_TUNE +//TNP_4EC_FORBIDDEN_TUNE +//TNP_AF_FINESEARCH_DRIVEBACK +//TNP_FLASH_ALG +//TNP_GAS_ALPHA_OTP +//TNP_AWB_MODUL_COMP +//TNP_AWB_INIT_QUEUE +//TNP_AWB_GRID_LOWBR +//TNP_AWB_GRID_MODULECOMP*/ + + 0x0028D000, + 0x002A1000, + 0x0F120001, + /* End of FACTORY ONLY. */ + + /*AF setting */ + 0x00287000, + 0x002A01FC, + 0x0F120001, /*REG_TC_IPRM_LedGpio */ + /*70001720 0100 Only STW Use IT */ + 0x002A01FE, + 0x0F120003, + 0x0F120000, + 0x002A0204, + 0x0F120061, + 0x002A020C, + 0x0F122F0C, + 0x0F120190, + 0x002A0294, + 0x0F120100, + 0x0F1200E3, + 0x0F120200, + 0x0F120238, + 0x0F1201C6, + 0x0F120166, + 0x0F120074, + 0x0F120132, + 0x0F120001, + + 0x002A070E, + 0x0F1200FF, + 0x002A071E, + 0x0F120001, + 0x002A163C, + 0x0F120000, + + 0x002A1648, + 0x0F129002, /*2nd search on when 2nd search lens opsite direct moving*/ + 0x002A1652, + 0x0F120002, + 0x0F120000, + 0x002A15E0, + 0x0F120801, /* when 2nd search 1code distance 6+1 position move */ + + 0x002A164C, + 0x0F120003, + 0x002A163E, + 0x0F1200E5, + 0x0F1200CC, /*98(60%) -> CC(80%) */ + 0x002A15D4, + 0x0F120000, + 0x0F12D000, + 0x002A169A, + 0x0F12FF95, + 0x002A166A, + 0x0F120280, + 0x002A1676, + 0x0F1203A0, + 0x0F120320, + 0x002A16BC, + 0x0F120030, + 0x002A16E0, + 0x0F120060, + 0x002A16D4, + 0x0F120010, + 0x002A1656, + 0x0F120000, + 0x002A15E6, + 0x0F12003C, + + 0x0F120017, /*af_pos_usTableLastInd */ + 0x0F120026, + 0x0F12002C, + 0x0F120032, + 0x0F120038, + 0x0F12003E, + 0x0F120044, + 0x0F12004A, + 0x0F120050, + 0x0F120056, + 0x0F12005C, + 0x0F120062, + 0x0F120068, + 0x0F12006E, + 0x0F120074, + 0x0F12007A, + 0x0F120080, + 0x0F120086, + 0x0F12008C, + 0x0F120092, + 0x0F120098, + 0x0F12009E, + 0x0F1200A4, + 0x0F1200AA, + 0x0F1200B0, + + 0x002A1722, + 0x0F128000, + 0x0F120006, + 0x0F123FF0, + 0x0F1203E8, + 0x0F120000, + 0x0F120080, /*delay2 when threshold upper lens moving when moving*/ + 0x0F120009, /*threshold */ + 0x0F120020, /*delay1 when threshold lower lens moving when moving*/ + 0x0F120040, + 0x0F120080, + 0x0F1200C0, + 0x0F1200E0, + + 0x002A028C, + 0x0F120003, /*REG_TC_AF_AfCmd */ + +/*=================================================================== +//04.Gas_Anti Shading_Otp +//==================================================================*/ + 0x002A08B4, + 0x0F120001, /*wbt_bUseOutdoorASH */ + +/* Refer Mon_AWB_RotGain*/ + 0x002A08BC, + 0x0F1200C0, /*TVAR_ash_AwbAshCord_0_ 2300K*/ + 0x0F1200DF, /*TVAR_ash_AwbAshCord_1_ 2750K*/ + 0x0F120100, /*TVAR_ash_AwbAshCord_2_ 3300K*/ + 0x0F120125, /*TVAR_ash_AwbAshCord_3_ 4150K*/ + 0x0F12015F, /*TVAR_ash_AwbAshCord_4_ 5250K*/ + 0x0F12017C, /*TVAR_ash_AwbAshCord_5_ 6400K*/ + 0x0F120194, /*TVAR_ash_AwbAshCord_6_ 7500K*/ + +/* GAS Alpha Table*/ + 0x002A08F6, + 0x0F124000, /*TVAR_ash_GASAlpha_0__0_ R // 2300K */ + 0x0F124000, /*TVAR_ash_GASAlpha_0__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_0__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_0__3_ B */ + 0x0F124000, /*TVAR_ash_GASAlpha_1__0_ R // 2750K */ + 0x0F124000, /*TVAR_ash_GASAlpha_1__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_1__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_1__3_ B */ + 0x0F124000, /*TVAR_ash_GASAlpha_2__0_ R // 3300K */ + 0x0F124000, /*TVAR_ash_GASAlpha_2__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_2__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_2__3_ B */ + 0x0F123C00, /*TVAR_ash_GASAlpha_3__0_ R // 4150K */ + 0x0F124000, /*TVAR_ash_GASAlpha_3__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_3__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_3__3_ B */ + 0x0F123E00, /*TVAR_ash_GASAlpha_4__0_ R // 5250K */ + 0x0F124000, /*TVAR_ash_GASAlpha_4__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_4__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_4__3_ B */ + 0x0F124100, /*TVAR_ash_GASAlpha_5__0_ R // 6400K */ + 0x0F124000, /*TVAR_ash_GASAlpha_5__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_5__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_5__3_ B */ + 0x0F124200, /*TVAR_ash_GASAlpha_6__0_ R // 7500K */ + 0x0F124000, /*TVAR_ash_GASAlpha_6__1_ GR */ + 0x0F124000, /*TVAR_ash_GASAlpha_6__2_ GB */ + 0x0F124000, /*TVAR_ash_GASAlpha_6__3_ B */ + +/* Outdoor GAS Alpha*/ + 0x0F124500, /*TVAR_ash_GASOutdoorAlpha_0_ R */ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_1_ GR */ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_2_ GB */ + 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_3_ B */ + + 0x002A08F4, + 0x0F120001, /*ash_bUseGasAlpha */ + +/*================================================================= +// 09.Auto Flicker Detection +//================================================================*/ + + 0x002A0F30, + 0x0F120001, /*AFC_D_ConvAccelerPower */ + +/*Auto Flicker (60Mhz start)*/ + 0x002A0F2A, + 0x0F120000, /*AFC_Default BIT[0] 1:60Hz 0:50Hz */ + 0x002A04E6, + 0x0F12077F, /*REG_TC_DBG 7F: 60Hz 5F:50Hz */ + +/*=========================================================== +// 10.AE Setting +//==========================================================*/ + 0x002A1484, + 0x0F12003C, /*TVAR_ae_BrAve */ + 0x002A148A, + 0x0F12000F, /*ae_StatMode */ + 0x002A058C, + 0x0F123520, + 0x0F120000, /*lt_uMaxExp1 */ + 0x0F12C350, + 0x0F120000, /*lt_uMaxExp2 */ + 0x0F123520, + 0x0F120000, /*lt_uCapMaxExp1 */ + 0x0F12C350, + 0x0F120000, /*lt_uCapMaxExp2*/ + 0x002A059C, + 0x0F120470, /*lt_uMaxAnGain1 */ + 0x0F120C00, /*lt_uMaxAnGain2 */ + 0x0F120100, /*lt_uMaxDigGain */ + 0x0F121000, /*lt_uMaxTotGain */ + + 0x002A0544, + 0x0F120111, /*lt_uLimitHigh */ + 0x0F1200EF, /*lt_uLimitLow */ + + 0x002A0F2A, + 0x0F120000, /*AFC_Default60Hz 0001:60Hz 0000h:50Hz */ + 0x002A04E6, + 0x0F12077F, /*REG_TC_DBG */ + + 0x002A0F30, + 0x0F120001, /*AFC_D_ConvAccelerPower */ + + 0x002A0608, + 0x0F120001, /*lt_ExpGain_uSubsamplingmode */ + 0x0F120001, /*lt_ExpGain_uNonSubsampling */ + 0x0F120800, /*lt_ExpGain_ExpCurveGainMaxStr */ + 0x0F120100,/*0100 //lt_ExpGain_ExpCurveGainMaxStr_0_uMaxDigGain*/ + 0x0F120001, /*0001 */ + 0x0F120000,/*0000 //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpIn_0_ */ + 0x0F120A3C, /*0A3C */ + 0x0F120000, /*0000 */ + 0x0F120D05, /*0D05 */ + 0x0F120000, /*0000 */ + 0x0F124008, /*4008 */ + 0x0F120000, /*0000 */ + 0x0F127000, /*7400 //?? //700Lux */ + 0x0F120000, /*0000 */ + 0x0F129C00, /*C000 //?? //9C00->9F->A5 //400Lux */ + 0x0F120000, /*0000 */ + 0x0F12AD00, /*AD00 */ + 0x0F120001, /*0001 */ + 0x0F12F1D4, /*F1D4 */ + 0x0F120002, /*0002 */ + 0x0F12DC00, /*DC00 */ + 0x0F120005, /*0005 */ + 0x0F12DC00, /*DC00 */ + 0x0F120005, /*0005 */ + /**/ + 0x002A0638, /*0638 */ + 0x0F120001, /*0001 */ + 0x0F120000,/*0000 //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_*/ + 0x0F120A3C, /*0A3C */ + 0x0F120000, /*0000 */ + 0x0F120D05, /*0D05 */ + 0x0F120000, /*0000 */ + 0x0F123408, /*3408 */ + 0x0F120000, /*0000 */ + 0x0F123408, /*3408 */ + 0x0F120000, /*0000 */ + 0x0F126810, /*6810 */ + 0x0F120000, /*0000 */ + 0x0F128214, /*8214 */ + 0x0F120000, /*0000 */ + 0x0F12C350, /*C350 */ + 0x0F120000, /*0000 */ + 0x0F12C350, /*C350 */ + 0x0F120000, /*0000 */ + 0x0F12C350, /*C350 */ + 0x0F120000, /*0000 */ + 0x002A0660, + 0x0F120650, /*lt_ExpGain_ExpCurveGainMaxStr_1_ */ + 0x0F120100, /*lt_ExpGain_ExpCurveGainMaxStr_1__uMaxDigGain */ + 0x002A06B8, + 0x0F12452C, + 0x0F120005, /*lt_uMaxLei */ + +/*=========================================================== +// 11.AE Weight (Normal) +//==========================================================*/ + 0x002A1492, + 0x0F120100, + 0x0F120101, + 0x0F120101, + 0x0F120001, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120201, + 0x0F120202, + 0x0F120202, + 0x0F120102, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + +/*============================================ +// 14.AWB-BASIC setting +//============================================*/ + +/*AWB init Start point*/ + 0x002A145E, + 0x0F120580, + 0x0F120428, + 0x0F1207B0, + + /*AWB Init */ +/*White Locus*/ + 0x002A11F0, + 0x0F120120, /*awbb_IntcR */ + 0x0F120121, /*awbb_IntcB */ + +/*Indoor Zone*/ + 0x002A101C, + 0x0F120386, + 0x0F1203A8, + 0x0F12033C, + 0x0F120394, + 0x0F1202FE, + 0x0F120372, + 0x0F1202A8, + 0x0F120352, + 0x0F12027C, + 0x0F120300, + 0x0F120264, + 0x0F1202C8, + 0x0F120244, + 0x0F1202A8, + 0x0F12022C, + 0x0F1202A0, + 0x0F12020C, + 0x0F1202A0, + 0x0F1201F4, + 0x0F120298, + 0x0F1201D4, + 0x0F120290, + 0x0F1201CC, + 0x0F120276, + 0x0F1201D2, + 0x0F120260, + 0x0F1201F6, + 0x0F12023A, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, /*awbb_IndoorGrZones_m_GridStep */ + 0x0F120005, + 0x002A1070, /*awbb_IndoorGrZones_ZInfo_m_GridSz */ + 0x0F12000F, + 0x002A1074, /*awbb_IndoorGrZones_m_Boffs */ + 0x0F120126, +/* Outdoor Zone*/ + 0x002A1078, + 0x0F120270, + 0x0F120296, + 0x0F12024A, + 0x0F1202AC, + 0x0F120240, + 0x0F1202B0, + 0x0F120234, + 0x0F1202B0, + 0x0F120228, + 0x0F1202AE, + 0x0F12021E, + 0x0F1202A8, + 0x0F120212, + 0x0F1202A0, + 0x0F120210, + 0x0F120294, + 0x0F12020E, + 0x0F120288, + 0x0F120218, + 0x0F12027E, + 0x0F120234, + 0x0F120256, + 0x0F120000, + 0x0F120000, + + 0x0F120004, /*awbb_OutdoorGrZones_m_GridStep */ + 0x002A10AC, + 0x0F12000B, /*awbb_OutdoorGrZones_ZInfo_m_GridSz */ + 0x002A10B0, + 0x0F1201E8, /*awbb_OutdoorGrZones_m_Boffs */ + + /*LowBR Zone */ + 0x002A10B4, + 0x0F120350, + 0x0F120422, + 0x0F1202C4, + 0x0F120452, + 0x0F120278, + 0x0F12041C, + 0x0F120230, + 0x0F1203EE, + 0x0F1201F0, + 0x0F120392, + 0x0F1201C0, + 0x0F120340, + 0x0F120194, + 0x0F120302, + 0x0F12016E, + 0x0F1202C2, + 0x0F120148, + 0x0F120286, + 0x0F12018A, + 0x0F120242, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + + 0x0F120006, /*awbb_LowBrGrZones_m_GridStep */ + 0x002A10E8, + 0x0F12000A, /*awbb_LowBrGrZones_ZInfo_m_GridSz */ + 0x002A10EC, + 0x0F120106, /*awbb_LowBrGrZones_m_Boffs */ + + /*LowTemp Zone */ + 0x002A10F0, + 0x0F120380, + 0x0F120000, /*awbb_CrclLowT_R_c */ + 0x0F120168, + 0x0F120000, /*awbb_CrclLowT_B_c */ + 0x0F122D90, + 0x0F120000, /*awbb_CrclLowT_Rad_c */ + + /*AWB Convergence Speed */ + 0x002A1464, + 0x0F120008, + 0x0F120190, + 0x0F1200A0, + + 0x002A1228, + 0x0F1200C0, + 0x002A122C, + 0x0F120010, + 0x002A122A, + 0x0F120010, + + 0x002A120A, + 0x0F1205D5, /*awbb_MvEq_RBthresh */ + 0x002A120E, + 0x0F120000, + + 0x0F120771, + 0x0F1203A4, + 0x0F120036, + 0x0F12002A, + + 0x002A1278, + 0x0F12FEF7, + 0x0F120021, + 0x0F120AF0, /*0E74 */ + 0x0F120AF0, /*0E74 */ + 0x0F12018F, + 0x0F120096, + 0x0F12000E, + 0x002A1224, + 0x0F120032, + 0x0F12001E, + 0x0F1200C0, + 0x0F120010, + 0x0F120002, /*awbb_YThreshLow_Low */ + 0x002A2BA4, + 0x0F120006, /*Mon_AWB_ByPassMode */ + + 0x002A146C, + 0x0F120002, /*awbb_GridEnable */ + + /*Grid */ + 0x002A1434, + 0x0F1202CE, /* awbb_GridConst_1 */ + 0x0F120347, /* awbb_GridConst_1_1_ */ + 0x0F1203C2, /* awbb_GridConst_1_2_ */ + 0x0F1210A0, /* awbb_GridConst_2 */ + 0x0F1210A1, /* awbb_GridConst_2_1_ */ + 0x0F121185, /* awbb_GridConst_2_2_ */ + 0x0F121186, /* awbb_GridConst_2_3_ */ + 0x0F1211E5, /* awbb_GridConst_2_4_ */ + 0x0F1211E6, /* awbb_GridConst_2_5_ */ + 0x0F1200AB, /* awbb_GridCoeff_R_1 */ + 0x0F1200BF, /* awbb_GridCoeff_B_1 */ + 0x0F1200D2, /* awbb_GridCoeff_R_2 */ + 0x0F120093, /* awbb_GridCoeff_B_2 */ + + /*Indoor Grid Offset */ + 0x002A13A4, + 0x0F120000, /*0000 */ + 0x0F12FFE8, /*FFD8 */ + 0x0F12FFE8, /*FFD8 */ + 0x0F12FFC0, /*FFD8 */ + 0x0F12FFC0, /*FFD8 */ + 0x0F12FFD0, /*FFF6 B */ + /**/ + 0x0F120000,/*0000 */ + 0x0F12FFD8, /*FFD8 */ + 0x0F12FFD8, /*FFD8 */ + 0x0F12FFC0, /*FFD8 */ + 0x0F12FFC0, /*FFD8 */ + 0x0F12FFD0, /*FFF6 */ + /**/ + 0x0F120000,/*0000 */ + 0x0F12FFD8, /*FFD8 */ + 0x0F12FFD8, /*FFD8 */ + 0x0F12FFC0, /*FFD8 */ + 0x0F12FFC0, /*FFD8 */ + 0x0F12FFD0, /*FFF6 */ + /**/ + 0x0F12FFEC,/*FFEC*/ + 0x0F120010,/*000A */ + 0x0F120010, /*000A */ + 0x0F12FFC0, /*FFC4 */ + 0x0F12FFC0, /*FFC4 */ + 0x0F12FFBC, /*FF56 7 */ + /**/ + 0x0F12FFEC,/*FFEC*/ + 0x0F120010,/*000A */ + 0x0F120010, /*000A */ + 0x0F12FFC0, /*FFC4 */ + 0x0F12FFC0, /*FFC4 */ + 0x0F12FFBC, /*FF56 */ + /**/ + 0x0F12FFEC,/*FFEC*/ + 0x0F120010,/*000A */ + 0x0F120010, /*000A */ + 0x0F12FFC0, /*FFC4 */ + 0x0F12FFC0, /*FFC4 */ + 0x0F12FFBC, /*FF56 */ + +/*Outdoor Grid Offset*/ + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F120000, + 0x0F120000, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F120000, + 0x0F120000, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F12FFE0, + 0x0F120000, + 0x0F120000, + 0x0F12FFB0, + 0x0F12FFA8, + 0x0F12FFA8, + 0x0F12FFA8, + 0x0F120000, + 0x0F120000, + 0x0F12FFB0, + 0x0F12FFA8, + 0x0F12FFA8, + 0x0F12FFA8, + 0x0F120000, + 0x0F120000, + 0x0F12FFB0, + 0x0F12FFA8, + 0x0F12FFA8, + 0x0F12FFA8, + 0x0F120000, + 0x0F120000, + 0x002A1208, + 0x0F120020, + + 0x002A144E, + 0x0F120000, /*awbb_RGainOff */ + 0x0F12FFE0, /*awbb_BGainOff */ + 0x0F120000, /*awbb_GGainOff */ + +/*====================================================== +// 15.CCM Setting +//=====================================================*/ + /*CCM*/ + 0x002A08A6, + 0x0F1200C0, + 0x0F120100, + 0x0F120125, + 0x0F12015F, + 0x0F12017C, + 0x0F120194, + + 0x0F120001, + + 0x002A0898, + 0x0F124800, + 0x0F127000, + 0x002A08A0, + 0x0F1248D8, + 0x0F127000, + 0x002A4800,/*Horizon */ + 0x0F120208, + 0x0F12FFB5, + 0x0F12FFE8, + 0x0F12FF20, + 0x0F1201BF, + 0x0F12FF53, + 0x0F120022, + 0x0F12FFEA, + 0x0F1201C2, + 0x0F1200C6, + 0x0F120095, + 0x0F12FEFD, + 0x0F120206, + 0x0F12FF7F, + 0x0F120191, + 0x0F12FF06, + 0x0F1201BA, + 0x0F120108, + + 0x0F120208, /* inca A */ + 0x0F12FFB5, + 0x0F12FFE8, + 0x0F12FF20, + 0x0F1201BF, + 0x0F12FF53, + 0x0F120022, + 0x0F12FFEA, + 0x0F1201C2, + 0x0F1200C6, + 0x0F120095, + 0x0F12FEFD, + 0x0F120206, + 0x0F12FF7F, + 0x0F120191, + 0x0F12FF06, + 0x0F1201BA, + 0x0F120108, + 0x0F120208,/*WW*/ + 0x0F12FFB5, + 0x0F12FFE8, + 0x0F12FF20, + 0x0F1201BF, + 0x0F12FF53, + 0x0F120022, + 0x0F12FFEA, + 0x0F1201C2, + 0x0F1200C6, + 0x0F120095, + 0x0F12FEFD, + 0x0F120206, + 0x0F12FF7F, + 0x0F120191, + 0x0F12FF06, + 0x0F1201BA, + 0x0F120108, + 0x0F120204,/*CW*/ + 0x0F12FFB2, + 0x0F12FFF5, + 0x0F12FEF1, + 0x0F12014E, + 0x0F12FF18, + 0x0F12FFE6, + 0x0F12FFDD, + 0x0F1201B2, + 0x0F1200F2, + 0x0F1200CA, + 0x0F12FF48, + 0x0F120151, + 0x0F12FF50, + 0x0F120147, + 0x0F12FF75, + 0x0F120187, + 0x0F1201BF, + 0x0F1201F5,/*D50*/ + 0x0F12FFB4, + 0x0F120001, + 0x0F12FED7, + 0x0F12014B, + 0x0F12FF35, + 0x0F12FFE6, + 0x0F12FFDD, + 0x0F1201B2, + 0x0F1200F2, + 0x0F1200CA, + 0x0F12FF48, + 0x0F120151, + 0x0F12FF50, + 0x0F120147, + 0x0F12FF75, + 0x0F120187, + 0x0F1201BF, + 0x0F1201F5,/*D65 */ + 0x0F12FFB4, + 0x0F120001, + 0x0F12FED7, + 0x0F12014B, + 0x0F12FF35, + 0x0F12FFE6, + 0x0F12FFDD, + 0x0F1201B2, + 0x0F1200F2, + 0x0F1200CA, + 0x0F12FF48, + 0x0F120151, + 0x0F12FF50, + 0x0F120147, + 0x0F12FF75, + 0x0F120187, + 0x0F1201BF, + 0x0F1201E5,/*Y hue-5. TVAR_wbt_pOutdoorCcm[0] */ + 0x0F12FFA4, + 0x0F12FFDC, + 0x0F12FE90, + 0x0F12013F, + 0x0F12FF1B, + 0x0F12FFD2, + 0x0F12FFDF, + 0x0F120236, + 0x0F1200F0, + 0x0F1200C9, + 0x0F12FF59, + 0x0F1201CE, + 0x0F12FF83, + 0x0F120195, + 0x0F12FEF3, + 0x0F120126, + 0x0F120162, +/*================================================================== +// 16.GAMMA +//================================================================*/ + 0x002A0734,/*R*/ + 0x0F120000, + 0x0F120001, + 0x0F120006, + 0x0F120017, + 0x0F12004A, + 0x0F1200C9, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + + 0x0F120000,/*G*/ + 0x0F120001, + 0x0F120006, + 0x0F120017, + 0x0F12004A, + 0x0F1200C9, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + + 0x0F120000,/*B*/ + 0x0F120001, + 0x0F120006, + 0x0F120017, + 0x0F12004A, + 0x0F1200C9, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, +/*RGB OutdoorGamma*/ + 0x0F120000, + 0x0F12000B, + 0x0F120019, + 0x0F120036, + 0x0F12006F, + 0x0F1200D8, + 0x0F120135, + 0x0F12015F, + 0x0F120185, + 0x0F1201C1, + 0x0F1201F3, + 0x0F120220, + 0x0F12024A, + 0x0F120291, + 0x0F1202D0, + 0x0F12032A, + 0x0F12036A, + 0x0F12039F, + 0x0F1203CC, + 0x0F1203F9, + 0x0F120000, + 0x0F12000B, + 0x0F120019, + 0x0F120036, + 0x0F12006F, + 0x0F1200D8, + 0x0F120135, + 0x0F12015F, + 0x0F120185, + 0x0F1201C1, + 0x0F1201F3, + 0x0F120220, + 0x0F12024A, + 0x0F120291, + 0x0F1202D0, + 0x0F12032A, + 0x0F12036A, + 0x0F12039F, + 0x0F1203CC, + 0x0F1203F9, + 0x0F120000, + 0x0F12000B, + 0x0F120019, + 0x0F120036, + 0x0F12006F, + 0x0F1200D8, + 0x0F120135, + 0x0F12015F, + 0x0F120185, + 0x0F1201C1, + 0x0F1201F3, + 0x0F120220, + 0x0F12024A, + 0x0F120291, + 0x0F1202D0, + 0x0F12032A, + 0x0F12036A, + 0x0F12039F, + 0x0F1203CC, + 0x0F1203F9, +/*=========================================================== +// 17.AFIT +//==========================================================*/ + 0x002A0944, + 0x0F120050,/*afit_uNoiseIndInDoor */ + 0x0F1200B0, /*afit_uNoiseIndInDoor */ + 0x0F120196, /*afit_uNoiseIndInDoor */ + 0x0F120245, /*afit_uNoiseIndInDoor */ + 0x0F120300, /*afit_uNoiseIndInDoor */ + + 0x002A0938, + 0x0F120000,/* on/off AFIT by NB option */ + 0x0F120014, /*SARR_uNormBrInDoor */ + 0x0F1200D2, /*SARR_uNormBrInDoor */ + 0x0F120384, /*SARR_uNormBrInDoor */ + 0x0F1207D0, /*SARR_uNormBrInDoor */ + 0x0F121388, /*SARR_uNormBrInDoor */ + + 0x002A0976, + 0x0F120070,/*afit_usGamutTh */ + 0x0F120005, /*afit_usNeargrayOffset */ + 0x0F120000, /*afit_bUseSenBpr */ + 0x0F1201CC, /*afit_usBprThr_0_ */ + 0x0F1201CC, /*afit_usBprThr_1_ */ + 0x0F1201CC, /*afit_usBprThr_2_ */ + 0x0F1201CC, /*afit_usBprThr_3_ */ + 0x0F1201CC, /*afit_usBprThr_4_ */ + 0x0F120180, /*afit_NIContrastAFITValue */ + 0x0F120196, /*afit_NIContrastTh */ + + 0x002A098C, + 0x0F12FFEC, /*7000098C//_BRIGHTNESS */ + 0x0F120000, /*7000098E//_CONTRAST */ + 0x0F120000, /*70000990//_SATURATION */ + 0x0F120000, /*70000992//_SHARP_BLUR */ + 0x0F120000, /*70000994//_GLAMOUR */ + 0x0F1200C0, /*70000996//_bnr_edge_high */ + 0x0F120064, /*70000998//_postdmsc_iLowBright */ + 0x0F120384, /*7000099A//_postdmsc_iHighBright */ + 0x0F12005F, /*7000099C//_postdmsc_iLowSat */ + 0x0F1201F4, /*7000099E//_postdmsc_iHighSat */ + 0x0F120070, /*700009A0//_postdmsc_iTune */ + 0x0F120040, /*700009A2//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*700009A4//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*700009A6//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*700009A8//_yuvemix_mPosRanges_0 */ + 0x0F120040, /*700009AA//_yuvemix_mPosRanges_1 */ + 0x0F1200A0, /*700009AC//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*700009AE//_bnr_edge_low */ + 0x0F120201, /*700009B0//_bnr_repl_force */ + 0x0F120204, /*700009B2//_bnr_iHotThreshLow */ + 0x0F123604, /*700009B4//_bnr_iColdThreshLow */ + 0x0F12032A, /*700009B6//_bnr_DispTH_High */ + 0x0F120403, /*700009B8//_bnr_DISP_Limit_High */ + 0x0F121B06, /*700009BA//_bnr_iDistSigmaMax */ + 0x0F126015, /*700009BC//_bnr_iDiffSigmaHigh */ + 0x0F1200C0, /*700009BE//_bnr_iNormalizedSTD_Limit */ + 0x0F126080, /*700009C0//_bnr_iDirMinThres */ + 0x0F124080, /*700009C2//_bnr_iDirFltDiffThresLow */ + 0x0F120640, /*700009C4//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*700009C6//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*700009C8//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*700009CA//_bnr_iSlopeBlurStrength */ + 0x0F120000, /*700009CC//_bnr_AddNoisePower1 */ + 0x0F120400, /*700009CE//_bnr_iRadialTune */ + 0x0F12365A, /*700009D0//_bnr_iRadialLimit */ + 0x0F12102A, /*700009D2//_ee_iFSMagThHigh */ + 0x0F12000B, /*700009D4//_ee_iFSVarThHigh */ + 0x0F120600, /*700009D6//_ee_iFSThHigh */ + 0x0F125A0F, /*700009D8//_ee_iFSVarCountTh */ + 0x0F120505, /*700009DA//_ee_iRadialPower */ + 0x0F121802, /*700009DC//_ee_iROADThres */ + 0x0F120000, /*700009DE//_ee_iROADSubMaxNR */ + 0x0F122006, /*700009E0//_ee_iROADNeiThres */ + 0x0F123028, /*700009E2//_ee_iSmoothEdgeThres */ + 0x0F120418, /*700009E4//_ee_iWSharpen */ + 0x0F120101, /*700009E6//_ee_iWShThresh */ + 0x0F120800, /*700009E8//_ee_iEmbossCentAdd */ + 0x0F121804, /*700009EA//_ee_iReduceEdgeThresh */ + 0x0F124008, /*700009EC//_dmsc_iDesatThresh */ + 0x0F120540, /*700009EE//_dmsc_iDemBlurLow */ + 0x0F128006, /*700009F0//_dmsc_iDecisionThresh */ + 0x0F120020, /*700009F2//_dmsc_iMonochrom */ + 0x0F120000, /*700009F4//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*700009F6//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*700009F8//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*700009FA//_postdmsc_iBCoeff */ + 0x0F12000B, /*700009FC//_postdmsc_iWideMult */ + 0x0F120607, /*700009FE//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000A00//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000A02//_yuvemix_mPosSlopes_1 */ + 0x0F120705, /*70000A04//_yuvemix_mPosSlopes_3 */ + 0x0F120206, /*70000A06//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000A08//_yuviirnr_iHighYNorm */ + 0x0F120309, /*70000A0A//_yuviirnr_iHighUVNorm */ + 0x0F120305, /*70000A0C//_yuviirnr_iUVNormShift */ + 0x0F122006, /*70000A0E//_yuviirnr_iVertLength_UV */ + 0x0F121320, /*70000A10//_yuviirnr_iDiffThreshH_Y */ + 0x0F121014, /*70000A12//_yuviirnr_iDiffThreshH_UV */ + 0x0F121010, /*70000A14//_yuviirnr_iMaxThreshH_Y */ + 0x0F120C10, /*70000A16//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A0C, /*70000A18//_yuviirnr_iYNRStrengthH */ + 0x0F124A18, /*70000A1A//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000A1C//_RGBGamma2_iLinearity */ + 0x0F120350, /*70000A1E//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000A20//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000A22//_bnr_iClustMulT_H */ + 0x0F120101, /*70000A24//_bnr_iClustThresh_H */ + 0x0F122A36, /*70000A26//_bnr_iDenThreshLow */ + 0x0F126024, /*70000A28//_ee_iLowSharpPower */ + 0x0F122A36, /*70000A2A//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000A2C//_ee_iLowSharpClamp */ + 0x0F120808, /*70000A2E//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000A30//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000A32//_bnr_iClustMulT_C_Bin */ + 0x0F122701, /*70000A34//_bnr_iClustThresh_C_Bin */ + 0x0F12241E, /*70000A36//_bnr_iDenThreshHigh_Bin */ + 0x0F122E60, /*70000A38//_ee_iHighSharpPower_Bin */ + 0x0F12FF22, /*70000A3A//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000A3C//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000A3E//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000A40//_bnr_nClustLevel_C */ + 0x0F120000, /*70000A42//_BRIGHTNESS */ + 0x0F120000, /*70000A44//_CONTRAST */ + 0x0F120000, /*70000A46//_SATURATION */ + 0x0F120000, /*70000A48//_SHARP_BLUR */ + 0x0F120000, /*70000A4A//_GLAMOUR */ + 0x0F1200C0, /*70000A4C//_bnr_edge_high */ + 0x0F120064, /*70000A4E//_postdmsc_iLowBright */ + 0x0F120384, /*70000A50//_postdmsc_iHighBright */ + 0x0F120051, /*70000A52//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000A54//_postdmsc_iHighSat */ + 0x0F120070, /*70000A56//_postdmsc_iTune */ + 0x0F120040, /*70000A58//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000A5A//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000A5C//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000A5E//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000A60//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000A62//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000A64//_bnr_edge_low */ + 0x0F120201, /*70000A66//_bnr_repl_force */ + 0x0F120204, /*70000A68//_bnr_iHotThreshLow */ + 0x0F122404, /*70000A6A//_bnr_iColdThreshLow */ + 0x0F12031B, /*70000A6C//_bnr_DispTH_High */ + 0x0F120103, /*70000A6E//_bnr_DISP_Limit_High */ + 0x0F121205, /*70000A70//_bnr_iDistSigmaMax */ + 0x0F12400D, /*70000A72//_bnr_iDiffSigmaHigh */ + 0x0F120080, /*70000A74//_bnr_iNormalizedSTD_Limit */ + 0x0F121980, /*70000A76//_bnr_iDirMinThres */ + 0x0F12272E, /*70000A78//_bnr_iDirFltDiffThresLow */ + 0x0F120629, /*70000A7A//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000A7C//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000A7E//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000A80//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000A82//_bnr_AddNoisePower1 */ + 0x0F120300, /*70000A84//_bnr_iRadialTune */ + 0x0F12245A, /*70000A86//_bnr_iRadialLimit */ + 0x0F121018, /*70000A88//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000A8A//_ee_iFSVarThHigh */ + 0x0F120B00, /*70000A8C//_ee_iFSThHigh */ + 0x0F125A0F, /*70000A8E//_ee_iFSVarCountTh */ + 0x0F120505, /*70000A90//_ee_iRadialPower */ + 0x0F121802, /*70000A92//_ee_iROADThres */ + 0x0F120000, /*70000A94//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000A96//_ee_iROADNeiThres */ + 0x0F123828, /*70000A98//_ee_iSmoothEdgeThres */ + 0x0F120425, /*70000A9A//_ee_iWSharpen */ + 0x0F120101, /*70000A9C//_ee_iWShThresh */ + 0x0F120800, /*70000A9E//_ee_iEmbossCentAdd */ + 0x0F121004, /*70000AA0//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000AA2//_dmsc_iDesatThresh */ + 0x0F120540, /*70000AA4//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000AA6//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000AA8//_dmsc_iMonochrom */ + 0x0F120000, /*70000AAA//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000AAC//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000AAE//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000AB0//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000AB2//_postdmsc_iWideMult */ + 0x0F120607, /*70000AB4//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000AB6//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000AB8//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000ABA//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*70000ABC//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000ABE//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000AC0//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*70000AC2//_yuviirnr_iUVNormShift */ + 0x0F120407, /*70000AC4//_yuviirnr_iVertLength_UV */ + 0x0F122204, /*70000AC6//_yuviirnr_iDiffThreshH_Y */ + 0x0F12021C, /*70000AC8//_yuviirnr_iDiffThreshH_UV */ + 0x0F121102, /*70000ACA//_yuviirnr_iMaxThreshH_Y */ + 0x0F120611, /*70000ACC//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000ACE//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000AD0//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000AD2//_RGBGamma2_iLinearity */ + 0x0F120374, /*70000AD4//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000AD6//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000AD8//_bnr_iClustMulT_H */ + 0x0F120101, /*70000ADA//_bnr_iClustThresh_H */ + 0x0F12141D, /*70000ADC//_bnr_iDenThreshLow */ + 0x0F126024, /*70000ADE//_ee_iLowSharpPower */ + 0x0F121217, /*70000AE0//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000AE2//_ee_iLowSharpClamp */ + 0x0F120808, /*70000AE4//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000AE6//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000AE8//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000AEA//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000AEC//_bnr_iDenThreshHigh_Bin */ + 0x0F121660, /*70000AEE//_ee_iHighSharpPower_Bin */ + 0x0F12FF10, /*70000AF0//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000AF2//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000AF4//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000AF6//_bnr_nClustLevel_C */ + 0x0F120000, /*70000AF8//_BRIGHTNESS AFIT 2 */ + 0x0F120000, /*70000AFA//_CONTRAST */ + 0x0F120000, /*70000AFC//_SATURATION */ + 0x0F120000, /*70000AFE//_SHARP_BLUR */ + 0x0F120000, /*70000B00//_GLAMOUR */ + 0x0F1200C0, /*70000B02//_bnr_edge_high */ + 0x0F120064, /*70000B04//_postdmsc_iLowBright */ + 0x0F120384, /*70000B06//_postdmsc_iHighBright */ + 0x0F120043, /*70000B08//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000B0A//_postdmsc_iHighSat */ + 0x0F120070, /*70000B0C//_postdmsc_iTune */ + 0x0F120040, /*70000B0E//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000B10//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000B12//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000B14//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000B16//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000B18//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000B1A//_bnr_edge_low */ + 0x0F120201, /*70000B1C//_bnr_repl_force */ + 0x0F120204, /*70000B1E//_bnr_iHotThreshLow */ + 0x0F121B04, /*70000B20//_bnr_iColdThreshLow */ + 0x0F120312, /*70000B22//_bnr_DispTH_High */ + 0x0F120003, /*70000B24//_bnr_DISP_Limit_High */ + 0x0F120C03, /*70000B26//_bnr_iDistSigmaMax */ + 0x0F122806, /*70000B28//_bnr_iDiffSigmaHigh */ + 0x0F120060, /*70000B2A//_bnr_iNormalizedSTD_Limit */ + 0x0F121580, /*70000B2C//_bnr_iDirMinThres */ + 0x0F122020, /*70000B2E//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*70000B30//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000B32//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000B34//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000B36//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000B38//_bnr_AddNoisePower1 */ + 0x0F120300, /*70000B3A//_bnr_iRadialTune */ + 0x0F12145A, /*70000B3C//_bnr_iRadialLimit */ + 0x0F121010, /*70000B3E//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000B40//_ee_iFSVarThHigh */ + 0x0F120E00, /*70000B42//_ee_iFSThHigh */ + 0x0F125A0F, /*70000B44//_ee_iFSVarCountTh */ + 0x0F120504, /*70000B46//_ee_iRadialPower */ + 0x0F121802, /*70000B48//_ee_iROADThres */ + 0x0F120000, /*70000B4A//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000B4C//_ee_iROADNeiThres */ + 0x0F123828, /*70000B4E//_ee_iSmoothEdgeThres */ + 0x0F120428, /*70000B50//_ee_iWSharpen */ + 0x0F120101, /*70000B52//_ee_iWShThresh */ + 0x0F128000, /*70000B54//_ee_iEmbossCentAdd */ + 0x0F120A04, /*70000B56//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000B58//_dmsc_iDesatThresh */ + 0x0F120540, /*70000B5A//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000B5C//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000B5E//_dmsc_iMonochrom */ + 0x0F120000, /*70000B60//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000B62//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000B64//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000B66//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000B68//_postdmsc_iWideMult */ + 0x0F120607, /*70000B6A//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000B6C//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000B6E//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000B70//_yuvemix_mPosSlopes_3 */ + 0x0F120207, /*70000B72//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000B74//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000B76//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*70000B78//_yuviirnr_iUVNormShift */ + 0x0F120407, /*70000B7A//_yuviirnr_iVertLength_UV */ + 0x0F122404, /*70000B7C//_yuviirnr_iDiffThreshH_Y */ + 0x0F120221, /*70000B7E//_yuviirnr_iDiffThreshH_UV */ + 0x0F121202, /*70000B80//_yuviirnr_iMaxThreshH_Y */ + 0x0F120613, /*70000B82//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000B84//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000B86//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000B88//_RGBGamma2_iLinearity */ + 0x0F120080, /*70000B8A//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000B8C//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000B8E//_bnr_iClustMulT_H */ + 0x0F120101, /*70000B90//_bnr_iClustThresh_H */ + 0x0F12121B, /*70000B92//_bnr_iDenThreshLow */ + 0x0F126024, /*70000B94//_ee_iLowSharpPower */ + 0x0F120C0C, /*70000B96//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000B98//_ee_iLowSharpClamp */ + 0x0F120808, /*70000B9A//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000B9C//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000B9E//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000BA0//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000BA2//_bnr_iDenThreshHigh_Bin */ + 0x0F120460, /*70000BA4//_ee_iHighSharpPower_Bin */ + 0x0F12FF04, /*70000BA6//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000BA8//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000BAA//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000BAC//_bnr_nClustLevel_C */ + 0x0F120000, /*70000BAE//_BRIGHTNESS AFIT 3 */ + 0x0F120000, /*70000BB0//_CONTRAST */ + 0x0F120000, /*70000BB2//_SATURATION */ + 0x0F120000, /*70000BB4//_SHARP_BLUR */ + 0x0F120000, /*70000BB6//_GLAMOUR */ + 0x0F1200C0, /*70000BB8//_bnr_edge_high */ + 0x0F120064, /*70000BBA//_postdmsc_iLowBright */ + 0x0F120384, /*70000BBC//_postdmsc_iHighBright */ + 0x0F120032, /*70000BBE//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000BC0//_postdmsc_iHighSat */ + 0x0F120070, /*70000BC2//_postdmsc_iTune */ + 0x0F120040, /*70000BC4//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000BC6//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000BC8//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000BCA//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000BCC//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000BCE//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000BD0//_bnr_edge_low */ + 0x0F120201, /*70000BD2//_bnr_repl_force */ + 0x0F120204, /*70000BD4//_bnr_iHotThreshLow */ + 0x0F121504, /*70000BD6//_bnr_iColdThreshLow */ + 0x0F12030F, /*70000BD8//_bnr_DispTH_High */ + 0x0F120003, /*70000BDA//_bnr_DISP_Limit_High */ + 0x0F120902, /*70000BDC//_bnr_iDistSigmaMax */ + 0x0F122004, /*70000BDE//_bnr_iDiffSigmaHigh */ + 0x0F120050, /*70000BE0//_bnr_iNormalizedSTD_Limit */ + 0x0F121140, /*70000BE2//_bnr_iDirMinThres */ + 0x0F12201C, /*70000BE4//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*70000BE6//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000BE8//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000BEA//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000BEC//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000BEE//_bnr_AddNoisePower1 */ + 0x0F120300, /*70000BF0//_bnr_iRadialTune */ + 0x0F12145A, /*70000BF2//_bnr_iRadialLimit */ + 0x0F121010, /*70000BF4//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000BF6//_ee_iFSVarThHigh */ + 0x0F121000, /*70000BF8//_ee_iFSThHigh */ + 0x0F125A0F, /*70000BFA//_ee_iFSVarCountTh */ + 0x0F120503, /*70000BFC//_ee_iRadialPower */ + 0x0F121802, /*70000BFE//_ee_iROADThres */ + 0x0F120000, /*70000C00//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000C02//_ee_iROADNeiThres */ + 0x0F123C28, /*70000C04//_ee_iSmoothEdgeThres */ + 0x0F12042C, /*70000C06//_ee_iWSharpen */ + 0x0F120101, /*70000C08//_ee_iWShThresh */ + 0x0F12FF00, /*70000C0A//_ee_iEmbossCentAdd */ + 0x0F120904, /*70000C0C//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000C0E//_dmsc_iDesatThresh */ + 0x0F120540, /*70000C10//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000C12//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000C14//_dmsc_iMonochrom */ + 0x0F120000, /*70000C16//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000C18//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000C1A//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000C1C//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000C1E//_postdmsc_iWideMult */ + 0x0F120607, /*70000C20//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000C22//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000C24//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000C26//_yuvemix_mPosSlopes_3 */ + 0x0F120206, /*70000C28//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000C2A//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000C2C//_yuviirnr_iHighUVNorm */ + 0x0F120305, /*70000C2E//_yuviirnr_iUVNormShift */ + 0x0F120406, /*70000C30//_yuviirnr_iVertLength_UV */ + 0x0F122804, /*70000C32//_yuviirnr_iDiffThreshH_Y */ + 0x0F120228, /*70000C34//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*70000C36//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*70000C38//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000C3A//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000C3C//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000C3E//_RGBGamma2_iLinearity */ + 0x0F120080, /*70000C40//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000C42//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000C44//_bnr_iClustMulT_H */ + 0x0F120101, /*70000C46//_bnr_iClustThresh_H */ + 0x0F120F15, /*70000C48//_bnr_iDenThreshLow */ + 0x0F126024, /*70000C4A//_ee_iLowSharpPower */ + 0x0F120A0A, /*70000C4C//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000C4E//_ee_iLowSharpClamp */ + 0x0F120808, /*70000C50//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000C52//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000C54//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000C56//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000C58//_bnr_iDenThreshHigh_Bin */ + 0x0F120260, /*70000C5A//_ee_iHighSharpPower_Bin */ + 0x0F12FF02, /*70000C5C//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000C5E//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000C60//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000C62//_bnr_nClustLevel_C */ + 0x0F120000, /*70000C64//_BRIGHTNESS AFIT 4 */ + 0x0F120000, /*70000C66//_CONTRAST */ + 0x0F120000, /*70000C68//_SATURATION */ + 0x0F120000, /*70000C6A//_SHARP_BLUR */ + 0x0F120000, /*70000C6C//_GLAMOUR */ + 0x0F1200C0, /*70000C6E//_bnr_edge_high */ + 0x0F120064, /*70000C70//_postdmsc_iLowBright */ + 0x0F120384, /*70000C72//_postdmsc_iHighBright */ + 0x0F120032, /*70000C74//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000C76//_postdmsc_iHighSat */ + 0x0F120070, /*70000C78//_postdmsc_iTune */ + 0x0F120040, /*70000C7A//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000C7C//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000C7E//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000C80//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000C82//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000C84//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000C86//_bnr_edge_low */ + 0x0F120201, /*70000C88//_bnr_repl_force */ + 0x0F120204, /*70000C8A//_bnr_iHotThreshLow */ + 0x0F120F04, /*70000C8C//_bnr_iColdThreshLow */ + 0x0F12030C, /*70000C8E//_bnr_DispTH_High */ + 0x0F120003, /*70000C90//_bnr_DISP_Limit_High */ + 0x0F120602, /*70000C92//_bnr_iDistSigmaMax */ + 0x0F121803, /*70000C94//_bnr_iDiffSigmaHigh */ + 0x0F120040, /*70000C96//_bnr_iNormalizedSTD_Limit */ + 0x0F120E20, /*70000C98//_bnr_iDirMinThres */ + 0x0F122018, /*70000C9A//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*70000C9C//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000C9E//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000CA0//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000CA2//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000CA4//_bnr_AddNoisePower1 */ + 0x0F120200, /*70000CA6//_bnr_iRadialTune */ + 0x0F12145A, /*70000CA8//_bnr_iRadialLimit */ + 0x0F121010, /*70000CAA//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000CAC//_ee_iFSVarThHigh */ + 0x0F121200, /*70000CAE//_ee_iFSThHigh */ + 0x0F125A0F, /*70000CB0//_ee_iFSVarCountTh */ + 0x0F120502, /*70000CB2//_ee_iRadialPower */ + 0x0F121802, /*70000CB4//_ee_iROADThres */ + 0x0F120000, /*70000CB6//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000CB8//_ee_iROADNeiThres */ + 0x0F124028, /*70000CBA//_ee_iSmoothEdgeThres */ + 0x0F120430, /*70000CBC//_ee_iWSharpen */ + 0x0F120101, /*70000CBE//_ee_iWShThresh */ + 0x0F12FF00, /*70000CC0//_ee_iEmbossCentAdd */ + 0x0F120804, /*70000CC2//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000CC4//_dmsc_iDesatThresh */ + 0x0F120540, /*70000CC6//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000CC8//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000CCA//_dmsc_iMonochrom */ + 0x0F120000, /*70000CCC//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000CCE//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000CD0//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000CD2//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000CD4//_postdmsc_iWideMult */ + 0x0F120607, /*70000CD6//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000CD8//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000CDA//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000CDC//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*70000CDE//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000CE0//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000CE2//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*70000CE4//_yuviirnr_iUVNormShift */ + 0x0F120407, /*70000CE6//_yuviirnr_iVertLength_UV */ + 0x0F122C04, /*70000CE8//_yuviirnr_iDiffThreshH_Y */ + 0x0F12022C, /*70000CEA//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*70000CEC//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*70000CEE//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000CF0//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000CF2//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000CF4//_RGBGamma2_iLinearity */ + 0x0F120080, /*70000CF6//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000CF8//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000CFA//_bnr_iClustMulT_H */ + 0x0F120101, /*70000CFC//_bnr_iClustThresh_H */ + 0x0F120C0F, /*70000CFE//_bnr_iDenThreshLow */ + 0x0F126024, /*70000D00//_ee_iLowSharpPower */ + 0x0F120808, /*70000D02//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000D04//_ee_iLowSharpClamp */ + 0x0F120808, /*70000D06//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000D08//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000D0A//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000D0C//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000D0E//_bnr_iDenThreshHigh_Bin */ + 0x0F120060, /*70000D10//_ee_iHighSharpPower_Bin */ + 0x0F12FF00, /*70000D12//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000D14//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000D16//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000D18//_bnr_nClustLevel_C */ + + 0x0F1223CE, /*70000D1A//[0]CAFITB_bnr_bypass */ + 0x0F12FDC8, /*70000D1C//[0]CAFITB_bnr_bSlopenessTune */ + 0x0F12112E, /*70000D1E//[0]CAFITB_ee_bReduceNegMedSh */ + 0x0F1293A5, /*70000D20//[0]CAFITB_dmsc_bDoDesat */ + 0x0F12FE67, /*70000D22//[0]CAFITB_postdmsc_bSat */ + 0x0F120000, /*70000D24//[0]CAFITB_yuviirnr_bWideY */ + +/*======================================================= +// 06.Clock Setting +//=======================================================*/ +/*Input Clock (Mclk)*/ + 0x002A01F8, + 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs */ + 0x002A0212, + 0x0F120000, /*REG_TC_IPRM_UseNPviClocks */ + 0x0F120002, /*REG_TC_IPRM_UseNMipiClocks */ + 0x0F120002, /*REG_TC_IPRM_NumberOfMipiLanes */ + +/*System Clock & Output clock (Pclk)*/ + + 0x002A021A, + 0x0F123A98, /*REG_TC_IPRM_OpClk4KHz_0 */ + 0x0F12278D, /*4F1A //REG_TC_IPRM_MinOutRate4KHz_0 */ + 0x0F12278D, /*4F1A //REG_TC_IPRM_MaxOutRate4KHz_0 */ + + 0x0F124F1A, /*REG_TC_IPRM_OpClk4KHz_11 */ + 0x0F12278D, /*4F1A //REG_TC_IPRM_MinOutRate4KHz_1 */ + 0x0F12278D, /*4F1A //REG_TC_IPRM_MaxOutRate4KHz_1 */ + + 0x002A022C, + 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated */ + +/*============================================================= +// 18.JPEG Thumnail Setting +//=============================================================*/ + + 0x002A0478, + 0x0F12005F, /*REG_TC_BRC_usPrevQuality */ + 0x0F12005F, /*REG_TC_BRC_usCaptureQuality */ + +/*JPEG Thumnail*/ + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight */ + 0x0F120005, /*REG_TC_THUMB_Thumb_Format */ + + 0x002A17DC, + 0x0F120054, /*jpeg_ManualMBCV */ + 0x002A1AE4, + 0x0F12001C, /*senHal_bExtraAddLine */ + 0x002A0284, + 0x0F120001, /*REG_TC_GP_bBypassScalerJpg */ + 0x002A028A, + 0x0F120000, /*REG_TC_GP_bUse1FrameCaptureMode */ + + 0x002A1CC2, /*DRx_uDRxWeight for AutoCont function */ + 0x0F120100, + 0x0F120100, + 0x0F120100, + 0x0F120100, + 0x002A147C, /*bp_uMaxBrightnessFactor*/ + 0x0F120170, + 0x002A1482, /*bp_uMinBrightnessFactor */ + 0x0F1201E0, + +/*======================================================= +// 07.Input Size Setting +//======================================================*/ +/*Input Size*/ + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth */ + 0x0F120780, /*REG_TC_GP_PrevReqInputHeight */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs */ + 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs */ + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs */ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth */ + 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + +/*=========================================================== +// 08.Preview & Capture Configration Setting +//=======================================================*/ +/*Preview config[0] 640 480 10~30fps*/ + 0x002A02A6, + 0x0F120280, /*REG_0TC_PCFG_usWidth */ + 0x0F1201E0, /*REG_0TC_PCFG_usHeight */ + 0x0F120005, /*REG_0TC_PCFG_Format */ + 0x0F12278D, /*4F1A //REG_0TC_PCFG_usMaxOut4KHzRate */ + 0x0F12278D, /*4F1A //REG_0TC_PCFG_usMinOut4KHzRate */ + 0x0F120100, /*REG_0TC_PCFG_OutClkPerPix88 */ + 0x0F120300, /*REG_0TC_PCFG_uBpp88 */ + 0x0F120012, /*REG_0TC_PCFG_PVIMask */ + 0x0F120000, /*REG_0TC_PCFG_OIFMask */ + 0x0F1201E0, /*REG_0TC_PCFG_usJpegPacketSize */ + 0x0F120000, /*REG_0TC_PCFG_usJpegTotalPackets */ + 0x0F120000, /*REG_0TC_PCFG_uClockInd */ + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F1203E8, /*029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 */ + 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 */ + 0x002A02D0, + 0x0F120000, /*REG_0TC_PCFG_uPrevMirror 0711 0000->000A */ + 0x0F120000, /*REG_0TC_PCFG_uCaptureMirror 0711 0000->000A */ + +/*Capture Config[0] 2560 1920 7.5~15fps*/ + 0x002A0396, + 0x0F120000, /*REG_0TC_CCFG_uCaptureMode */ + 0x0F120A00, /*REG_0TC_CCFG_usWidth */ + 0x0F120780, /*REG_0TC_CCFG_usHeight */ + 0x0F120009, /*REG_0TC_CCFG_Format */ + 0x0F12278D, /*4F1A //REG_0TC_CCFG_usMaxOut4KHzRate */ + 0x0F12278D, /*4F1A //REG_0TC_CCFG_usMinOut4KHzRate */ + 0x0F120100, /*REG_0TC_CCFG_OutClkPerPix88 */ + 0x0F120300, /*REG_0TC_CCFG_uBpp88 */ + 0x0F120012, /*REG_0TC_CCFG_PVIMask */ + 0x0F120040, /*REG_0TC_CCFG_OIFMask */ + 0x0F120810, /*REG_0TC_CCFG_usJpegPacketSize */ + 0x0F120000, /*REG_0TC_CCFG_usJpegTotalPackets */ + 0x0F120001, /*REG_0TC_CCFG_uClockInd */ + 0x0F120000, /*REG_0TC_CCFG_usFrTimeType */ + 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType */ + 0x0F120535, /*REG_0TC_CCFG_usMaxFrTimeMsecMult10 */ + 0x0F12029A, /*REG_0TC_CCFG_usMinFrTimeMsecMult10 */ + +/* Delay 100ms*/ + +/*=========================================================== +// 19.Select Cofigration Display +//===========================================================*/ + /*PREVIEW*/ + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + 0x002A023E, + 0x0F120001, /*REG_TC_GP_EnablePreview */ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */ + + 0x00287000, + 0x002A0484, + 0x0F120002, /* capture flash on */ + + 0x002A183A, + 0x0F120001, /* one frame AE */ + + 0x002A17F6, + 0x0F12023C, /*210, 258 // AWB R point */ + 0x0F12020C, /*288, 228 ->258 -> 208 // AWB B point */ + + 0x002A1840, + 0x0F120001, /* Fls AE tune start */ + + 0x0F120100, /* fls_afl_FlsAFIn Rin */ + 0x0F120120, + 0x0F120180, + 0x0F120200, + 0x0F120400, + 0x0F120800, + 0x0F120A00, + 0x0F121000, + + 0x0F120100, /* fls_afl_FlsAFOut Rout */ + 0x0F1200A0, + 0x0F120090, + 0x0F120080, + 0x0F120070, + 0x0F120045, + 0x0F120030, + 0x0F120010, + + 0x002A1884, + 0x0F120100, /* fls_afl_FlsNBOut flash NB default */ + 0x0F120100, + 0x0F120100, + 0x0F120100, + 0x0F120100, + 0x0F120100, + 0x0F120100, + 0x0F120100, + + 0x002A1826, + + 0x0F120100, /* fls_afl_FlashWP_Weight flash NB default */ + 0x0F1200C0, + 0x0F120080, + 0x0F12000A, + 0x0F120000, + + 0x0F120030, /* fls_afl_FlashWP_Weight flash NB default */ + 0x0F120040, + 0x0F120048, + 0x0F120050, + 0x0F120060, + + 0x002A4784, + 0x0F1200A0, /*TNP_Regs_FlsWeightRIn weight tune start in */ + 0x0F1200C0, + 0x0F1200D0, + 0x0F120100, + 0x0F120200, + 0x0F120300, + + 0x0F120088, /* TNP_Regs_FlsWeightROut weight tune start out */ + 0x0F1200B0, + 0x0F1200C0, + 0x0F120100, + 0x0F120200, + 0x0F120300, + + 0x002A479C, + + 0x0F120120, /*Fls BRIn */ + 0x0F120150, + 0x0F120200, + + 0x0F12003C, /* Fls BROut */ + 0x0F12003B, + 0x0F120026, /*brightness // 23 //26 //30 */ +}; + +static const u32 s5k4ecgx_DTP_init_EVT1[] = { +/*Delay 500ms*/ + 0xFCFCD000, + 0x00287000, + 0x002A0944, + 0x0F12FFF0, /*af_uNoise_0_*/ + 0x0F12FFF1, /*afit_uNoiseIndInDoor_1_ */ + 0x0F12FFF2, /*afit_uNoiseIndInDoor_2_ */ + 0x0F12FFF3, /*afit_uNoiseIndInDoor_3_ */ + 0x0F12FFF4, /*afit_uNoiseIndInDoor_4_ */ + 0x002A0938, + 0x0F120000, /*afit_bUseNB_Afit */ + 0x0F12FFF0, /*SARR_uNormBrInDoor_0_ */ + 0x0F12FFF1, /*SARR_uNormBrInDoor_1_ */ + 0x0F12FFF2, /*SARR_uNormBrInDoor_2_ */ + 0x0F12FFF3, /*SARR_uNormBrInDoor_3_ */ + 0x0F12FFF4, /*SARR_uNormBrInDoor_4_ */ + 0x00287000, + 0x002A04A6, + 0x0F120001, + 0x002A04AA, + 0x0F120001, + 0x0028D000, + 0x002A4200, + 0x0F1208A3, /*GAS bypass */ + 0x002A6600, + 0x0F120001, /*CCM bypass */ + 0x002A6700, + 0x0F120001, /*Gamma bypass */ + 0x002A4900, + 0x0F120001, /*AWB bypass */ + +/*Delay 50ms*/ + 0x0028D000, + 0x002A3100, + 0x0F120002, /*Colorbar pattern */ + +}; + +static const u32 s5k4ecgx_DTP_stop_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0944, + 0x0F12004B, /*afit_uNoiser0*/ + 0x0F120092, /*afit_uNoiseIndInDoor_1_ */ + 0x0F120196, /*afit_uNoiseIndInDoor_2_ */ + 0x0F120217, /*afit_uNoiseIndInDoor_3_ */ + 0x0F1202B0, /*afit_uNoiseIndInDoor_4_ */ + + /* Normal Brightness setting */ + 0x002A0938, + 0x0F120000, /*afit_bUseNB_Afit */ + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120384, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x00287000, + 0x002A04A6, + 0x0F120000, + 0x002A04AA, + 0x0F120001, + 0x0028D000, + 0x002A4200, + 0x0F1208A2, /*GAS bypass */ + 0x002A6600, + 0x0F120000, /*CCM bypass */ + 0x002A6700, + 0x0F120000, /*Gamma bypass */ + 0x002A4900, + 0x0F120000, /*AWB bypass */ + 0xFFFE0032, /*p50 */ + 0x0028D000, + 0x002A3100, + 0x0F120000, /*Colorbar pattern */ + +}; + +static const u32 s5k4ecgx_FPS_Auto_EVT1[] = { +/* frame rate 10~30fps*/ + 0xFCFCD000, + 0x00287000, + 0x002A02BE, + 0x0F120000, /*usFrTimeType*/ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F1203E8, /*029A/REG_0TC_PCFG_usMaxFrTimeMsecMult10 029Ah:15fps*/ + 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps*/ + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ +}; + +static const u32 s5k4ecgx_FPS_5_EVT1[] = { + +}; + +static const u32 s5k4ecgx_FPS_7_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType*/ + 0x0F120535, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //0535h:7.5fps */ + 0x0F120535, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //0535h:7.5fps */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_FPS_10_EVT1[] = { + +}; + +static const u32 s5k4ecgx_FPS_15_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F12029A, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //029Ah:15fps */ + 0x0F12029A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //029Ah:15fps */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_FPS_20_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F1201F4, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //01F4h:20fps */ + 0x0F1201F4, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //01F4h:20fps */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ +}; + +static const u32 s5k4ecgx_FPS_24_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A02B4, + 0x0F120052, + 0x002A02BE, + 0x0F120000, + 0x0F120001, + 0x0F1201A1, + 0x0F1201A1, + 0x002A02D0, + 0x0F120000, + 0x0F120000, + 0x002A0266, + 0x0F120000, + 0x002A026A, + 0x0F120001, + 0x002A024E, + 0x0F120001, + 0x002A0268, + 0x0F120001, +}; + +static const u32 s5k4ecgx_FPS_25_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F120190, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //014Ah:30fps */ + 0x0F120190, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ +}; + + +static const u32 s5k4ecgx_FPS_30_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F12014A, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //014Ah:30fps */ + 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_FPS_60_EVT1[] = { + +}; + +static const u32 s5k4ecgx_FPS_120_EVT1[] = { + +}; + +static const u32 s5k4ecgx_Effect_Normal_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A023C, + 0x0F120000, +}; + +static const u32 s5k4ecgx_Effect_Solarization_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A023C, + 0x0F120002, +}; + +static const u32 s5k4ecgx_Effect_Negative_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A023C, + 0x0F120003, +}; + +static const u32 s5k4ecgx_Effect_Sepia_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A023C, + 0x0F120004, +}; + +static const u32 s5k4ecgx_Effect_Black_White_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A023C, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Auto_EVT1[] = { + 0xFCFCD000, + 0x00287000, +}; + +static const u32 s5k4ecgx_WB_Sunny_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04BA, + 0x0F1205C0, + + 0x002A04BE, + 0x0F1203D0, + + 0x002A04C2, + 0x0F120550, + + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Cloudy_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04BA, + 0x0F1206D8, + + 0x002A04BE, + 0x0F1203D0, + + 0x002A04C2, + 0x0F1204B0, + + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Tungsten_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04BA, + 0x0F1203B0, + + 0x002A04BE, + 0x0F1203D0, + + 0x002A04C2, + 0x0F1209B0, + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Fluorescent_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04BA, + 0x0F1205E0, + + 0x002A04BE, + 0x0F120440, + + 0x002A04C2, + 0x0F120998, + + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Auto_ISO_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002a04E6, + 0x0f12075F, +}; + +static const u32 s5k4ecgx_WB_Sunny_ISO_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0f120757, + 0x002A04BA, + 0x0F1205C0, + + 0x002A04BE, + 0x0F1203D0, + + 0x002A04C2, + 0x0F120580, + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Cloudy_ISO_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0f120757, + 0x002A04BA, + 0x0F1206E0, + + 0x002A04BE, + 0x0F1203D0, + + 0x002A04C2, + 0x0F1204B0, + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Tungsten_ISO_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0f120757, + 0x002A04BA, + 0x0F1203B0, + + 0x002A04BE, + 0x0F1203D0, + + 0x002A04C2, + 0x0F1209F0, + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WB_Fluorescent_ISO_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0f120757, + 0x002A04BA, + 0x0F120600, + + 0x002A04BE, + 0x0F120440, + + 0x002A04C2, + 0x0F1209E0, + 0x002A04C6, + 0x0F120001, +}; + +static const u32 s5k4ecgx_WDR_on_EVT1[] = { + +}; + +static const u32 s5k4ecgx_WDR_off_EVT1[] = { + +}; + +static const u32 s5k4ecgx_ISO_Auto_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, /*afit_bUseNB_Afit */ + 0x0F120000, + 0x0F120014, /*SARR_uNormBrInDoor_0_*/ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120384, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F12003C, + 0x002A0F2A, /*AFC_Default60Hz */ + 0x0F120000, /*00:50Hz 01:60Hz */ + 0x002A04D0, + 0x0F120000, /*REG_SF_USER_IsoType */ + 0x0F120000, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120200, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_50_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120384, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType*/ + 0x0F120100, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_100_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120384, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F120044, + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F12018A, /*REG_SF_USER_IsoVal/1BA/1CA:16.9msec/1AA: 17.8msec */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_200_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120114, /*SARR_uNormBrInDoor_0_ */ + 0x0F1204A2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120584, /*SARR_uNormBrInDoor_2_ */ + 0x0F1208D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F120044, + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120300, /*REG_SF_IsoVal/36A/370:8.9msec/360:8.8msec/400:7.5msec*/ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ + +}; + +static const u32 s5k4ecgx_ISO_400_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120214, /*SARR_uNormBrInDoor_0_ */ + 0x0F120BD2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120C84, /*SARR_uNormBrInDoor_2_ */ + 0x0F1210D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F120044, + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120764, /*REGSFUSER_IsoVal/6F4*/ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_Auto_MWB_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, /*afit_bUseNB_Afit */ + 0x0F120000, + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120384, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F12003C, + 0x002A0F2A, /*AFC_Default60Hz */ + 0x0F120000, /*00:50Hz 01:60Hz */ + 0x002A04E6, /*REG_TC_DBG_AutoAlgEnBits */ + 0x0F120777, + 0x002A04D0, + 0x0F120000, /*REG_SF_USER_IsoType */ + 0x0F120000, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120200, /*lt_bUseSecISODgain */ + +}; + +static const u32 s5k4ecgx_ISO_50_MWB_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit*/ + 0x0F120014, /*SARR_uNormBrInDoor_0_*/ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_*/ + 0x0F120384, /*SARR_uNormBrInDoor_2_*/ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_*/ + 0x0F121388, /*SARR_uNormBrInDoor_4_*/ + + 0x002A04E6, + 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */ + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120100, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_100_MWB_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120384, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F120044, + 0x002A04E6, + 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */ + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F12018A, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_200_MWB_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1203A2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120484, /*SARR_uNormBrInDoor_2_ */ + 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F120044, + 0x002A04E6, + 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */ + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120300, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_ISO_400_MWB_on_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + 0x0F120014, /*SARR_uNormBrInDoor_0_ */ + 0x0F1208D2, /*SARR_uNormBrInDoor_1_ */ + 0x0F120C84, /*SARR_uNormBrInDoor_2_ */ + 0x0F1210D0, /*SARR_uNormBrInDoor_3_ */ + 0x0F121388, /*SARR_uNormBrInDoor_4_ */ + 0x002A1484, + 0x0F120044, + 0x002A04E6, + 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */ + 0x002A04D6, + 0x0F120000, /*REG_SF_USER_FlickerQuant */ + 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120764, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120100, /*lt_bUseSecISODgain */ +}; + +static const u32 s5k4ecgx_Metering_Matrix_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1492, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + + 0x002A0268, /*REG_TC_GP_PrevConfigChanged */ + 0x0F120001, +}; + +static const u32 s5k4ecgx_Metering_Center_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1492, + 0x0F120100, + 0x0F120101, + 0x0F120101, + 0x0F120001, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + + 0x002A0268, /*REG_TC_GP_PrevConfigChanged */ + 0x0F120001, +}; + +static const u32 s5k4ecgx_Metering_Spot_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1492, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120101, + 0x0F120101, + 0x0F120000, + 0x0F120000, + 0x0F12010F, + 0x0F120F01, + 0x0F120000, + 0x0F120000, + 0x0F12010F, + 0x0F120F01, + 0x0F120000, + 0x0F120000, + 0x0F120101, + 0x0F120101, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + + 0x002A0268, /*REG_TC_GP_PrevConfigChanged */ + 0x0F120001, +}; + +static const u32 s5k4ecgx_EV_Minus_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120018, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Minus_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F12001E, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Minus_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120025, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Minus_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120030, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Default_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F12003C, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Plus_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F12004E, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Plus_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120060, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Plus_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120070, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_EV_Plus_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120080, /*TVAR_ae_BrAve */ +}; + +static const u32 s5k4ecgx_Contrast_Minus_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F12FF81, +}; + +static const u32 s5k4ecgx_Contrast_Minus_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F12FFA0, +}; + +static const u32 s5k4ecgx_Contrast_Minus_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F12FFC0, +}; + +static const u32 s5k4ecgx_Contrast_Minus_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F12FFE0, +}; + +static const u32 s5k4ecgx_Contrast_Default_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F120000, +}; + +static const u32 s5k4ecgx_Contrast_Plus_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F120020, +}; + +static const u32 s5k4ecgx_Contrast_Plus_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F120040, +}; + +static const u32 s5k4ecgx_Contrast_Plus_3_EVT1[] = {/*Setting Unavailable*/ + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F120060, +}; + +static const u32 s5k4ecgx_Contrast_Plus_4_EVT1[] = {/*Setting Unavailable*/ + 0xFCFCD000, + 0x00287000, + 0x002A0232, + 0x0F12007F, +}; + +static const u32 s5k4ecgx_Auto_Contrast_ON_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A098E, + 0x0F12FFB0, + + 0x002A0A44, + 0x0F12FFB0, + + 0x002A0AFA, + 0x0F12FFB0, + + 0x002A0BB0, + 0x0F12FFB0, + + 0x002A0C66, + 0x0F12FFB0, +}; + +static const u32 s5k4ecgx_Auto_Contrast_OFF_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A098E, + 0x0F120000, + + 0x002A0A44, + 0x0F120000, + + 0x002A0AFA, + 0x0F120000, + + 0x002A0BB0, + 0x0F120000, + + 0x002A0C66, + 0x0F120000, +}; + +static const u32 s5k4ecgx_Sharpness_Minus_3_EVT1[] = {/*Setting Unavailable*/ + 0x00287000, + 0x002A0A28, + 0x0F120000, + 0x002A0ADE, + 0x0F120000, + 0x002A0B94, + 0x0F120000, + 0x002A0C4A, + 0x0F120000, + 0x002A0D00, + 0x0F120000, +}; + +static const u32 s5k4ecgx_Sharpness_Minus_2_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F122010, + 0x002A0ADE, + 0x0F122010, + 0x002A0B94, + 0x0F122010, + 0x002A0C4A, + 0x0F122010, + 0x002A0D00, + 0x0F122010, +}; + +static const u32 s5k4ecgx_Sharpness_Minus_1_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F124020, + 0x002A0ADE, + 0x0F124020, + 0x002A0B94, + 0x0F124020, + 0x002A0C4A, + 0x0F124020, + 0x002A0D00, + 0x0F124020, +}; + +static const u32 s5k4ecgx_Sharpness_Default_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F126024, + 0x002A0ADE, + 0x0F126024, + 0x002A0B94, + 0x0F126024, + 0x002A0C4A, + 0x0F126024, + 0x002A0D00, + 0x0F126024, +}; + +static const u32 s5k4ecgx_Sharpness_Plus_1_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F128040, + 0x002A0ADE, + 0x0F128040, + 0x002A0B94, + 0x0F128040, + 0x002A0C4A, + 0x0F128040, + 0x002A0D00, + 0x0F128040, +}; + +static const u32 s5k4ecgx_Sharpness_Plus_2_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F12A060, + 0x002A0ADE, + 0x0F12A060, + 0x002A0B94, + 0x0F12A060, + 0x002A0C4A, + 0x0F12A060, + 0x002A0D00, + 0x0F12A060, +}; + +static const u32 s5k4ecgx_Sharpness_Plus_3_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F12C080, + 0x002A0ADE, + 0x0F12C080, + 0x002A0B94, + 0x0F12C080, + 0x002A0C4A, + 0x0F12C080, + 0x002A0D00, + 0x0F12C080, +}; + +static const u32 s5k4ecgx_Saturation_Minus_2_EVT1[] = { + 0x00287000, + 0x002A0234, + 0x0F12FF81, +}; + +static const u32 s5k4ecgx_Saturation_Minus_1_EVT1[] = { + 0x00287000, + 0x002A0234, + 0x0F12FFC0, +}; + +static const u32 s5k4ecgx_Saturation_Default_EVT1[] = { + 0x00287000, + 0x002A0234, + 0x0F120000, +}; + +static const u32 s5k4ecgx_Saturation_Plus_1_EVT1[] = { + 0x00287000, + 0x002A0234, + 0x0F120040, +}; + +static const u32 s5k4ecgx_Saturation_Plus_2_EVT1[] = { + 0x00287000, + 0x002A0234, + 0x0F12007F, +}; + +static const u32 s5k4ecgx_Jpeg_Quality_High_EVT1[] = { + 0x00287000, + 0x002A0478, + 0x0F12005F, + 0x0F12005F, +}; + +static const u32 s5k4ecgx_Jpeg_Quality_Normal_EVT1[] = { + 0x00287000, + 0x002A0478, + 0x0F12005A, + 0x0F12005A, +}; + +static const u32 s5k4ecgx_Jpeg_Quality_Low_EVT1[] = { + 0x00287000, + 0x002A0478, + 0x0F120054, + 0x0F120054, +}; + +static const u32 s5k4ecgx_Scene_Default_EVT1[] = { +/*scene Backlight landscape*/ + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F12003C, + 0x002A1492, + 0x0F120100, + 0x0F120101, + 0x0F120101, + 0x0F120001, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + +/* Sharpness 0*/ + 0x002A0A28, + 0x0F126024, /*_ee_iLowSharpPower*/ + 0x002A0ADE, + 0x0F126024, /*_ee_iLowSharpPower*/ + 0x002A0B94, + 0x0F126024, /*_ee_iLowSharpPower*/ + 0x002A0C4A, + 0x0F126024, /*_ee_iLowSharpPower*/ + 0x002A0D00, + 0x0F126024, /*_ee_iLowSharpPower*/ + +/* Saturation 0*/ + 0x002A0234, + 0x0F120000, /*REG_TC_UserSaturation */ + 0x002A06B8, + 0x0F12452C, + 0x0F120005, /*lt_uMaxLei */ + + 0x002A0A1E, + 0x0F120350,/*_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset*/ + + 0x002A0638, + 0x0F120001, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ */ + 0x0F120A3C, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */ + 0x0F120D05, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */ + 0x0F126810, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */ + 0x0F128214, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */ + 0x0F12C350, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */ + 0x0F12C350, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */ + 0x0F12C350, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */ + + 0x002A02C2, + 0x0F12029A,/*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //029Ah:15fps */ + 0x0F12014A,/*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */ + 0x002A03B4, + 0x0F120535,/*REG_0TC_CCFG_usMaxFrTimeMsecMult10 //0535h:7.5fps */ + 0x0F12029A,/*REG_0TC_CCFG_usMinFrTimeMsecMult10 //029Ah:15fps */ + + 0x002A0938, + 0x0F120000, /*afit_bUseNB_Afit */ + + 0x002A04E6, + 0x0F12077F, /*REG_TC_DBG_AutoAlgEnBits */ + + 0x002A04D0, + 0x0F120000, /*REG_SF_USER_IsoType */ + 0x0F120000, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + + 0x002A06C2, + 0x0F120200, /*lt_bUseSecISODgain */ + + 0x002A1648, + 0x0F129002, /*af_search_usSingleAfFlags */ + + 0x002A15E8, + 0x0F120015, /*af_pos_usTableLastInd */ + 0x0F120027, /*af_pos_usTable_0_ */ + 0x0F120030, /*af_pos_usTable_1_ */ + 0x0F120036, /*af_pos_usTable_2_ */ + 0x0F12003C, /*af_pos_usTable_3_ */ + 0x0F120042, /*af_pos_usTable_4_ */ + 0x0F120048, /*af_pos_usTable_5_ */ + 0x0F12004E, /*af_pos_usTable_6_ */ + 0x0F120054, /*af_pos_usTable_7_ */ + 0x0F12005A, /*af_pos_usTable_8_ */ + 0x0F120060, /*af_pos_usTable_9_ */ + 0x0F120066, /*af_pos_usTable_10 */ + 0x0F12006C, /*af_pos_usTable_11_ */ + 0x0F120072, /*af_pos_usTable_12_ */ + 0x0F120078, /*af_pos_usTable_13_ */ + 0x0F12007E, /*af_pos_usTable_14_ */ + 0x0F120084, /*af_pos_usTable_15_ */ + 0x0F12008A, /*af_pos_usTable_16_ */ + 0x0F120090, /*af_pos_usTable_17_ */ + 0x0F120096, /*af_pos_usTable_18_ */ + 0x0F12009C, /*af_pos_usTable_19_ */ + 0x0F1200A2, /*af_pos_usTable_20_ */ + 0x0F1200A8, /*af_pos_usTable_21_ */ + 0x0F1200AE, /*af_pos_usTable_22_ */ + 0x0F1200B4, /*af_pos_usTable_23_ */ + 0x0F1200BA, /*af_pos_usTable_24_ */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + 0x002A023E, + 0x0F120001, /*REG_TC_GP_EnablePreview */ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */ + +}; + +static const u32 s5k4ecgx_Scene_Portrait_EVT1[] = { + 0x00287000, + 0x002A0A28, + 0x0F124020, + 0x002A0ADE, + 0x0F124020, + 0x002A0B94, + 0x0F124020, + 0x002A0C4A, + 0x0F124020, + 0x002A0D00, + 0x0F124020, +}; + +static const u32 s5k4ecgx_Scene_Nightshot_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A06B8, + 0x0F12FFFF, /*lt_uMaxLei */ + 0x0F1200FF, /*lt_usMinExp */ + + 0x002A0A1E, + 0x0F1215C0,/*_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset*/ + + 0x002A0638, + 0x0F120001, + 0x0F120000,/*ltExpGainExpCurveGainMaxStr_0_ulExpOut0*/ + 0x0F121478, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */ + 0x0F121A0A, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */ + 0x0F126810, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */ + 0x0F126810, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */ + 0x0F12D020, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */ + 0x0F120428, + 0x0F120001,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */ + 0x0F121A80, + 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */ + 0x0F121A80, + 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */ + 0x0F121A80, + 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */ + + 0x002A02C2, + 0x0F1209C4,/*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //09C4h:4fps */ + 0x0F12014A,/*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */ + 0x002A03B4, + 0x0F121388,/*REG_0TC_CCFG_usMaxFrTimeMsecMult10 //1388h:2fps */ + 0x0F121388,/*REG_0TC_CCFG_usMinFrTimeMsecMult10 //1388h:2fps */ + + 0x002A1648, /*af_search_usSingleAfFlags */ + 0x0F129000, + + 0x002A15E8, + 0x0F120006, /*af_pos_usTableLastInd */ + 0x0F120036, + 0x0F12003A, + 0x0F120040, + 0x0F120048, + 0x0F120050, + 0x0F120058, + 0x0F120060, + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + 0x002A023E, + 0x0F120001, /*REG_TC_GP_EnablePreview */ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */ + +}; + +static const u32 s5k4ecgx_Scene_Backlight_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1492, + 0x0F120000, /*ae_WeightTbl_16 */ + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120101, + 0x0F120101, + 0x0F120000, + 0x0F120000, + 0x0F12010F, + 0x0F120F01, + 0x0F120000, + 0x0F120000, + 0x0F12010F, + 0x0F120F01, + 0x0F120000, + 0x0F120000, + 0x0F120101, + 0x0F120101, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + 0x0F120000, + +}; + +static const u32 s5k4ecgx_Scene_Landscape_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1492, + 0x0F120101, /*ae_WeightTbl_16 */ + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + + 0x002A0A28, + 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0ADE, + 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0B94, + 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0C4A, + 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0D00, + 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + + 0x002A0234, + 0x0F120030, /*REG_TC_UserSaturation */ +}; + +static const u32 s5k4ecgx_Scene_Sports_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0638, + 0x0F120001, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ */ + 0x0F120A3C, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */ + 0x0F120D05, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */ + 0x0F123408, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */ + + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120200, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120150, /*lt_bUseSecISODgain */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + 0x002A023E, + 0x0F120001, /*REG_TC_GP_EnablePreview */ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */ + +}; + +static const u32 s5k4ecgx_Scene_Party_Indoor_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F120340, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120180, /*lt_bUseSecISODgain */ + + 0x002A0234, + 0x0F120030, /*REG_TC_UserSaturation */ +}; + +static const u32 s5k4ecgx_Scene_Beach_Snow_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1484, + 0x0F120045, /*TVAR_ae_BrAve */ + + 0x002A0938, + 0x0F120001, /*afit_bUseNB_Afit */ + + 0x002A04D0, + 0x0F120001, /*REG_SF_USER_IsoType */ + 0x0F1200D0, /*REG_SF_USER_IsoVal */ + 0x0F120001, /*REG_SF_USER_IsoChanged */ + 0x002A06C2, + 0x0F120150, /*lt_bUseSecISODgain */ + + 0x002A0234, + 0x0F120030, /*REG_TC_UserSaturation */ +}; + +static const u32 s5k4ecgx_Scene_Sunset_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0F120777, /*REG_TC_DBG_AutoAlgEnBits //AWB Off */ + + 0x002A04BA, + 0x0F1205F0, /*REG_SF_USER_Rgain */ + 0x002A04BE, + 0x0F120400, /*REG_SF_USER_Ggain */ + 0x002A04C2, + 0x0F120588, /*REG_SF_USER_Bgain */ + + 0x002A04C6, + 0x0F120001, /*REG_SF_USER_RGBGainChanged */ +}; + +static const u32 s5k4ecgx_Scene_Duskdawn_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0F120777, /*REG_TC_DBG_AutoAlgEnBits //AWB Off */ + + 0x002A04BA, + 0x0F1205A5, /*REG_SF_USER_Rgain */ + 0x002A04BE, + 0x0F120400, /*REG_SF_USER_Ggain */ + 0x002A04C2, + 0x0F1208A8, /*REG_SF_USER_Bgain */ + + 0x002A04C6, + 0x0F120001, /*REG_SF_USER_RGBGainChanged */ +}; + +static const u32 s5k4ecgx_Scene_Fall_Color_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0234, + 0x0F120060, +}; + +static const u32 s5k4ecgx_Scene_Fireworks_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0638, + 0x0F120001, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ */ + 0x0F121478, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */ + 0x0F121A0A, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */ + 0x0F126810, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */ + 0x0F126810, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */ + 0x0F12D020, + 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */ + 0x0F120428, + 0x0F120001,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */ + 0x0F121A80, + 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */ + 0x0F121A80, + 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */ + 0x0F121A80, + 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */ + + 0x002A03B4, + 0x0F122710,/*REG_0TC_CCFG_usMaxFrTimeMsecMult10 //2710h:1fps */ + 0x0F122710,/*REG_0TC_CCFG_usMinFrTimeMsecMult10 //2710h:1fps */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + 0x002A023E, + 0x0F120001, /*REG_TC_GP_EnablePreview */ + 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */ +}; + +static const u32 s5k4ecgx_Scene_Text_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0A28, + 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0ADE, + 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0B94, + 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0C4A, + 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ + 0x002A0D00, + 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/ +}; + +static const u32 s5k4ecgx_Scene_Candle_Light_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A04E6, + 0x0F120777, /*REG_TC_DBG_AutoAlgEnBits //AWB Off */ + + 0x002A04BA, + 0x0F1205F0, /*REG_SF_USER_Rgain */ + 0x002A04BE, + 0x0F120400, /*REG_SF_USER_Ggain */ + 0x002A04C2, + 0x0F120588, /*REG_SF_USER_Bgain */ + + 0x002A04C6, + 0x0F120001, /*REG_SF_USER_RGBGainChanged */ +}; + + /* AE Lock */ +static const u32 s5k4ecgx_ae_lock_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A2C5E, + 0x0F120000, +}; + + /* AE unLock */ +static const u32 s5k4ecgx_ae_unlock_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A2C5E, + 0x0F120001, +}; + + /* AWB Lock */ +static const u32 s5k4ecgx_awb_lock_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A2C66, + 0x0F120000, +}; + + /* AWB unLock */ +static const u32 s5k4ecgx_awb_unlock_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A2C66, + 0x0F120001, +}; + +static const u32 s5k4ecgx_Night_Mode_Off_EVT1[] = { + +}; + +static const u32 s5k4ecgx_AF_Return_Inf_pos_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A15D6, + 0x0F12D000, +}; + +static const u32 s5k4ecgx_AF_Return_Macro_pos_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A15E8, + 0x0F120018, + 0x0F12002A, + 0x0F120030, + 0x0F120036, + 0x0F12003C, + 0x0F120042, + 0x0F120048, + 0x0F12004E, + 0x0F120054, + 0x0F12005A, + 0x0F120060, + 0x0F120066, + 0x0F12006C, + 0x0F120072, + 0x0F120078, + 0x0F12007E, + 0x0F120084, + 0x0F12008A, + 0x0F120090, + 0x0F120096, + 0x0F12009C, + 0x0F1200A2, + 0x0F1200A8, + 0x0F1200AE, + 0x0F1200B4, + 0x0F1200BA, +}; + +static const u32 s5k4ecgx_AF_Normal_mode_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1648, + 0x0F129002, +}; + +static const u32 s5k4ecgx_AF_Normal_mode_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A028E, + 0x0F120000, +}; + +static const u32 s5k4ecgx_AF_Normal_mode_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A028C, + 0x0F120004, +}; + +static const u32 s5k4ecgx_AF_Normal_mode_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1648, + 0x0F129002, + + 0x002A15E8, + 0x0F120017, /*af_pos_usTableLastInd */ + 0x0F120026, + 0x0F12002C, + 0x0F120032, + 0x0F120038, + 0x0F12003E, + 0x0F120044, + 0x0F12004A, + 0x0F120050, + 0x0F120056, + 0x0F12005C, + 0x0F120062, + 0x0F120068, + 0x0F12006E, + 0x0F120074, + 0x0F12007A, + 0x0F120080, + 0x0F120086, + 0x0F12008C, + 0x0F120092, + 0x0F120098, + 0x0F12009E, + 0x0F1200A4, + 0x0F1200AA, + 0x0F1200B0, +}; + +static const u32 s5k4ecgx_AF_Macro_mode_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A028E, + 0x0F1200D0, +}; + +static const u32 s5k4ecgx_AF_Macro_mode_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A028C, + 0x0F120004, +}; + +static const u32 s5k4ecgx_AF_Macro_mode_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1648, + 0x0F129042, + + 0x002A15E8, + 0x0F120015, /*af_pos_usTableLastInd */ + 0x0F120032, + 0x0F120038, + 0x0F12003E, + 0x0F120044, + 0x0F12004A, + 0x0F120050, + 0x0F120056, + 0x0F12005C, + 0x0F120062, + 0x0F120068, + 0x0F12006E, + 0x0F120074, + 0x0F12007A, + 0x0F120080, + 0x0F120086, + 0x0F12008C, + 0x0F120092, + 0x0F120098, + 0x0F12009E, + 0x0F1200A4, + 0x0F1200AA, + 0x0F1200B0, + + 0x002A15DA, + 0x0F121500,/* 16 start number of table 00 End number of table */ +}; + +static const u32 s5k4ecgx_AF_Low_Light_normal_mode_1_EVT1[] = { + +}; + +static const u32 s5k4ecgx_AF_Low_Light_normal_mode_2_EVT1[] = { + +}; + +static const u32 s5k4ecgx_AF_Low_Light_normal_mode_3_EVT1[] = { + +}; + +static const u32 s5k4ecgx_AF_Low_Light_Macro_mode_1_EVT1[] = { + +}; + +static const u32 s5k4ecgx_AF_Low_Light_Macro_mode_2_EVT1[] = { + +}; + +static const u32 s5k4ecgx_AF_Low_Light_Macro_mode_3_EVT1[] = { + +}; + +static const u32 s5k4ecgx_Single_AF_Start_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A028C, + 0x0F120005, +}; + +static const u32 s5k4ecgx_Single_AF_Off_1_EVT1[] = { + +}; + +static const u32 s5k4ecgx_Single_AF_Off_2_EVT1[] = { + +}; + +static const u32 s5k4ecgx_Single_AF_Off_3_EVT1[] = { + +}; + +static const u32 s5k4ecgx_Face_Detection_On_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0294, + 0x0F120100, + 0x0F1200E3, + 0x0F120200, + 0x0F120238, + 0x0F1201C6, + 0x0F120166, + 0x0F120074, + 0x0F120132, + 0x0F120001, +}; + +static const u32 s5k4ecgx_Face_Detection_Off_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0294, + 0x0F120100, + 0x0F1200E3, + 0x0F120200, + 0x0F120238, + 0x0F1201C6, + 0x0F120166, + 0x0F120074, + 0x0F120132, + 0x0F120001, +}; + +static const u32 s5k4ecgx_Low_Cap_On_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A06B8, + 0x0F12552C, /*lt_uMaxLei */ + 0x0F120006, /*lt_usMinExp */ + + 0x002A0608, + 0x0F120001, /*lt_ExpGain_uSubsamplingmode */ + 0x0F120001, /*lt_ExpGain_uNonSubsampling */ + 0x0F120900, /*lt_ExpGain_ExpCurveGainMaxStr_0__uMaxAnGain */ + +}; + +static const u32 s5k4ecgx_Low_Cap_Off_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A06B8, + 0x0F12452C, /*lt_uMaxLei */ + 0x0F120005, /*lt_usMinExp // 0725 000C->0005 */ + + 0x002A0608, + 0x0F120001, /*lt_ExpGain_uSubsamplingmode */ + 0x0F120001, /*lt_ExpGain_uNonSubsampling */ + 0x0F120800, /*lt_ExpGain_ExpCurveGainMaxStr_0__uMaxAnGain */ + +}; + +static const u32 s5k4ecgx_Night_Mode_On_EVT1[] = { + +}; + +static const u32 s5k4ecgx_Capture_Start_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0242, + 0x0F120001, + 0x002A024E, + 0x0F120001, + 0x002A0244, + 0x0F120001, +}; + +static const u32 s5k4ecgx_Preview_Return_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A0242, + 0x0F120000, /*REG_TC_GP_EnableCapture*/ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync*/ + 0x002A0244, + 0x0F120001, /*REG_TC_GP_EnableCaptureChanged*/ + +}; + + /* Flash Control */ +static const u32 s5k4ecgx_Flash_init_EVT1[] = { +/* Include initial setting*/ +}; + +static const u32 s5k4ecgx_Pre_Flash_On_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A17FC, /* fls_FlashWP_0_Pre_Flash_Start*/ + 0x0F120001, +}; + +static const u32 s5k4ecgx_Pre_Flash_Off_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A1800, /*fls_afl_FlashWP_Weight_0_Pre_Flash_end*/ + 0x0F120001, +}; + +static const u32 s5k4ecgx_Main_Flash_On_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A17E8,/*fls_afl_FlashMode:Flash alg start*/ + 0x0F120001, + 0x002A180C,/*fls_afl_FlashWP_Weight_4:flash br avg*/ + 0x0F120027, +}; + +static const u32 s5k4ecgx_Main_Flash_Off_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A17E8, /*fls_afl_FlashMode Flash alg end*/ + 0x0F120000, +}; + +static const u32 s5k4ecgx_5M_Capture_EVT1[] = { /* 2560 x 1920 */ + 0xFCFCD000, + 0x00287000, + 0x002A0258, + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */ + + 0x002A0264, + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A049C, + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + + 0x002A047C, + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */ + + 0x002A0398, + 0x0F120A00, /*REG_0TC_CCFG_usWidth //2560 */ + 0x0F120780, /*REG_0TC_CCFG_usHeight //1920 */ + + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ +}; + +static const u32 s5k4ecgx_3M_Capture_EVT1[] = { /*2048 x 1536 */ + 0xFCFCD000, + 0x00287000, + 0x002A0258, + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */ + + 0x002A0264, + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A049C, + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + + 0x002A047C, + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */ + + 0x002A0398, + 0x0F120800, /*REG_0TC_CCFG_usWidth //2048 */ + 0x0F120600, /*REG_0TC_CCFG_usHeight //1536 */ + + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + +}; + +static const u32 s5k4ecgx_2M_Capture_EVT1[] = { /*1600 x 1200 */ + 0xFCFCD000, + 0x00287000, + 0x002A0258, + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */ + + 0x002A0264, + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A049C, + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + + 0x002A047C, + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */ + + 0x002A0398, + 0x0F120640, /*REG_0TC_CCFG_usWidth //1600 */ + 0x0F1204B0, /*REG_0TC_CCFG_usHeight //1200 */ + + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ +}; + +static const u32 s5k4ecgx_1M_Capture_EVT1[] = { /* 1280 x 960 */ + 0xFCFCD000, + 0x00287000, + 0x002A0258, + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */ + + 0x002A0264, + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A049C, + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + + 0x002A047C, + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */ + + 0x002A0398, + 0x0F120500, /*REG_0TC_CCFG_usWidth //1280 */ + 0x0F1203C0, /*REG_0TC_CCFG_usHeight //960 */ + + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ + +}; + + /* 1024 x 768 */ +static const u32 s5k4ecgx_XGA_Capture_EVT1[] = { +/* 0725 add*/ + 0xFCFCD000, + 0x00287000, + 0x002A0258, + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */ + + 0x002A0264, + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A049C, + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + + 0x002A047C, + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */ + + 0x002A0398, + 0x0F120400, /*REG_0TC_CCFG_usWidth //1024 */ + 0x0F120300, /*REG_0TC_CCFG_usHeight //768 */ + + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ +}; + +static const u32 s5k4ecgx_VGA_Capture_EVT1[] = { /* 640 x 480 */ + 0xFCFCD000, + 0x00287000, + 0x002A0258, + 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */ + + 0x002A0264, + 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */ + + 0x002A049C, + 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */ + + 0x002A047C, + 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */ + 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */ + 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */ + + 0x002A0398, + 0x0F120280, /*REG_0TC_CCFG_usWidth //640 */ + 0x0F1201E0, /*REG_0TC_CCFG_usHeight //480 */ + + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0270, + 0x0F120001, /*REG_TC_GP_CapConfigChanged */ +}; + +static const u32 s5k4ecgx_QVGA_Capture_EVT1[] = { /* 320 x 240 */ + +}; + +static const u32 s5k4ecgx_1280_Preview_EVT1[] = { /* 1280 x 720 */ + /*720P enable setting */ + 0xFCFCD000, + 0x00287000, + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1207DC, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + /* Size */ + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */ + 0x0F1205A0, /*REG_TC_GP_PrevReqInputHeight //1440 */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs //(2592-2560)/2 */ + 0x0F1200FC, /*REG_TC_GP_PrevInputHeightOfs //(1944-1440)/2*/ + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */ + 0x0F1205A0, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1440 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + 0x002A02A6, + 0x0F120500, /*REG_0TC_PCFG_usWidth //1280 */ + 0x0F1202D0, /*REG_0TC_PCFG_usHeight //720 */ + + /* Frame Rate */ + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F12014A,/*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //014Ah:30fps */ + 0x0F12014A,/*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */ + + /* AE Target */ + 0x002A1484, + 0x0F12002A, /*003C //TVAR_ae_BrAve */ + + /* AE Weight Matrix */ + 0x002A1492, + 0x0F120101, /*0100 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0001 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0201 */ + 0x0F120101, /*0102 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0202 */ + 0x0F120101, /*0202 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0201 */ + 0x0F120101, /*0302 */ + 0x0F120101, /*0203 */ + 0x0F120101, /*0102 */ + 0x0F120101, /*0201 */ + 0x0F120101, /*0302 */ + 0x0F120101, /*0203 */ + 0x0F120101, /*0102 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0202 */ + 0x0F120101, /*0202 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0201 */ + 0x0F120101, /*0102 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + 0x0F120101, /*0101 */ + + /* Slow AE */ + 0x002A1568, + 0x0F120030, /*0010 //ae_GainIn_0_ */ + 0x0F120090, /*0020 //ae_GainIn_1_ */ + 0x0F1200A8, /*0040 //ae_GainIn_2_ */ + 0x0F1200C0, /*0080 //ae_GainIn_3_ */ + 0x0F120100, /*0010 //ae_GainIn_4_ FIX */ + 0x0F120140, /*0200 //ae_GainIn_5_ */ + 0x0F120180, /*0400 //ae_GainIn_6_ */ + 0x0F120400, /*0800 //ae_GainIn_7_ */ + 0x0F122000, /*0800 //ae_GainIn_8_ */ + 0x0F120080, /*0010 //ae_GainOut_0_ */ + 0x0F1200D0, /*0020 //ae_GainOut_1_ */ + 0x0F1200D8, /*0040 //ae_GainOut_2_ */ + 0x0F1200F8, /*0080 //ae_GainOut_3_ */ + 0x0F120100, /*0100 //ae_GainOut_4_ FIX */ + 0x0F120103, /*0200 //ae_GainOut_5_ */ + 0x0F120110, /*0400 //ae_GainOut_6_ */ + 0x0F120150, /*0800 //ae_GainOut_7_ */ + 0x0F120400, /*2000 //ae_GainOut_8_*/ + 0x002A0544, + 0x0F120105, /*0111 //lt_uLimitHigh */ + 0x0F1200FA, /*00EF //lt_uLimitLow */ + 0x002A0588, + 0x0F120001, /*0000 //lt_uInitPostToleranceCnt */ + 0x002A0582, + 0x0F1200D0, /*0000 //lt_uSlowFilterCoef */ + + 0x002A0734, /*R*/ + 0x0F120000, + 0x0F120005, + 0x0F12000F, + 0x0F120026, + 0x0F120066, + 0x0F1200D5, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + + 0x0F120000, /*G*/ + 0x0F120005, + 0x0F12000F, + 0x0F120026, + 0x0F120066, + 0x0F1200D5, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + + 0x0F120000, /*B*/ + 0x0F120005, + 0x0F12000F, + 0x0F120026, + 0x0F120066, + 0x0F1200D5, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + + /* Slow AWB */ + 0x002A139A, + 0x0F120158, /*0258 //awbb_GainsMaxMove */ + + /* AWB Convergence Speed */ + 0x002A1464, + 0x0F120008, /*awbb_WpFilterMinThr */ + 0x0F12FFFF, /*0190 //awbb_WpFilterMaxThr */ + 0x0F120010, /*00A0 //awbb_WpFilterCoef */ + 0x0F120020, /*0004 //awbb_WpFilterSize */ + 0x002A0938, + 0x0F120001,/*0000 // on/off AFIT by NB option */ + 0x0F120014, /*0014//SARR_uNormBrInDoor */ + 0x0F1200D2, /*00D2//SARR_uNormBrInDoor */ + 0x0F120784, /*0384//SARR_uNormBrInDoor */ + 0x0F1210D0, /*07D0//SARR_uNormBrInDoor */ + 0x0F121388, /*1388//SARR_uNormBrInDoor */ + 0x002A098C, + 0x0F120000, /*0000//7000098C//_BRIGHTNESS AFIT 0 */ + 0x0F120000, /*0000//7000098E//_CONTRAST */ + 0x0F120000, /*0000//70000990//_SATURATION */ + 0x0F120000, /*0000//70000992//_SHARP_BLUR */ + 0x0F120000, /*0000//70000994//_GLAMOUR */ + 0x0F1200C0, /*00C0//70000996//_bnr_edge_high */ + 0x0F120064, /*0064//70000998//_postdmsc_iLowBright */ + 0x0F120384, /*0384//7000099A//_postdmsc_iHighBright */ + 0x0F120051, /*005F//7000099C//_postdmsc_iLowSat */ + 0x0F1201F4, /*01F4//7000099E//_postdmsc_iHighSat */ + 0x0F120070, /*0070//700009A0//_postdmsc_iTune */ + 0x0F120040, /*0040//700009A2//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*00A0//700009A4//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*0100//700009A6//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*0010//700009A8//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*0040//700009AA//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*00A0//700009AC//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*1430//700009AE//_bnr_edge_low */ + 0x0F120201, /*0201//700009B0//_bnr_repl_force */ + 0x0F120204, /*0204//700009B2//_bnr_iHotThreshLow */ + 0x0F122404, /*3604//700009B4//_bnr_iColdThreshLow */ + 0x0F12031B, /*032A//700009B6//_bnr_DispTH_High */ + 0x0F120103, /*0403//700009B8//_bnr_DISP_Limit_High */ + 0x0F121205, /*1B06//700009BA//_bnr_iDistSigmaMax */ + 0x0F12400D, /*6015//700009BC//_bnr_iDiffSigmaHigh */ + 0x0F120080, /*00C0//700009BE//_bnr_iNormalizedSTD_Limit */ + 0x0F122080, /*6080//700009C0//_bnr_iDirMinThres */ + 0x0F123040, /*4080//700009C2//_bnr_iDirFltDiffThresLow*/ + 0x0F120630, /*0640//700009C4//_bnr_iDirSmoothPowerLow*/ + 0x0F120306, /*0306//700009C6//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*2003//700009C8//_bnr_iHighSlopeThresh*/ + 0x0F12FF01, /*FF01//700009CA//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*0000//700009CC//_bnr_AddNoisePower1 */ + 0x0F120300, /*0400//700009CE//_bnr_iRadialTune */ + 0x0F12245A, /*365A//700009D0//_bnr_iRadialLimit */ + 0x0F121018, /*102A//700009D2//_ee_iFSMagThHigh */ + 0x0F12000B, /*000B//700009D4//_ee_iFSVarThHigh */ + 0x0F120B00, /*0600//700009D6//_ee_iFSThHigh */ + 0x0F125A0F, /*5A0F//700009D8//_ee_iFSVarCountTh */ + 0x0F120505, /*0505//700009DA//_ee_iRadialPower */ + 0x0F121802, /*1802//700009DC//_ee_iROADThres */ + 0x0F120000, /*0000//700009DE//_ee_iROADSubMaxNR */ + 0x0F122006, /*2006//700009E0//_ee_iROADNeiThres */ + 0x0F123428, /*3028//700009E2//_ee_iSmoothEdgeThres */ + 0x0F12041C, /*0418//700009E4//_ee_iWSharpen */ + 0x0F120101, /*0101//700009E6//_ee_iWShThresh */ + 0x0F120800, /*0800//700009E8//_ee_iEmbossCentAdd */ + 0x0F121004, /*1804//700009EA//_ee_iReduceEdgeThresh */ + 0x0F124008, /*4008//700009EC//_dmsc_iDesatThresh */ + 0x0F120540, /*0540//700009EE//_dmsc_iDemBlurLow */ + 0x0F128006, /*8006//700009F0//_dmsc_iDecisionThresh */ + 0x0F120020, /*0020//700009F2//_dmsc_iMonochrom */ + 0x0F120000, /*0000//700009F4//_dmsc_iGRDenoiseVal */ + 0x0F121800, /*2000//700009F6//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*0000//700009F8//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*1E10//700009FA//_postdmsc_iBCoeff */ + 0x0F12000B, /*000B//700009FC//_postdmsc_iWideMult */ + 0x0F120607, /*0607//700009FE//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*0005//70000A00//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*0607//70000A02//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*0705//70000A04//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*0206//70000A06//_yuviirnr_iXSupportUV */ + 0x0F120304, /*0304//70000A08//_yuviirnr_iHighYNorm */ + 0x0F120409, /*0309//70000A0A//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*0305//70000A0C//_yuviirnr_iUVNormShift */ + 0x0F120407, /*2006//70000A0E//_yuviirnr_iVertLength_UV */ + 0x0F121F04, /*1320//70000A10//_yuviirnr_iDiffThreshH_Y */ + 0x0F120218, /*1014//70000A12//_yuviirnr_iDiffThreshH_UV */ + 0x0F121102, /*1010//70000A14//_yuviirnr_iMaxThreshH_Y */ + 0x0F120611, /*0C10//70000A16//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*1A0C//70000A18//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*4A18//70000A1A//_yuviirnr_iUVNRStrengthH */ + 0x0F1200B0, /*0080//70000A1C//_RGBGamma2_iLinearity */ + 0x0F121080, /*0350//70000A1E//_ccm_oscar_iSaturation */ + 0x0F120180, /*0180//70000A20//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*0A0A//70000A22//_bnr_iClustMulT_H */ + 0x0F120101, /*0101//70000A24//_bnr_iClustThresh_H */ + 0x0F121B24, /*2A36//70000A26//_bnr_iDenThreshLow */ + 0x0F126024, /*6024//70000A28//_ee_iLowSharpPower */ + 0x0F121D22, /*2A36//70000A2A//_ee_iLowShDenoise */ + 0x0F12FFFF, /*FFFF//70000A2C//_ee_iLowSharpClamp */ + 0x0F120808, /*0808//70000A2E//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*0A01//70000A30//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*010A//70000A32//_bnr_iClustMulT_C_Bin */ + 0x0F122401, /*2701//70000A34//_bnr_iClustThresh_C_Bin*/ + 0x0F12241B, /*241E//70000A36//_bnr_iDenThreshHigh_Bin*/ + 0x0F121E60, /*2E60//70000A38//_ee_iHighSharpPower_Bin*/ + 0x0F12FF18, /*FF22//70000A3A//_ee_iHighShDenoise_Bin */ + 0x0F1208FF, /*40FF//70000A3C//_ee_iHighSharpClamp_Bin */ + 0x0F120008, /*0009//70000A3E//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*0001//70000A40//_bnr_nClustLevel_C */ + 0x0F120000, /*0000//70000A42//_BRIGHTNESS AFIT 1 */ + 0x0F120000, /*0000//70000A44//_CONTRAST */ + 0x0F120000, /*0000//70000A46//_SATURATION */ + 0x0F120000, /*0000//70000A48//_SHARP_BLUR */ + 0x0F120000, /*0000//70000A4A//_GLAMOUR */ + 0x0F1200C0, /*00C0//70000A4C//_bnr_edge_high */ + 0x0F120064, /*0064//70000A4E//_postdmsc_iLowBright */ + 0x0F120384, /*0384//70000A50//_postdmsc_iHighBright */ + 0x0F120051, /*0051//70000A52//_postdmsc_iLowSat */ + 0x0F1201F4, /*01F4//70000A54//_postdmsc_iHighSat */ + 0x0F120070, /*0070//70000A56//_postdmsc_iTune */ + 0x0F120040, /*0040//70000A58//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*00A0//70000A5A//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*0100//70000A5C//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*0010//70000A5E//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*0060//70000A60//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*0100//70000A62//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*1430//70000A64//_bnr_edge_low */ + 0x0F120201, /*0201//70000A66//_bnr_repl_force */ + 0x0F120204, /*0204//70000A68//_bnr_iHotThreshLow */ + 0x0F121B04, /*2404//70000A6A//_bnr_iColdThreshLow */ + 0x0F120312, /*031B//70000A6C//_bnr_DispTH_High */ + 0x0F120003, /*0103//70000A6E//_bnr_DISP_Limit_High */ + 0x0F120C03, /*1205//70000A70//_bnr_iDistSigmaMax */ + 0x0F122806, /*400D//70000A72//_bnr_iDiffSigmaHigh */ + 0x0F120060, /*0080//70000A74//_bnr_iNormalizedSTD_Limit */ + 0x0F121540, /*1980//70000A76//_bnr_iDirMinThres */ + 0x0F12201C, /*272E//70000A78//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*0629//70000A7A//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*0306//70000A7C//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*2003//70000A7E//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*FF01//70000A80//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*0404//70000A82//_bnr_AddNoisePower1 */ + 0x0F120300, /*0300//70000A84//_bnr_iRadialTune */ + 0x0F12145A, /*245A//70000A86//_bnr_iRadialLimit */ + 0x0F121010, /*1018//70000A88//_ee_iFSMagThHigh */ + 0x0F12000B, /*000B//70000A8A//_ee_iFSVarThHigh */ + 0x0F120B00, /*0B00//70000A8C//_ee_iFSThHigh */ + 0x0F125A0F, /*5A0F//70000A8E//_ee_iFSVarCountTh */ + 0x0F120503, /*0505//70000A90//_ee_iRadialPower */ + 0x0F121802, /*1802//70000A92//_ee_iROADThres */ + 0x0F120000, /*0000//70000A94//_ee_iROADSubMaxNR */ + 0x0F122006, /*2006//70000A96//_ee_iROADNeiThres */ + 0x0F123C28, /*3828//70000A98//_ee_iSmoothEdgeThres */ + 0x0F120428, /*0425//70000A9A//_ee_iWSharpen */ + 0x0F120101, /*0101//70000A9C//_ee_iWShThresh */ + 0x0F128000, /*0800//70000A9E//_ee_iEmbossCentAdd */ + 0x0F121004, /*1004//70000AA0//_ee_iReduceEdgeThresh */ + 0x0F124008, /*4008//70000AA2//_dmsc_iDesatThresh */ + 0x0F120540, /*0540//70000AA4//_dmsc_iDemBlurLow */ + 0x0F128006, /*8006//70000AA6//_dmsc_iDecisionThresh */ + 0x0F120020, /*0020//70000AA8//_dmsc_iMonochrom */ + 0x0F120000, /*0000//70000AAA//_dmsc_iGRDenoiseVal */ + 0x0F121800, /*2000//70000AAC//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*0000//70000AAE//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*1E10//70000AB0//_postdmsc_iBCoeff */ + 0x0F12000B, /*000B//70000AB2//_postdmsc_iWideMult */ + 0x0F120607, /*0607//70000AB4//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*0005//70000AB6//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*0607//70000AB8//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*0405//70000ABA//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*0205//70000ABC//_yuviirnr_iXSupportUV */ + 0x0F120304, /*0304//70000ABE//_yuviirnr_iHighYNorm */ + 0x0F120409, /*0409//70000AC0//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*0306//70000AC2//_yuviirnr_iUVNormShift */ + 0x0F120407, /*0407//70000AC4//_yuviirnr_iVertLength_UV*/ + 0x0F121F04, /*2204//70000AC6//_yuviirnr_iDiffThreshH_Y*/ + 0x0F120228, /*021C//70000AC8//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*1102//70000ACA//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*0611//70000ACC//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*1A02//70000ACE//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*8018//70000AD0//_yuviirnr_iUVNRStrengthH*/ + 0x0F1200A0, /*0080//70000AD2//_RGBGamma2_iLinearity */ + 0x0F121080, /*0374//70000AD4//_ccm_oscar_iSaturation */ + 0x0F120180, /*0180//70000AD6//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*0A0A//70000AD8//_bnr_iClustMulT_H */ + 0x0F120101, /*0101//70000ADA//_bnr_iClustThresh_H */ + 0x0F121B24, /*141D//70000ADC//_bnr_iDenThreshLow */ + 0x0F126024, /*6024//70000ADE//_ee_iLowSharpPower */ + 0x0F120C0C, /*1217//70000AE0//_ee_iLowShDenoise */ + 0x0F12FFFF, /*FFFF//70000AE2//_ee_iLowSharpClamp */ + 0x0F120808, /*0808//70000AE4//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*0A01//70000AE6//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*010A//70000AE8//_bnr_iClustMulT_C_Bin */ + 0x0F121501, /*0001//70000AEA//_bnr_iClustThresh_C_Bin*/ + 0x0F12240F, /*2400//70000AEC//_bnr_iDenThreshHigh_Bin*/ + 0x0F120C60, /*1660//70000AEE//_ee_iHighSharpPower_Bin*/ + 0x0F12FF0C, /*FF10//70000AF0//_ee_iHighShDenoise_Bin */ + 0x0F1208FF, /*40FF//70000AF2//_ee_iHighSharpClamp_Bin*/ + 0x0F120008, /*0009//70000AF4//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*0001//70000AF6//_bnr_nClustLevel_C */ + 0x0F120000, /*0000//70000AF8//_BRIGHTNESS AFIT 2 */ + 0x0F120000, /*0000//70000AFA//_CONTRAST */ + 0x0F120000, /*0000//70000AFC//_SATURATION */ + 0x0F120000, /*0000//70000AFE//_SHARP_BLUR */ + 0x0F120000, /*0000//70000B00//_GLAMOUR */ + 0x0F1200C0, /*00C0//70000B02//_bnr_edge_high */ + 0x0F120064, /*0064//70000B04//_postdmsc_iLowBright */ + 0x0F120384, /*0384//70000B06//_postdmsc_iHighBright */ + 0x0F120043, /*0043//70000B08//_postdmsc_iLowSat */ + 0x0F1201F4, /*01F4//70000B0A//_postdmsc_iHighSat */ + 0x0F120070, /*0070//70000B0C//_postdmsc_iTune */ + 0x0F120040, /*0040//70000B0E//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*00A0//70000B10//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*0100//70000B12//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*0010//70000B14//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*0060//70000B16//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*0100//70000B18//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*1430//70000B1A//_bnr_edge_low */ + 0x0F120201, /*0201//70000B1C//_bnr_repl_force */ + 0x0F120204, /*0204//70000B1E//_bnr_iHotThreshLow */ + 0x0F121B04, /*1B04//70000B20//_bnr_iColdThreshLow */ + 0x0F120312, /*0312//70000B22//_bnr_DispTH_High */ + 0x0F120003, /*0003//70000B24//_bnr_DISP_Limit_High */ + 0x0F120C03, /*0C03//70000B26//_bnr_iDistSigmaMax */ + 0x0F122806, /*2806//70000B28//_bnr_iDiffSigmaHigh */ + 0x0F120060, /*0060//70000B2A//_bnr_iNormalizedSTD_Limit*/ + 0x0F121540, /*1580//70000B2C//_bnr_iDirMinThres */ + 0x0F12201C, /*2020//70000B2E//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*0620//70000B30//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*0306//70000B32//_bnr_iHighMaxSlopeAllowed*/ + 0x0F122003, /*2003//70000B34//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*FF01//70000B36//_bnr_iSlopeBlurStrength*/ + 0x0F120404, /*0404//70000B38//_bnr_AddNoisePower1 */ + 0x0F120300, /*0300//70000B3A//_bnr_iRadialTune */ + 0x0F12145A, /*145A//70000B3C//_bnr_iRadialLimit */ + 0x0F121010, /*1010//70000B3E//_ee_iFSMagThHigh*/ + 0x0F12000B, /*000B//70000B40//_ee_iFSVarThHigh*/ + 0x0F120E00, /*0E00//70000B42//_ee_iFSThHigh */ + 0x0F125A0F, /*5A0F//70000B44//_ee_iFSVarCountTh */ + 0x0F120503, /*0504//70000B46//_ee_iRadialPower*/ + 0x0F121802, /*1802//70000B48//_ee_iROADThres */ + 0x0F120000, /*0000//70000B4A//_ee_iROADSubMaxNR */ + 0x0F122006, /*2006//70000B4C//_ee_iROADNeiThres */ + 0x0F123C28, /*3828//70000B4E//_ee_iSmoothEdgeThres */ + 0x0F120428, /*0428//70000B50//_ee_iWSharpen */ + 0x0F120101, /*0101//70000B52//_ee_iWShThresh */ + 0x0F128000, /*8000//70000B54//_ee_iEmbossCentAdd */ + 0x0F120A04, /*0A04//70000B56//_ee_iReduceEdgeThresh */ + 0x0F124008, /*4008//70000B58//_dmsc_iDesatThresh */ + 0x0F120540, /*0540//70000B5A//_dmsc_iDemBlurLow */ + 0x0F128006, /*8006//70000B5C//_dmsc_iDecisionThresh */ + 0x0F120020, /*0020//70000B5E//_dmsc_iMonochrom */ + 0x0F120000, /*0000//70000B60//_dmsc_iGRDenoiseVal */ + 0x0F121800, /*2000//70000B62//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*0000//70000B64//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*1E10//70000B66//_postdmsc_iBCoeff */ + 0x0F12000B, /*000B//70000B68//_postdmsc_iWideMult */ + 0x0F120607, /*0607//70000B6A//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*0005//70000B6C//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*0607//70000B6E//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*0405//70000B70//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*0207//70000B72//_yuviirnr_iXSupportUV */ + 0x0F120304, /*0304//70000B74//_yuviirnr_iHighYNorm */ + 0x0F120409, /*0409//70000B76//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*0306//70000B78//_yuviirnr_iUVNormShift */ + 0x0F120407, /*0407//70000B7A//_yuviirnr_iVertLength_UV*/ + 0x0F122404, /*2404//70000B7C//_yuviirnr_iDiffThreshH_Y*/ + 0x0F120228, /*0221//70000B7E//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*1202//70000B80//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*0613//70000B82//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*1A02//70000B84//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*8018//70000B86//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*0080//70000B88//_RGBGamma2_iLinearity */ + 0x0F121080, /*0080//70000B8A//_ccm_oscar_iSaturation */ + 0x0F120180, /*0180//70000B8C//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*0A0A//70000B8E//_bnr_iClustMulT_H */ + 0x0F120101, /*0101//70000B90//_bnr_iClustThresh_H */ + 0x0F12141D, /*121B//70000B92//_bnr_iDenThreshLow */ + 0x0F126024, /*6024//70000B94//_ee_iLowSharpPower */ + 0x0F120C0C, /*0C0C//70000B96//_ee_iLowShDenoise */ + 0x0F12FFFF, /*FFFF//70000B98//_ee_iLowSharpClamp */ + 0x0F120808, /*0808//70000B9A//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*0A01//70000B9C//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*010A//70000B9E//_bnr_iClustMulT_C_Bin */ + 0x0F121501, /*0001//70000BA0//_bnr_iClustThresh_C_Bin*/ + 0x0F12240F, /*2400//70000BA2//_bnr_iDenThreshHigh_Bin*/ + 0x0F120C60, /*0460//70000BA4//_ee_iHighSharpPower_Bin*/ + 0x0F12FF0C, /*FF04//70000BA6//_ee_iHighShDenoise_Bin*/ + 0x0F1208FF, /*40FF//70000BA8//_ee_iHighSharpClamp_Bin */ + 0x0F120008, /*0009//70000BAA//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*0001//70000BAC//_bnr_nClustLevel_C */ + 0x0F120000, /*0000//70000BAE//_BRIGHTNESS AFIT 3 */ + 0x0F120000, /*0000//70000BB0//_CONTRAST */ + 0x0F120000, /*0000//70000BB2//_SATURATION */ + 0x0F120000, /*0000//70000BB4//_SHARP_BLUR */ + 0x0F120000, /*0000//70000BB6//_GLAMOUR */ + 0x0F1200C0, /*00C0//70000BB8//_bnr_edge_high */ + 0x0F120064, /*0064//70000BBA//_postdmsc_iLowBright */ + 0x0F120384, /*0384//70000BBC//_postdmsc_iHighBright */ + 0x0F120032, /*0032//70000BBE//_postdmsc_iLowSat */ + 0x0F1201F4, /*01F4//70000BC0//_postdmsc_iHighSat */ + 0x0F120070, /*0070//70000BC2//_postdmsc_iTune */ + 0x0F120040, /*0040//70000BC4//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*00A0//70000BC6//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*0100//70000BC8//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*0010//70000BCA//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*0060//70000BCC//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*0100//70000BCE//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*1430//70000BD0//_bnr_edge_low */ + 0x0F120201, /*0201//70000BD2//_bnr_repl_force */ + 0x0F120204, /*0204//70000BD4//_bnr_iHotThreshLow */ + 0x0F121504, /*1504//70000BD6//_bnr_iColdThreshLow */ + 0x0F12030F, /*030F//70000BD8//_bnr_DispTH_High */ + 0x0F120003, /*0003//70000BDA//_bnr_DISP_Limit_High */ + 0x0F120902, /*0902//70000BDC//_bnr_iDistSigmaMax */ + 0x0F122004, /*2004//70000BDE//_bnr_iDiffSigmaHigh */ + 0x0F120050, /*0050//70000BE0//_bnr_iNormalizedSTD_Limit*/ + 0x0F121140, /*1140//70000BE2//_bnr_iDirMinThres */ + 0x0F12201C, /*201C//70000BE4//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*0620//70000BE6//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*0306//70000BE8//_bnr_iHighMaxSlopeAllowed*/ + 0x0F122003, /*2003//70000BEA//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*FF01//70000BEC//_bnr_iSlopeBlurStrength*/ + 0x0F120404, /*0404//70000BEE//_bnr_AddNoisePower1 */ + 0x0F120300, /*0300//70000BF0//_bnr_iRadialTune */ + 0x0F12145A, /*145A//70000BF2//_bnr_iRadialLimit */ + 0x0F121010, /*1010//70000BF4//_ee_iFSMagThHigh */ + 0x0F12000B, /*000B//70000BF6//_ee_iFSVarThHigh */ + 0x0F121000, /*1000//70000BF8//_ee_iFSThHigh */ + 0x0F125A0F, /*5A0F//70000BFA//_ee_iFSVarCountTh */ + 0x0F120503, /*0503//70000BFC//_ee_iRadialPower */ + 0x0F121802, /*1802//70000BFE//_ee_iROADThres */ + 0x0F120000, /*0000//70000C00//_ee_iROADSubMaxNR */ + 0x0F122006, /*2006//70000C02//_ee_iROADNeiThres */ + 0x0F123C28, /*3C28//70000C04//_ee_iSmoothEdgeThres */ + 0x0F12042C, /*042C//70000C06//_ee_iWSharpen */ + 0x0F120101, /*0101//70000C08//_ee_iWShThresh */ + 0x0F128000, /*FF00//70000C0A//_ee_iEmbossCentAdd */ + 0x0F120904, /*0904//70000C0C//_ee_iReduceEdgeThresh */ + 0x0F124008, /*4008//70000C0E//_dmsc_iDesatThresh */ + 0x0F120540, /*0540//70000C10//_dmsc_iDemBlurLow */ + 0x0F128006, /*8006//70000C12//_dmsc_iDecisionThresh */ + 0x0F120020, /*0020//70000C14//_dmsc_iMonochrom */ + 0x0F120000, /*0000//70000C16//_dmsc_iGRDenoiseVal */ + 0x0F121800, /*2000//70000C18//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*0000//70000C1A//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*1E10//70000C1C//_postdmsc_iBCoeff */ + 0x0F12000B, /*000B//70000C1E//_postdmsc_iWideMult */ + 0x0F120607, /*0607//70000C20//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*0005//70000C22//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*0607//70000C24//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*0405//70000C26//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*0206//70000C28//_yuviirnr_iXSupportUV */ + 0x0F120304, /*0304//70000C2A//_yuviirnr_iHighYNorm */ + 0x0F120409, /*0409//70000C2C//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*0305//70000C2E//_yuviirnr_iUVNormShift */ + 0x0F120407, /*0406//70000C30//_yuviirnr_iVertLength_UV*/ + 0x0F122804, /*2804//70000C32//_yuviirnr_iDiffThreshH_Y*/ + 0x0F120228, /*0228//70000C34//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*1402//70000C36//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*0618//70000C38//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*1A02//70000C3A//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*8018//70000C3C//_yuviirnr_iUVNRStrengthH*/ + 0x0F120080, /*0080//70000C3E//_RGBGamma2_iLinearity */ + 0x0F121080, /*0080//70000C40//_ccm_oscar_iSaturation */ + 0x0F120180, /*0180//70000C42//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*0A0A//70000C44//_bnr_iClustMulT_H */ + 0x0F120101, /*0101//70000C46//_bnr_iClustThresh_H */ + 0x0F121117, /*0F15//70000C48//_bnr_iDenThreshLow */ + 0x0F126024, /*6024//70000C4A//_ee_iLowSharpPower */ + 0x0F120A0A, /*0A0A//70000C4C//_ee_iLowShDenoise */ + 0x0F12FFFF, /*FFFF//70000C4E//_ee_iLowSharpClamp */ + 0x0F120808, /*0808//70000C50//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*0A01//70000C52//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*010A//70000C54//_bnr_iClustMulT_C_Bin */ + 0x0F121501, /*0001//70000C56//_bnr_iClustThresh_C_Bin*/ + 0x0F12240F, /*2400//70000C58//_bnr_iDenThreshHigh_Bin*/ + 0x0F120A60, /*0260//70000C5A//_ee_iHighSharpPower_Bin*/ + 0x0F12FF0A, /*FF02//70000C5C//_ee_iHighShDenoise_Bin */ + 0x0F1208FF, /*40FF//70000C5E//_ee_iHighSharpClamp_Bin*/ + 0x0F120008, /*0009//70000C60//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*0001//70000C62//_bnr_nClustLevel_C */ + 0x0F120000, /*0000//70000C64//_BRIGHTNESS AFIT 4 */ + 0x0F120000, /*0000//70000C66//_CONTRAST */ + 0x0F120000, /*0000//70000C68//_SATURATION */ + 0x0F120000, /*0000//70000C6A//_SHARP_BLUR */ + 0x0F120000, /*0000//70000C6C//_GLAMOUR */ + 0x0F1200C0, /*00C0//70000C6E//_bnr_edge_high */ + 0x0F120064, /*0064//70000C70//_postdmsc_iLowBright */ + 0x0F120384, /*0384//70000C72//_postdmsc_iHighBright */ + 0x0F120032, /*0032//70000C74//_postdmsc_iLowSat */ + 0x0F1201F4, /*01F4//70000C76//_postdmsc_iHighSat */ + 0x0F120070, /*0070//70000C78//_postdmsc_iTune */ + 0x0F120040, /*0040//70000C7A//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*00A0//70000C7C//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*0100//70000C7E//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*0010//70000C80//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*0060//70000C82//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*0100//70000C84//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*1430//70000C86//_bnr_edge_low */ + 0x0F120201, /*0201//70000C88//_bnr_repl_force */ + 0x0F120204, /*0204//70000C8A//_bnr_iHotThreshLow */ + 0x0F120F04, /*0F04//70000C8C//_bnr_iColdThreshLow */ + 0x0F12030C, /*030C//70000C8E//_bnr_DispTH_High */ + 0x0F120003, /*0003//70000C90//_bnr_DISP_Limit_High */ + 0x0F120602, /*0602//70000C92//_bnr_iDistSigmaMax */ + 0x0F121803, /*1803//70000C94//_bnr_iDiffSigmaHigh */ + 0x0F120040, /*0040//70000C96//_bnr_iNormalizedSTD_Limit*/ + 0x0F120E20, /*0E20//70000C98//_bnr_iDirMinThres */ + 0x0F122018, /*2018//70000C9A//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*0620//70000C9C//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*0306//70000C9E//_bnr_iHighMaxSlopeAllowed*/ + 0x0F122003, /*2003//70000CA0//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*FF01//70000CA2//_bnr_iSlopeBlurStrength*/ + 0x0F120404, /*0404//70000CA4//_bnr_AddNoisePower1 */ + 0x0F120200, /*0200//70000CA6//_bnr_iRadialTune */ + 0x0F12145A, /*145A//70000CA8//_bnr_iRadialLimit */ + 0x0F121010, /*1010//70000CAA//_ee_iFSMagThHigh */ + 0x0F12000B, /*000B//70000CAC//_ee_iFSVarThHigh */ + 0x0F121200, /*1200//70000CAE//_ee_iFSThHigh */ + 0x0F125A0F, /*5A0F//70000CB0//_ee_iFSVarCountTh */ + 0x0F120502, /*0502//70000CB2//_ee_iRadialPower */ + 0x0F121802, /*1802//70000CB4//_ee_iROADThres */ + 0x0F120000, /*0000//70000CB6//_ee_iROADSubMaxNR */ + 0x0F122006, /*2006//70000CB8//_ee_iROADNeiThres */ + 0x0F124028, /*4028//70000CBA//_ee_iSmoothEdgeThres */ + 0x0F120430, /*0430//70000CBC//_ee_iWSharpen */ + 0x0F120101, /*0101//70000CBE//_ee_iWShThresh */ + 0x0F12FF00, /*FF00//70000CC0//_ee_iEmbossCentAdd */ + 0x0F120804, /*0804//70000CC2//_ee_iReduceEdgeThresh */ + 0x0F124008, /*4008//70000CC4//_dmsc_iDesatThresh */ + 0x0F120540, /*0540//70000CC6//_dmsc_iDemBlurLow */ + 0x0F128006, /*8006//70000CC8//_dmsc_iDecisionThresh */ + 0x0F120020, /*0020//70000CCA//_dmsc_iMonochrom */ + 0x0F120000, /*0000//70000CCC//_dmsc_iGRDenoiseVal */ + 0x0F121800, /*2000//70000CCE//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*0000//70000CD0//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*1E10//70000CD2//_postdmsc_iBCoeff */ + 0x0F12000B, /*000B//70000CD4//_postdmsc_iWideMult */ + 0x0F120607, /*0607//70000CD6//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*0005//70000CD8//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*0607//70000CDA//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*0405//70000CDC//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*0205//70000CDE//_yuviirnr_iXSupportUV */ + 0x0F120304, /*0304//70000CE0//_yuviirnr_iHighYNorm */ + 0x0F120409, /*0409//70000CE2//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*0306//70000CE4//_yuviirnr_iUVNormShift */ + 0x0F120407, /*0407//70000CE6//_yuviirnr_iVertLength_UV*/ + 0x0F122C04, /*2C04//70000CE8//_yuviirnr_iDiffThreshH_Y*/ + 0x0F12022C, /*022C//70000CEA//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*1402//70000CEC//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*0618//70000CEE//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*1A02//70000CF0//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*8018//70000CF2//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*0080//70000CF4//_RGBGamma2_iLinearity */ + 0x0F121080, /*0080//70000CF6//_ccm_oscar_iSaturation */ + 0x0F120180, /*0180//70000CF8//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*0A0A//70000CFA//_bnr_iClustMulT_H */ + 0x0F120101, /*0101//70000CFC//_bnr_iClustThresh_H */ + 0x0F120C0F, /*0C0F//70000CFE//_bnr_iDenThreshLow */ + 0x0F126024, /*6024//70000D00//_ee_iLowSharpPower */ + 0x0F120808, /*0808//70000D02//_ee_iLowShDenoise */ + 0x0F12FFFF, /*FFFF//70000D04//_ee_iLowSharpClamp */ + 0x0F120808, /*0808//70000D06//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*0A01//70000D08//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*010A//70000D0A//_bnr_iClustMulT_C_Bin */ + 0x0F120F01, /*0001//70000D0C//_bnr_iClustThresh_C_Bin*/ + 0x0F12240C, /*2400//70000D0E//_bnr_iDenThreshHigh_Bin*/ + 0x0F120860, /*0060//70000D10//_ee_iHighSharpPower_Bin*/ + 0x0F12FF08, /*FF00//70000D12//_ee_iHighShDenoise_Bin */ + 0x0F1208FF, /*40FF//70000D14//_ee_iHighSharpClamp_Bin*/ + 0x0F120008, /*0009//70000D16//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*0001//70000D18//_bnr_nClustLevel_C */ + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_1280_Preview_Disable_EVT1[] = {/*1280x720 */ + /* 720P disable setting */ + 0xFCFCD000, + 0x00287000, + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + /* Size */ + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs/(2592-2560)/2*/ + 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs/(1944-1920)/2*/ + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + 0x002A02A6, + 0x0F120280, /*REG_0TC_PCFG_usWidth //640 */ + 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */ + + /* Frame Rate */ + 0x002A02BE, + 0x0F120000, /*REG_0TC_PCFG_usFrTimeType*/ + 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */ + 0x0F1203E8, /*029A/REG_0TC_PCFG_usMaxFrTimeMsecMult10/029Ah:15fps*/ + 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10/014Ah:30fps*/ + + /* AE Target */ + 0x002A1484, + 0x0F12003C, /*TVAR_ae_BrAve */ + + /* AE Weight Matrix */ + 0x002A1492, + 0x0F120100, + 0x0F120101, + 0x0F120101, + 0x0F120001, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120201, + 0x0F120302, + 0x0F120203, + 0x0F120102, + 0x0F120101, + 0x0F120202, + 0x0F120202, + 0x0F120101, + 0x0F120101, + 0x0F120201, + 0x0F120102, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + 0x0F120101, + + /* Slow AE */ + 0x002A1568, + 0x0F120010, /*ae_GainIn_0_ */ + 0x0F120020, /*ae_GainIn_1_ */ + 0x0F120040, /*ae_GainIn_2_ */ + 0x0F120080, /*ae_GainIn_3_ */ + 0x0F120100, /*ae_GainIn_4_ FIX */ + 0x0F120200, /*ae_GainIn_5_ */ + 0x0F120400, /*ae_GainIn_6_ */ + 0x0F120800, /*ae_GainIn_7_ */ + 0x0F120800, /*ae_GainIn_8_ */ + 0x0F120010, /*ae_GainOut_0_ */ + 0x0F120020, /*ae_GainOut_1_ */ + 0x0F120040, /*ae_GainOut_2_ */ + 0x0F120080, /*ae_GainOut_3_ */ + 0x0F120100, /*ae_GainOut_4_ FIX */ + 0x0F120200, /*ae_GainOut_5_ */ + 0x0F120400, /*ae_GainOut_6_ */ + 0x0F120800, /*ae_GainOut_7_ */ + 0x0F122000, /*ae_GainOut_8_ */ + 0x002A0544, + 0x0F120111, /*lt_uLimitHigh */ + 0x0F1200EF, /*lt_uLimitLow */ + 0x002A0588, + 0x0F120000, /*lt_uInitPostToleranceCnt */ + 0x002A0582, + 0x0F120000, /*lt_uSlowFilterCoef */ + 0x002A0734, /*R*/ + 0x0F120000, + 0x0F120001, + 0x0F120006, + 0x0F120017, + 0x0F12004A, + 0x0F1200C9, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + 0x0F120000, /*G*/ + 0x0F120001, + 0x0F120006, + 0x0F120017, + 0x0F12004A, + 0x0F1200C9, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + 0x0F120000, /*B*/ + 0x0F120001, + 0x0F120006, + 0x0F120017, + 0x0F12004A, + 0x0F1200C9, + 0x0F120138, + 0x0F120163, + 0x0F120189, + 0x0F1201C6, + 0x0F1201F8, + 0x0F120222, + 0x0F120247, + 0x0F120282, + 0x0F1202B5, + 0x0F12030F, + 0x0F12035F, + 0x0F1203A2, + 0x0F1203D8, + 0x0F1203FF, + + /* Slow AWB */ + 0x002A139A, + 0x0F120258, /*awbb_GainsMaxMove */ + + /* AWB Convergence Speed */ + 0x002A1464, + 0x0F120008, /*awbb_WpFilterMinThr */ + 0x0F120190, /*awbb_WpFilterMaxThr */ + 0x0F1200A0, /*awbb_WpFilterCoef */ + 0x0F120004, /*awbb_WpFilterSize */ + 0x002A0938, + 0x0F120000, /* on/off AFIT by NB option */ + 0x0F120014, /*SARR_uNormBrInDoor */ + 0x0F1200D2, /*SARR_uNormBrInDoor */ + 0x0F120384, /*SARR_uNormBrInDoor */ + 0x0F1207D0, /*SARR_uNormBrInDoor */ + 0x0F121388, /*SARR_uNormBrInDoor */ + 0x002A098C, + 0x0F120000, /*7000098C//_BRIGHTNESS AFIT 0 */ + 0x0F120000, /*7000098E//_CONTRAST */ + 0x0F120000, /*70000990//_SATURATION */ + 0x0F120000, /*70000992//_SHARP_BLUR */ + 0x0F120000, /*70000994//_GLAMOUR */ + 0x0F1200C0, /*70000996//_bnr_edge_high */ + 0x0F120064, /*70000998//_postdmsc_iLowBright */ + 0x0F120384, /*7000099A//_postdmsc_iHighBright */ + 0x0F12005F, /*7000099C//_postdmsc_iLowSat */ + 0x0F1201F4, /*7000099E//_postdmsc_iHighSat */ + 0x0F120070, /*700009A0//_postdmsc_iTune */ + 0x0F120040, /*700009A2//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*700009A4//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*700009A6//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*700009A8//_yuvemix_mPosRanges_0 */ + 0x0F120040, /*700009AA//_yuvemix_mPosRanges_1 */ + 0x0F1200A0, /*700009AC//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*700009AE//_bnr_edge_low */ + 0x0F120201, /*700009B0//_bnr_repl_force */ + 0x0F120204, /*700009B2//_bnr_iHotThreshLow */ + 0x0F123604, /*700009B4//_bnr_iColdThreshLow */ + 0x0F12032A, /*700009B6//_bnr_DispTH_High */ + 0x0F120403, /*700009B8//_bnr_DISP_Limit_High */ + 0x0F121B06, /*700009BA//_bnr_iDistSigmaMax */ + 0x0F126015, /*700009BC//_bnr_iDiffSigmaHigh */ + 0x0F1200C0, /*700009BE//_bnr_iNormalizedSTD_Limit */ + 0x0F126080, /*700009C0//_bnr_iDirMinThres */ + 0x0F124080, /*700009C2//_bnr_iDirFltDiffThresLow */ + 0x0F120640, /*700009C4//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*700009C6//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*700009C8//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*700009CA//_bnr_iSlopeBlurStrength */ + 0x0F120000, /*700009CC//_bnr_AddNoisePower1 */ + 0x0F120400, /*700009CE//_bnr_iRadialTune */ + 0x0F12365A, /*700009D0//_bnr_iRadialLimit */ + 0x0F12102A, /*700009D2//_ee_iFSMagThHigh */ + 0x0F12000B, /*700009D4//_ee_iFSVarThHigh */ + 0x0F120600, /*700009D6//_ee_iFSThHigh */ + 0x0F125A0F, /*700009D8//_ee_iFSVarCountTh */ + 0x0F120505, /*700009DA//_ee_iRadialPower */ + 0x0F121802, /*700009DC//_ee_iROADThres */ + 0x0F120000, /*700009DE//_ee_iROADSubMaxNR */ + 0x0F122006, /*700009E0//_ee_iROADNeiThres */ + 0x0F123028, /*700009E2//_ee_iSmoothEdgeThres */ + 0x0F120418, /*700009E4//_ee_iWSharpen */ + 0x0F120101, /*700009E6//_ee_iWShThresh */ + 0x0F120800, /*700009E8//_ee_iEmbossCentAdd */ + 0x0F121804, /*700009EA//_ee_iReduceEdgeThresh */ + 0x0F124008, /*700009EC//_dmsc_iDesatThresh */ + 0x0F120540, /*700009EE//_dmsc_iDemBlurLow */ + 0x0F128006, /*700009F0//_dmsc_iDecisionThresh */ + 0x0F120020, /*700009F2//_dmsc_iMonochrom */ + 0x0F120000, /*700009F4//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*700009F6//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*700009F8//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*700009FA//_postdmsc_iBCoeff */ + 0x0F12000B, /*700009FC//_postdmsc_iWideMult */ + 0x0F120607, /*700009FE//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000A00//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000A02//_yuvemix_mPosSlopes_1 */ + 0x0F120705, /*70000A04//_yuvemix_mPosSlopes_3 */ + 0x0F120206, /*70000A06//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000A08//_yuviirnr_iHighYNorm */ + 0x0F120309, /*70000A0A//_yuviirnr_iHighUVNorm */ + 0x0F120305, /*70000A0C//_yuviirnr_iUVNormShift */ + 0x0F122006, /*70000A0E//_yuviirnr_iVertLength_UV */ + 0x0F121320, /*70000A10//_yuviirnr_iDiffThreshH_Y */ + 0x0F121014, /*70000A12//_yuviirnr_iDiffThreshH_UV */ + 0x0F121010, /*70000A14//_yuviirnr_iMaxThreshH_Y */ + 0x0F120C10, /*70000A16//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A0C, /*70000A18//_yuviirnr_iYNRStrengthH */ + 0x0F124A18, /*70000A1A//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000A1C//_RGBGamma2_iLinearity */ + 0x0F120350, /*70000A1E//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000A20//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000A22//_bnr_iClustMulT_H */ + 0x0F120101, /*70000A24//_bnr_iClustThresh_H */ + 0x0F122A36, /*70000A26//_bnr_iDenThreshLow */ + 0x0F126024, /*70000A28//_ee_iLowSharpPower */ + 0x0F122A36, /*70000A2A//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000A2C//_ee_iLowSharpClamp */ + 0x0F120808, /*70000A2E//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000A30//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000A32//_bnr_iClustMulT_C_Bin */ + 0x0F122701, /*70000A34//_bnr_iClustThresh_C_Bin */ + 0x0F12241E, /*70000A36//_bnr_iDenThreshHigh_Bin */ + 0x0F122E60, /*70000A38//_ee_iHighSharpPower_Bin */ + 0x0F12FF22, /*70000A3A//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000A3C//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000A3E//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000A40//_bnr_nClustLevel_C */ + 0x0F120000, /*70000A42//_BRIGHTNESS AFIT 1 */ + 0x0F120000, /*70000A44//_CONTRAST */ + 0x0F120000, /*70000A46//_SATURATION */ + 0x0F120000, /*70000A48//_SHARP_BLUR */ + 0x0F120000, /*70000A4A//_GLAMOUR */ + 0x0F1200C0, /*70000A4C//_bnr_edge_high */ + 0x0F120064, /*70000A4E//_postdmsc_iLowBright */ + 0x0F120384, /*70000A50//_postdmsc_iHighBright */ + 0x0F120051, /*70000A52//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000A54//_postdmsc_iHighSat */ + 0x0F120070, /*70000A56//_postdmsc_iTune */ + 0x0F120040, /*70000A58//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000A5A//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000A5C//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000A5E//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000A60//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000A62//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000A64//_bnr_edge_low */ + 0x0F120201, /*70000A66//_bnr_repl_force */ + 0x0F120204, /*70000A68//_bnr_iHotThreshLow */ + 0x0F122404, /*70000A6A//_bnr_iColdThreshLow */ + 0x0F12031B, /*70000A6C//_bnr_DispTH_High */ + 0x0F120103, /*70000A6E//_bnr_DISP_Limit_High */ + 0x0F121205, /*70000A70//_bnr_iDistSigmaMax */ + 0x0F12400D, /*70000A72//_bnr_iDiffSigmaHigh */ + 0x0F120080, /*70000A74//_bnr_iNormalizedSTD_Limit */ + 0x0F121980, /*70000A76//_bnr_iDirMinThres */ + 0x0F12272E, /*70000A78//_bnr_iDirFltDiffThresLow */ + 0x0F120629, /*70000A7A//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000A7C//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000A7E//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000A80//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000A82//_bnr_AddNoisePower1 */ + 0x0F120300, /*70000A84//_bnr_iRadialTune */ + 0x0F12245A, /*70000A86//_bnr_iRadialLimit */ + 0x0F121018, /*70000A88//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000A8A//_ee_iFSVarThHigh */ + 0x0F120B00, /*70000A8C//_ee_iFSThHigh */ + 0x0F125A0F, /*70000A8E//_ee_iFSVarCountTh */ + 0x0F120505, /*70000A90//_ee_iRadialPower */ + 0x0F121802, /*70000A92//_ee_iROADThres */ + 0x0F120000, /*70000A94//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000A96//_ee_iROADNeiThres */ + 0x0F123828, /*70000A98//_ee_iSmoothEdgeThres */ + 0x0F120425, /*70000A9A//_ee_iWSharpen */ + 0x0F120101, /*70000A9C//_ee_iWShThresh */ + 0x0F120800, /*70000A9E//_ee_iEmbossCentAdd */ + 0x0F121004, /*70000AA0//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000AA2//_dmsc_iDesatThresh */ + 0x0F120540, /*70000AA4//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000AA6//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000AA8//_dmsc_iMonochrom */ + 0x0F120000, /*70000AAA//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000AAC//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000AAE//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000AB0//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000AB2//_postdmsc_iWideMult */ + 0x0F120607, /*70000AB4//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000AB6//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000AB8//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000ABA//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*70000ABC//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000ABE//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000AC0//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*70000AC2//_yuviirnr_iUVNormShift */ + 0x0F120407, /*70000AC4//_yuviirnr_iVertLength_UV */ + 0x0F122204, /*70000AC6//_yuviirnr_iDiffThreshH_Y */ + 0x0F12021C, /*70000AC8//_yuviirnr_iDiffThreshH_UV */ + 0x0F121102, /*70000ACA//_yuviirnr_iMaxThreshH_Y */ + 0x0F120611, /*70000ACC//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000ACE//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000AD0//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000AD2//_RGBGamma2_iLinearity */ + 0x0F120374, /*70000AD4//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000AD6//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000AD8//_bnr_iClustMulT_H */ + 0x0F120101, /*70000ADA//_bnr_iClustThresh_H */ + 0x0F12141D, /*70000ADC//_bnr_iDenThreshLow */ + 0x0F126024, /*70000ADE//_ee_iLowSharpPower */ + 0x0F121217, /*70000AE0//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000AE2//_ee_iLowSharpClamp */ + 0x0F120808, /*70000AE4//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000AE6//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000AE8//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000AEA//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000AEC//_bnr_iDenThreshHigh_Bin */ + 0x0F121660, /*70000AEE//_ee_iHighSharpPower_Bin */ + 0x0F12FF10, /*70000AF0//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000AF2//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000AF4//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000AF6//_bnr_nClustLevel_C */ + 0x0F120000, /*70000AF8//_BRIGHTNESS AFIT 2 */ + 0x0F120000, /*70000AFA//_CONTRAST */ + 0x0F120000, /*70000AFC//_SATURATION */ + 0x0F120000, /*70000AFE//_SHARP_BLUR */ + 0x0F120000, /*70000B00//_GLAMOUR */ + 0x0F1200C0, /*70000B02//_bnr_edge_high */ + 0x0F120064, /*70000B04//_postdmsc_iLowBright */ + 0x0F120384, /*70000B06//_postdmsc_iHighBright */ + 0x0F120043, /*70000B08//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000B0A//_postdmsc_iHighSat */ + 0x0F120070, /*70000B0C//_postdmsc_iTune */ + 0x0F120040, /*70000B0E//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000B10//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000B12//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000B14//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000B16//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000B18//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000B1A//_bnr_edge_low */ + 0x0F120201, /*70000B1C//_bnr_repl_force */ + 0x0F120204, /*70000B1E//_bnr_iHotThreshLow */ + 0x0F121B04, /*70000B20//_bnr_iColdThreshLow */ + 0x0F120312, /*70000B22//_bnr_DispTH_High */ + 0x0F120003, /*70000B24//_bnr_DISP_Limit_High */ + 0x0F120C03, /*70000B26//_bnr_iDistSigmaMax */ + 0x0F122806, /*70000B28//_bnr_iDiffSigmaHigh */ + 0x0F120060, /*70000B2A//_bnr_iNormalizedSTD_Limit */ + 0x0F121580, /*70000B2C//_bnr_iDirMinThres */ + 0x0F122020, /*70000B2E//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*70000B30//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000B32//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000B34//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000B36//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000B38//_bnr_AddNoisePower1 */ + 0x0F120300, /*70000B3A//_bnr_iRadialTune */ + 0x0F12145A, /*70000B3C//_bnr_iRadialLimit */ + 0x0F121010, /*70000B3E//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000B40//_ee_iFSVarThHigh */ + 0x0F120E00, /*70000B42//_ee_iFSThHigh */ + 0x0F125A0F, /*70000B44//_ee_iFSVarCountTh */ + 0x0F120504, /*70000B46//_ee_iRadialPower */ + 0x0F121802, /*70000B48//_ee_iROADThres */ + 0x0F120000, /*70000B4A//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000B4C//_ee_iROADNeiThres */ + 0x0F123828, /*70000B4E//_ee_iSmoothEdgeThres */ + 0x0F120428, /*70000B50//_ee_iWSharpen */ + 0x0F120101, /*70000B52//_ee_iWShThresh */ + 0x0F128000, /*70000B54//_ee_iEmbossCentAdd */ + 0x0F120A04, /*70000B56//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000B58//_dmsc_iDesatThresh */ + 0x0F120540, /*70000B5A//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000B5C//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000B5E//_dmsc_iMonochrom */ + 0x0F120000, /*70000B60//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000B62//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000B64//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000B66//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000B68//_postdmsc_iWideMult */ + 0x0F120607, /*70000B6A//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000B6C//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000B6E//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000B70//_yuvemix_mPosSlopes_3 */ + 0x0F120207, /*70000B72//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000B74//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000B76//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*70000B78//_yuviirnr_iUVNormShift */ + 0x0F120407, /*70000B7A//_yuviirnr_iVertLength_UV */ + 0x0F122404, /*70000B7C//_yuviirnr_iDiffThreshH_Y */ + 0x0F120221, /*70000B7E//_yuviirnr_iDiffThreshH_UV */ + 0x0F121202, /*70000B80//_yuviirnr_iMaxThreshH_Y*/ + 0x0F120613, /*70000B82//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000B84//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000B86//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000B88//_RGBGamma2_iLinearity */ + 0x0F120080, /*70000B8A//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000B8C//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000B8E//_bnr_iClustMulT_H */ + 0x0F120101, /*70000B90//_bnr_iClustThresh_H */ + 0x0F12121B, /*70000B92//_bnr_iDenThreshLow */ + 0x0F126024, /*70000B94//_ee_iLowSharpPower */ + 0x0F120C0C, /*70000B96//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000B98//_ee_iLowSharpClamp */ + 0x0F120808, /*70000B9A//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000B9C//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000B9E//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000BA0//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000BA2//_bnr_iDenThreshHigh_Bin */ + 0x0F120460, /*70000BA4//_ee_iHighSharpPower_Bin */ + 0x0F12FF04, /*70000BA6//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000BA8//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000BAA//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000BAC//_bnr_nClustLevel_C */ + 0x0F120000, /*70000BAE//_BRIGHTNESS AFIT 3 */ + 0x0F120000, /*70000BB0//_CONTRAST */ + 0x0F120000, /*70000BB2//_SATURATION */ + 0x0F120000, /*70000BB4//_SHARP_BLUR */ + 0x0F120000, /*70000BB6//_GLAMOUR */ + 0x0F1200C0, /*70000BB8//_bnr_edge_high */ + 0x0F120064, /*70000BBA//_postdmsc_iLowBright */ + 0x0F120384, /*70000BBC//_postdmsc_iHighBright */ + 0x0F120032, /*70000BBE//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000BC0//_postdmsc_iHighSat */ + 0x0F120070, /*70000BC2//_postdmsc_iTune */ + 0x0F120040, /*70000BC4//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000BC6//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000BC8//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000BCA//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000BCC//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000BCE//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000BD0//_bnr_edge_low */ + 0x0F120201, /*70000BD2//_bnr_repl_force */ + 0x0F120204, /*70000BD4//_bnr_iHotThreshLow */ + 0x0F121504, /*70000BD6//_bnr_iColdThreshLow */ + 0x0F12030F, /*70000BD8//_bnr_DispTH_High */ + 0x0F120003, /*70000BDA//_bnr_DISP_Limit_High */ + 0x0F120902, /*70000BDC//_bnr_iDistSigmaMax */ + 0x0F122004, /*70000BDE//_bnr_iDiffSigmaHigh */ + 0x0F120050, /*70000BE0//_bnr_iNormalizedSTD_Limit */ + 0x0F121140, /*70000BE2//_bnr_iDirMinThres */ + 0x0F12201C, /*70000BE4//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*70000BE6//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000BE8//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000BEA//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000BEC//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000BEE//_bnr_AddNoisePower1 */ + 0x0F120300, /*70000BF0//_bnr_iRadialTune */ + 0x0F12145A, /*70000BF2//_bnr_iRadialLimit */ + 0x0F121010, /*70000BF4//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000BF6//_ee_iFSVarThHigh */ + 0x0F121000, /*70000BF8//_ee_iFSThHigh */ + 0x0F125A0F, /*70000BFA//_ee_iFSVarCountTh */ + 0x0F120503, /*70000BFC//_ee_iRadialPower */ + 0x0F121802, /*70000BFE//_ee_iROADThres */ + 0x0F120000, /*70000C00//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000C02//_ee_iROADNeiThres */ + 0x0F123C28, /*70000C04//_ee_iSmoothEdgeThres */ + 0x0F12042C, /*70000C06//_ee_iWSharpen */ + 0x0F120101, /*70000C08//_ee_iWShThresh */ + 0x0F12FF00, /*70000C0A//_ee_iEmbossCentAdd */ + 0x0F120904, /*70000C0C//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000C0E//_dmsc_iDesatThresh */ + 0x0F120540, /*70000C10//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000C12//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000C14//_dmsc_iMonochrom */ + 0x0F120000, /*70000C16//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000C18//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000C1A//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000C1C//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000C1E//_postdmsc_iWideMult */ + 0x0F120607, /*70000C20//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000C22//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000C24//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000C26//_yuvemix_mPosSlopes_3 */ + 0x0F120206, /*70000C28//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000C2A//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000C2C//_yuviirnr_iHighUVNorm */ + 0x0F120305, /*70000C2E//_yuviirnr_iUVNormShift */ + 0x0F120406, /*70000C30//_yuviirnr_iVertLength_UV */ + 0x0F122804, /*70000C32//_yuviirnr_iDiffThreshH_Y */ + 0x0F120228, /*70000C34//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*70000C36//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*70000C38//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000C3A//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000C3C//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000C3E//_RGBGamma2_iLinearity */ + 0x0F120080, /*70000C40//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000C42//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000C44//_bnr_iClustMulT_H */ + 0x0F120101, /*70000C46//_bnr_iClustThresh_H */ + 0x0F120F15, /*70000C48//_bnr_iDenThreshLow */ + 0x0F126024, /*70000C4A//_ee_iLowSharpPower */ + 0x0F120A0A, /*70000C4C//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000C4E//_ee_iLowSharpClamp */ + 0x0F120808, /*70000C50//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000C52//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000C54//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000C56//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000C58//_bnr_iDenThreshHigh_Bin */ + 0x0F120260, /*70000C5A//_ee_iHighSharpPower_Bin */ + 0x0F12FF02, /*70000C5C//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000C5E//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000C60//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000C62//_bnr_nClustLevel_C */ + 0x0F120000, /*70000C64//_BRIGHTNESS AFIT 4 */ + 0x0F120000, /*70000C66//_CONTRAST */ + 0x0F120000, /*70000C68//_SATURATION */ + 0x0F120000, /*70000C6A//_SHARP_BLUR */ + 0x0F120000, /*70000C6C//_GLAMOUR */ + 0x0F1200C0, /*70000C6E//_bnr_edge_high */ + 0x0F120064, /*70000C70//_postdmsc_iLowBright */ + 0x0F120384, /*70000C72//_postdmsc_iHighBright */ + 0x0F120032, /*70000C74//_postdmsc_iLowSat */ + 0x0F1201F4, /*70000C76//_postdmsc_iHighSat */ + 0x0F120070, /*70000C78//_postdmsc_iTune */ + 0x0F120040, /*70000C7A//_yuvemix_mNegRanges_0 */ + 0x0F1200A0, /*70000C7C//_yuvemix_mNegRanges_1 */ + 0x0F120100, /*70000C7E//_yuvemix_mNegRanges_2 */ + 0x0F120010, /*70000C80//_yuvemix_mPosRanges_0 */ + 0x0F120060, /*70000C82//_yuvemix_mPosRanges_1 */ + 0x0F120100, /*70000C84//_yuvemix_mPosRanges_2 */ + 0x0F121430, /*70000C86//_bnr_edge_low */ + 0x0F120201, /*70000C88//_bnr_repl_force */ + 0x0F120204, /*70000C8A//_bnr_iHotThreshLow */ + 0x0F120F04, /*70000C8C//_bnr_iColdThreshLow */ + 0x0F12030C, /*70000C8E//_bnr_DispTH_High */ + 0x0F120003, /*70000C90//_bnr_DISP_Limit_High */ + 0x0F120602, /*70000C92//_bnr_iDistSigmaMax */ + 0x0F121803, /*70000C94//_bnr_iDiffSigmaHigh */ + 0x0F120040, /*70000C96//_bnr_iNormalizedSTD_Limit */ + 0x0F120E20, /*70000C98//_bnr_iDirMinThres */ + 0x0F122018, /*70000C9A//_bnr_iDirFltDiffThresLow */ + 0x0F120620, /*70000C9C//_bnr_iDirSmoothPowerLow */ + 0x0F120306, /*70000C9E//_bnr_iHighMaxSlopeAllowed */ + 0x0F122003, /*70000CA0//_bnr_iHighSlopeThresh */ + 0x0F12FF01, /*70000CA2//_bnr_iSlopeBlurStrength */ + 0x0F120404, /*70000CA4//_bnr_AddNoisePower1 */ + 0x0F120200, /*70000CA6//_bnr_iRadialTune */ + 0x0F12145A, /*70000CA8//_bnr_iRadialLimit */ + 0x0F121010, /*70000CAA//_ee_iFSMagThHigh */ + 0x0F12000B, /*70000CAC//_ee_iFSVarThHigh */ + 0x0F121200, /*70000CAE//_ee_iFSThHigh */ + 0x0F125A0F, /*70000CB0//_ee_iFSVarCountTh */ + 0x0F120502, /*70000CB2//_ee_iRadialPower */ + 0x0F121802, /*70000CB4//_ee_iROADThres */ + 0x0F120000, /*70000CB6//_ee_iROADSubMaxNR */ + 0x0F122006, /*70000CB8//_ee_iROADNeiThres */ + 0x0F124028, /*70000CBA//_ee_iSmoothEdgeThres */ + 0x0F120430, /*70000CBC//_ee_iWSharpen */ + 0x0F120101, /*70000CBE//_ee_iWShThresh */ + 0x0F12FF00, /*70000CC0//_ee_iEmbossCentAdd */ + 0x0F120804, /*70000CC2//_ee_iReduceEdgeThresh */ + 0x0F124008, /*70000CC4//_dmsc_iDesatThresh */ + 0x0F120540, /*70000CC6//_dmsc_iDemBlurLow */ + 0x0F128006, /*70000CC8//_dmsc_iDecisionThresh */ + 0x0F120020, /*70000CCA//_dmsc_iMonochrom */ + 0x0F120000, /*70000CCC//_dmsc_iGRDenoiseVal */ + 0x0F122000, /*70000CCE//_dmsc_iEdgeDesatThrLow */ + 0x0F120000, /*70000CD0//_dmsc_iNearGrayDesat */ + 0x0F121E10, /*70000CD2//_postdmsc_iBCoeff */ + 0x0F12000B, /*70000CD4//_postdmsc_iWideMult */ + 0x0F120607, /*70000CD6//_yuvemix_mNegSlopes_1 */ + 0x0F120005, /*70000CD8//_yuvemix_mNegSlopes_3 */ + 0x0F120607, /*70000CDA//_yuvemix_mPosSlopes_1 */ + 0x0F120405, /*70000CDC//_yuvemix_mPosSlopes_3 */ + 0x0F120205, /*70000CDE//_yuviirnr_iXSupportUV */ + 0x0F120304, /*70000CE0//_yuviirnr_iHighYNorm */ + 0x0F120409, /*70000CE2//_yuviirnr_iHighUVNorm */ + 0x0F120306, /*70000CE4//_yuviirnr_iUVNormShift */ + 0x0F120407, /*70000CE6//_yuviirnr_iVertLength_UV */ + 0x0F122C04, /*70000CE8//_yuviirnr_iDiffThreshH_Y */ + 0x0F12022C, /*70000CEA//_yuviirnr_iDiffThreshH_UV */ + 0x0F121402, /*70000CEC//_yuviirnr_iMaxThreshH_Y */ + 0x0F120618, /*70000CEE//_yuviirnr_iMaxThreshH_UV */ + 0x0F121A02, /*70000CF0//_yuviirnr_iYNRStrengthH */ + 0x0F128018, /*70000CF2//_yuviirnr_iUVNRStrengthH */ + 0x0F120080, /*70000CF4//_RGBGamma2_iLinearity */ + 0x0F120080, /*70000CF6//_ccm_oscar_iSaturation */ + 0x0F120180, /*70000CF8//_RGB2YUV_iRGBGain */ + 0x0F120A0A, /*70000CFA//_bnr_iClustMulT_H */ + 0x0F120101, /*70000CFC//_bnr_iClustThresh_H */ + 0x0F120C0F, /*70000CFE//_bnr_iDenThreshLow */ + 0x0F126024, /*70000D00//_ee_iLowSharpPower */ + 0x0F120808, /*70000D02//_ee_iLowShDenoise */ + 0x0F12FFFF, /*70000D04//_ee_iLowSharpClamp */ + 0x0F120808, /*70000D06//_ee_iReduceEdgeMinMult */ + 0x0F120A01, /*70000D08//_bnr_nClustLevel_H_Bin */ + 0x0F12010A, /*70000D0A//_bnr_iClustMulT_C_Bin */ + 0x0F120001, /*70000D0C//_bnr_iClustThresh_C_Bin */ + 0x0F122400, /*70000D0E//_bnr_iDenThreshHigh_Bin */ + 0x0F120060, /*70000D10//_ee_iHighSharpPower_Bin */ + 0x0F12FF00, /*70000D12//_ee_iHighShDenoise_Bin */ + 0x0F1240FF, /*70000D14//_ee_iHighSharpClamp_Bin */ + 0x0F120009, /*70000D16//_ee_iReduceEdgeSlope_Bin */ + 0x0F120001, /*70000D18//_bnr_nClustLevel_C */ + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_800_Preview_EVT1[] = { /* 800 x 480 // */ + 0xFCFCD000, + 0x00287000, + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */ + 0x0F120600, /*REG_TC_GP_PrevReqInputHeight //1536 */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs //(2592-2560)/2*/ + 0x0F1200CC, /*REG_TC_GP_PrevInputHeightOfs/(1944-1536)/2*/ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */ + 0x0F120600, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1536 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + + 0x002A02A6, + 0x0F120320, /*REG_0TC_PCFG_usWidth //800 */ + 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_720_Preview_EVT1[] = { /* 720 x 480 */ + 0xFCFCD000, + 0x00287000, + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */ + 0x0F1206A8, /*REG_TC_GP_PrevReqInputHeight //1704 */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs/(2592-2560)/2*/ + 0x0F120078, /*REG_TC_GP_PrevInputHeightOfs //(1944-1704)/2*/ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */ + 0x0F1206A8, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1704 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + + 0x002A02A6, + 0x0F1202D0, /*REG_0TC_PCFG_usWidth //720 */ + 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ +}; + +static const u32 s5k4ecgx_640_Preview_EVT1[] = { /* 640 x 480 */ + 0xFCFCD000, + 0x00287000, + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs/(2592-2560)/2*/ + 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs/(1944-1920)/2*/ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + + 0x002A02A6, + 0x0F120280, /*REG_0TC_PCFG_usWidth //640 */ + 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_352_Preview_EVT1[] = { /* 352 x 288 */ + 0xFCFCD000, + 0x00287000, + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + 0x002A0250, + 0x0F120928, /*REG_TC_GP_PrevReqInputWidth //2344 */ + 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */ + 0x0F12007C, /*REG_TC_GP_PrevInputWidthOfs //(2592-2344)/2 */ + 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs //(1944-1920)/2 */ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + + 0x002A0494, + 0x0F120928, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2344 */ + 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + + 0x002A02A6, + 0x0F120160, /*REG_0TC_PCFG_usWidth //352 */ + 0x0F120120, /*REG_0TC_PCFG_usHeight //288 */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_320_Preview_EVT1[] = { /* 320 x 240 */ + 0xFCFCD000, + 0x00287000, + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + 0x002A0250, + 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */ + 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs //(2592-2560)/2 */ + 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs //(1944-1920)/2*/ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + + 0x002A0494, + 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */ + 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + + 0x002A02A6, + 0x0F120140, /*REG_0TC_PCFG_usWidth //320 */ + 0x0F1200F0, /*REG_0TC_PCFG_usHeight //240 */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ + +}; + +static const u32 s5k4ecgx_176_Preview_EVT1[] = { /* 176 x 144 */ + 0xFCFCD000, + 0x00287000, + + 0x002A18AC, + 0x0F120060, /*senHal_uAddColsBin */ + 0x0F120060, /*senHal_uAddColsNoBin */ + 0x0F1205C0, /*senHal_uMinColsBin */ + 0x0F1205C0, /*senHal_uMinColsNoBin */ + + 0x002A0250, + 0x0F120928, /*REG_TC_GP_PrevReqInputWidth //2344 */ + 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */ + 0x0F12007C, /*REG_TC_GP_PrevInputWidthOfs //(2592-2344)/2 */ + 0x0F12000C,/*REG_TC_GP_PrevInputHeightOfs/(1944-1920)/2*/ + + 0x002A0262, + 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */ + + 0x002A0494, + 0x0F120928, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2344 */ + 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */ + 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */ + + 0x002A02A6, + 0x0F1200B0, /*REG_0TC_PCFG_usWidth //176 */ + 0x0F120090, /*REG_0TC_PCFG_usHeight //144 */ + + 0x002A0266, + 0x0F120000, /*REG_TC_GP_ActivePrevConfig */ + 0x002A026A, + 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */ + 0x002A024E, + 0x0F120001, /*REG_TC_GP_NewConfigSync */ + 0x002A0268, + 0x0F120001, /*REG_TC_GP_PrevConfigChanged */ +}; + +/* Zoom set for 320,176*/ +static const u32 s5k4ecgx_X4_Zoom_0_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120100, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120120, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120140, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120160, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120180, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_5_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201A0, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_6_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201C0, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_7_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201E0, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X4_Zoom_8_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120200, + 0x002A04A4, + 0x0F120005, +}; + +/* Zoom set for 1280 x 640*/ +static const u32 s5k4ecgx_X2_Zoom_0_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120100, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120120, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120140, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120160, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120180, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_5_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201A0, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_6_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201C0, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_7_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201E0, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X2_Zoom_8_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120200, + 0x002A04A4, + 0x0F120005, +}; + +/* Zoom set for 720*/ +static const u32 s5k4ecgx_X1_77_Zoom_0_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120100, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120118, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120130, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120148, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120160, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_5_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120178, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_6_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120190, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_7_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201A8, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_77_Zoom_8_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F1201C5, + 0x002A04A4, + 0x0F120005, +}; + +/* Zoom set for 1600 */ +static const u32 s5k4ecgx_X1_6_Zoom_0_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120100, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120113, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120126, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120139, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F12014C, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_5_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F12015F, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_6_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120172, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_7_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120185, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_6_Zoom_8_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F12019A, + 0x002A04A4, + 0x0F120005, +}; + +/* Zoom set for 2048 */ +static const u32 s5k4ecgx_X1_25_Zoom_0_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120100, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_1_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120108, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_2_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120110, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_3_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120118, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_4_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120120, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_5_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120128, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_6_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120130, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_7_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120138, + 0x002A04A4, + 0x0F120005, +}; + +static const u32 s5k4ecgx_X1_25_Zoom_8_EVT1[] = { + 0xFCFCD000, + 0x00287000, + 0x002A048E, + 0x0F120140, + 0x002A04A4, + 0x0F120005, +}; + +#endif /* __S5K4ECGX_SETFILE_H */ diff --git a/drivers/media/video/sr200pc20m.h b/drivers/media/video/sr200pc20m.h index 1a42088..64a3dd9 100644 --- a/drivers/media/video/sr200pc20m.h +++ b/drivers/media/video/sr200pc20m.h @@ -252,18 +252,10 @@ static s32 large_file; #define dbg_setfile(fmt, ...) #endif /* 0 */ -#ifdef CONFIG_MACH_S2PLUS -#define TUNING_FILE_PATH "/mnt/sdcard/sr200pc20m_regs-s2plus.h" -#else #define TUNING_FILE_PATH "/mnt/sdcard/sr200pc20m_regs.h" -#endif /* CONFIG_VIDEO_SR200PC20M */ #endif /* CONFIG_LOAD_FILE */ -#ifdef CONFIG_MACH_S2PLUS -#include "sr200pc20m_regs-s2plus.h" -#else #include "sr200pc20m_regs.h" -#endif #endif /* __SR200PC20M_H */ diff --git a/drivers/media/video/sr200pc20m_regs-s2plus.h b/drivers/media/video/sr200pc20m_regs-s2plus.h deleted file mode 100644 index b2b18f3..0000000 --- a/drivers/media/video/sr200pc20m_regs-s2plus.h +++ /dev/null @@ -1,4168 +0,0 @@ -/* - * Driver for SR200PC20M 2M ISP from Samsung - * Latest version: 11/11/23 - * - * Copyright (c) 2011, Samsung Electronics. All rights reserved - * Author: DongSeong Lim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef __SR200PC20M_REGS_H -#define __SR200PC20M_REGS_H - -#include - -/* - * sr200pc20m register configuration for combinations of initialization - */ -/* 2M mipi setting-common from PARTRON */ -/******************************************************* -* Name: SR200PC20M Initial Setfile -* PLL mode: MCLK=24MHz / SYSCLK=28MHz / PCLK=48MHz -* FPS: VGA 7.5~15fps / UXGA 7.5fps / recording 25fps -* Made by: ZEROHOY -* Date: 2011.03.07 -* History: -*******************************************************/ -regs_short_t front_init_regs[] = { -/* Self-Cam -continuous*/ -/* CAMERA INITIAL for Self Camera(Variable Frame)*/ - -{0x01, 0xf9},/* sleep on */ -{0x01, 0xfb},/* sleep on */ -{0x01, 0xf9},/* sleep on */ -{0x08, 0x20},/* sleep on */ -{0x0a, 0x3f},/* sleep on */ - -/* PAGE 20 */ -{0x03, 0x20},/* page 20 */ -{0x10, 0x0c},/* AE off 60hz */ - -/* PAGE 22 */ -{0x03, 0x22},/* page 22 */ -{0x10, 0x69},/* AWB off */ - -{0x03, 0x12}, -{0x20, 0x00}, -{0x21, 0x00}, - -{0x03, 0x13}, -{0x10, 0xcb}, - -/* Initial Start */ -/* PAGE 0 START */ -{0x03, 0x00}, -{0x10, 0x11},/* Vsync Active High B:[3] , Sub1/2 + Preview 1mode */ -{0x11, 0x90}, -{0x12, 0x04},/* Pclk Falling Edge B:[2] *//* 1016 0x04->0x00 */ - -{0x0b, 0xaa},/* ESD Check Register */ -{0x0c, 0xaa},/* ESD Check Register */ -{0x0d, 0xaa},/* ESD Check Register */ - -{0x20, 0x00}, -{0x21, 0x02},/* modify 20110929 0x04->0x02 */ -{0x22, 0x00}, -{0x23, 0x0a},/* modify 20110929 0x14->0x0a */ - -{0x24, 0x04}, -{0x25, 0xb0}, -{0x26, 0x06}, -{0x27, 0x40}, - -{0x28, 0x0c}, -{0x29, 0x04}, -{0x2a, 0x02}, -{0x2b, 0x04}, -{0x2c, 0x06}, -{0x2d, 0x02}, - -{0x40, 0x01},/* Hblank_360 */ -{0x41, 0x68}, -{0x42, 0x00}, -{0x43, 0x44},/* Flick Stop 60hz */ -{0x44, 0x09},/* VSCLIP */ - -{0x45, 0x04}, -{0x46, 0x18}, -{0x47, 0xd8}, - - /*BLC*/ {0x80, 0x2e}, -{0x81, 0x7e}, -{0x82, 0x90}, -{0x83, 0x00}, -{0x84, 0x0c}, -{0x85, 0x00}, -{0x90, 0x0f},/* BLC_TIME_TH_ON */ -{0x91, 0x0f},/* BLC_TIME_TH_OFF */ -{0x92, 0xd8},/* BLC_AG_TH_ON */ -{0x93, 0xd0},/* BLC_AG_TH_OFF */ -{0x94, 0xff}, -{0x95, 0xff}, -{0x96, 0xdc}, -{0x97, 0xfe}, -{0x98, 0x38}, - -/*Dark BLC*/ -{0xa0, 0x00}, -{0xa2, 0x00}, -{0xa4, 0x00}, -{0xa6, 0x00}, - -/*Normal BLC*/ -{0xa8, 0x43}, -{0xaa, 0x43}, -{0xac, 0x43}, -{0xae, 0x43}, - -/*OutDoor BLC*/ -{0x99, 0x43}, -{0x9a, 0x43}, -{0x9b, 0x43}, -{0x9c, 0x43}, -/* PAGE 0 END */ - -/* PAGE 2 START */ -{0x03, 0x02}, -{0x12, 0x03}, -{0x13, 0x03}, -{0x16, 0x00}, -{0x17, 0x8C}, -{0x18, 0x4c},/* Double_AG */ -{0x19, 0x00}, -{0x1a, 0x39},/* Double_AG 38 ->39 */ -{0x1c, 0x09}, -{0x1d, 0x40}, -{0x1e, 0x30}, -{0x1f, 0x10}, - -{0x20, 0x77}, -{0x21, 0xde}, -{0x22, 0xa7}, -{0x23, 0x30},/* CLAMP */ -{0x27, 0x3c}, -{0x2b, 0x80}, -{0x2e, 0x00}, -{0x2f, 0x00}, -{0x30, 0x05},/* For Hi-253 never no change 0x05 */ - -{0x50, 0x20}, -{0x51, 0x03},/* 20110826 Ãß°¡ */ -{0x52, 0x01},/* 0x03 --> 0x01 */ -{0x53, 0xc1},/* 20110818 Ãß°¡ */ -{0x55, 0x1c}, -{0x56, 0x11}, -{0x5d, 0xa2}, -{0x5e, 0x5a}, - -{0x60, 0x87}, -{0x61, 0x99}, -{0x62, 0x88}, -{0x63, 0x97}, -{0x64, 0x88}, -{0x65, 0x97}, - -{0x67, 0x0c}, -{0x68, 0x0c}, -{0x69, 0x0c}, - -{0x72, 0x89}, -{0x73, 0x96}, -{0x74, 0x89}, -{0x75, 0x96}, -{0x76, 0x89}, -{0x77, 0x96}, - -{0x7c, 0x85}, -{0x7d, 0xaf}, -{0x80, 0x01}, -{0x81, 0x7f}, -{0x82, 0x13}, -{0x83, 0x24}, -{0x84, 0x7d}, -{0x85, 0x81}, -{0x86, 0x7d}, -{0x87, 0x81}, - -{0x92, 0x48}, -{0x93, 0x54}, -{0x94, 0x7d}, -{0x95, 0x81}, -{0x96, 0x7d}, -{0x97, 0x81}, - -{0xa0, 0x02}, -{0xa1, 0x7b}, -{0xa2, 0x02}, -{0xa3, 0x7b}, -{0xa4, 0x7b}, -{0xa5, 0x02}, -{0xa6, 0x7b}, -{0xa7, 0x02}, - -{0xa8, 0x85}, -{0xa9, 0x8c}, -{0xaa, 0x85}, -{0xab, 0x8c}, -{0xac, 0x10}, -{0xad, 0x16}, -{0xae, 0x10}, -{0xaf, 0x16}, - -{0xb0, 0x99}, -{0xb1, 0xa3}, -{0xb2, 0xa4}, -{0xb3, 0xae}, -{0xb4, 0x9b}, -{0xb5, 0xa2}, -{0xb6, 0xa6}, -{0xb7, 0xac}, -{0xb8, 0x9b}, -{0xb9, 0x9f}, -{0xba, 0xa6}, -{0xbb, 0xaa}, -{0xbc, 0x9b}, -{0xbd, 0x9f}, -{0xbe, 0xa6}, -{0xbf, 0xaa}, - -{0xc4, 0x2c}, -{0xc5, 0x43}, -{0xc6, 0x63}, -{0xc7, 0x79}, - -{0xc8, 0x2d}, -{0xc9, 0x42}, -{0xca, 0x2d}, -{0xcb, 0x42}, -{0xcc, 0x64}, -{0xcd, 0x78}, -{0xce, 0x64}, -{0xcf, 0x78}, -{0xd0, 0x0a}, -{0xd1, 0x09}, -{0xd4, 0x0f},/* DCDC_TIME_TH_ON */ -{0xd5, 0x0f},/* DCDC_TIME_TH_OFF */ -{0xd6, 0xd8},/* DCDC_AG_TH_ON */ -{0xd7, 0xd0},/* DCDC_AG_TH_OFF */ -{0xe0, 0xc4}, -{0xe1, 0xc4}, -{0xe2, 0xc4}, -{0xe3, 0xc4}, -{0xe4, 0x00}, -{0xe8, 0x80}, -{0xe9, 0x40}, -{0xea, 0x7f}, - -{0xf0, 0x01}, -{0xf1, 0x01}, -{0xf2, 0x01}, -{0xf3, 0x01}, -{0xf4, 0x01}, - -/* PAGE 2 END */ - -/* PAGE 3 */ -{0x03, 0x03}, -{0x10, 0x10}, -/* PAGE 3 END */ - -/* PAGE 10 START */ -{0x03, 0x10}, -{0x10, 0x01},/* CrYCbY 03 00 */ -{0x12, 0x30}, -{0x20, 0x00}, -{0x30, 0x00}, -{0x31, 0x00}, -{0x32, 0x00}, -{0x33, 0x00}, - -{0x34, 0x30}, -{0x35, 0x00}, -{0x36, 0x00}, -{0x38, 0x00}, -{0x3e, 0x58}, -{0x3f, 0x02},/* For Preview */ - -{0x40, 0x80}, -{0x41, 0x00}, - -{0x60, 0x6b}, -{0x61, 0x7a},/* 77 */ -{0x62, 0x72},/* 77 */ -{0x63, 0x50},/* Double_AG 50->30 */ -{0x64, 0x80}, - -{0x66, 0x42}, -{0x67, 0x20}, - -{0x6a, 0x80},/* 8a */ -{0x6b, 0x84},/* 74 */ -{0x6c, 0x7a},/* 7e */ -{0x6d, 0x80},/* 8e */ - -/* PAGE 11 START */ -{0x03, 0x11}, -{0x10, 0x7f}, -{0x11, 0x40}, -{0x12, 0x0a},/* Blue Max-Filter Delete */ -{0x13, 0xbb}, - -{0x26, 0x31},/* Double_AG 31->20 */ -{0x27, 0x34},/* Double_AG 34->22 */ -{0x28, 0x0f}, -{0x29, 0x10}, -{0x2b, 0x30}, -{0x2c, 0x32}, - -/*Out2 D-LPF th*/ -{0x30, 0x70}, -{0x31, 0x10}, -{0x32, 0x58}, -{0x33, 0x09}, -{0x34, 0x06}, -{0x35, 0x03}, - -/*Out1 D-LPF th*/ -{0x36, 0x70}, -{0x37, 0x18}, -{0x38, 0x58}, -{0x39, 0x20}, -{0x3a, 0x1f}, -{0x3b, 0x03}, - -/*Indoor D-LPF th*/ -{0x3c, 0x80}, -{0x3d, 0x18}, -{0x3e, 0x80}, -{0x3f, 0x0c}, -{0x40, 0x09}, -{0x41, 0x06}, - -/*Dark1 D-LPF th*/ -{0x42, 0x80}, -{0x43, 0x18}, -{0x44, 0x80}, -{0x45, 0x0f}, -{0x46, 0x0c}, -{0x47, 0x0b}, - -/*Dark2 D-LPF th*/ -{0x48, 0x88}, -{0x49, 0x2c}, -{0x4a, 0x80}, -{0x4b, 0x0f}, -{0x4c, 0x0c}, -{0x4d, 0x0b}, - -/*Dark3 D-LPF th*/ -{0x4e, 0x80}, -{0x4f, 0x23}, -{0x50, 0x80}, -{0x51, 0x0f}, -{0x52, 0x0c}, -{0x53, 0x0c}, - -{0x54, 0x11}, -{0x55, 0x17}, -{0x56, 0x20}, -{0x57, 0x01}, -{0x58, 0x00}, -{0x59, 0x00}, - -{0x5a, 0x18}, -{0x5b, 0x00}, -{0x5c, 0x00}, - -{0x60, 0x3f}, -{0x62, 0x60}, -{0x70, 0x06}, -/* PAGE 11 END */ - -/* PAGE 12 START */ -{0x03, 0x12}, - -{0x25, 0x00},/* 0x30 */ - -{0x28, 0x00}, -{0x29, 0x00}, -{0x2a, 0x00}, - -{0x30, 0x50}, -{0x31, 0x18}, -{0x32, 0x32}, -{0x33, 0x40}, -{0x34, 0x50}, -{0x35, 0x70}, -{0x36, 0xa0}, - -/*Out2 th*/ -{0x40, 0xa0}, -{0x41, 0x40}, -{0x42, 0xa0}, -{0x43, 0x90}, -{0x44, 0x90}, -{0x45, 0x80}, - -/*Out1 th*/ -{0x46, 0xb0}, -{0x47, 0x55}, -{0x48, 0xb0}, -{0x49, 0xb0}, -{0x4a, 0x90}, -{0x4b, 0x80}, - -/*Indoor th*/ -{0x4c, 0xb0}, -{0x4d, 0x40}, -{0x4e, 0x90}, -{0x4f, 0x90}, -{0x50, 0xa0}, -{0x51, 0x80}, - -/*Dark1 th*/ -{0x52, 0xb0}, -{0x53, 0x50}, -{0x54, 0xa8}, -{0x55, 0xa8}, -{0x56, 0xb0}, -{0x57, 0x7b}, - -/*Dark2 th*/ -{0x58, 0xa0}, -{0x59, 0x40}, -{0x5a, 0xb8}, -{0x5b, 0xb8}, -{0x5c, 0xc8}, -{0x5d, 0x7b}, - -/*Dark3 th*/ -{0x5e, 0x9c}, -{0x5f, 0x40}, -{0x60, 0xc0}, -{0x61, 0xc0}, -{0x62, 0xc8}, -{0x63, 0x7b}, - -{0x70, 0x15}, -{0x71, 0x01},/* Don't Touch register */ - -{0x72, 0x18}, -{0x73, 0x01},/* Don't Touch register */ - -{0x74, 0x25}, -{0x75, 0x15}, - -{0x80, 0x20}, -{0x81, 0x40}, -{0x82, 0x65}, -{0x85, 0x1a}, -{0x88, 0x00}, -{0x89, 0x00}, -{0x90, 0x00},/* For Preview */ - -/*Dont Touch register*/ -{0xD0, 0x0c}, -{0xD1, 0x80}, - -/*only for Preview DPC*/ -{0xD2, 0x17}, - -{0xD3, 0x00}, -{0xD4, 0x00}, - -/*only for Preview DPC*/ -{0xd5, 0x0f}, - -{0xD6, 0xff}, - -/*only for Preview DPC*/ -{0xd7, 0xff}, - -/*End*/ -{0x3b, 0x06}, -{0x3c, 0x06}, - -/*Dont Touch register*/ -{0xc5, 0x30},/* 55->48 */ -{0xc6, 0x2a},/* 48->40 */ -/* PAGE 12 END */ - -/* PAGE 13 START */ - -{0x03, 0x13}, -{0x11, 0x7b}, -{0x12, 0x07}, -{0x14, 0x00}, - -{0x20, 0x15}, -{0x21, 0x13}, -{0x22, 0x33}, -{0x23, 0x05}, -{0x24, 0x09}, - -{0x25, 0x0a}, - -{0x26, 0x18}, -{0x27, 0x30}, -{0x29, 0x12}, -{0x2a, 0x50}, - -/*Low clip th*/ -{0x2b, 0x02}, -{0x2c, 0x02}, -{0x25, 0x06}, -{0x2d, 0x0c}, -{0x2e, 0x12}, -{0x2f, 0x12}, - -/*Out2 Edge*/ -{0x50, 0x10}, -{0x51, 0x14}, -{0x52, 0x12}, -{0x53, 0x0c}, -{0x54, 0x0f}, -{0x55, 0x0c}, - -/*Out1 Edge*/ -{0x56, 0x0f}, -{0x57, 0x12}, -{0x58, 0x12}, -{0x59, 0x09}, -{0x5a, 0x0c}, -{0x5b, 0x0c}, - -/*Indoor Edge*/ -{0x5c, 0x0a}, -{0x5d, 0x0b}, -{0x5e, 0x0a}, -{0x5f, 0x08}, -{0x60, 0x09}, -{0x61, 0x08}, - -/*Dark1 Edge*/ -{0x62, 0x09}, -{0x63, 0x09}, -{0x64, 0x09}, -{0x65, 0x07}, -{0x66, 0x07}, -{0x67, 0x07}, - -/*Dark2 Edge*/ -{0x68, 0x08}, -{0x69, 0x08}, -{0x6a, 0x08}, -{0x6b, 0x06}, -{0x6c, 0x06}, -{0x6d, 0x06}, - -/*Dark3 Edge*/ -{0x6e, 0x08}, -{0x6f, 0x08}, -{0x70, 0x08}, -{0x71, 0x06}, -{0x72, 0x06}, -{0x73, 0x06}, - -/*2DY*/ -{0x80, 0x00}, -{0x81, 0x1f}, -{0x82, 0x05}, -{0x83, 0x31}, - -{0x90, 0x05}, -{0x91, 0x05}, -{0x92, 0x33}, -{0x93, 0x30}, -{0x94, 0x03}, -{0x95, 0x14}, -{0x97, 0x20}, -{0x99, 0x20}, - -{0xa0, 0x01}, -{0xa1, 0x02}, -{0xa2, 0x01}, -{0xa3, 0x02}, -{0xa4, 0x05}, -{0xa5, 0x05}, -{0xa6, 0x07}, -{0xa7, 0x08}, -{0xa8, 0x07}, -{0xa9, 0x08}, -{0xaa, 0x07}, -{0xab, 0x08}, - -/*Out2*/ -{0xb0, 0x22}, -{0xb1, 0x2a}, -{0xb2, 0x28}, -{0xb3, 0x22}, -{0xb4, 0x2a}, -{0xb5, 0x28}, - -/*Out1*/ -{0xb6, 0x22}, -{0xb7, 0x2a}, -{0xb8, 0x28}, -{0xb9, 0x22}, -{0xba, 0x2a}, -{0xbb, 0x28}, - -/*Indoor*/ -{0xbc, 0x25}, -{0xbd, 0x2a}, -{0xbe, 0x27}, -{0xbf, 0x25}, -{0xc0, 0x2a}, -{0xc1, 0x27}, - -/*Dark1*/ -{0xc2, 0x1e}, -{0xc3, 0x24}, -{0xc4, 0x20}, -{0xc5, 0x1e}, -{0xc6, 0x24}, -{0xc7, 0x20}, - -/*Dark2*/ -{0xc8, 0x18}, -{0xc9, 0x20}, -{0xca, 0x1e}, -{0xcb, 0x18}, -{0xcc, 0x20}, -{0xcd, 0x1e}, - -/*Dark3*/ -{0xce, 0x18}, -{0xcf, 0x20}, -{0xd0, 0x1e}, -{0xd1, 0x18}, -{0xd2, 0x20}, -{0xd3, 0x1e}, -/* PAGE 13 END */ - -/* PAGE 14 START */ -{0x03, 0x14}, -{0x10, 0x11}, - -{0x14, 0x80},/* GX */ -{0x15, 0x80},/* GY */ -{0x16, 0x80},/* RX */ -{0x17, 0x80},/* RY */ -{0x18, 0x80},/* BX */ -{0x19, 0x80},/* BY */ - -{0x20, 0x80},/* X */ -{0x21, 0x80},/* Y */ - -{0x22, 0x80}, -{0x23, 0x80}, -{0x24, 0x80}, - -{0x30, 0xc8}, -{0x31, 0x2b}, -{0x32, 0x00}, -{0x33, 0x00}, -{0x34, 0x90}, - -{0x40, 0x37}, -{0x50, 0x26},/* 2d */ -{0x60, 0x22},/* 26 */ -{0x70, 0x26},/* 2d */ -/* PAGE 14 END */ - -/* PAGE 15 START */ -{0x03, 0x15}, -{0x10, 0x0f}, - -/*Rstep H 16*/ -/*Rstep L 14*/ -{0x14, 0x46},/* CMCOFSGH */ -{0x15, 0x36},/* CMCOFSGM */ -{0x16, 0x26},/* CMCOFSGL */ -{0x17, 0x2f},/* CMC SIGN */ - - /*CMC*/ {0x30, 0x8f}, -{0x31, 0x59}, -{0x32, 0x0a}, -{0x33, 0x15}, -{0x34, 0x5b}, -{0x35, 0x06}, -{0x36, 0x07}, -{0x37, 0x40}, -{0x38, 0x87}, - -/*CMC OFS*/ -{0x40, 0x94}, -{0x41, 0x20}, -{0x42, 0x89}, -{0x43, 0x84}, -{0x44, 0x03}, -{0x45, 0x01}, -{0x46, 0x88}, -{0x47, 0x9c}, -{0x48, 0x28}, - -/*CMC POFS*/ -{0x50, 0x02}, -{0x51, 0x82}, -{0x52, 0x00}, -{0x53, 0x07}, -{0x54, 0x11}, -{0x55, 0x98}, -{0x56, 0x00}, -{0x57, 0x0b}, -{0x58, 0x8b}, - -{0x80, 0x00}, -{0x85, 0x80}, -{0x87, 0x02}, -{0x88, 0x00}, -{0x89, 0x00}, -{0x8a, 0x00}, -/* PAGE 15 END */ - -/* PAGE 16 START */ -{0x03, 0x16}, -{0x10, 0x31}, -{0x18, 0x5e},/* Double_AG 5e->37 */ -{0x19, 0x5d},/* Double_AG 5e->36 */ -{0x1a, 0x0e}, -{0x1b, 0x01}, -{0x1c, 0xdc}, -{0x1d, 0xfe}, - -/*GMA Default*/ -{0x30, 0x00}, -{0x31, 0x08}, -{0x32, 0x1c}, -{0x33, 0x32}, -{0x34, 0x54}, -{0x35, 0x70}, -{0x36, 0x87}, -{0x37, 0x9a}, -{0x38, 0xaa}, -{0x39, 0xb9}, -{0x3a, 0xc4}, -{0x3b, 0xcf}, -{0x3c, 0xd8}, -{0x3d, 0xe0}, -{0x3e, 0xe9}, -{0x3f, 0xf0}, -{0x40, 0xf7}, -{0x41, 0xfc}, -{0x42, 0xff}, - -{0x50, 0x00}, -{0x51, 0x08}, -{0x52, 0x1e}, -{0x53, 0x36}, -{0x54, 0x5a}, -{0x55, 0x75}, -{0x56, 0x8d}, -{0x57, 0xa1}, -{0x58, 0xb2}, -{0x59, 0xbe}, -{0x5a, 0xc9}, -{0x5b, 0xd2}, -{0x5c, 0xdb}, -{0x5d, 0xe3}, -{0x5e, 0xeb}, -{0x5f, 0xf0}, -{0x60, 0xf5}, -{0x61, 0xf7}, -{0x62, 0xf8}, - -{0x70, 0x00}, -{0x71, 0x0b}, -{0x72, 0x1a}, -{0x73, 0x37}, -{0x74, 0x58}, -{0x75, 0x70}, -{0x76, 0x86}, -{0x77, 0x99}, -{0x78, 0xa9}, -{0x79, 0xb7}, -{0x7a, 0xc3}, -{0x7b, 0xcf}, -{0x7c, 0xd9}, -{0x7d, 0xe1}, -{0x7e, 0xe8}, -{0x7f, 0xef}, -{0x80, 0xf4}, -{0x81, 0xfa}, -{0x82, 0xff}, -/* PAGE 16 END */ - -/* PAGE 17 START */ -{0x03, 0x17}, -{0x10, 0xf7}, -/* PAGE 17 END */ - -/* PAGE 18 START */ -{0x03, 0x18}, -{0x10, 0x07}, -{0x11, 0x00}, -{0x12, 0x58}, -{0x20, 0x05}, -{0x21, 0x00}, -{0x22, 0x01}, -{0x23, 0xe0}, -{0x24, 0x00}, -{0x25, 0x04}, -{0x26, 0x00}, -{0x27, 0x04}, -{0x28, 0x05}, -{0x29, 0x04}, -{0x2a, 0x01}, -{0x2b, 0xe4}, -{0x2c, 0x0a}, -{0x2d, 0x00}, -{0x2e, 0x0a}, -{0x2f, 0x00}, -{0x30, 0x46}, -/* PAGE 18 END */ - -/* PAGE 20 START */ -{0x03, 0x20}, -{0x11, 0x1c}, -{0x18, 0x30}, -{0x1a, 0x08}, -{0x20, 0x05}, -{0x21, 0x30}, -{0x22, 0x10}, -{0x23, 0x00}, -{0x24, 0x00}, - -{0x28, 0xef}, -{0x29, 0x0d},/* 20100305 ad->0d */ -{0x2a, 0xff}, -{0x2b, 0xf4}, - -{0x2c, 0xc2}, -{0x2d, 0xff}, -{0x2e, 0x33}, -{0x30, 0xf8}, -{0x32, 0x03}, -{0x33, 0x2e}, -{0x34, 0x30}, -{0x35, 0xd4}, -{0x36, 0xfe}, -{0x37, 0x32}, -{0x38, 0x04}, -{0x39, 0x22}, -{0x3a, 0xde}, -{0x3b, 0x22}, -{0x3c, 0xde}, - -{0x50, 0x45}, -{0x51, 0x88}, - -{0x56, 0x03}, -{0x57, 0xf7}, -{0x58, 0x14}, -{0x59, 0x88}, -{0x5a, 0x04}, - -{0x60, 0xaa}, -{0x61, 0xaa}, -{0x62, 0xaa}, -{0x63, 0xaa}, -{0x64, 0xaa}, -{0x65, 0xaa}, -{0x66, 0xab}, -{0x67, 0xEa}, -{0x68, 0xab}, -{0x69, 0xEa}, -{0x6a, 0xaa}, -{0x6b, 0xaa}, -{0x6c, 0xaa}, -{0x6d, 0xaa}, -{0x6e, 0xaa}, -{0x6f, 0xaa}, - -{0x70, 0x70},/* 6c */ -{0x71, 0x82},/* 82(+8) */ - -{0x76, 0x43}, -{0x77, 0x02}, -{0x78, 0x24},/* 24 */ -{0x79, 0x48},/* Y Target 70 => 25, 72 => 26 */ -{0x7a, 0x23},/* 23 */ -{0x7b, 0x22},/* 22 */ -{0x7d, 0x23}, - -{0x83, 0x01},/* EXP Normal 30.00 fps */ -{0x84, 0x86}, -{0x85, 0xa0}, - -{0x86, 0x01},/* EXPMin 6000.00 fps */ -{0x87, 0xf4}, - -{0x88, 0x05},/* EXP Max 8.00 fps */ -{0x89, 0xb8}, -{0x8a, 0xd8}, - -{0x8B, 0x75},/* EXP100, PLLx2 Mclk24 */ -{0x8C, 0x30}, - -{0x8D, 0x61},/* EXP120, PLLx2 Mclk24 */ -{0x8E, 0xa8}, - -{0x98, 0x9d}, -{0x99, 0x45}, -{0x9a, 0x0d}, -{0x9b, 0xde}, - -{0x9c, 0x17},/* EXP Limit 500.00 fps, PLLx2 Mclk24 */ -{0x9d, 0x70}, - -{0x9e, 0x01},/* EXP Unit, PLLx2 Mclk24 */ -{0x9f, 0xf4}, - -{0xb0, 0x18}, -{0xb1, 0x14}, -{0xb2, 0xe0}, -{0xb3, 0x18}, -{0xb4, 0x1a}, -{0xb5, 0x44}, -{0xb6, 0x2f}, -{0xb7, 0x28}, -{0xb8, 0x25}, -{0xb9, 0x22}, -{0xba, 0x21}, -{0xbb, 0x20}, -{0xbc, 0x32}, -{0xbd, 0x32}, - -{0xc0, 0x10}, -{0xc1, 0x2b}, -{0xc2, 0x2b}, -{0xc3, 0x2b}, -{0xc4, 0x08}, - -{0xc8, 0x80}, -{0xc9, 0x80}, -/* PAGE 20 END */ - -/* PAGE 22 START */ -{0x03, 0x22}, -{0x10, 0xfd}, -{0x11, 0x2e}, -{0x19, 0x01},/* Low On */ -{0x20, 0x10}, -{0x21, 0x80}, -{0x24, 0x01}, -/*0x2500, 7f New Lock Cond & New light stable */ - -{0x30, 0x80}, -{0x31, 0x80}, -{0x38, 0x11}, -{0x39, 0x34}, -{0x40, 0xf3}, - -{0x41, 0x32},/* 33 */ -{0x42, 0x22},/* 22 */ -{0x43, 0xf0},/* f6 */ -{0x44, 0x44},/* 44 */ -{0x45, 0x44},/* 33 */ -{0x46, 0x00}, -{0x50, 0xb2}, -{0x51, 0x81}, -{0x52, 0x98}, - -{0x80, 0x38}, -{0x81, 0x20}, -{0x82, 0x36},/* 3a */ - -{0x83, 0x5e},/* 5e */ -{0x84, 0x22},/* 24 21 22 Spec AWB H modify */ -{0x85, 0x4f},/* 54 51 4f Spec AWB H modify */ -{0x86, 0x20},/* 24 */ - -{0x87, 0x48}, -{0x88, 0x38}, -{0x89, 0x37},/* 38 */ -{0x8a, 0x29},/* 2a */ - -{0x8b, 0x40},/* 47 */ -{0x8c, 0x38}, -{0x8d, 0x34}, -{0x8e, 0x29},/* 2c */ - -{0x8f, 0x5c}, -{0x90, 0x5b}, -{0x91, 0x57}, -{0x92, 0x4f}, -{0x93, 0x43}, -{0x94, 0x3e}, -{0x95, 0x34}, -{0x96, 0x2c}, -{0x97, 0x23}, -{0x98, 0x20}, -{0x99, 0x1f}, -{0x9a, 0x1f}, - -{0x9b, 0x77}, -{0x9c, 0x66}, -{0x9d, 0x48}, -{0x9e, 0x38}, -{0x9f, 0x30}, - -{0xa0, 0x60}, -{0xa1, 0x34}, -{0xa2, 0x6f}, -{0xa3, 0xff}, - -{0xa4, 0x14},/* 1500fps */ -{0xa5, 0x2c},/* 700fps */ -{0xa6, 0xcf}, - -{0xad, 0x40}, -{0xae, 0x4a}, - -{0xaf, 0x28},/* low temp Rgain */ -{0xb0, 0x26},/* low temp Rgain */ - -{0xb1, 0x00},/* 0x20 -> 0x00 0405 modify */ -{0xb4, 0xea}, -{0xb8, 0xa1},/* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify */ -{0xb9, 0x00}, -/* PAGE 22 END */ - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -/*0x17cc*/ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:0x02, 48MHz:0x03 */ -/*0x17c4,*/ /*MHSHIM*/ -/*0x17c0,*/ /*MHSHIM*/ -/*0x1700,*/ /*MHSHIM*/ -{0x50, 0x00}, -/* PAGE 48 END*/ - -/* PAGE 20 */ -{0x03, 0x20}, -{0x10, 0x8c},/*AE on 60hz */ - -/* PAGE 22 */ -{0x03, 0x22}, -{0x10, 0xe9}, - -/* PAGE 0 */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x03, 0x00}, -{0x01, 0xf8}, - -{0xff, 0x0a},/* NEED Delay 100ms */ -}; - -/*==================================================*/ -/* CAMERA INITIAL for Self Recording 24 Fixed Frame */ -/*==================================================*/ -regs_short_t front_init_recording_regs[] = { -/* Recording 25fps Anti-Flicker 60Hz END of Initial */ -/* CAMERA INITIAL for Self Recording 24 Fixed Frame */ -{0x01, 0xf9},/*sleep on */ -{0x01, 0xfb},/* sleep on */ -{0x01, 0xf9},/*sleep on */ -{0x08, 0x20},/* sleep on */ -{0x0a, 0x3f},/* sleep on */ - -/* PAGE 20 */ -{0x03, 0x20},/*page 20 */ -{0x10, 0x0c},/*AE off 60hz */ - -/* PAGE 22 */ -{0x03, 0x22},/*page 22 */ -{0x10, 0x69},/* AWB off */ - -{0x03, 0x12}, -{0x20, 0x00}, -{0x21, 0x00}, - -{0x03, 0x13}, -{0x10, 0xcb}, - -/*Initial Start*/ -/* PAGE 0 START */ -{0x03, 0x00}, -{0x10, 0x03},/* Vsync Active High B:[3] , Sub1/2 + Preview 1 */ -{0x11, 0x94}, -{0x12, 0x04},/* Pclk Falling Edge B:[2] 1016 0x04->0x00 */ - -{0x0b, 0xaa}, -{0x0c, 0xaa}, -{0x0d, 0xaa}, - -{0x20, 0x00}, -{0x21, 0x04}, -{0x22, 0x00}, -{0x23, 0x06}, - -{0x24, 0x04}, -{0x25, 0xb0}, -{0x26, 0x06}, -{0x27, 0x40}, - -{0x28, 0x0c}, -{0x29, 0x04}, -{0x2a, 0x02}, -{0x2b, 0x04}, -{0x2c, 0x06}, -{0x2d, 0x02}, - -{0x40, 0x01},/*Hblank 352 */ -{0x41, 0x60}, -{0x42, 0x00},/*Vblank 20 */ -{0x43, 0x14}, - -{0x45, 0x04}, -{0x46, 0x18}, -{0x47, 0xd8}, - - /*BLC*/ {0x80, 0x2e}, -{0x81, 0x7e}, -{0x82, 0x90}, -{0x83, 0x00}, -{0x84, 0x0c}, -{0x85, 0x00}, -{0x90, 0x05},/*BLC_TIME_TH_ON */ -{0x91, 0x05},/*BLC_TIME_TH_OFF */ -{0x92, 0xb0},/*BLC_AG_TH_ON */ -{0x93, 0xa8},/*BLC_AG_TH_OFF */ -{0x94, 0xff}, -{0x95, 0xff}, -{0x96, 0xdc}, -{0x97, 0xfe}, -{0x98, 0x38}, - -/*Dark BLC*/ -{0xa0, 0x00}, -{0xa2, 0x00}, -{0xa4, 0x00}, -{0xa6, 0x00}, - -/*Normal BLC*/ -{0xa8, 0x43}, -{0xaa, 0x43}, -{0xac, 0x43}, -{0xae, 0x43}, - -/*OutDoor BLC*/ -{0x99, 0x43}, -{0x9a, 0x43}, -{0x9b, 0x43}, -{0x9c, 0x43}, -/* PAGE 0 END */ - -/* PAGE 2 START */ -{0x03, 0x02}, -{0x12, 0x03}, -{0x13, 0x03}, -{0x16, 0x00}, -{0x17, 0x8C}, -{0x18, 0x4c},/*Double_AG */ -{0x19, 0x00}, -{0x1a, 0x39},/*Double_AG 38 ->39 */ -{0x1c, 0x09}, -{0x1d, 0x40}, -{0x1e, 0x30}, -{0x1f, 0x10}, - -{0x20, 0x77}, -{0x21, 0xde}, -{0x22, 0xa7}, -{0x23, 0x30}, /*CLAMP*/ {0x27, 0x3c}, -{0x2b, 0x80}, -{0x2e, 0x00}, -{0x2f, 0x00}, -{0x30, 0x05},/*For Hi-253 never no change 0x05 */ - -{0x50, 0x20}, -{0x51, 0x03},/*20110826 */ -{0x52, 0x01},/*0x03 --> 0x01 */ -{0x53, 0xc1},/*20110818 Ãß°¡ */ -{0x55, 0x1c}, -{0x56, 0x11}, -{0x5d, 0xa2}, -{0x5e, 0x5a}, - -{0x60, 0x87}, -{0x61, 0x99}, -{0x62, 0x88}, -{0x63, 0x97}, -{0x64, 0x88}, -{0x65, 0x97}, - -{0x67, 0x0c}, -{0x68, 0x0c}, -{0x69, 0x0c}, - -{0x72, 0x89}, -{0x73, 0x96}, -{0x74, 0x89}, -{0x75, 0x96}, -{0x76, 0x89}, -{0x77, 0x96}, - -{0x7c, 0x85}, -{0x7d, 0xaf}, -{0x80, 0x01}, -{0x81, 0x7f}, -{0x82, 0x13}, -{0x83, 0x24}, -{0x84, 0x7d}, -{0x85, 0x81}, -{0x86, 0x7d}, -{0x87, 0x81}, - -{0x92, 0x48}, -{0x93, 0x54}, -{0x94, 0x7d}, -{0x95, 0x81}, -{0x96, 0x7d}, -{0x97, 0x81}, - -{0xa0, 0x02}, -{0xa1, 0x7b}, -{0xa2, 0x02}, -{0xa3, 0x7b}, -{0xa4, 0x7b}, -{0xa5, 0x02}, -{0xa6, 0x7b}, -{0xa7, 0x02}, - -{0xa8, 0x85}, -{0xa9, 0x8c}, -{0xaa, 0x85}, -{0xab, 0x8c}, -{0xac, 0x10}, -{0xad, 0x16}, -{0xae, 0x10}, -{0xaf, 0x16}, - -{0xb0, 0x99}, -{0xb1, 0xa3}, -{0xb2, 0xa4}, -{0xb3, 0xae}, -{0xb4, 0x9b}, -{0xb5, 0xa2}, -{0xb6, 0xa6}, -{0xb7, 0xac}, -{0xb8, 0x9b}, -{0xb9, 0x9f}, -{0xba, 0xa6}, -{0xbb, 0xaa}, -{0xbc, 0x9b}, -{0xbd, 0x9f}, -{0xbe, 0xa6}, -{0xbf, 0xaa}, - -{0xc4, 0x2c}, -{0xc5, 0x43}, -{0xc6, 0x63}, -{0xc7, 0x79}, - -{0xc8, 0x2d}, -{0xc9, 0x42}, -{0xca, 0x2d}, -{0xcb, 0x42}, -{0xcc, 0x64}, -{0xcd, 0x78}, -{0xce, 0x64}, -{0xcf, 0x78}, -{0xd0, 0x0a}, -{0xd1, 0x09}, -{0xd4, 0x05},/*DCDC_TIME_TH_ON */ -{0xd5, 0x05},/*DCDC_TIME_TH_OFF */ -{0xd6, 0xb0},/*DCDC_AG_TH_ON */ -{0xd7, 0xa8},/*DCDC_AG_TH_OFF */ -{0xe0, 0xc4}, -{0xe1, 0xc4}, -{0xe2, 0xc4}, -{0xe3, 0xc4}, -{0xe4, 0x00}, -{0xe8, 0x80}, -{0xe9, 0x40}, -{0xea, 0x7f}, - -{0xf0, 0x01}, -{0xf1, 0x01}, -{0xf2, 0x01}, -{0xf3, 0x01}, -{0xf4, 0x01}, - -/* PAGE 2 END */ - -/* PAGE 3 */ -{0x03, 0x03}, -{0x10, 0x10}, -/* PAGE 3 END */ - -/* PAGE 10 START */ -{0x03, 0x10}, -{0x10, 0x01},/* CrYCbY */ -{0x12, 0x30}, -{0x20, 0x00}, -{0x30, 0x00}, -{0x31, 0x00}, -{0x32, 0x00}, -{0x33, 0x00}, - -{0x34, 0x30}, -{0x35, 0x00}, -{0x36, 0x00}, -{0x38, 0x00}, -{0x3e, 0x58}, -{0x3f, 0x00},/*Setting For Camcorder 24 */ - -{0x40, 0x80}, -{0x41, 0x00}, - -{0x60, 0x67},/*Setting For Camcorder 24 */ -{0x61, 0x7a},/*77 */ -{0x62, 0x79},/*77 */ -{0x63, 0x50},/* Double_AG 50->30 */ -{0x64, 0x80}, - -{0x66, 0x42}, -{0x67, 0x20}, - -{0x6a, 0x80},/*8a */ -{0x6b, 0x84},/*74 */ -{0x6c, 0x7a},/*7e */ -{0x6d, 0x80},/*8e */ - -/* PAGE 11 START */ -{0x03, 0x11}, -{0x10, 0x7f}, -{0x11, 0x40}, -{0x12, 0x0a},/* Blue Max-Filter Delete */ -{0x13, 0xbb}, - -{0x26, 0x31},/* Double_AG 31->20 */ -{0x27, 0x34},/* Double_AG 34->22 */ -{0x28, 0x0f}, -{0x29, 0x10}, -{0x2b, 0x30}, -{0x2c, 0x32}, - -/*Out2 D-LPF th*/ -{0x30, 0x70}, -{0x31, 0x10}, -{0x32, 0x58}, -{0x33, 0x09}, -{0x34, 0x06}, -{0x35, 0x03}, - -/*Out1 D-LPF th*/ -{0x36, 0x70}, -{0x37, 0x18}, -{0x38, 0x58}, -{0x39, 0x20}, -{0x3a, 0x1f}, -{0x3b, 0x03}, - -/*Indoor D-LPF th*/ -{0x3c, 0x80}, -{0x3d, 0x18}, -{0x3e, 0x80}, -{0x3f, 0x0c}, -{0x40, 0x09}, -{0x41, 0x06}, - -/*Dark1 D-LPF th*/ -{0x42, 0x80}, -{0x43, 0x18}, -{0x44, 0x80}, -{0x45, 0x0c}, -{0x46, 0x09}, -{0x47, 0x06}, - -/*Dark2 D-LPF th*/ -{0x48, 0x80}, -{0x49, 0x18}, -{0x4a, 0x80}, -{0x4b, 0x0c}, -{0x4c, 0x09}, -{0x4d, 0x06}, - -/*Dark3 D-LPF th*/ -{0x4e, 0x80}, -{0x4f, 0x18}, -{0x50, 0x80}, -{0x51, 0x0c}, -{0x52, 0x09}, -{0x53, 0x06}, - -{0x54, 0x11}, -{0x55, 0x17}, -{0x56, 0x20}, -{0x57, 0x01}, -{0x58, 0x00}, -{0x59, 0x00}, - -{0x5a, 0x18}, -{0x5b, 0x00}, -{0x5c, 0x00}, - -{0x60, 0x3f}, -{0x62, 0x60}, -{0x70, 0x06}, -/* PAGE 11 END */ - -/* PAGE 12 START */ -{0x03, 0x12}, -{0x20, 0x0f},/*Setting For Camcorder 24 */ -{0x21, 0x0f},/*Setting For Camcorder 24 */ - -{0x25, 0x00},/*0x30 */ - -{0x28, 0x00}, -{0x29, 0x00}, -{0x2a, 0x00}, - -{0x30, 0x50}, -{0x31, 0x18}, -{0x32, 0x32}, -{0x33, 0x40}, -{0x34, 0x50}, -{0x35, 0x70}, -{0x36, 0xa0}, - -/*Out2 th*/ -{0x40, 0xa0}, -{0x41, 0x40}, -{0x42, 0xa0}, -{0x43, 0x90}, -{0x44, 0x90}, -{0x45, 0x80}, - -/*Out1 th*/ -{0x46, 0xb0}, -{0x47, 0x55}, -{0x48, 0xb0}, -{0x49, 0xb0}, -{0x4a, 0x90}, -{0x4b, 0x80}, - -/*Indoor th*/ -{0x4c, 0xb0}, -{0x4d, 0x40}, -{0x4e, 0x90}, -{0x4f, 0x90}, -{0x50, 0xa0}, -{0x51, 0x80}, - -/*Dark1 th*/ -{0x52, 0xb0}, -{0x53, 0x40}, -{0x54, 0x90}, -{0x55, 0x90}, -{0x56, 0xa0}, -{0x57, 0x78}, - -/*Dark2 th*/ -{0x58, 0xb0}, -{0x59, 0x40}, -{0x5a, 0x90}, -{0x5b, 0x90}, -{0x5c, 0xa0}, -{0x5d, 0x78}, - -/*Dark3 th*/ -{0x5e, 0xb0}, -{0x5f, 0x40}, -{0x60, 0x90}, -{0x61, 0x90}, -{0x62, 0xa0}, -{0x63, 0x78}, - -{0x70, 0x15}, -{0x71, 0x01},/*Don't Touch register */ - -{0x72, 0x18}, -{0x73, 0x01},/*Don't Touch register */ - -{0x74, 0x25}, -{0x75, 0x15}, - -{0x80, 0x20}, -{0x81, 0x40}, -{0x82, 0x65}, -{0x85, 0x1a}, -{0x88, 0x00}, -{0x89, 0x00}, -{0x90, 0x5d},/*Setting For Camcorder 24 */ - -/*Dont Touch register*/ -{0xD0, 0x0c}, -{0xD1, 0x80}, -{0xD2, 0x67}, -{0xD3, 0x00}, -{0xD4, 0x00}, -{0xD5, 0x02}, -{0xD6, 0xff}, -{0xD7, 0x18}, -/*End*/ -{0x3b, 0x06}, -{0x3c, 0x06}, - -/*Dont Touch register*/ -{0xc5, 0x30},/*55->48 */ -{0xc6, 0x2a},/*48->40 */ -/* PAGE 12 END */ - -/* PAGE 13 START */ -{0x03, 0x13}, -/*Edge*/ -{0x10, 0xcb}, -{0x11, 0x7b}, -{0x12, 0x07}, -{0x14, 0x00}, - -{0x20, 0x15}, -{0x21, 0x13}, -{0x22, 0x33}, -{0x23, 0x05}, -{0x24, 0x09}, - -{0x25, 0x0a}, - -{0x26, 0x18}, -{0x27, 0x30}, -{0x29, 0x12}, -{0x2a, 0x50}, - -/*Low clip th*/ -{0x2b, 0x02}, -{0x2c, 0x02}, -{0x25, 0x06}, -{0x2d, 0x0c}, -{0x2e, 0x12}, -{0x2f, 0x12}, - -/*Out2 Edge*/ -{0x50, 0x10}, -{0x51, 0x14}, -{0x52, 0x12}, -{0x53, 0x0c}, -{0x54, 0x0f}, -{0x55, 0x0c}, - -/*Out1 Edge*/ -{0x56, 0x0f}, -{0x57, 0x12}, -{0x58, 0x12}, -{0x59, 0x09}, -{0x5a, 0x0c}, -{0x5b, 0x0c}, - -/*Indoor Edge*/ -{0x5c, 0x0a}, -{0x5d, 0x0b}, -{0x5e, 0x0a}, -{0x5f, 0x08}, -{0x60, 0x09}, -{0x61, 0x08}, - -/*Dark1 Edge*/ -{0x62, 0x0a}, -{0x63, 0x0b}, -{0x64, 0x0a}, -{0x65, 0x08}, -{0x66, 0x09}, -{0x67, 0x08}, - -/*Dark2 Edge*/ -{0x68, 0x0a}, -{0x69, 0x0b}, -{0x6a, 0x0a}, -{0x6b, 0x08}, -{0x6c, 0x09}, -{0x6d, 0x08}, - -/*Dark3 Edge*/ -{0x6e, 0x0a}, -{0x6f, 0x0b}, -{0x70, 0x0a}, -{0x71, 0x08}, -{0x72, 0x09}, -{0x73, 0x08}, - -/*2DY*/ -{0x80, 0xfd},/*Setting For Camcorder 24 */ -{0x81, 0x1f}, -{0x82, 0x05}, -{0x83, 0x31}, - -{0x90, 0x05}, -{0x91, 0x05}, -{0x92, 0x33}, -{0x93, 0x30}, -{0x94, 0x03}, -{0x95, 0x14}, -{0x97, 0x20}, -{0x99, 0x20}, - -{0xa0, 0x01}, -{0xa1, 0x02}, -{0xa2, 0x01}, -{0xa3, 0x02}, -{0xa4, 0x05}, -{0xa5, 0x05}, -{0xa6, 0x07}, -{0xa7, 0x08}, -{0xa8, 0x07}, -{0xa9, 0x08}, -{0xaa, 0x07}, -{0xab, 0x08}, - -/*Out2*/ -{0xb0, 0x22}, -{0xb1, 0x2a}, -{0xb2, 0x28}, -{0xb3, 0x22}, -{0xb4, 0x2a}, -{0xb5, 0x28}, - -/*Out1*/ -{0xb6, 0x22}, -{0xb7, 0x2a}, -{0xb8, 0x28}, -{0xb9, 0x22}, -{0xba, 0x2a}, -{0xbb, 0x28}, - -/*Indoor*/ -{0xbc, 0x25}, -{0xbd, 0x2a}, -{0xbe, 0x27}, -{0xbf, 0x25}, -{0xc0, 0x2a}, -{0xc1, 0x27}, - -/*Dark1*/ -{0xc2, 0x1e}, -{0xc3, 0x24}, -{0xc4, 0x20}, -{0xc5, 0x1e}, -{0xc6, 0x24}, -{0xc7, 0x20}, - -/*Dark2*/ -{0xc8, 0x18}, -{0xc9, 0x20}, -{0xca, 0x1e}, -{0xcb, 0x18}, -{0xcc, 0x20}, -{0xcd, 0x1e}, - -/*Dark3*/ -{0xce, 0x18}, -{0xcf, 0x20}, -{0xd0, 0x1e}, -{0xd1, 0x18}, -{0xd2, 0x20}, -{0xd3, 0x1e}, -/* PAGE 13 END */ - -/* PAGE 14 START */ -{0x03, 0x14}, -{0x10, 0x11}, - -{0x14, 0x80},/* GX */ -{0x15, 0x80},/* GY */ -{0x16, 0x80},/* RX */ -{0x17, 0x80},/* RY */ -{0x18, 0x80},/* BX */ -{0x19, 0x80},/* BY */ - -{0x20, 0x80}, /*X*/ {0x21, 0x80}, /*Y*/ {0x22, 0x80}, -{0x23, 0x80}, -{0x24, 0x80}, - -{0x30, 0xc8}, -{0x31, 0x2b}, -{0x32, 0x00}, -{0x33, 0x00}, -{0x34, 0x90}, - -{0x40, 0x37}, -{0x50, 0x26},/*2d */ -{0x60, 0x22},/*26 */ -{0x70, 0x26},/*2d */ -/* PAGE 14 END */ - -/* PAGE 15 START */ -{0x03, 0x15}, -{0x10, 0x0f}, - -/*Rstep H 16*/ -/*Rstep L 14*/ -{0x14, 0x46}, /*CMCOFSGH*/ -{0x15, 0x36}, /*CMCOFSGM*/ -{0x16, 0x26}, /*CMCOFSGL*/ -{0x17, 0x2f}, /*CMC SIGN */ - -/*CMC*/ -{0x30, 0x8f}, -{0x31, 0x59}, -{0x32, 0x0a}, -{0x33, 0x15}, -{0x34, 0x5b}, -{0x35, 0x06}, -{0x36, 0x07}, -{0x37, 0x40}, -{0x38, 0x87}, - -/*CMC OFS*/ -{0x40, 0x94}, -{0x41, 0x20}, -{0x42, 0x89}, -{0x43, 0x84}, -{0x44, 0x03}, -{0x45, 0x01}, -{0x46, 0x88}, -{0x47, 0x9c}, -{0x48, 0x28}, - -/*CMC POFS*/ -{0x50, 0x02}, -{0x51, 0x82}, -{0x52, 0x00}, -{0x53, 0x07}, -{0x54, 0x11}, -{0x55, 0x98}, -{0x56, 0x00}, -{0x57, 0x0b}, -{0x58, 0x8b}, - -{0x80, 0x00}, -{0x85, 0x80}, -{0x87, 0x02}, -{0x88, 0x00}, -{0x89, 0x00}, -{0x8a, 0x00}, -/* PAGE 15 END */ - -/* PAGE 16 START */ -{0x03, 0x16}, -{0x10, 0x31}, -{0x18, 0x5e},/* Double_AG 5e->37 */ -{0x19, 0x5d},/* Double_AG 5e->36 */ -{0x1a, 0x0e}, -{0x1b, 0x01}, -{0x1c, 0xdc}, -{0x1d, 0xfe}, - -/*GMA Default*/ -{0x30, 0x00}, -{0x31, 0x08}, -{0x32, 0x1c}, -{0x33, 0x32}, -{0x34, 0x54}, -{0x35, 0x70}, -{0x36, 0x87}, -{0x37, 0x9a}, -{0x38, 0xaa}, -{0x39, 0xb9}, -{0x3a, 0xc4}, -{0x3b, 0xcf}, -{0x3c, 0xd8}, -{0x3d, 0xe0}, -{0x3e, 0xe9}, -{0x3f, 0xf0}, -{0x40, 0xf7}, -{0x41, 0xfc}, -{0x42, 0xff}, - -{0x50, 0x00}, -{0x51, 0x08}, -{0x52, 0x1e}, -{0x53, 0x36}, -{0x54, 0x5a}, -{0x55, 0x75}, -{0x56, 0x8d}, -{0x57, 0xa1}, -{0x58, 0xb2}, -{0x59, 0xbe}, -{0x5a, 0xc9}, -{0x5b, 0xd2}, -{0x5c, 0xdb}, -{0x5d, 0xe3}, -{0x5e, 0xeb}, -{0x5f, 0xf0}, -{0x60, 0xf5}, -{0x61, 0xf7}, -{0x62, 0xf8}, - -{0x70, 0x00}, -{0x71, 0x08}, -{0x72, 0x1c}, -{0x73, 0x32}, -{0x74, 0x54}, -{0x75, 0x70}, -{0x76, 0x87}, -{0x77, 0x9a}, -{0x78, 0xaa}, -{0x79, 0xb9}, -{0x7a, 0xc4}, -{0x7b, 0xcf}, -{0x7c, 0xd8}, -{0x7d, 0xe0}, -{0x7e, 0xe9}, -{0x7f, 0xf0}, -{0x80, 0xf7}, -{0x81, 0xfc}, -{0x82, 0xff}, -/* PAGE 16 END */ - -/* PAGE 17 START */ -{0x03, 0x17}, -{0x10, 0xf7}, -/* PAGE 17 END */ - -/* PAGE 18 START */ -{0x03, 0x18}, -{0x10, 0x07}, -{0x11, 0x00}, -{0x12, 0x58}, -{0x20, 0x02}, -{0x21, 0x80}, -{0x22, 0x01}, -{0x23, 0xe0}, -{0x24, 0x00}, -{0x25, 0x03}, -{0x26, 0x00}, -{0x27, 0x04}, -{0x28, 0x02}, -{0x29, 0x83}, -{0x2a, 0x01}, -{0x2b, 0xe4}, -{0x2c, 0x0a}, -{0x2d, 0x00}, -{0x2e, 0x0a}, -{0x2f, 0x00}, -{0x30, 0x25}, - -/* PAGE 18 END */ - -/* PAGE 20 START */ -{0x03, 0x20}, -{0x11, 0x1c}, -{0x18, 0x30}, -{0x1a, 0x08}, -{0x20, 0x05}, -{0x21, 0x30}, -{0x22, 0x10}, -{0x23, 0x00}, -{0x24, 0x00}, - -{0x28, 0xef}, -{0x29, 0x0d},/*20100305 ad->0d */ -{0x2a, 0x03}, -{0x2b, 0xf5}, - -{0x2c, 0xc2}, -{0x2d, 0xff}, -{0x2e, 0x33}, -{0x30, 0xf8}, -{0x32, 0x03}, -{0x33, 0x2e}, -{0x34, 0x30}, -{0x35, 0xd4}, -{0x36, 0xfe}, -{0x37, 0x32}, -{0x38, 0x04}, -{0x39, 0x22}, -{0x3a, 0xde}, -{0x3b, 0x22}, -{0x3c, 0xde}, - -{0x50, 0x45}, -{0x51, 0x88}, - -{0x56, 0x03}, -{0x57, 0xf7}, -{0x58, 0x14}, -{0x59, 0x88}, -{0x5a, 0x04}, - -{0x60, 0xaa}, -{0x61, 0xaa}, -{0x62, 0xaa}, -{0x63, 0xaa}, -{0x64, 0xaa}, -{0x65, 0xaa}, -{0x66, 0xab}, -{0x67, 0xEa}, -{0x68, 0xab}, -{0x69, 0xEa}, -{0x6a, 0xaa}, -{0x6b, 0xaa}, -{0x6c, 0xaa}, -{0x6d, 0xaa}, -{0x6e, 0xaa}, -{0x6f, 0xaa}, - -{0x70, 0x7a}, -{0x71, 0x80}, - -{0x76, 0x43}, -{0x77, 0x02}, -{0x78, 0x24}, -{0x79, 0x49}, -{0x7a, 0x23}, -{0x7b, 0x22}, -{0x7d, 0x23}, - -{0x83, 0x01},/*EXP Normal 30.00 fps */ -{0x84, 0x86}, -{0x85, 0x78}, - -{0x86, 0x01},/*EXPMin 10204.08 fps */ -{0x87, 0x26}, - -{0x88, 0x01},/*EXP Max 24.00 fps */ -{0x89, 0xe8}, -{0x8a, 0x16}, - -{0x8B, 0x75},/*EXP100 */ -{0x8C, 0x24}, - -{0x8D, 0x61},/*EXP120 */ -{0x8E, 0x9e}, - -{0x91, 0x01},/*EXP Fix 23.93 fps */ -{0x92, 0xe9}, -{0x93, 0xcf}, - -{0x98, 0x9d},/*9d */ -{0x99, 0x45}, -{0x9a, 0x0d}, -{0x9b, 0xde}, - -{0x9c, 0x0e},/*EXP Limit 784.93 fps */ -{0x9d, 0xee}, - -{0x9e, 0x01},/*EXP Unit */ -{0x9f, 0x26}, - -{0xb0, 0x18}, -{0xb1, 0x14}, -{0xb2, 0xb8}, -{0xb3, 0x18}, -{0xb4, 0x1a}, -{0xb5, 0x44}, -{0xb6, 0x2f}, -{0xb7, 0x28}, -{0xb8, 0x25}, -{0xb9, 0x22}, -{0xba, 0x21}, -{0xbb, 0x20}, -{0xbc, 0x32}, -{0xbd, 0x32}, - -{0xc0, 0x10}, -{0xc1, 0x2b}, -{0xc2, 0x2b}, -{0xc3, 0x2b}, -{0xc4, 0x08}, - -{0xc8, 0x80}, -{0xc9, 0x80}, -/* PAGE 20 END */ - -/* PAGE 22 START */ -{0x03, 0x22}, -{0x10, 0xfd}, -{0x11, 0x2e}, -{0x19, 0x01}, -{0x20, 0x30}, -{0x21, 0x80}, -{0x24, 0x01}, -/*0x2500, 7f New Lock Cond & New light stable*/ - -{0x30, 0x80}, -{0x31, 0x80}, -{0x38, 0x11}, -{0x39, 0x34}, -{0x40, 0xf3}, - -{0x41, 0x32},/*33 */ -{0x42, 0x22},/*22 */ -{0x43, 0xf0},/*f6 */ -{0x44, 0x44},/*44 */ -{0x45, 0x44},/*33 */ -{0x46, 0x00}, -{0x50, 0xb2}, -{0x51, 0x81}, -{0x52, 0x98}, - -{0x80, 0x38}, -{0x81, 0x20}, -{0x82, 0x36},/*3a */ - -{0x83, 0x5e},/*5e */ -{0x84, 0x22},/* 24 21 22 Spec AWB H modify */ -{0x85, 0x4f},/* 54 51 4f Spec AWB H modify */ -{0x86, 0x20},/*24 */ - -{0x87, 0x48}, -{0x88, 0x38}, -{0x89, 0x37},/*38 */ -{0x8a, 0x29},/*2a */ - -{0x8b, 0x40},/* 47 */ -{0x8c, 0x38}, -{0x8d, 0x34}, -{0x8e, 0x29},/*2c */ - -{0x8f, 0x5c}, -{0x90, 0x5b}, -{0x91, 0x57}, -{0x92, 0x4f}, -{0x93, 0x43}, -{0x94, 0x3e}, -{0x95, 0x34}, -{0x96, 0x2c}, -{0x97, 0x23}, -{0x98, 0x20}, -{0x99, 0x1f}, -{0x9a, 0x1f}, - -{0x9b, 0x77}, -{0x9c, 0x66}, -{0x9d, 0x48}, -{0x9e, 0x38}, -{0x9f, 0x30}, - -{0xa0, 0x60}, -{0xa1, 0x34}, -{0xa2, 0x6f}, -{0xa3, 0xff}, - -{0xa4, 0x14},/*1500fps */ -{0xa5, 0x2c},/* 700fps */ -{0xa6, 0xcf}, - -{0xad, 0x40}, -{0xae, 0x4a}, - -{0xaf, 0x28},/* low temp Rgain */ -{0xb0, 0x26},/* low temp Rgain */ - -{0xb1, 0x00},/*0x20 -> 0x00 0405 modify */ -{0xb4, 0xea}, -{0xb8, 0xa1},/* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify */ -{0xb9, 0x00}, -/* PAGE 22 END */ - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x81}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0c}, -{0x1d, 0x0f}, -{0x1e, 0x05}, -{0x1f, 0x05}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x03},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x03},/*drivability 24MHZ:02, 48MHz:03 */ -{0x50, 0x00}, -/* PAGE 48 END*/ - -/* PAGE 20 */ -{0x03, 0x20}, -{0x10, 0x8c},/*AE on 60hz */ - -/* PAGE 22 */ -{0x03, 0x22}, -{0x10, 0xe9}, - -/* PAGE 0 */ -{0x03, 0x00}, -{0x11, 0x94}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x03, 0x00}, -{0x01, 0xf8}, -{0xff, 0x28},/*NEED Delay 400ms */ -}; - -/*============================================================*/ -/* CAMERA INITIAL for VT Preview 15 Fixed Frame (VGA SETTING) */ -/*============================================================*/ -regs_short_t front_init_vt_regs[] = { -/* SKT-VT - continuous */ -{0x01, 0xf9},/* sleep on */ -{0x01, 0xfb},/* sleep on */ -{0x01, 0xf9},/* sleep on */ -{0x08, 0x20},/* sleep on */ -{0x0a, 0x3f},/* sleep on */ - -/* PAGE 20 */ -{0x03, 0x20},/* page 20 */ -{0x10, 0x0c},/* AE off 60hz */ - -/* PAGE 22 */ -{0x03, 0x22},/* page 22 */ -{0x10, 0x69},/* AWB off */ - -{0x03, 0x12}, -{0x20, 0x00}, -{0x21, 0x00}, - -{0x03, 0x13}, -{0x10, 0xcb}, - -/* Initial Start */ -/* PAGE 0 START */ -{0x03, 0x00}, -{0x10, 0x10},/* Vsync Active High B:[3] , Sub1/2mode */ -{0x11, 0x94}, -{0x12, 0x04},/* Pclk Falling Edge B:[2] */ - -{0x0b, 0xaa},/* ESD Check Register */ -{0x0c, 0xaa},/* ESD Check Register */ -{0x0d, 0xaa},/* ESD Check Register */ - -{0x20, 0x00}, -{0x21, 0x0a},/* modify 20110929 0x04->0x02 */ -{0x22, 0x00}, -{0x23, 0x0a},/* modify 20110929 0x14->0x0a */ - -{0x24, 0x04}, -{0x25, 0xb0}, -{0x26, 0x06}, -{0x27, 0x40}, - -{0x28, 0x0c}, -{0x29, 0x04}, -{0x2a, 0x02}, -{0x2b, 0x04}, -{0x2c, 0x06}, -{0x2d, 0x02}, - -{0x40, 0x01},/* Hblank_360 */ -{0x41, 0x68}, -{0x42, 0x00}, -{0x43, 0x44},/* Flick Stop 60hz */ -{0x44, 0x09},/* VSCLIP */ - -{0x45, 0x04}, -{0x46, 0x18}, -{0x47, 0xd8}, - - /*BLC*/ {0x80, 0x2e}, -{0x81, 0x7e}, -{0x82, 0x90}, -{0x83, 0x00}, -{0x84, 0x0c}, -{0x85, 0x00}, -{0x90, 0x0e},/* BLC_TIME_TH_ON */ -{0x91, 0x0e},/* BLC_TIME_TH_OFF */ -{0x92, 0xd8},/* BLC_AG_TH_ON */ -{0x93, 0xd0},/* BLC_AG_TH_OFF */ -{0x94, 0xff}, -{0x95, 0xff}, -{0x96, 0xdc}, -{0x97, 0xfe}, -{0x98, 0x38}, - -/*Dark BLC*/ -{0xa0, 0x00}, -{0xa2, 0x00}, -{0xa4, 0x00}, -{0xa6, 0x00}, - -/*Normal BLC*/ -{0xa8, 0x43}, -{0xaa, 0x43}, -{0xac, 0x43}, -{0xae, 0x43}, - -/*OutDoor BLC*/ -{0x99, 0x43}, -{0x9a, 0x43}, -{0x9b, 0x43}, -{0x9c, 0x43}, -/* PAGE 0 END */ - -/* PAGE 2 START */ -{0x03, 0x02}, -{0x12, 0x03}, -{0x13, 0x03}, -{0x16, 0x00}, -{0x17, 0x8C}, -{0x18, 0x4c},/* Double_AG */ -{0x19, 0x00}, -{0x1a, 0x39},/* Double_AG 38 ->39 */ -{0x1c, 0x09}, -{0x1d, 0x40}, -{0x1e, 0x30}, -{0x1f, 0x10}, - -{0x20, 0x77}, -{0x21, 0xde}, -{0x22, 0xa7}, -{0x23, 0x30},/* CLAMP */ -{0x27, 0x3c}, -{0x2b, 0x80}, -{0x2e, 0x00}, -{0x2f, 0x00}, -{0x30, 0x05},/* For Hi-253 never no change 0x05 */ - -{0x50, 0x20}, -{0x51, 0x03},/* 20110826 Ãß°¡ */ -{0x52, 0x01},/* 0x03 --> 0x01 */ -{0x53, 0xc1},/* 20110818 Ãß°¡ */ -{0x55, 0x1c}, -{0x56, 0x11}, -{0x5d, 0xa2}, -{0x5e, 0x5a}, - -{0x60, 0x87}, -{0x61, 0x99}, -{0x62, 0x88}, -{0x63, 0x97}, -{0x64, 0x88}, -{0x65, 0x97}, - -{0x67, 0x0c}, -{0x68, 0x0c}, -{0x69, 0x0c}, - -{0x72, 0x89}, -{0x73, 0x96}, -{0x74, 0x89}, -{0x75, 0x96}, -{0x76, 0x89}, -{0x77, 0x96}, - -{0x7c, 0x85}, -{0x7d, 0xaf}, -{0x80, 0x01}, -{0x81, 0x7f}, -{0x82, 0x13}, -{0x83, 0x24}, -{0x84, 0x7d}, -{0x85, 0x81}, -{0x86, 0x7d}, -{0x87, 0x81}, - -{0x92, 0x48}, -{0x93, 0x54}, -{0x94, 0x7d}, -{0x95, 0x81}, -{0x96, 0x7d}, -{0x97, 0x81}, - -{0xa0, 0x02}, -{0xa1, 0x7b}, -{0xa2, 0x02}, -{0xa3, 0x7b}, -{0xa4, 0x7b}, -{0xa5, 0x02}, -{0xa6, 0x7b}, -{0xa7, 0x02}, - -{0xa8, 0x85}, -{0xa9, 0x8c}, -{0xaa, 0x85}, -{0xab, 0x8c}, -{0xac, 0x10}, -{0xad, 0x16}, -{0xae, 0x10}, -{0xaf, 0x16}, - -{0xb0, 0x99}, -{0xb1, 0xa3}, -{0xb2, 0xa4}, -{0xb3, 0xae}, -{0xb4, 0x9b}, -{0xb5, 0xa2}, -{0xb6, 0xa6}, -{0xb7, 0xac}, -{0xb8, 0x9b}, -{0xb9, 0x9f}, -{0xba, 0xa6}, -{0xbb, 0xaa}, -{0xbc, 0x9b}, -{0xbd, 0x9f}, -{0xbe, 0xa6}, -{0xbf, 0xaa}, - -{0xc4, 0x2c}, -{0xc5, 0x43}, -{0xc6, 0x63}, -{0xc7, 0x79}, - -{0xc8, 0x2d}, -{0xc9, 0x42}, -{0xca, 0x2d}, -{0xcb, 0x42}, -{0xcc, 0x64}, -{0xcd, 0x78}, -{0xce, 0x64}, -{0xcf, 0x78}, -{0xd0, 0x0a}, -{0xd1, 0x09}, -{0xd4, 0x0e},/* DCDC_TIME_TH_ON */ -{0xd5, 0x0e},/* DCDC_TIME_TH_OFF */ -{0xd6, 0xd8},/* DCDC_AG_TH_ON */ -{0xd7, 0xd0},/* DCDC_AG_TH_OFF */ -{0xe0, 0xc4}, -{0xe1, 0xc4}, -{0xe2, 0xc4}, -{0xe3, 0xc4}, -{0xe4, 0x00}, -{0xe8, 0x80}, -{0xe9, 0x40}, -{0xea, 0x7f}, - -{0xf0, 0x01}, -{0xf1, 0x01}, -{0xf2, 0x01}, -{0xf3, 0x01}, -{0xf4, 0x01}, - -/* PAGE 2 END */ - -/* PAGE 3 */ -{0x03, 0x03}, -{0x10, 0x10}, -/* PAGE 3 END */ - -/* PAGE 10 START */ -{0x03, 0x10}, -{0x10, 0x01},/* CrYCbY */ -{0x12, 0x30}, -{0x20, 0x00}, -{0x30, 0x00}, -{0x31, 0x00}, -{0x32, 0x00}, -{0x33, 0x00}, - -{0x34, 0x30}, -{0x35, 0x00}, -{0x36, 0x00}, -{0x38, 0x00}, -{0x3e, 0x58}, -{0x3f, 0x02},/* For Preview */ - -{0x40, 0x80}, -{0x41, 0x2c}, - -{0x60, 0x6b}, -{0x61, 0x7a},/* 77 */ -{0x62, 0x72},/* 77 */ -{0x63, 0x50},/* Double_AG 50->30 */ -{0x64, 0x80}, - -{0x66, 0x42}, -{0x67, 0x20}, - -{0x6a, 0x80},/* 8a */ -{0x6b, 0x84},/* 74 */ -{0x6c, 0x7a},/* 7e */ -{0x6d, 0x80},/* 8e */ - -/* PAGE 11 START */ -{0x03, 0x11}, -{0x10, 0x7f}, -{0x11, 0x40}, -{0x12, 0x0a},/* Blue Max-Filter Delete */ -{0x13, 0xbb}, - -{0x26, 0x31},/* Double_AG 31->20 */ -{0x27, 0x34},/* Double_AG 34->22 */ -{0x28, 0x0f}, -{0x29, 0x10}, -{0x2b, 0x30}, -{0x2c, 0x32}, - -/*Out2 D-LPF th*/ -{0x30, 0x70}, -{0x31, 0x10}, -{0x32, 0x58}, -{0x33, 0x09}, -{0x34, 0x06}, -{0x35, 0x03}, - -/*Out1 D-LPF th*/ -{0x36, 0x70}, -{0x37, 0x18}, -{0x38, 0x58}, -{0x39, 0x20}, -{0x3a, 0x1f}, -{0x3b, 0x03}, - -/*Indoor D-LPF th*/ -{0x3c, 0x80}, -{0x3d, 0x18}, -{0x3e, 0x80}, -{0x3f, 0x0c}, -{0x40, 0x09}, -{0x41, 0x06}, - -/*Dark1 D-LPF th*/ -{0x42, 0x80}, -{0x43, 0x18}, -{0x44, 0x80}, -{0x45, 0x0f}, -{0x46, 0x0c}, -{0x47, 0x0b}, - -/*Dark2 D-LPF th*/ -{0x48, 0x88}, -{0x49, 0x2c}, -{0x4a, 0x80}, -{0x4b, 0x0f}, -{0x4c, 0x0c}, -{0x4d, 0x0b}, - -/*Dark3 D-LPF th*/ -{0x4e, 0x80}, -{0x4f, 0x23}, -{0x50, 0x80}, -{0x51, 0x0f}, -{0x52, 0x0c}, -{0x53, 0x0c}, - -{0x54, 0x11}, -{0x55, 0x17}, -{0x56, 0x20}, -{0x57, 0x01}, -{0x58, 0x00}, -{0x59, 0x00}, - -{0x5a, 0x18}, -{0x5b, 0x00}, -{0x5c, 0x00}, - -{0x60, 0x3f}, -{0x62, 0x60}, -{0x70, 0x06}, -/* PAGE 11 END */ - -/* PAGE 12 START */ -{0x03, 0x12}, -{0x20, 0x0f}, -{0x21, 0x0f}, - -{0x25, 0x00},/* 0x30 */ - -{0x28, 0x00}, -{0x29, 0x00}, -{0x2a, 0x00}, - -{0x30, 0x50}, -{0x31, 0x18}, -{0x32, 0x32}, -{0x33, 0x40}, -{0x34, 0x50}, -{0x35, 0x70}, -{0x36, 0xa0}, - -/*Out2 th*/ -{0x40, 0xa0}, -{0x41, 0x40}, -{0x42, 0xa0}, -{0x43, 0x90}, -{0x44, 0x90}, -{0x45, 0x80}, - -/*Out1 th*/ -{0x46, 0xb0}, -{0x47, 0x55}, -{0x48, 0xb0}, -{0x49, 0xb0}, -{0x4a, 0x90}, -{0x4b, 0x80}, - -/*Indoor th*/ -{0x4c, 0xb0}, -{0x4d, 0x40}, -{0x4e, 0x90}, -{0x4f, 0x90}, -{0x50, 0xa0}, -{0x51, 0x80}, - -/*Dark1 th*/ -{0x52, 0xb0}, -{0x53, 0x50}, -{0x54, 0xa8}, -{0x55, 0xa8}, -{0x56, 0xb0}, -{0x57, 0x7b}, - -/*Dark2 th*/ -{0x58, 0xa0}, -{0x59, 0x40}, -{0x5a, 0xb8}, -{0x5b, 0xb8}, -{0x5c, 0xc8}, -{0x5d, 0x7b}, - -/*Dark3 th*/ -{0x5e, 0x9c}, -{0x5f, 0x40}, -{0x60, 0xc0}, -{0x61, 0xc0}, -{0x62, 0xc8}, -{0x63, 0x7b}, - -{0x70, 0x15}, -{0x71, 0x01},/* Don't Touch register */ - -{0x72, 0x18}, -{0x73, 0x01},/* Don't Touch register */ - -{0x74, 0x25}, -{0x75, 0x15}, - -{0x80, 0x20}, -{0x81, 0x40}, -{0x82, 0x65}, -{0x85, 0x1a}, -{0x88, 0x00}, -{0x89, 0x00}, -{0x90, 0x5d},/* For SK VT */ - -/*Dont Touch register*/ -{0xD0, 0x0c}, -{0xD1, 0x80}, - -/*only For SK VT */ -{0xD2, 0x67}, - -{0xD3, 0x00}, -{0xD4, 0x00}, - -/*only For SK VT */ -{0xd5, 0x02}, - -{0xD6, 0xff}, - -/*only For SK VT */ -{0xd7, 0x18}, - -/*End*/ -{0x3b, 0x06}, -{0x3c, 0x06}, - -/*Dont Touch register*/ -{0xc5, 0x30},/* 55->48 */ -{0xc6, 0x2a},/* 48->40 */ -/* PAGE 12 END */ - -/* PAGE 13 START */ -{0x03, 0x13}, -/*Edge*/ -{0x10, 0xcb}, -{0x11, 0x7b}, -{0x12, 0x07}, -{0x14, 0x00}, - -{0x20, 0x15}, -{0x21, 0x13}, -{0x22, 0x33}, -{0x23, 0x05}, -{0x24, 0x09}, - -{0x25, 0x0a}, - -{0x26, 0x18}, -{0x27, 0x30}, -{0x29, 0x12}, -{0x2a, 0x50}, - -/*Low clip th*/ -{0x2b, 0x02}, -{0x2c, 0x02}, -{0x25, 0x06}, -{0x2d, 0x0c}, -{0x2e, 0x12}, -{0x2f, 0x12}, - -/*Out2 Edge*/ -{0x50, 0x10}, -{0x51, 0x14}, -{0x52, 0x12}, -{0x53, 0x0c}, -{0x54, 0x0f}, -{0x55, 0x0c}, - -/*Out1 Edge*/ -{0x56, 0x0f}, -{0x57, 0x12}, -{0x58, 0x12}, -{0x59, 0x09}, -{0x5a, 0x0c}, -{0x5b, 0x0c}, - -/*Indoor Edge*/ -{0x5c, 0x0a}, -{0x5d, 0x0b}, -{0x5e, 0x0a}, -{0x5f, 0x08}, -{0x60, 0x09}, -{0x61, 0x08}, - -/*Dark1 Edge*/ -{0x62, 0x09}, -{0x63, 0x09}, -{0x64, 0x09}, -{0x65, 0x07}, -{0x66, 0x07}, -{0x67, 0x07}, - -/*Dark2 Edge*/ -{0x68, 0x08}, -{0x69, 0x08}, -{0x6a, 0x08}, -{0x6b, 0x06}, -{0x6c, 0x06}, -{0x6d, 0x06}, - -/*Dark3 Edge*/ -{0x6e, 0x08}, -{0x6f, 0x08}, -{0x70, 0x08}, -{0x71, 0x06}, -{0x72, 0x06}, -{0x73, 0x06}, - -/*2DY*/ -{0x80, 0xfd},/*only For SK VT */ -{0x81, 0x1f}, -{0x82, 0x05}, -{0x83, 0x31}, - -{0x90, 0x05}, -{0x91, 0x05}, -{0x92, 0x33}, -{0x93, 0x30}, -{0x94, 0x03}, -{0x95, 0x14}, -{0x97, 0x20}, -{0x99, 0x20}, - -{0xa0, 0x01}, -{0xa1, 0x02}, -{0xa2, 0x01}, -{0xa3, 0x02}, -{0xa4, 0x05}, -{0xa5, 0x05}, -{0xa6, 0x07}, -{0xa7, 0x08}, -{0xa8, 0x07}, -{0xa9, 0x08}, -{0xaa, 0x07}, -{0xab, 0x08}, - -/*Out2*/ -{0xb0, 0x22}, -{0xb1, 0x2a}, -{0xb2, 0x28}, -{0xb3, 0x22}, -{0xb4, 0x2a}, -{0xb5, 0x28}, - -/*Out1*/ -{0xb6, 0x22}, -{0xb7, 0x2a}, -{0xb8, 0x28}, -{0xb9, 0x22}, -{0xba, 0x2a}, -{0xbb, 0x28}, - -/*Indoor*/ -{0xbc, 0x25}, -{0xbd, 0x2a}, -{0xbe, 0x27}, -{0xbf, 0x25}, -{0xc0, 0x2a}, -{0xc1, 0x27}, - -/*Dark1*/ -{0xc2, 0x1e}, -{0xc3, 0x24}, -{0xc4, 0x20}, -{0xc5, 0x1e}, -{0xc6, 0x24}, -{0xc7, 0x20}, - -/*Dark2*/ -{0xc8, 0x18}, -{0xc9, 0x20}, -{0xca, 0x1e}, -{0xcb, 0x18}, -{0xcc, 0x20}, -{0xcd, 0x1e}, - -/*Dark3*/ -{0xce, 0x18}, -{0xcf, 0x20}, -{0xd0, 0x1e}, -{0xd1, 0x18}, -{0xd2, 0x20}, -{0xd3, 0x1e}, -/* PAGE 13 END */ - -/* PAGE 14 START */ -{0x03, 0x14}, -{0x10, 0x11}, - -{0x14, 0x80},/* GX */ -{0x15, 0x80},/* GY */ -{0x16, 0x80},/* RX */ -{0x17, 0x80},/* RY */ -{0x18, 0x80},/* BX */ -{0x19, 0x80},/* BY */ - -{0x20, 0x80},/* X */ -{0x21, 0x80},/* Y */ - -{0x22, 0x80}, -{0x23, 0x80}, -{0x24, 0x80}, - -{0x30, 0xc8}, -{0x31, 0x2b}, -{0x32, 0x00}, -{0x33, 0x00}, -{0x34, 0x90}, - -{0x40, 0x37}, -{0x50, 0x26},/* 2d */ -{0x60, 0x22},/* 26 */ -{0x70, 0x26},/* 2d */ -/* PAGE 14 END */ - -/* PAGE 15 START */ -{0x03, 0x15}, -{0x10, 0x0f}, - -/*Rstep H 16*/ -/*Rstep L 14*/ -{0x14, 0x46},/* CMCOFSGH */ -{0x15, 0x36},/* CMCOFSGM */ -{0x16, 0x26},/* CMCOFSGL */ -{0x17, 0x2f},/* CMC SIGN */ - - /*CMC*/ {0x30, 0x8f}, -{0x31, 0x59}, -{0x32, 0x0a}, -{0x33, 0x15}, -{0x34, 0x5b}, -{0x35, 0x06}, -{0x36, 0x07}, -{0x37, 0x40}, -{0x38, 0x87}, - -/*CMC OFS*/ -{0x40, 0x94}, -{0x41, 0x20}, -{0x42, 0x89}, -{0x43, 0x84}, -{0x44, 0x03}, -{0x45, 0x01}, -{0x46, 0x88}, -{0x47, 0x9c}, -{0x48, 0x28}, - -/*CMC POFS*/ -{0x50, 0x02}, -{0x51, 0x82}, -{0x52, 0x00}, -{0x53, 0x07}, -{0x54, 0x11}, -{0x55, 0x98}, -{0x56, 0x00}, -{0x57, 0x0b}, -{0x58, 0x8b}, - -{0x80, 0x00}, -{0x85, 0x80}, -{0x87, 0x02}, -{0x88, 0x00}, -{0x89, 0x00}, -{0x8a, 0x00}, -/* PAGE 15 END */ - -/* PAGE 16 START */ -{0x03, 0x16}, -{0x10, 0x31}, -{0x18, 0x5e},/* Double_AG 5e->37 */ -{0x19, 0x5d},/* Double_AG 5e->36 */ -{0x1a, 0x0e}, -{0x1b, 0x01}, -{0x1c, 0xdc}, -{0x1d, 0xfe}, - -/*GMA Default*/ -{0x30, 0x00}, -{0x31, 0x08}, -{0x32, 0x1c}, -{0x33, 0x32}, -{0x34, 0x54}, -{0x35, 0x70}, -{0x36, 0x87}, -{0x37, 0x9a}, -{0x38, 0xaa}, -{0x39, 0xb9}, -{0x3a, 0xc4}, -{0x3b, 0xcf}, -{0x3c, 0xd8}, -{0x3d, 0xe0}, -{0x3e, 0xe9}, -{0x3f, 0xf0}, -{0x40, 0xf7}, -{0x41, 0xfc}, -{0x42, 0xff}, - -{0x50, 0x00}, -{0x51, 0x08}, -{0x52, 0x1e}, -{0x53, 0x36}, -{0x54, 0x5a}, -{0x55, 0x75}, -{0x56, 0x8d}, -{0x57, 0xa1}, -{0x58, 0xb2}, -{0x59, 0xbe}, -{0x5a, 0xc9}, -{0x5b, 0xd2}, -{0x5c, 0xdb}, -{0x5d, 0xe3}, -{0x5e, 0xeb}, -{0x5f, 0xf0}, -{0x60, 0xf5}, -{0x61, 0xf7}, -{0x62, 0xf8}, - -{0x70, 0x00}, -{0x71, 0x0b}, -{0x72, 0x1a}, -{0x73, 0x37}, -{0x74, 0x58}, -{0x75, 0x70}, -{0x76, 0x86}, -{0x77, 0x99}, -{0x78, 0xa9}, -{0x79, 0xb7}, -{0x7a, 0xc3}, -{0x7b, 0xcf}, -{0x7c, 0xd9}, -{0x7d, 0xe1}, -{0x7e, 0xe8}, -{0x7f, 0xef}, -{0x80, 0xf4}, -{0x81, 0xfa}, -{0x82, 0xff}, -/* PAGE 16 END */ - -/* PAGE 17 START */ -{0x03, 0x17}, -{0x10, 0xf7}, -/* PAGE 17 END */ - -/* PAGE 18 START */ -{0x03, 0x18}, -{0x10, 0x07}, -{0x11, 0x00}, -{0x12, 0x98}, -{0x20, 0x05}, -{0x21, 0x00}, -{0x22, 0x03}, -{0x23, 0xc0}, -{0x24, 0x00}, -{0x25, 0x04}, -{0x26, 0x00}, -{0x27, 0x08}, -{0x28, 0x05}, -{0x29, 0x04}, -{0x2a, 0x03}, -{0x2b, 0xc8}, -{0x2c, 0x0a}, -{0x2d, 0x00}, -{0x2e, 0x0a}, -{0x2f, 0x00}, -{0x30, 0x46}, -/* PAGE 18 END */ - -/* PAGE 20 START */ -{0x03, 0x20}, -{0x11, 0x1c}, -{0x18, 0x30}, -{0x1a, 0x08}, -{0x20, 0x05}, -{0x21, 0x30}, -{0x22, 0x10}, -{0x23, 0x00}, -{0x24, 0x04}, - -{0x28, 0xef}, -{0x29, 0x0d},/* 20100305 ad->0d */ -{0x2a, 0x03}, -{0x2b, 0xf5}, - -{0x2c, 0xc2}, -{0x2d, 0xff}, -{0x2e, 0x33}, -{0x30, 0xf8}, -{0x32, 0x03}, -{0x33, 0x2e}, -{0x34, 0x30}, -{0x35, 0xd4}, -{0x36, 0xfe}, -{0x37, 0x32}, -{0x38, 0x04}, -{0x39, 0x22}, -{0x3a, 0xde}, -{0x3b, 0x22}, -{0x3c, 0xde}, - -{0x50, 0x45}, -{0x51, 0x88}, - -{0x56, 0x03}, -{0x57, 0xf7}, -{0x58, 0x14}, -{0x59, 0x88}, -{0x5a, 0x04}, - -{0x60, 0xaa}, -{0x61, 0xaa}, -{0x62, 0xaa}, -{0x63, 0xaa}, -{0x64, 0xaa}, -{0x65, 0xaa}, -{0x66, 0xab}, -{0x67, 0xEa}, -{0x68, 0xab}, -{0x69, 0xEa}, -{0x6a, 0xaa}, -{0x6b, 0xaa}, -{0x6c, 0xaa}, -{0x6d, 0xaa}, -{0x6e, 0xaa}, -{0x6f, 0xaa}, - -{0x70, 0x70},/* 6c */ -{0x71, 0x82},/* 82(+8) */ - -{0x76, 0x43}, -{0x77, 0x02}, -{0x78, 0x24},/* 24 */ -{0x79, 0x48},/* Y Target 70 => 25, 72 => 26 */ -{0x7a, 0x23},/* 23 */ -{0x7b, 0x22},/* 22 */ -{0x7d, 0x23}, - -{0x83, 0x01},/* EXP Normal 30.00 fps */ -{0x84, 0x86}, -{0x85, 0xa0}, - -{0x86, 0x01},/* EXPMin 6000.00 fps */ -{0x87, 0xf4}, - -{0x88, 0x05},/* EXP Max 8.57 fps */ -{0x89, 0x57}, -{0x8a, 0x30}, - -{0x8B, 0x75},/* EXP100, PLLx2 Mclk24 */ -{0x8C, 0x30}, - -{0x8D, 0x61},/* EXP120, PLLx2 Mclk24 */ -{0x8E, 0xa8}, - -{0x91, 0x05},/* EXP Fix 8.00 fps */ -{0x92, 0xb8}, -{0x93, 0xd8}, - -{0x98, 0x9d}, -{0x99, 0x45}, -{0x9a, 0x0d}, -{0x9b, 0xde}, - -{0x9c, 0x17},/* EXP Limit 500.00 fps, PLLx2 Mclk24 */ -{0x9d, 0x70}, - -{0x9e, 0x01},/* EXP Unit, PLLx2 Mclk24 */ -{0x9f, 0xf4}, - -{0xb0, 0x18}, -{0xb1, 0x14}, -{0xb2, 0xe0}, -{0xb3, 0x18}, -{0xb4, 0x1a}, -{0xb5, 0x44}, -{0xb6, 0x2f}, -{0xb7, 0x28}, -{0xb8, 0x25}, -{0xb9, 0x22}, -{0xba, 0x21}, -{0xbb, 0x20}, -{0xbc, 0x32}, -{0xbd, 0x32}, - -{0xc0, 0x10}, -{0xc1, 0x2b}, -{0xc2, 0x2b}, -{0xc3, 0x2b}, -{0xc4, 0x08}, - -{0xc8, 0x80}, -{0xc9, 0x80}, -/* PAGE 20 END */ - -/* PAGE 22 START */ -{0x03, 0x22}, -{0x10, 0xfd}, -{0x11, 0x2e}, -{0x19, 0x01},/* Low On */ -{0x20, 0x10}, -{0x21, 0x80}, -{0x24, 0x01}, -/*0x2500, 7f New Lock Cond & New light stable */ - -{0x30, 0x80}, -{0x31, 0x80}, -{0x38, 0x11}, -{0x39, 0x34}, -{0x40, 0xf3}, - -{0x41, 0x32},/* 33 */ -{0x42, 0x22},/* 22 */ -{0x43, 0xf0},/* f6 */ -{0x44, 0x44},/* 44 */ -{0x45, 0x44},/* 33 */ -{0x46, 0x00}, -{0x50, 0xb2}, -{0x51, 0x81}, -{0x52, 0x98}, - -{0x80, 0x38}, -{0x81, 0x20}, -{0x82, 0x36},/* 3a */ - -{0x83, 0x5e},/* 5e */ -{0x84, 0x22},/* 24 21 22 Spec AWB H modify */ -{0x85, 0x4f},/* 54 51 4f Spec AWB H modify */ -{0x86, 0x20},/* 24 */ - -{0x87, 0x48}, -{0x88, 0x38}, -{0x89, 0x37},/* 38 */ -{0x8a, 0x29},/* 2a */ - -{0x8b, 0x40},/* 47 */ -{0x8c, 0x38}, -{0x8d, 0x34}, -{0x8e, 0x29},/* 2c */ - -{0x8f, 0x5c}, -{0x90, 0x5b}, -{0x91, 0x57}, -{0x92, 0x4f}, -{0x93, 0x43}, -{0x94, 0x3e}, -{0x95, 0x34}, -{0x96, 0x2c}, -{0x97, 0x23}, -{0x98, 0x20}, -{0x99, 0x1f}, -{0x9a, 0x1f}, - -{0x9b, 0x77}, -{0x9c, 0x66}, -{0x9d, 0x48}, -{0x9e, 0x38}, -{0x9f, 0x30}, - -{0xa0, 0x60}, -{0xa1, 0x34}, -{0xa2, 0x6f}, -{0xa3, 0xff}, - -{0xa4, 0x14},/* 1500fps */ -{0xa5, 0x2c},/* 700fps */ -{0xa6, 0xcf}, - -{0xad, 0x40}, -{0xae, 0x4a}, - -{0xaf, 0x28},/* low temp Rgain */ -{0xb0, 0x26},/* low temp Rgain */ - -{0xb1, 0x00},/* 0x20 -> 0x00 0405 modify */ -{0xb4, 0xea}, -{0xb8, 0xa1},/* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify */ -{0xb9, 0x00}, -/* PAGE 22 END */ - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x01 -> 0x00 not Continues */ -/*0x17cc*/ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04}, - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */ - -/*0x17c4,*/ /*MHSHIM*/ -/*0x17c0,*/ /*MHSHIM*/ -/*0x1700,*/ /*MHSHIM*/ -{0x50, 0x00}, -/* PAGE 48 END*/ - -/* PAGE 20 */ -{0x03, 0x20}, -{0x10, 0x8c},/*AE on 60hz */ - -/* PAGE 22 */ -{0x03, 0x22}, -{0x10, 0xe9}, - -/* PAGE 0 */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x03, 0x00}, -{0x01, 0xf8}, - -{0xff, 0x28},/* NEED Delay 400ms */ -}; - -regs_short_t front_preview_camera_regs[] = { -{0x03, 0x00},/*Sleep On */ -{0x01, 0xf9}, - -{0x03, 0x20},/*page 20 */ -{0x18, 0x30},/*for Preview */ -{0x10, 0x0c},/*AE off 60hz */ - -{0x03, 0x22},/*page 22 */ -{0x10, 0x69},/*awb off */ - -{0x03, 0x00}, -{0x10, 0x11}, - -{0x11, 0x90}, - -{0x20, 0x00}, -{0x21, 0x02},/*modify 20110929 0x04->0x02 */ -{0x22, 0x00}, -{0x23, 0x0a},/*modify 20110929 0x14->0x0a */ - -{0x42, 0x00},/*VBlank */ -{0x43, 0x44},/*68 */ - -/*Page10*/ -{0x03, 0x10}, -{0x3f, 0x02}, -{0x60, 0x6b}, - -/*Page12*/ -{0x03, 0x12}, -{0x20, 0x00}, -{0x21, 0x00}, -{0x90, 0x00}, - -/*only for Preview DPC */ -{0xd2, 0x17}, -{0xd5, 0x0f}, -{0xd7, 0xff}, - -/*Page13*/ -{0x03, 0x13}, -{0x80, 0x00}, - -/*Page18*/ -{0x03, 0x18}, -{0x10, 0x07}, - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -/*0x17cc,*/ /*MHSHIM*/ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x01}, -{0x36, 0x03}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */ -/*0x17c4,*/ /*MHSHIM*/ -/*0x17c0,*/ /*MHSHIM*/ -/*0x1700,*/ /*MHSHIM*/ -{0x50, 0x00}, -/* PAGE 48 END*/ - -{0x03, 0x20}, -{0x10, 0x8c},/*AE on 60hz */ - -{0x03, 0x22}, -{0x10, 0xe9},/*AWB ON */ - -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x03, 0x00},/*Sleep Off */ -{0x01, 0xf8}, - -{0xff, 0x28},/*400ms */ -}; - -regs_short_t front_snapshot_normal_regs[] = { -{0x03, 0x00}, -{0x01, 0xf9}, - -{0x03, 0x22},/*Page 22 */ -{0x10, 0x69},/*AWB Off */ - -{0x03, 0x00}, -{0x10, 0x00}, -{0x11, 0x90}, - -{0x20, 0x00}, -{0x21, 0x0a},/*modify 20110929 0x0c->0x0a */ -{0x22, 0x00}, -{0x23, 0x0a},/*modify 20110929 0x14->0x0a */ - -/*Page10*/ -{0x03, 0x10}, -{0x3f, 0x00}, -{0x60, 0x67}, - -/*Page12*/ -{0x03, 0x12}, -{0x20, 0x0f}, -{0x21, 0x0f}, -{0x90, 0x5d}, - -/*only for Preview DPC Off*/ -{0xd2, 0x67}, -{0xd5, 0x02}, -{0xd7, 0x18}, - -/*Page13*/ -{0x03, 0x13}, -{0x80, 0xfd}, - -/* PAGE 18 START */ -{0x03, 0x18}, -{0x10, 0x00},/* Scaling Off */ - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x81}, -{0x70, 0x85},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0c}, -{0x1d, 0x0f}, -{0x1e, 0x05}, -{0x1f, 0x05}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x80},/*1600x1200 MiPi OutPut */ -{0x31, 0x0c}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x03},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x03},/*drivability 24MHZ:02, 48MHz:03 */ -/*0x17c4,*/ /*MHSHIM*/ -/*0x17c0,*/ /*MHSHIM*/ -/*0x1700,*/ /*MHSHIM*/ -{0x50, 0x00}, -/* PAGE 48 END*/ - -/*Page0*/ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00},/*Dummy 750us */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x03, 0x00}, -{0x01, 0xf8},/*Sleep Off */ - -{0xff, 0x03},/*Increase from 30ms */ -}; - -regs_short_t front_ev_minus_4_regs[] = { -{0x03, 0x10}, -{0x40, 0xd0}, -}; - -regs_short_t front_ev_minus_3_regs[] = { -{0x03, 0x10}, -{0x40, 0xc0}, -}; - -regs_short_t front_ev_minus_2_regs[] = { -{0x03, 0x10}, -{0x40, 0xb0}, -}; - -regs_short_t front_ev_minus_1_regs[] = { -{0x03, 0x10}, -{0x40, 0xa0}, -}; - -regs_short_t front_ev_default_regs[] = { -{0x03, 0x10}, -{0x40, 0x00}, -}; - -regs_short_t front_ev_plus_1_regs[] = { -{0x03, 0x10}, -{0x40, 0x20}, -}; - -regs_short_t front_ev_plus_2_regs[] = { -{0x03, 0x10}, -{0x40, 0x30}, -}; - -regs_short_t front_ev_plus_3_regs[] = { -{0x03, 0x10}, -{0x40, 0x40}, -}; - -regs_short_t front_ev_plus_4_regs[] = { -{0x03, 0x10}, -{0x40, 0x50}, -}; - -regs_short_t front_vt_pretty_default[] = { -{0x03, 0x10}, -{0x40, 0x50}, -}; - -regs_short_t front_vt_pretty_1[] = { -{0x03, 0x10}, -{0x40, 0x50}, -}; - -regs_short_t front_vt_pretty_2[] = { -{0x03, 0x10}, -{0x40, 0x50}, -}; - -regs_short_t front_vt_pretty_3[] = { -{0x03, 0x10}, -{0x40, 0x50}, -}; - -regs_short_t front_fps_auto_regs[] = { -}; - -regs_short_t front_fps_7_regs[] = { -/* Fixed 7fps Mode */ -{0x03, 0x00}, -{0x01, 0xf9}, -{0x11, 0x90}, - -{0x40, 0x01},/*Hblank 360 */ -{0x41, 0x68}, -{0x42, 0x00},/*Vsync 20 */ -{0x43, 0x14}, - -{0x90, 0x11},/*BLC_TIME_TH_ON */ -{0x91, 0x11},/*BLC_TIME_TH_OFF */ -{0x92, 0xd8},/*BLC_AG_TH_ON */ -{0x93, 0xd0},/*BLC_AG_TH_OFF */ - -{0x03, 0x02},/*PAGE 2 */ -{0xd4, 0x11},/*DCDC_TIME_TH_ON */ -{0xd5, 0x11},/*DCDC_TIME_TH_OFF */ -{0xd6, 0xd8},/*DCDC_AG_TH_ON */ -{0xd7, 0xd0},/*DCDC_AG_TH_OFF */ - -{0x03, 0x20}, -{0x10, 0x0C},/*AE off 60hz */ - -{0x03, 0x22}, -{0x10, 0x69}, - -{0x03, 0x20}, -{0x2a, 0x03}, -{0x2b, 0xf5}, - -{0x88, 0x06},/*EXP Max 7.06 fps */ -{0x89, 0x7c}, -{0x8a, 0x28}, - -{0x91, 0x06},/*EXP Fix 07.00 fps */ -{0x92, 0x89}, -{0x93, 0xd4}, - -{0x9c, 0x17},/*EXP Limit 500.00 fps */ -{0x9d, 0x70}, -{0x9e, 0x01},/*EXP Unit */ -{0x9f, 0xf4}, - -{0x03, 0x20}, -{0x10, 0x8C},/*AE on 60hz */ - -{0x03, 0x22}, -{0x10, 0xe9}, - -{0x03, 0x00}, -{0x11, 0x94}, - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */ -{0x50, 0x00}, -/* PAGE 48 END*/ - -{0x03, 0x00}, -{0x03, 0x00},/*Dummy 750us */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x01, 0xf8}, - -{0xff, 0x28},/*NEED Delay 400ms */ -}; - -regs_short_t front_fps_10_regs[] = { -/* Fixed 10fps Mode */ -{0x03, 0x00}, -{0x01, 0xf9}, -{0x11, 0x90}, - -{0x40, 0x01},/*Hblank 360 */ -{0x41, 0x68}, -{0x42, 0x00},/*Vsync 20 */ -{0x43, 0x14}, - -{0x90, 0x0b},/*BLC_TIME_TH_ON */ -{0x91, 0x0b},/*BLC_TIME_TH_OFF */ -{0x92, 0xd8},/*BLC_AG_TH_ON */ -{0x93, 0xd0},/*BLC_AG_TH_OFF */ - -{0x03, 0x02},/*PAGE 2 */ -{0xd4, 0x0b},/*DCDC_TIME_TH_ON */ -{0xd5, 0x0b},/*DCDC_TIME_TH_OFF */ -{0xd6, 0xd8},/*DCDC_AG_TH_ON */ -{0xd7, 0xd0},/*DCDC_AG_TH_OFF */ - -{0x03, 0x20}, -{0x10, 0x0C},/*AE off 60hz */ - -{0x03, 0x22}, -{0x10, 0x69}, - -{0x03, 0x20}, -{0x2a, 0x03}, -{0x2b, 0xf5}, - -{0x88, 0x04},/*EXP Max 10.91 fps */ -{0x89, 0x32}, -{0x8a, 0x38}, - -{0x91, 0x04},/*EXP Fix 10.00 fps */ -{0x92, 0x93}, -{0x93, 0xe0}, - -{0x9c, 0x17},/*EXP Limit 500.00 fps */ -{0x9d, 0x70}, -{0x9e, 0x01},/*EXP Unit */ -{0x9f, 0xf4}, - -{0x03, 0x20}, -{0x10, 0x8C},/*AE on 60hz */ - -{0x03, 0x22}, -{0x10, 0xe9}, - -{0x03, 0x00}, -{0x11, 0x94}, - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */ -{0x50, 0x00}, -/* PAGE 48 END*/ - -{0x03, 0x00}, -{0x03, 0x00},/*Dummy 750us */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x01, 0xf8}, - -{0xff, 0x28},/*NEED Delay 400ms */ -}; - -regs_short_t front_fps_15_regs[] = { -/* Fixed 15fps Mode */ -{0x03, 0x00}, -{0x01, 0xf9}, -{0x11, 0x90}, - -{0x40, 0x01},/*Hblank 360 */ -{0x41, 0x68}, -{0x42, 0x00},/*Vsync 20 */ -{0x43, 0x14}, - -{0x90, 0x08},/*BLC_TIME_TH_ON */ -{0x91, 0x08},/*BLC_TIME_TH_OFF */ -{0x92, 0xd8},/*BLC_AG_TH_ON */ -{0x93, 0xd0},/*BLC_AG_TH_OFF */ - -{0x03, 0x02},/*PAGE 2 */ -{0xd4, 0x08},/*DCDC_TIME_TH_ON */ -{0xd5, 0x08},/*DCDC_TIME_TH_OFF */ -{0xd6, 0xd8},/*DCDC_AG_TH_ON */ -{0xd7, 0xd0},/*DCDC_AG_TH_OFF */ - -{0x03, 0x20}, -{0x10, 0x0C},/*AE off 60hz */ - -{0x03, 0x22}, -{0x10, 0x69}, - -{0x03, 0x20}, -{0x2a, 0x03}, -{0x2b, 0xf5}, - -{0x88, 0x03},/*EXP Max 15.00 fps */ -{0x89, 0x0d}, -{0x8a, 0x40}, - -{0x91, 0x03},/*EXP Fix 14.91 fps */ -{0x92, 0x12}, -{0x93, 0x22}, - -{0x9c, 0x17},/*EXP Limit 500.00 fps */ -{0x9d, 0x70}, -{0x9e, 0x01},/*EXP Unit */ -{0x9f, 0xf4}, - -{0x03, 0x20}, -{0x10, 0x8C},/*AE on 60hz */ - -{0x03, 0x22}, -{0x10, 0xe9}, - -{0x03, 0x00}, -{0x11, 0x94}, - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */ -{0x50, 0x00}, -/* PAGE 48 END*/ - -{0x03, 0x00}, -{0x03, 0x00},/*Dummy 750us */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x01, 0xf8}, - -{0xff, 0x28},/*NEED Delay 400ms */ - -}; - -regs_short_t front_fps_24_regs[] = { -/* Need to add Fixed 24fps Mode */ -/* Temporary setting, Fixed 15fps Mode */ -{0x03, 0x00}, -{0x01, 0xf9}, -{0x11, 0x90}, - -{0x40, 0x01},/*Hblank 360 */ -{0x41, 0x68}, -{0x42, 0x00},/*Vsync 20 */ -{0x43, 0x14}, - -{0x90, 0x08},/*BLC_TIME_TH_ON */ -{0x91, 0x08},/*BLC_TIME_TH_OFF */ -{0x92, 0xd8},/*BLC_AG_TH_ON */ -{0x93, 0xd0},/*BLC_AG_TH_OFF */ - -{0x03, 0x02},/*PAGE 2 */ -{0xd4, 0x08},/*DCDC_TIME_TH_ON */ -{0xd5, 0x08},/*DCDC_TIME_TH_OFF */ -{0xd6, 0xd8},/*DCDC_AG_TH_ON */ -{0xd7, 0xd0},/*DCDC_AG_TH_OFF */ - -{0x03, 0x20}, -{0x10, 0x0C},/*AE off 60hz */ - -{0x03, 0x22}, -{0x10, 0x69}, - -{0x03, 0x20}, -{0x2a, 0x03}, -{0x2b, 0xf5}, - -{0x88, 0x03},/*EXP Max 15.00 fps */ -{0x89, 0x0d}, -{0x8a, 0x40}, - -{0x91, 0x03},/*EXP Fix 14.91 fps */ -{0x92, 0x12}, -{0x93, 0x22}, - -{0x9c, 0x17},/*EXP Limit 500.00 fps */ -{0x9d, 0x70}, -{0x9e, 0x01},/*EXP Unit */ -{0x9f, 0xf4}, - -{0x03, 0x20}, -{0x10, 0x8C},/*AE on 60hz */ - -{0x03, 0x22}, -{0x10, 0xe9}, - -{0x03, 0x00}, -{0x11, 0x94}, - -/* PAGE 48 START*/ -{0x03, 0x48}, - -/* PLL Setting */ -{0x70, 0x05}, -{0x71, 0x30},/*MiPi Pllx2 */ -{0x72, 0x85}, -{0x70, 0xa5},/* PLL Enable */ -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x03, 0x48}, -{0x70, 0x95},/* CLK_GEN_ENABLE */ - -/* MIPI TX Setting */ -{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */ -{0x10, 0x1c}, -{0x12, 0x00}, -{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */ -{0x16, 0x04},/* 1016 0x04->0x05 */ - -{0x19, 0x00}, -{0x1a, 0x32}, -{0x1b, 0x17}, -{0x1c, 0x0e}, -{0x1d, 0x0f}, -{0x1e, 0x04}, -{0x1f, 0x04}, -{0x20, 0x00}, - -{0x23, 0x01}, -{0x24, 0x1e}, -{0x25, 0x00}, -{0x26, 0x00}, -{0x27, 0x01}, -{0x28, 0x00}, -{0x2a, 0x06}, -{0x2b, 0x40}, -{0x2c, 0x04}, -{0x2d, 0xb0}, - -{0x30, 0x00},/*640x480 MiPi OutPut */ -{0x31, 0x05}, - -/*0x3040, 800x600 MiPi OutPut*/ -/*0x3106,*/ - -{0x32, 0x06}, -{0x33, 0x0a}, -{0x34, 0x02},/*CLK LP->HS Prepare time 24MHz:0x02, 48MHz:0x03 */ -{0x35, 0x03}, -{0x36, 0x01}, -{0x37, 0x07}, -{0x38, 0x02}, -{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */ -{0x50, 0x00}, -/* PAGE 48 END*/ - -{0x03, 0x00}, -{0x03, 0x00},/*Dummy 750us */ -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, -{0x03, 0x00}, - -{0x01, 0xf8}, - -{0xff, 0x28},/*NEED Delay 400ms */ -}; - -regs_short_t front_pattern_on_regs[] = { -{0x03, 0x00}, -{0x50, 0x05}, -}; - -regs_short_t front_pattern_off_regs[] = { -{0x03, 0x00}, -{0x50, 0x00}, -}; - -#endif/* __SR200PC20M_REGS_H */ diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index f3e2cc7..348aa61 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -2308,6 +2308,10 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, struct v4l2_ext_controls *ctrls = parg; if (ctrls->count != 0) { + if (ctrls->count > V4L2_CID_MAX_CTRLS) { + ret = -EINVAL; + break; + } *user_ptr = (void __user *)ctrls->controls; *kernel_ptr = (void **)&ctrls->controls; *array_size = sizeof(struct v4l2_ext_control) -- cgit v1.1