summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog5
-rwxr-xr-xdebian/rules2
-rwxr-xr-xdriver/product/kernel/Documentation/devicetree/bindings/arm/mali-midgard.txt96
-rwxr-xr-xdriver/product/kernel/Documentation/dma-buf-test-exporter.txt40
-rwxr-xr-xdriver/product/kernel/Documentation/kds.txt268
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_lock/sconscript23
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_lock/src/Kbuild18
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_lock/src/Makefile32
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.c481
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.h42
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_lock/src/sconscript33
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_test_exporter/Kbuild18
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_test_exporter/Kconfig20
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_test_exporter/Makefile30
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_test_exporter/dma-buf-test-exporter.c703
-rwxr-xr-xdriver/product/kernel/drivers/base/dma_buf_test_exporter/sconscript19
-rwxr-xr-xdriver/product/kernel/drivers/base/kds/Kbuild18
-rwxr-xr-xdriver/product/kernel/drivers/base/kds/Kconfig20
-rwxr-xr-xdriver/product/kernel/drivers/base/kds/Makefile37
-rwxr-xr-xdriver/product/kernel/drivers/base/kds/kds.c559
-rwxr-xr-xdriver/product/kernel/drivers/base/kds/sconscript42
-rwxr-xr-xdriver/product/kernel/drivers/base/sconscript36
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/Kbuild18
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/Kconfig26
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/docs/Doxyfile125
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/docs/sconscript31
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/example_kernel_api.c73
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/example_user_api.c153
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/sconscript21
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/Kbuild50
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/Makefile81
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/Makefile.common19
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/arch-arm/config.h27
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/arch-arm64/config.h27
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.c756
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.h228
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.c162
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.h94
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/common/ump_kernel_priv.h80
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/imports/ion/Makefile53
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/imports/ion/sconscript49
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c204
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/imports/sconscript25
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux.c831
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.c250
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.h26
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/sconscript46
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/src/ump_arch.h42
-rwxr-xr-xdriver/product/kernel/drivers/base/ump/ump_ref_drv.h33
-rwxr-xr-xdriver/product/kernel/drivers/gpu/arm/Kbuild17
-rwxr-xr-xdriver/product/kernel/drivers/gpu/arm/Kconfig19
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/Kbuild (renamed from mali-midgard-16.0/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/Kconfig (renamed from mali-midgard-16.0/Kconfig)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/Makefile (renamed from mali-midgard-16.0/Makefile)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/Makefile.kbase (renamed from mali-midgard-16.0/Makefile.kbase)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/Kbuild (renamed from mali-midgard-16.0/backend/gpu/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_backend_config.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_backend_config.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_cache_policy_backend.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_cache_policy_backend.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_cache_policy_backend.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_cache_policy_backend.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_debug_job_fault_backend.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_debug_job_fault_backend.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_devfreq.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_devfreq.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_device_hw.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_device_hw.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_device_internal.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_device_internal.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_gpu.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_gpu.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_gpuprops_backend.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_gpuprops_backend.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_backend.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_instr_backend.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_defs.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_instr_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_internal.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_instr_internal.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_internal.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_irq_internal.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_irq_linux.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_as.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_jm_as.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_defs.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_jm_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_hw.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_jm_hw.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_internal.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_jm_internal.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_rb.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_jm_rb.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_rb.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_jm_rb.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_affinity.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_js_affinity.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_affinity.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_js_affinity.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_backend.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_js_backend.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_internal.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_js_internal.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_mmu_hw_direct.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_mmu_hw_direct.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_always_on.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_always_on.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_always_on.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_always_on.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_backend.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_backend.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca_fixed.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca_fixed.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca_fixed.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca_fixed.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_coarse_demand.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_coarse_demand.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_coarse_demand.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_coarse_demand.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_defs.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_demand.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_demand.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_demand.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_demand.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_driver.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_internal.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_metrics.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_metrics.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_policy.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_pm_policy.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_time.c (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_time.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_time.h (renamed from mali-midgard-16.0/backend/gpu/mali_kbase_time.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/docs/Doxyfile (renamed from mali-midgard-16.0/docs/Doxyfile)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/docs/policy_operation_diagram.dot (renamed from mali-midgard-16.0/docs/policy_operation_diagram.dot)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/docs/policy_overview.dot (renamed from mali-midgard-16.0/docs/policy_overview.dot)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/ipa/Kbuild (renamed from mali-midgard-16.0/ipa/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa.c (renamed from mali-midgard-16.0/ipa/mali_kbase_ipa.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa.h (renamed from mali-midgard-16.0/ipa/mali_kbase_ipa.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa_generic.c (renamed from mali-midgard-16.0/ipa/mali_kbase_ipa_generic.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_base_hwconfig_features.h (renamed from mali-midgard-16.0/mali_base_hwconfig_features.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_base_hwconfig_issues.h (renamed from mali-midgard-16.0/mali_base_hwconfig_issues.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_base_kernel.h (renamed from mali-midgard-16.0/mali_base_kernel.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_base_mem_priv.h (renamed from mali-midgard-16.0/mali_base_mem_priv.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_base_vendor_specific_func.h (renamed from mali-midgard-16.0/mali_base_vendor_specific_func.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h (renamed from mali-midgard-16.0/mali_kbase.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_10969_workaround.c (renamed from mali-midgard-16.0/mali_kbase_10969_workaround.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_10969_workaround.h (renamed from mali-midgard-16.0/mali_kbase_10969_workaround.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_as_fault_debugfs.c (renamed from mali-midgard-16.0/mali_kbase_as_fault_debugfs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_as_fault_debugfs.h (renamed from mali-midgard-16.0/mali_kbase_as_fault_debugfs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_cache_policy.c (renamed from mali-midgard-16.0/mali_kbase_cache_policy.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_cache_policy.h (renamed from mali-midgard-16.0/mali_kbase_cache_policy.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config.c (renamed from mali-midgard-16.0/mali_kbase_config.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config.h (renamed from mali-midgard-16.0/mali_kbase_config.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h (renamed from mali-midgard-16.0/mali_kbase_config_defaults.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c (renamed from mali-midgard-16.0/mali_kbase_context.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.h (renamed from mali-midgard-16.0/mali_kbase_context.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c (renamed from mali-midgard-16.0/mali_kbase_core_linux.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug.c (renamed from mali-midgard-16.0/mali_kbase_debug.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug.h (renamed from mali-midgard-16.0/mali_kbase_debug.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_job_fault.c (renamed from mali-midgard-16.0/mali_kbase_debug_job_fault.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_job_fault.h (renamed from mali-midgard-16.0/mali_kbase_debug_job_fault.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c (renamed from mali-midgard-16.0/mali_kbase_debug_mem_view.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.h (renamed from mali-midgard-16.0/mali_kbase_debug_mem_view.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h (renamed from mali-midgard-16.0/mali_kbase_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c (renamed from mali-midgard-16.0/mali_kbase_device.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_disjoint_events.c (renamed from mali-midgard-16.0/mali_kbase_disjoint_events.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_dma_fence.c (renamed from mali-midgard-16.0/mali_kbase_dma_fence.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_dma_fence.h (renamed from mali-midgard-16.0/mali_kbase_dma_fence.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_event.c (renamed from mali-midgard-16.0/mali_kbase_event.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator.h (renamed from mali-midgard-16.0/mali_kbase_gator.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_api.c (renamed from mali-midgard-16.0/mali_kbase_gator_api.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_api.h (renamed from mali-midgard-16.0/mali_kbase_gator_api.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names.h (renamed from mali-midgard-16.0/mali_kbase_gator_hwcnt_names.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_thex.h (renamed from mali-midgard-16.0/mali_kbase_gator_hwcnt_names_thex.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_tmix.h (renamed from mali-midgard-16.0/mali_kbase_gator_hwcnt_names_tmix.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_tsix.h (renamed from mali-midgard-16.0/mali_kbase_gator_hwcnt_names_tsix.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_id.h (renamed from mali-midgard-16.0/mali_kbase_gpu_id.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_memory_debugfs.c (renamed from mali-midgard-16.0/mali_kbase_gpu_memory_debugfs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_memory_debugfs.h (renamed from mali-midgard-16.0/mali_kbase_gpu_memory_debugfs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c (renamed from mali-midgard-16.0/mali_kbase_gpuprops.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.h (renamed from mali-midgard-16.0/mali_kbase_gpuprops.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops_types.h (renamed from mali-midgard-16.0/mali_kbase_gpuprops_types.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hw.c (renamed from mali-midgard-16.0/mali_kbase_hw.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hw.h (renamed from mali-midgard-16.0/mali_kbase_hw.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_backend.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_backend.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_defs.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_gpuprops.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_gpuprops.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_instr.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_instr.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_jm.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_jm.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_pm.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_time.h (renamed from mali-midgard-16.0/mali_kbase_hwaccess_time.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwcnt_reader.h (renamed from mali-midgard-16.0/mali_kbase_hwcnt_reader.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd.c (renamed from mali-midgard-16.0/mali_kbase_jd.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd_debugfs.c (renamed from mali-midgard-16.0/mali_kbase_jd_debugfs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd_debugfs.h (renamed from mali-midgard-16.0/mali_kbase_jd_debugfs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jm.c (renamed from mali-midgard-16.0/mali_kbase_jm.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jm.h (renamed from mali-midgard-16.0/mali_kbase_jm.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js.c (renamed from mali-midgard-16.0/mali_kbase_js.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js.h (renamed from mali-midgard-16.0/mali_kbase_js.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_ctx_attr.c (renamed from mali-midgard-16.0/mali_kbase_js_ctx_attr.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_ctx_attr.h (renamed from mali-midgard-16.0/mali_kbase_js_ctx_attr.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_defs.h (renamed from mali-midgard-16.0/mali_kbase_js_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_linux.h (renamed from mali-midgard-16.0/mali_kbase_linux.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c (renamed from mali-midgard-16.0/mali_kbase_mem.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h (renamed from mali-midgard-16.0/mali_kbase_mem.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c (renamed from mali-midgard-16.0/mali_kbase_mem_linux.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.h (renamed from mali-midgard-16.0/mali_kbase_mem_linux.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_lowlevel.h (renamed from mali-midgard-16.0/mali_kbase_mem_lowlevel.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c (renamed from mali-midgard-16.0/mali_kbase_mem_pool.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool_debugfs.c (renamed from mali-midgard-16.0/mali_kbase_mem_pool_debugfs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool_debugfs.h (renamed from mali-midgard-16.0/mali_kbase_mem_pool_debugfs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs.c (renamed from mali-midgard-16.0/mali_kbase_mem_profile_debugfs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs.h (renamed from mali-midgard-16.0/mali_kbase_mem_profile_debugfs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs_buf_size.h (renamed from mali-midgard-16.0/mali_kbase_mem_profile_debugfs_buf_size.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu.c (renamed from mali-midgard-16.0/mali_kbase_mmu.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_hw.h (renamed from mali-midgard-16.0/mali_kbase_mmu_hw.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode.h (renamed from mali-midgard-16.0/mali_kbase_mmu_mode.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode_aarch64.c (renamed from mali-midgard-16.0/mali_kbase_mmu_mode_aarch64.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode_lpae.c (renamed from mali-midgard-16.0/mali_kbase_mmu_mode_lpae.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_platform_fake.c (renamed from mali-midgard-16.0/mali_kbase_platform_fake.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_pm.c (renamed from mali-midgard-16.0/mali_kbase_pm.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_pm.h (renamed from mali-midgard-16.0/mali_kbase_pm.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_profiling_gator_api.h (renamed from mali-midgard-16.0/mali_kbase_profiling_gator_api.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_regs_history_debugfs.c (renamed from mali-midgard-16.0/mali_kbase_regs_history_debugfs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_regs_history_debugfs.h (renamed from mali-midgard-16.0/mali_kbase_regs_history_debugfs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_replay.c (renamed from mali-midgard-16.0/mali_kbase_replay.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c (renamed from mali-midgard-16.0/mali_kbase_smc.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.h (renamed from mali-midgard-16.0/mali_kbase_smc.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c (renamed from mali-midgard-16.0/mali_kbase_softjobs.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_strings.c (renamed from mali-midgard-16.0/mali_kbase_strings.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_strings.h (renamed from mali-midgard-16.0/mali_kbase_strings.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.c (renamed from mali-midgard-16.0/mali_kbase_sync.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.h (renamed from mali-midgard-16.0/mali_kbase_sync.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync_user.c (renamed from mali-midgard-16.0/mali_kbase_sync_user.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c (renamed from mali-midgard-16.0/mali_kbase_tlstream.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.h (renamed from mali-midgard-16.0/mali_kbase_tlstream.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_defs.h (renamed from mali-midgard-16.0/mali_kbase_trace_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline.c (renamed from mali-midgard-16.0/mali_kbase_trace_timeline.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline.h (renamed from mali-midgard-16.0/mali_kbase_trace_timeline.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline_defs.h (renamed from mali-midgard-16.0/mali_kbase_trace_timeline_defs.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_uku.h (renamed from mali-midgard-16.0/mali_kbase_uku.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_utility.c (renamed from mali-midgard-16.0/mali_kbase_utility.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_utility.h (renamed from mali-midgard-16.0/mali_kbase_utility.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_vinstr.c (renamed from mali-midgard-16.0/mali_kbase_vinstr.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_vinstr.h (renamed from mali-midgard-16.0/mali_kbase_vinstr.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_linux_kbase_trace.h (renamed from mali-midgard-16.0/mali_linux_kbase_trace.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_linux_trace.h (renamed from mali-midgard-16.0/mali_linux_trace.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_malisw.h (renamed from mali-midgard-16.0/mali_malisw.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_midg_coherency.h (renamed from mali-midgard-16.0/mali_midg_coherency.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_midg_regmap.h (renamed from mali-midgard-16.0/mali_midg_regmap.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_timeline.h (renamed from mali-midgard-16.0/mali_timeline.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/mali_uk.h (renamed from mali-midgard-16.0/mali_uk.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/Kbuild (renamed from mali-midgard-16.0/platform/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/Kconfig (renamed from mali-midgard-16.0/platform/Kconfig)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/Kbuild (renamed from mali-midgard-16.0/platform/devicetree/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_devicetree.c (renamed from mali-midgard-16.0/platform/devicetree/mali_kbase_config_devicetree.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h (renamed from mali-midgard-16.0/platform/devicetree/mali_kbase_config_platform.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c (renamed from mali-midgard-16.0/platform/devicetree/mali_kbase_runtime_pm.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/Kbuild (renamed from mali-midgard-16.0/platform/juno_soc/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/juno_mali_opp.c (renamed from mali-midgard-16.0/platform/juno_soc/juno_mali_opp.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_juno_soc.c (renamed from mali-midgard-16.0/platform/juno_soc/mali_kbase_config_juno_soc.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_platform.h (renamed from mali-midgard-16.0/platform/juno_soc/mali_kbase_config_platform.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/mali_kbase_platform_common.h (renamed from mali-midgard-16.0/platform/mali_kbase_platform_common.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/mali_kbase_platform_fake.h (renamed from mali-midgard-16.0/platform/mali_kbase_platform_fake.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/Kbuild (renamed from mali-midgard-16.0/platform/vexpress/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_config_platform.h (renamed from mali-midgard-16.0/platform/vexpress/mali_kbase_config_platform.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_config_vexpress.c (renamed from mali-midgard-16.0/platform/vexpress/mali_kbase_config_vexpress.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_cpu_vexpress.c (renamed from mali-midgard-16.0/platform/vexpress/mali_kbase_cpu_vexpress.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_cpu_vexpress.h (renamed from mali-midgard-16.0/platform/vexpress/mali_kbase_cpu_vexpress.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/Kbuild (renamed from mali-midgard-16.0/platform/vexpress_1xv7_a57/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/mali_kbase_config_platform.h (renamed from mali-midgard-16.0/platform/vexpress_1xv7_a57/mali_kbase_config_platform.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/mali_kbase_config_vexpress.c (renamed from mali-midgard-16.0/platform/vexpress_1xv7_a57/mali_kbase_config_vexpress.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/Kbuild (renamed from mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/Kbuild)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_platform.h (renamed from mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_platform.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_vexpress.c (renamed from mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_vexpress.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.c (renamed from mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.c)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.h (renamed from mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.h)0
-rwxr-xr-x[-rw-r--r--]driver/product/kernel/drivers/gpu/arm/midgard/platform_dummy/mali_ukk_os.h (renamed from mali-midgard-16.0/platform_dummy/mali_ukk_os.h)0
-rwxr-xr-xdriver/product/kernel/drivers/gpu/arm/midgard/sconscript86
-rwxr-xr-xdriver/product/kernel/drivers/gpu/arm/sconscript20
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/Kbuild28
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/Kconfig23
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/Makefile32
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_clcd_ext.h95
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm.h270
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_connector.c170
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_crtc.c449
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_cursor.c331
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_device.c338
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_dma_buf.c625
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_encoder.c107
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_fb.c202
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_funcs.h130
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_gem.c476
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_pl111.c417
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_platform.c151
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_suspend.c43
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_vma.c308
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/pl111/sconscript52
-rwxr-xr-xdriver/product/kernel/drivers/gpu/drm/sconscript23
-rwxr-xr-xdriver/product/kernel/drivers/gpu/sconscript21
-rwxr-xr-xdriver/product/kernel/drivers/sconscript116
-rwxr-xr-xdriver/product/kernel/include/linux/dma-buf-test-exporter.h78
-rwxr-xr-xdriver/product/kernel/include/linux/kds.h173
-rwxr-xr-xdriver/product/kernel/include/linux/ump-common.h252
-rwxr-xr-xdriver/product/kernel/include/linux/ump-import.h99
-rwxr-xr-xdriver/product/kernel/include/linux/ump-ioctl.h152
-rwxr-xr-xdriver/product/kernel/include/linux/ump.h481
-rwxr-xr-xdriver/product/kernel/license.txt198
-rwxr-xr-xdriver/product/kernel/patches/integrate_kds_with_dma_buf.patch188
-rwxr-xr-xdriver/product/kernel/sconscript23
-rw-r--r--mali-midgard-16.0/README21
-rwxr-xr-xmali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.c169
-rwxr-xr-xmali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.h47
-rw-r--r--mali-midgard-16.0/patches/0001-gpu-midgard-replace-device-tree-compatible-strings.patch35
-rw-r--r--mali-midgard-16.0/patches/0002-gpu-midgard-drop-clk_mali-name.patch29
-rw-r--r--mali-midgard-16.0/patches/0003-gpu-midgard-look-for-lower-case-IRQ-names.patch34
-rw-r--r--mali-midgard-16.0/patches/0004-gpu-midgard-add-deferring-in-log-when-clock-or-regul.patch40
-rw-r--r--mali-midgard-16.0/patches/arm64-standalone-headers.patch532
289 files changed, 12262 insertions, 910 deletions
diff --git a/debian/changelog b/debian/changelog
index ef8e012..009b813 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,9 @@
-mali-midgard (16.0-3) unstable; urgency=medium
+mali-midgard (16.0+pristine-1) unstable; urgency=medium
* Include patches for 4.14 kernel
+ * Use actual upstream tarball
- -- Wookey <wookey@debian.org> Mon, 15 Jan 2018 20:14:39 +0000
+ -- Wookey <wookey@debian.org> Wed, 14 Feb 2018 04:25:26 +0000
mali-midgard (16.0-2) unstable; urgency=medium
diff --git a/debian/rules b/debian/rules
index 85ac851..f06d9b5 100755
--- a/debian/rules
+++ b/debian/rules
@@ -8,7 +8,7 @@ VERSION := $(shell dpkg-parsechangelog -S Version | sed 's/-.*//')
dh $* --parallel --with dkms
override_dh_install:
- dh_install mali-midgard-$(VERSION) usr/src/
+ dh_install driver/product/kernel/drivers/gpu/arm/midgard/* usr/src/mali-midgard-$(VERSION)
find debian/mali-midgard-dkms/usr/src -type f -perm -5 -print0 2>/dev/null | xargs -0r chmod a-X
override_dh_dkms:
diff --git a/driver/product/kernel/Documentation/devicetree/bindings/arm/mali-midgard.txt b/driver/product/kernel/Documentation/devicetree/bindings/arm/mali-midgard.txt
new file mode 100755
index 0000000..687b9f2
--- /dev/null
+++ b/driver/product/kernel/Documentation/devicetree/bindings/arm/mali-midgard.txt
@@ -0,0 +1,96 @@
+#
+# (C) COPYRIGHT 2013-2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+* ARM Mali Midgard devices
+
+
+Required properties:
+
+- compatible : Should be mali<chip>, replacing digits with x from the back,
+until malit<Major>xx, ending with arm,mali-midgard, the latter not optional.
+- reg : Physical base address of the device and length of the register area.
+- interrupts : Contains the three IRQ lines required by T-6xx devices
+- interrupt-names : Contains the names of IRQ resources in the order they were
+provided in the interrupts property. Must contain: "JOB, "MMU", "GPU".
+
+Optional:
+
+- clocks : Phandle to clock for the Mali T-6xx device.
+- clock-names : Shall be "clk_mali".
+- mali-supply : Phandle to regulator for the Mali device. Refer to
+Documentation/devicetree/bindings/regulator/regulator.txt for details.
+- operating-points : Refer to Documentation/devicetree/bindings/power/opp.txt
+for details.
+- snoop_enable_smc : SMC function ID to enable CCI snooping on the GPU port(s).
+- snoop_disable_smc : SMC function ID to disable CCI snooping on the GPU port(s).
+- jm_config : For T860/T880. Sets job manager configuration. An array containing:
+ - 1 to override the TIMESTAMP value, 0 otherwise.
+ - 1 to override clock gate, forcing them to be always on, 0 otherwise.
+ - 1 to enable job throttle, limiting the number of cores that can be started
+ simultaneously, 0 otherwise.
+ - Value between 0 and 63 (including). If job throttle is enabled, this is one
+ less than the number of cores that can be started simultaneously.
+- power_model : Sets power model parameters. Note that this model was designed for the Juno
+ platform, and may not be suitable for other platforms. A structure containing :
+ - compatible: Should be arm,mali-simple-power-model
+ - voltage: Voltage at reference point. Specified in mV.
+ - frequency: Frequency at reference point. Specified in MHz.
+ - dynamic-power: Dynamic power at reference frequency and voltage. Specified in mW.
+ - static-power: Static power at reference frequency. Specified in mW.
+ - ts: An array containing coefficients for the temperature scaling factor.
+ Used as : tsf = ts[3]*T^3 + ts[2]*T^2 + ts[1]*T + ts[0], where T = temperature
+ - thermal-zone: A string identifying the thermal zone used for the GPU
+- system-coherency : Sets the coherency protocol to be used for coherent
+ accesses made from the GPU.
+ If not set then no coherency is used.
+ - 0 : ACE-Lite
+ - 1 : ACE
+ - 31 : No coherency
+- ipa-model : Sets the IPA model to be used for power management. GPU probe will fail if the
+ model is not found in the registered models list. If no model is specified here,
+ a gpu-id based model is picked if available, otherwise the default model is used.
+ - generic_ipa_model : Default model used on mali
+
+Example for a Mali-T602:
+
+gpu@0xfc010000 {
+ compatible = "arm,malit602", "arm,malit60x", "arm,malit6xx", "arm,mali-midgard";
+ reg = <0xfc010000 0x4000>;
+ interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
+ interrupt-names = "JOB", "MMU", "GPU";
+
+ clocks = <&pclk_mali>;
+ clock-names = "clk_mali";
+ mali-supply = <&vdd_mali>;
+ operating-points = <
+ /* KHz uV */
+ 533000 1250000,
+ 450000 1150000,
+ 400000 1125000,
+ 350000 1075000,
+ 266000 1025000,
+ 160000 925000,
+ 100000 912500,
+ >;
+ power_model {
+ compatible = "arm,mali-simple-power-model";
+ voltage = <800>;
+ frequency = <500>;
+ static-power = <500>;
+ dynamic-power = <1500>;
+ ts = <20000 2000 (-20) 2>;
+ thermal-zone = "gpu";
+ };
+};
diff --git a/driver/product/kernel/Documentation/dma-buf-test-exporter.txt b/driver/product/kernel/Documentation/dma-buf-test-exporter.txt
new file mode 100755
index 0000000..4208010
--- /dev/null
+++ b/driver/product/kernel/Documentation/dma-buf-test-exporter.txt
@@ -0,0 +1,40 @@
+#
+# (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+=====================
+dma-buf-test-exporter
+=====================
+
+Overview
+--------
+
+The dma-buf-test-exporter is a simple exporter of dma_buf objects.
+It has a private API to allocate and manipulate the buffers which are represented as dma_buf fds.
+The private API allows:
+* simple allocation of physically non-contiguous buffers
+* simple allocation of physically contiguous buffers
+* query kernel side API usage stats (number of attachments, number of mappings, mmaps)
+* failure mode configuration (fail attach, mapping, mmap)
+* kernel side memset of buffers
+
+The buffers support all of the dma_buf API, including mmap.
+
+It supports being compiled as a module both in-tree and out-of-tree.
+
+See include/linux/dma-buf-test-exporter.h for the ioctl interface.
+See Documentation/dma-buf-sharing.txt for details on dma_buf.
+
+
diff --git a/driver/product/kernel/Documentation/kds.txt b/driver/product/kernel/Documentation/kds.txt
new file mode 100755
index 0000000..639288c
--- /dev/null
+++ b/driver/product/kernel/Documentation/kds.txt
@@ -0,0 +1,268 @@
+#
+# (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+==============================
+kds - Kernel Dependency System
+==============================
+
+Introduction
+------------
+kds provides a mechanism for clients to atomically lock down multiple abstract resources.
+This can be done either synchronously or asynchronously.
+Abstract resources is used to allow a set of clients to use kds to control access to any
+resource, an example is structured memory buffers.
+
+kds supports that buffer is locked for exclusive access and sharing of buffers.
+
+kds can be built as either a integrated feature of the kernel or as a module.
+It supports being compiled as a module both in-tree and out-of-tree.
+
+
+Concepts
+--------
+A core concept in kds is abstract resources.
+A kds resource is just an abstraction for some client object, kds doesn't care what it is.
+Typically EGL will consider UMP buffers as being a resource, thus each UMP buffer has
+a kds resource for synchronization to the buffer.
+
+kds allows a client to create and destroy the abstract resource objects.
+A new resource object is made available asap (it is just a simple malloc with some initializations),
+while destroy it requires some external synchronization.
+
+The other core concept in kds is consumer of resources.
+kds is requested to allow a client to consume a set of resources and the client will be notified when it can consume the resources.
+
+Exclusive access allows only one client to consume a resource.
+Shared access permits multiple consumers to acceess a resource concurrently.
+
+
+APIs
+----
+kds provides simple resource allocate and destroy functions.
+Clients use this to instantiate and control the lifetime of the resources kds manages.
+
+kds provides two ways to wait for resources:
+- Asynchronous wait: the client specifies a function pointer to be called when wait is over
+- Synchronous wait: Function blocks until access is gained.
+
+The synchronous API has a timeout for the wait.
+The call can early out if a signal is delivered.
+
+After a client is done consuming the resource kds must be notified to release the resources and let some other client take ownership.
+This is done via resource set release call.
+
+A Windows comparison:
+kds implements WaitForMultipleObjectsEx(..., bWaitAll = TRUE, ...) but also has an asynchronous version in addition.
+kds resources can be seen as being the same as NT object manager resources.
+
+Internals
+---------
+kds guarantees atomicity when a set of resources is operated on.
+This is implemented via a global resource lock which is taken by kds when it updates resource objects.
+
+Internally a resource in kds is a linked list head with some flags.
+
+When a consumer requests access to a set of resources it is queued on each of the resources.
+The link from the consumer to the resources can be triggered. Once all links are triggered
+the registered callback is called or the blocking function returns.
+A link is considered triggered if it is the first on the list of consumers of a resource,
+or if all the links ahead of it is marked as shared and itself is of the type shared.
+
+When the client is done consuming the consumer object is removed from the linked lists of
+the resources and a potential new consumer becomes the head of the resources.
+As we add and remove consumers atomically across all resources we can guarantee that
+we never introduces a A->B + B->A type of loops/deadlocks.
+
+
+kbase/base implementation
+-------------------------
+A HW job needs access to a set of shared resources.
+EGL tracks this and encodes the set along with the atom in the ringbuffer.
+EGL allocates a (k)base dep object to represent the dependency to the set of resources and encodes that along with the list of resources.
+This dep object is use to create a dependency from a job chain(atom) to the resources it needs to run.
+When kbase decodes the atom in the ringbuffer it finds the set of resources and calls kds to request all the needed resources.
+As EGL needs to know when the kds request is delivered a new base event object is needed: atom enqueued. This event is only delivered for atoms which uses kds.
+The callback kbase registers trigger the dependency object described which would trigger the existing JD system to release the job chain.
+When the atom is done kds resource set release is call to release the resources.
+
+EGL will typically use exclusive access to the render target, while all buffers used as input can be marked as shared.
+
+
+Buffer publish/vsync
+--------------------
+EGL will use a separate ioctl or DRM flip to request the flip.
+If the LCD driver is integrated with kds EGL can do these operations early.
+The LCD driver must then implement the ioctl or DRM flip to be asynchronous with kds async call.
+The LCD driver binds a kds resource to each virtual buffer (2 buffers in case of double-buffering).
+EGL will make a dependency to the target kds resource in the kbase atom.
+After EGL receives a atom enqueued event it can ask the LCD driver to pan to the target kds resource.
+When the atom is completed it'll release the resource and the LCD driver will get its callback.
+In the callback it'll load the target buffer into the DMA unit of the LCD hardware.
+The LCD driver will be the consumer of both buffers for a short period.
+The LCD driver will call kds resource set release on the previous on-screen buffer when the next vsync/dma read end is handled.
+
+===============================================
+Kernel driver kds client design considerations
+===============================================
+
+Number of resources
+--------------------
+
+The kds api allows a client to wait for ownership of a number of resources, where by the client does not take on ownership of any of the resources in the resource set
+until all of the resources in the set are released. Consideration must be made with respect to performance, as waiting on large number of resources will incur
+a greater overhead and may increase system latency. It may be worth considering how independent each of the resources are, for example if the same set of resources
+are waited upon by each of the clients, then it may be possible to aggregate these into one resource that each client waits upon.
+
+Clients with shared access
+---------------------------
+
+The kds api allows a number of clients to gain shared access to a resource simultaneously, consideration must be made with respect to performance, large numbers of clients
+wanting shared access can incur a performance penalty and may increase system latency, specifically when the clients are granted access. Having an excessively high
+number of clients with shared access should be avoided, consideration should be made to the call back configuration being used. See Callbacks and Scenario 1 below.
+
+Callbacks
+----------
+
+Careful consideration must be made as to which callback type is most appropriate for kds clients, direct callbacks are called immediately from the context in which the
+ownership of the resource is passed to the next waiter in the list. Where as when using deferred callbacks the callback is deferred and called from outside the context
+that is relinquishing ownership, while this reduces the latency in the releasing clients context it does incur a cost as there is more latency between a resource
+becoming free and the new client owning the resource callback being executed.
+
+Obviously direct callbacks have a performance advantage, as the call back is immediate and does not have to wait for the kernel to context switch to schedule in the
+execution of the callback.
+
+However as the callback is immediate and within the context that is granting ownership it is important that the callback perform the MINIMUM amount of work necessary,
+long call backs could cause poor system latency. Special care and attention must be taken if the direct callbacks can be called from IRQ handlers, such as when
+kds_resource_set_release is called from an IRQ handler, in this case you have to avoid any calls that may sleep.
+
+Deferred contexts have the advantage that the call backs are deferred until they are scheduled by the kernel, therefore they are allowed to call functions that may sleep
+and if scheduled from IRQ context not incur as much system latency as would be seen with direct callbacks from within the IRQ.
+
+Once the clients callback has been called, the client is considered to be owning the resource. Within the callback the client may only need to perform a small amount of work
+before the client need to give up owner ship. The kds_resource_release function may be called from with in the call back, but consideration must be made when using direct
+callbacks, with both respect to execution time and stack usage. Consider the example in Scenario 2 with direct callbacks:
+
+Scenario 1 - Shared client access - direct callbacks:
+
+Resources: X
+Clients: A(S), B(S), C(S), D(S), E(E)
+where: (S) = shared user, (E) = exclusive
+
+Clients kds callback handler:
+
+client_<client>_cb( p1, p2 )
+{
+}
+
+Where <client> is either A,B,C,D
+ Queue |Owner
+1. E Requests X exclusive |
+2. E Owns X exclusive |E
+3. A Requests X shared A|E
+4. B Requests X shared BA|E
+5. C Requests X shared CBA|E
+6. D Requests X shared DCBA|E
+7. E Releases X |DCBA
+8. A Owns X shared |DCBA
+9. B Owns X shared |DCBA
+10. C Owns X shared |DCBA
+11. D Owns X shared |DCBA
+
+At point 7 it is important to note that when E releases X; A,B,C and D become the new shared owners of X and the call back for each of the client(A,B,C,D) triggered, so consideration
+must be made as to whether a direct or deferred callback is suitable, using direct callbacks would result in the call graph.
+
+Call graph when E releases X:
+ kds_resource_set_release( .. )
+ +->client_A_cb( .. )
+ +->client_B_cb( .. )
+ +->client_C_cb( .. )
+ +->client_D_cb( .. )
+
+
+Scenario 2 - Immediate resource release - direct callbacks:
+
+Resource: X
+Clients: A, B, C, D
+
+Clients kds callback handler:
+
+client_<client>_cb( p1, p2 )
+{
+ kds_resource_set_release( .. );
+}
+
+Where <client> is either A,B,C,D
+
+1. A Owns X exclusive
+2. B Requests X exclusive (direct callback)
+3. C Requests X exclusive (direct callback)
+4. D Requests X exclusive (direct callback)
+5. A Releases X
+
+Call graph when A releases X:
+ kds_resource_set_release( .. )
+ +->client_B_cb( .. )
+ +->kds_resource_set_release( .. )
+ +->client_C_cb( .. )
+ +->kds_resource_set_release( .. )
+ +->client_D_cb( .. )
+
+As can be seen when a client releases the resource, with direct call backs it is possible to create nested calls
+
+IRQ Considerations
+-------------------
+
+Usage of kds_resource_release in IRQ handlers should be carefully considered.
+
+Things to keep in mind:
+
+1.) Are you using direct or deferred callbacks?
+2.) How many resources are you releasing?
+3.) How many shared waiters are pending on the resource?
+
+Releasing ownership and wait cancellation
+------------------------------------------
+
+Client Wait Cancellation
+-------------------------
+
+It may be necessary in certain circumstances for the client to cancel the wait for kds resources for error handling, process termination etc. Cancellation is
+performed using kds_resource_set_release or kds_resource_set_release_sync using the rset that was received from kds_async_waitall, kds_resource_set_release_sync
+being used for waits which are using deferred callbacks.
+
+It is possible that while the request to cancel the wait is being issued by the client, the client is granted access to the resources. Normally after the client
+has taken ownership and finishes with that resource, it will release ownership to signal other waiters which are pending, this causes a race with the cancellation.
+To prevent KDS trying to remove a wait twice from the internal list and accessing memory that is potentially freed, it is very important that all releasers use the
+same rset pointer. Here is a simplified example of bad usage that must be avoided in any client implementation:
+
+Senario 3 - Bad release from multiple contexts:
+
+ This scenaro is highlighting bad usage of the kds API
+
+ kds_resource_set * rset;
+ kds_resource_set * rset_copy;
+
+ kds_async_waitall( &rset, ... ... ... );
+
+ /* Don't do this */
+ rset_copy = rset;
+
+Context A:
+ kds_resource_set_release( &rset )
+
+Context B:
+ kds_resource_set_release( &rset_copy )
+
diff --git a/driver/product/kernel/drivers/base/dma_buf_lock/sconscript b/driver/product/kernel/drivers/base/dma_buf_lock/sconscript
new file mode 100755
index 0000000..99293c3
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_lock/sconscript
@@ -0,0 +1,23 @@
+#
+# (C) COPYRIGHT 2012, 2014, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+import os
+import re
+Import('env')
+
+if env.KernelConfigEnabled("CONFIG_DMA_SHARED_BUFFER_USES_KDS"):
+ SConscript("src/sconscript")
+ if env["tests"] and Glob("tests/sconscript"):
+ SConscript("tests/sconscript")
diff --git a/driver/product/kernel/drivers/base/dma_buf_lock/src/Kbuild b/driver/product/kernel/drivers/base/dma_buf_lock/src/Kbuild
new file mode 100755
index 0000000..68dad07
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_lock/src/Kbuild
@@ -0,0 +1,18 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+ifneq ($(CONFIG_DMA_SHARED_BUFFER),)
+obj-m := dma_buf_lock.o
+endif
diff --git a/driver/product/kernel/drivers/base/dma_buf_lock/src/Makefile b/driver/product/kernel/drivers/base/dma_buf_lock/src/Makefile
new file mode 100755
index 0000000..cf76132
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_lock/src/Makefile
@@ -0,0 +1,32 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+# linux build system bootstrap for out-of-tree module
+
+# default to building for the host
+ARCH ?= $(shell uname -m)
+
+ifeq ($(KDIR),)
+$(error Must specify KDIR to point to the kernel to target))
+endif
+
+all: dma_buf_lock
+
+dma_buf_lock:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../include"
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
diff --git a/driver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.c b/driver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.c
new file mode 100755
index 0000000..9613ffc
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.c
@@ -0,0 +1,481 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 <asm/uaccess.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/atomic.h>
+#include <linux/dma-buf.h>
+#include <linux/kds.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+
+#include "dma_buf_lock.h"
+
+/* Maximum number of buffers that a single handle can address */
+#define DMA_BUF_LOCK_BUF_MAX 32
+
+#define DMA_BUF_LOCK_DEBUG 1
+
+static dev_t dma_buf_lock_dev;
+static struct cdev dma_buf_lock_cdev;
+static struct class *dma_buf_lock_class;
+static char dma_buf_lock_dev_name[] = "dma_buf_lock";
+
+#ifdef HAVE_UNLOCKED_IOCTL
+static long dma_buf_lock_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#else
+static int dma_buf_lock_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+#endif
+
+static struct file_operations dma_buf_lock_fops =
+{
+ .owner = THIS_MODULE,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = dma_buf_lock_ioctl,
+#else
+ .ioctl = dma_buf_lock_ioctl,
+#endif
+ .compat_ioctl = dma_buf_lock_ioctl,
+};
+
+typedef struct dma_buf_lock_resource
+{
+ int *list_of_dma_buf_fds; /* List of buffers copied from userspace */
+ atomic_t locked; /* Status of lock */
+ struct dma_buf **dma_bufs;
+ struct kds_resource **kds_resources; /* List of KDS resources associated with buffers */
+ struct kds_resource_set *resource_set;
+ unsigned long exclusive; /* Exclusive access bitmap */
+ wait_queue_head_t wait;
+ struct kds_callback cb;
+ struct kref refcount;
+ struct list_head link;
+ int count;
+} dma_buf_lock_resource;
+
+static LIST_HEAD(dma_buf_lock_resource_list);
+static DEFINE_MUTEX(dma_buf_lock_mutex);
+
+static inline int is_dma_buf_lock_file(struct file *);
+static void dma_buf_lock_dounlock(struct kref *ref);
+
+static int dma_buf_lock_handle_release(struct inode *inode, struct file *file)
+{
+ dma_buf_lock_resource *resource;
+
+ if (!is_dma_buf_lock_file(file))
+ return -EINVAL;
+
+ resource = file->private_data;
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_handle_release\n");
+#endif
+ mutex_lock(&dma_buf_lock_mutex);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+
+ return 0;
+}
+
+static void dma_buf_lock_kds_callback(void *param1, void *param2)
+{
+ dma_buf_lock_resource *resource = param1;
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_kds_callback\n");
+#endif
+ atomic_set(&resource->locked, 1);
+
+ wake_up(&resource->wait);
+}
+
+static unsigned int dma_buf_lock_handle_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ dma_buf_lock_resource *resource;
+ unsigned int ret = 0;
+
+ if (!is_dma_buf_lock_file(file))
+ return POLLERR;
+
+ resource = file->private_data;
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_handle_poll\n");
+#endif
+ if (1 == atomic_read(&resource->locked))
+ {
+ /* Resources have been locked */
+ ret = POLLIN | POLLRDNORM;
+ if (resource->exclusive)
+ {
+ ret |= POLLOUT | POLLWRNORM;
+ }
+ }
+ else
+ {
+ if (!poll_does_not_wait(wait))
+ {
+ poll_wait(file, &resource->wait, wait);
+ }
+ }
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_handle_poll : return %i\n", ret);
+#endif
+ return ret;
+}
+
+static const struct file_operations dma_buf_lock_handle_fops = {
+ .release = dma_buf_lock_handle_release,
+ .poll = dma_buf_lock_handle_poll,
+};
+
+/*
+ * is_dma_buf_lock_file - Check if struct file* is associated with dma_buf_lock
+ */
+static inline int is_dma_buf_lock_file(struct file *file)
+{
+ return file->f_op == &dma_buf_lock_handle_fops;
+}
+
+
+
+/*
+ * Start requested lock.
+ *
+ * Allocates required memory, copies dma_buf_fd list from userspace,
+ * acquires related KDS resources, and starts the lock.
+ */
+static int dma_buf_lock_dolock(dma_buf_lock_k_request *request)
+{
+ dma_buf_lock_resource *resource;
+ int size;
+ int fd;
+ int i;
+ int ret;
+
+ if (NULL == request->list_of_dma_buf_fds)
+ {
+ return -EINVAL;
+ }
+ if (request->count <= 0)
+ {
+ return -EINVAL;
+ }
+ if (request->count > DMA_BUF_LOCK_BUF_MAX)
+ {
+ return -EINVAL;
+ }
+ if (request->exclusive != DMA_BUF_LOCK_NONEXCLUSIVE &&
+ request->exclusive != DMA_BUF_LOCK_EXCLUSIVE)
+ {
+ return -EINVAL;
+ }
+
+ resource = kzalloc(sizeof(dma_buf_lock_resource), GFP_KERNEL);
+ if (NULL == resource)
+ {
+ return -ENOMEM;
+ }
+
+ atomic_set(&resource->locked, 0);
+ kref_init(&resource->refcount);
+ INIT_LIST_HEAD(&resource->link);
+ resource->count = request->count;
+
+ /* Allocate space to store dma_buf_fds received from user space */
+ size = request->count * sizeof(int);
+ resource->list_of_dma_buf_fds = kmalloc(size, GFP_KERNEL);
+
+ if (NULL == resource->list_of_dma_buf_fds)
+ {
+ kfree(resource);
+ return -ENOMEM;
+ }
+
+ /* Allocate space to store dma_buf pointers associated with dma_buf_fds */
+ size = sizeof(struct dma_buf *) * request->count;
+ resource->dma_bufs = kmalloc(size, GFP_KERNEL);
+
+ if (NULL == resource->dma_bufs)
+ {
+ kfree(resource->list_of_dma_buf_fds);
+ kfree(resource);
+ return -ENOMEM;
+ }
+ /* Allocate space to store kds_resources associated with dma_buf_fds */
+ size = sizeof(struct kds_resource *) * request->count;
+ resource->kds_resources = kmalloc(size, GFP_KERNEL);
+
+ if (NULL == resource->kds_resources)
+ {
+ kfree(resource->dma_bufs);
+ kfree(resource->list_of_dma_buf_fds);
+ kfree(resource);
+ return -ENOMEM;
+ }
+
+ /* Copy requested list of dma_buf_fds from user space */
+ size = request->count * sizeof(int);
+ if (0 != copy_from_user(resource->list_of_dma_buf_fds, (void __user *)request->list_of_dma_buf_fds, size))
+ {
+ kfree(resource->list_of_dma_buf_fds);
+ kfree(resource->dma_bufs);
+ kfree(resource->kds_resources);
+ kfree(resource);
+ return -ENOMEM;
+ }
+#if DMA_BUF_LOCK_DEBUG
+ for (i = 0; i < request->count; i++)
+ {
+ printk("dma_buf %i = %X\n", i, resource->list_of_dma_buf_fds[i]);
+ }
+#endif
+
+ /* Add resource to global list */
+ mutex_lock(&dma_buf_lock_mutex);
+
+ list_add(&resource->link, &dma_buf_lock_resource_list);
+
+ mutex_unlock(&dma_buf_lock_mutex);
+
+ for (i = 0; i < request->count; i++)
+ {
+ /* Convert fd into dma_buf structure */
+ resource->dma_bufs[i] = dma_buf_get(resource->list_of_dma_buf_fds[i]);
+
+ if (IS_ERR_VALUE(PTR_ERR(resource->dma_bufs[i])))
+ {
+ mutex_lock(&dma_buf_lock_mutex);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+ return -EINVAL;
+ }
+
+ /*Get kds_resource associated with dma_buf */
+ resource->kds_resources[i] = get_dma_buf_kds_resource(resource->dma_bufs[i]);
+
+ if (NULL == resource->kds_resources[i])
+ {
+ mutex_lock(&dma_buf_lock_mutex);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+ return -EINVAL;
+ }
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_dolock : dma_buf_fd %i dma_buf %X kds_resource %X\n", resource->list_of_dma_buf_fds[i],
+ (unsigned int)resource->dma_bufs[i], (unsigned int)resource->kds_resources[i]);
+#endif
+ }
+
+ kds_callback_init(&resource->cb, 1, dma_buf_lock_kds_callback);
+ init_waitqueue_head(&resource->wait);
+
+ kref_get(&resource->refcount);
+
+ /* Create file descriptor associated with lock request */
+ fd = anon_inode_getfd("dma_buf_lock", &dma_buf_lock_handle_fops,
+ (void *)resource, 0);
+ if (fd < 0)
+ {
+ mutex_lock(&dma_buf_lock_mutex);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+ return fd;
+ }
+
+ resource->exclusive = request->exclusive;
+
+ /* Start locking process */
+ ret = kds_async_waitall(&resource->resource_set,
+ &resource->cb, resource, NULL,
+ request->count, &resource->exclusive,
+ resource->kds_resources);
+
+ if (IS_ERR_VALUE(ret))
+ {
+ put_unused_fd(fd);
+
+ mutex_lock(&dma_buf_lock_mutex);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+
+ return ret;
+ }
+
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_dolock : complete\n");
+#endif
+ mutex_lock(&dma_buf_lock_mutex);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+
+ return fd;
+}
+
+static void dma_buf_lock_dounlock(struct kref *ref)
+{
+ int i;
+ dma_buf_lock_resource *resource = container_of(ref, dma_buf_lock_resource, refcount);
+
+ atomic_set(&resource->locked, 0);
+
+ kds_callback_term(&resource->cb);
+
+ kds_resource_set_release(&resource->resource_set);
+
+ list_del(&resource->link);
+
+ for (i = 0; i < resource->count; i++)
+ {
+ dma_buf_put(resource->dma_bufs[i]);
+ }
+
+ kfree(resource->kds_resources);
+ kfree(resource->dma_bufs);
+ kfree(resource->list_of_dma_buf_fds);
+ kfree(resource);
+}
+
+static int __init dma_buf_lock_init(void)
+{
+ int err;
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_init\n");
+#endif
+ err = alloc_chrdev_region(&dma_buf_lock_dev, 0, 1, dma_buf_lock_dev_name);
+
+ if (0 == err)
+ {
+ cdev_init(&dma_buf_lock_cdev, &dma_buf_lock_fops);
+
+ err = cdev_add(&dma_buf_lock_cdev, dma_buf_lock_dev, 1);
+
+ if (0 == err)
+ {
+ dma_buf_lock_class = class_create(THIS_MODULE, dma_buf_lock_dev_name);
+ if (IS_ERR(dma_buf_lock_class))
+ {
+ err = PTR_ERR(dma_buf_lock_class);
+ }
+ else
+ {
+ struct device *mdev;
+ mdev = device_create(dma_buf_lock_class, NULL, dma_buf_lock_dev, NULL, dma_buf_lock_dev_name);
+ if (!IS_ERR(mdev))
+ {
+ return 0;
+ }
+
+ err = PTR_ERR(mdev);
+ class_destroy(dma_buf_lock_class);
+ }
+ cdev_del(&dma_buf_lock_cdev);
+ }
+
+ unregister_chrdev_region(dma_buf_lock_dev, 1);
+ }
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_init failed\n");
+#endif
+ return err;
+}
+
+static void __exit dma_buf_lock_exit(void)
+{
+#if DMA_BUF_LOCK_DEBUG
+ printk("dma_buf_lock_exit\n");
+#endif
+
+ /* Unlock all outstanding references */
+ while (1)
+ {
+ mutex_lock(&dma_buf_lock_mutex);
+ if (list_empty(&dma_buf_lock_resource_list))
+ {
+ mutex_unlock(&dma_buf_lock_mutex);
+ break;
+ }
+ else
+ {
+ dma_buf_lock_resource *resource = list_entry(dma_buf_lock_resource_list.next,
+ dma_buf_lock_resource, link);
+ kref_put(&resource->refcount, dma_buf_lock_dounlock);
+ mutex_unlock(&dma_buf_lock_mutex);
+ }
+ }
+
+ device_destroy(dma_buf_lock_class, dma_buf_lock_dev);
+
+ class_destroy(dma_buf_lock_class);
+
+ cdev_del(&dma_buf_lock_cdev);
+
+ unregister_chrdev_region(dma_buf_lock_dev, 1);
+}
+
+#ifdef HAVE_UNLOCKED_IOCTL
+static long dma_buf_lock_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+#else
+static int dma_buf_lock_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+#endif
+{
+ dma_buf_lock_k_request request;
+ int size = _IOC_SIZE(cmd);
+
+ if (_IOC_TYPE(cmd) != DMA_BUF_LOCK_IOC_MAGIC)
+ {
+ return -ENOTTY;
+
+ }
+ if ((_IOC_NR(cmd) < DMA_BUF_LOCK_IOC_MINNR) || (_IOC_NR(cmd) > DMA_BUF_LOCK_IOC_MAXNR))
+ {
+ return -ENOTTY;
+ }
+
+ switch (cmd)
+ {
+ case DMA_BUF_LOCK_FUNC_LOCK_ASYNC:
+ if (size != sizeof(dma_buf_lock_k_request))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&request, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+#if DMA_BUF_LOCK_DEBUG
+ printk("DMA_BUF_LOCK_FUNC_LOCK_ASYNC - %i\n", request.count);
+#endif
+ return dma_buf_lock_dolock(&request);
+ }
+
+ return -ENOTTY;
+}
+
+module_init(dma_buf_lock_init);
+module_exit(dma_buf_lock_exit);
+
+MODULE_LICENSE("GPL");
+
diff --git a/driver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.h b/driver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.h
new file mode 100755
index 0000000..e1b9348
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_lock/src/dma_buf_lock.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 _DMA_BUF_LOCK_H
+#define _DMA_BUF_LOCK_H
+
+typedef enum dma_buf_lock_exclusive
+{
+ DMA_BUF_LOCK_NONEXCLUSIVE = 0,
+ DMA_BUF_LOCK_EXCLUSIVE = -1
+} dma_buf_lock_exclusive;
+
+typedef struct dma_buf_lock_k_request
+{
+ int count;
+ int *list_of_dma_buf_fds;
+ int timeout;
+ dma_buf_lock_exclusive exclusive;
+} dma_buf_lock_k_request;
+
+#define DMA_BUF_LOCK_IOC_MAGIC '~'
+
+#define DMA_BUF_LOCK_FUNC_LOCK_ASYNC _IOW(DMA_BUF_LOCK_IOC_MAGIC, 11, dma_buf_lock_k_request)
+
+#define DMA_BUF_LOCK_IOC_MINNR 11
+#define DMA_BUF_LOCK_IOC_MAXNR 11
+
+#endif /* _DMA_BUF_LOCK_H */
diff --git a/driver/product/kernel/drivers/base/dma_buf_lock/src/sconscript b/driver/product/kernel/drivers/base/dma_buf_lock/src/sconscript
new file mode 100755
index 0000000..b8724f1
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_lock/src/sconscript
@@ -0,0 +1,33 @@
+#
+# (C) COPYRIGHT 2012-2013, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+import os
+import re
+Import('env')
+
+src = [Glob('#kernel/drivers/base/dma_buf_lock/src/*.c'), Glob('#kernel/drivers/base/dma_buf_lock/src/*.h'), Glob('#kernel/drivers/base/dma_buf_lock/src/K*')]
+
+if env.GetOption('clean') :
+ # Clean module
+ env.Execute(Action("make clean", '[CLEAN] dma_buf_lock'))
+ cmd = env.Command('$STATIC_LIB_PATH/dma_buf_lock.ko', src, [])
+ env.KernelObjTarget('dma_buf_lock', cmd)
+
+else:
+ # Build module
+ makeAction=Action("cd ${SOURCE.dir} && make dma_buf_lock && cp dma_buf_lock.ko $STATIC_LIB_PATH/", '$MAKECOMSTR')
+ cmd = env.Command('$STATIC_LIB_PATH/dma_buf_lock.ko', src, [makeAction])
+ env.KernelObjTarget('dma_buf_lock', cmd)
+
diff --git a/driver/product/kernel/drivers/base/dma_buf_test_exporter/Kbuild b/driver/product/kernel/drivers/base/dma_buf_test_exporter/Kbuild
new file mode 100755
index 0000000..56b9f86
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_test_exporter/Kbuild
@@ -0,0 +1,18 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+ifneq ($(CONFIG_DMA_SHARED_BUFFER),)
+obj-$(CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER) += dma-buf-test-exporter.o
+endif
diff --git a/driver/product/kernel/drivers/base/dma_buf_test_exporter/Kconfig b/driver/product/kernel/drivers/base/dma_buf_test_exporter/Kconfig
new file mode 100755
index 0000000..974f0c2
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_test_exporter/Kconfig
@@ -0,0 +1,20 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+config DMA_SHARED_BUFFER_TEST_EXPORTER
+ tristate "Test exporter for the dma-buf framework"
+ depends on DMA_SHARED_BUFFER
+ help
+ This option enables the test exporter usable to help test importerts.
diff --git a/driver/product/kernel/drivers/base/dma_buf_test_exporter/Makefile b/driver/product/kernel/drivers/base/dma_buf_test_exporter/Makefile
new file mode 100755
index 0000000..06e3d5c
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_test_exporter/Makefile
@@ -0,0 +1,30 @@
+#
+# (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+# linux build system bootstrap for out-of-tree module
+
+# default to building for the host
+ARCH ?= $(shell uname -m)
+
+ifeq ($(KDIR),)
+$(error Must specify KDIR to point to the kernel to target))
+endif
+
+all:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../include" CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER=m
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
diff --git a/driver/product/kernel/drivers/base/dma_buf_test_exporter/dma-buf-test-exporter.c b/driver/product/kernel/drivers/base/dma_buf_test_exporter/dma-buf-test-exporter.c
new file mode 100755
index 0000000..08ab49a
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_test_exporter/dma-buf-test-exporter.c
@@ -0,0 +1,703 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2016 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include <linux/dma-buf-test-exporter.h>
+#include <linux/dma-buf.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/atomic.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
+#include <linux/dma-attrs.h>
+#endif
+#include <linux/dma-mapping.h>
+#endif
+
+struct dma_buf_te_alloc {
+ /* the real alloc */
+ int nr_pages;
+ struct page **pages;
+
+ /* the debug usage tracking */
+ int nr_attached_devices;
+ int nr_device_mappings;
+ int nr_cpu_mappings;
+
+ /* failure simulation */
+ int fail_attach;
+ int fail_map;
+ int fail_mmap;
+
+ bool contiguous;
+ dma_addr_t contig_dma_addr;
+ void *contig_cpu_addr;
+};
+
+static struct miscdevice te_device;
+
+static int dma_buf_te_attach(struct dma_buf *buf, struct device *dev, struct dma_buf_attachment *attachment)
+{
+ struct dma_buf_te_alloc *alloc;
+ alloc = buf->priv;
+
+ if (alloc->fail_attach)
+ return -EFAULT;
+
+ /* dma_buf is externally locked during call */
+ alloc->nr_attached_devices++;
+ return 0;
+}
+
+static void dma_buf_te_detach(struct dma_buf *buf, struct dma_buf_attachment *attachment)
+{
+ struct dma_buf_te_alloc *alloc;
+ alloc = buf->priv;
+ /* dma_buf is externally locked during call */
+
+ alloc->nr_attached_devices--;
+}
+
+static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment, enum dma_data_direction direction)
+{
+ struct sg_table *sg;
+ struct scatterlist *iter;
+ struct dma_buf_te_alloc *alloc;
+ int i;
+ int ret;
+
+ alloc = attachment->dmabuf->priv;
+
+ if (alloc->fail_map)
+ return ERR_PTR(-ENOMEM);
+
+#if !(defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
+ /* if the ARCH can't chain we can't have allocs larger than a single sg can hold */
+ if (alloc->nr_pages > SG_MAX_SINGLE_ALLOC)
+ return ERR_PTR(-EINVAL);
+#endif
+
+ sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+ if (!sg)
+ return ERR_PTR(-ENOMEM);
+
+ /* from here we access the allocation object, so lock the dmabuf pointing to it */
+ mutex_lock(&attachment->dmabuf->lock);
+
+ if (alloc->contiguous)
+ ret = sg_alloc_table(sg, 1, GFP_KERNEL);
+ else
+ ret = sg_alloc_table(sg, alloc->nr_pages, GFP_KERNEL);
+ if (ret) {
+ mutex_unlock(&attachment->dmabuf->lock);
+ kfree(sg);
+ return ERR_PTR(ret);
+ }
+
+ if (alloc->contiguous) {
+ sg_dma_len(sg->sgl) = alloc->nr_pages * PAGE_SIZE;
+ sg_set_page(sg->sgl, pfn_to_page(PFN_DOWN(alloc->contig_dma_addr)), alloc->nr_pages * PAGE_SIZE, 0);
+ sg_dma_address(sg->sgl) = alloc->contig_dma_addr;
+ } else {
+ for_each_sg(sg->sgl, iter, alloc->nr_pages, i)
+ sg_set_page(iter, alloc->pages[i], PAGE_SIZE, 0);
+ }
+
+ if (!dma_map_sg(attachment->dev, sg->sgl, sg->nents, direction)) {
+ mutex_unlock(&attachment->dmabuf->lock);
+ sg_free_table(sg);
+ kfree(sg);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ alloc->nr_device_mappings++;
+ mutex_unlock(&attachment->dmabuf->lock);
+ return sg;
+}
+
+static void dma_buf_te_unmap(struct dma_buf_attachment *attachment,
+ struct sg_table *sg, enum dma_data_direction direction)
+{
+ struct dma_buf_te_alloc *alloc;
+
+ alloc = attachment->dmabuf->priv;
+
+ dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, direction);
+ sg_free_table(sg);
+ kfree(sg);
+
+ mutex_lock(&attachment->dmabuf->lock);
+ alloc->nr_device_mappings--;
+ mutex_unlock(&attachment->dmabuf->lock);
+}
+
+static void dma_buf_te_release(struct dma_buf *buf)
+{
+ int i;
+ struct dma_buf_te_alloc *alloc;
+ alloc = buf->priv;
+ /* no need for locking */
+
+ if (alloc->contiguous) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+ dma_free_attrs(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ alloc->contig_cpu_addr,
+ alloc->contig_dma_addr,
+ DMA_ATTR_WRITE_COMBINE);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ DEFINE_DMA_ATTRS(attrs);
+
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ dma_free_attrs(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ alloc->contig_cpu_addr, alloc->contig_dma_addr, &attrs);
+#else
+ dma_free_writecombine(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ alloc->contig_cpu_addr, alloc->contig_dma_addr);
+#endif
+ } else {
+ for (i = 0; i < alloc->nr_pages; i++)
+ __free_page(alloc->pages[i]);
+ }
+ kfree(alloc->pages);
+ kfree(alloc);
+}
+
+
+static void dma_buf_te_mmap_open(struct vm_area_struct *vma)
+{
+ struct dma_buf *dma_buf;
+ struct dma_buf_te_alloc *alloc;
+ dma_buf = vma->vm_private_data;
+ alloc = dma_buf->priv;
+
+ mutex_lock(&dma_buf->lock);
+ alloc->nr_cpu_mappings++;
+ mutex_unlock(&dma_buf->lock);
+}
+
+static void dma_buf_te_mmap_close(struct vm_area_struct *vma)
+{
+ struct dma_buf *dma_buf;
+ struct dma_buf_te_alloc *alloc;
+ dma_buf = vma->vm_private_data;
+ alloc = dma_buf->priv;
+
+ BUG_ON(alloc->nr_cpu_mappings <= 0);
+ mutex_lock(&dma_buf->lock);
+ alloc->nr_cpu_mappings--;
+ mutex_unlock(&dma_buf->lock);
+}
+
+static int dma_buf_te_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct dma_buf_te_alloc *alloc;
+ struct dma_buf *dmabuf;
+ struct page *pageptr;
+
+ dmabuf = vma->vm_private_data;
+ alloc = dmabuf->priv;
+
+ if (vmf->pgoff > alloc->nr_pages)
+ return VM_FAULT_SIGBUS;
+
+ pageptr = alloc->pages[vmf->pgoff];
+
+ BUG_ON(!pageptr);
+
+ get_page(pageptr);
+ vmf->page = pageptr;
+
+ return 0;
+}
+
+struct vm_operations_struct dma_buf_te_vm_ops = {
+ .open = dma_buf_te_mmap_open,
+ .close = dma_buf_te_mmap_close,
+ .fault = dma_buf_te_mmap_fault
+};
+
+static int dma_buf_te_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+ struct dma_buf_te_alloc *alloc;
+ alloc = dmabuf->priv;
+
+ if (alloc->fail_mmap)
+ return -ENOMEM;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
+#else
+ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTEXPAND;
+#endif
+ vma->vm_ops = &dma_buf_te_vm_ops;
+ vma->vm_private_data = dmabuf;
+
+ /* we fault in the pages on access */
+
+ /* call open to do the ref-counting */
+ dma_buf_te_vm_ops.open(vma);
+
+ return 0;
+}
+
+static void *dma_buf_te_kmap_atomic(struct dma_buf *buf, unsigned long page_num)
+{
+ /* IGNORE */
+ return NULL;
+}
+
+static void *dma_buf_te_kmap(struct dma_buf *buf, unsigned long page_num)
+{
+ struct dma_buf_te_alloc *alloc;
+
+ alloc = buf->priv;
+ if (page_num >= alloc->nr_pages)
+ return NULL;
+
+ return kmap(alloc->pages[page_num]);
+}
+static void dma_buf_te_kunmap(struct dma_buf *buf,
+ unsigned long page_num, void *addr)
+{
+ struct dma_buf_te_alloc *alloc;
+
+ alloc = buf->priv;
+ if (page_num >= alloc->nr_pages)
+ return;
+
+ kunmap(alloc->pages[page_num]);
+ return;
+}
+
+static struct dma_buf_ops dma_buf_te_ops = {
+ /* real handlers */
+ .attach = dma_buf_te_attach,
+ .detach = dma_buf_te_detach,
+ .map_dma_buf = dma_buf_te_map,
+ .unmap_dma_buf = dma_buf_te_unmap,
+ .release = dma_buf_te_release,
+ .mmap = dma_buf_te_mmap,
+ .kmap = dma_buf_te_kmap,
+ .kunmap = dma_buf_te_kunmap,
+
+ /* nop handlers for mandatory functions we ignore */
+ .kmap_atomic = dma_buf_te_kmap_atomic
+};
+
+static int do_dma_buf_te_ioctl_version(struct dma_buf_te_ioctl_version __user *buf)
+{
+ struct dma_buf_te_ioctl_version v;
+
+ if (copy_from_user(&v, buf, sizeof(v)))
+ return -EFAULT;
+
+ if (v.op != DMA_BUF_TE_ENQ)
+ return -EFAULT;
+
+ v.op = DMA_BUF_TE_ACK;
+ v.major = DMA_BUF_TE_VER_MAJOR;
+ v.minor = DMA_BUF_TE_VER_MINOR;
+
+ if (copy_to_user(buf, &v, sizeof(v)))
+ return -EFAULT;
+ else
+ return 0;
+}
+
+static int do_dma_buf_te_ioctl_alloc(struct dma_buf_te_ioctl_alloc __user *buf, bool contiguous)
+{
+ struct dma_buf_te_ioctl_alloc alloc_req;
+ struct dma_buf_te_alloc *alloc;
+ struct dma_buf *dma_buf;
+ int i = 0;
+ int fd;
+
+ if (copy_from_user(&alloc_req, buf, sizeof(alloc_req))) {
+ dev_err(te_device.this_device, "%s: couldn't get user data", __func__);
+ goto no_input;
+ }
+
+ if (!alloc_req.size) {
+ dev_err(te_device.this_device, "%s: no size specified", __func__);
+ goto invalid_size;
+ }
+
+#if !(defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
+ /* Whilst it is possible to allocate larger buffer, we won't be able to
+ * map it during actual usage (mmap() still succeeds). We fail here so
+ * userspace code can deal with it early than having driver failure
+ * later on. */
+ if (alloc_req.size > SG_MAX_SINGLE_ALLOC) {
+ dev_err(te_device.this_device, "%s: buffer size of %llu pages exceeded the mapping limit of %lu pages",
+ __func__, alloc_req.size, SG_MAX_SINGLE_ALLOC);
+ goto invalid_size;
+ }
+#endif
+
+ alloc = kzalloc(sizeof(struct dma_buf_te_alloc), GFP_KERNEL);
+ if (NULL == alloc) {
+ dev_err(te_device.this_device, "%s: couldn't alloc object", __func__);
+ goto no_alloc_object;
+ }
+
+ alloc->nr_pages = alloc_req.size;
+ alloc->contiguous = contiguous;
+
+ alloc->pages = kzalloc(sizeof(struct page *) * alloc->nr_pages, GFP_KERNEL);
+ if (!alloc->pages) {
+ dev_err(te_device.this_device,
+ "%s: couldn't alloc %d page structures", __func__,
+ alloc->nr_pages);
+ goto free_alloc_object;
+ }
+
+ if (contiguous) {
+ dma_addr_t dma_aux;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+ alloc->contig_cpu_addr = dma_alloc_attrs(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ &alloc->contig_dma_addr,
+ GFP_KERNEL | __GFP_ZERO,
+ DMA_ATTR_WRITE_COMBINE);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ DEFINE_DMA_ATTRS(attrs);
+
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ alloc->contig_cpu_addr = dma_alloc_attrs(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ &alloc->contig_dma_addr,
+ GFP_KERNEL | __GFP_ZERO, &attrs);
+#else
+ alloc->contig_cpu_addr = dma_alloc_writecombine(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ &alloc->contig_dma_addr,
+ GFP_KERNEL | __GFP_ZERO);
+#endif
+ if (!alloc->contig_cpu_addr) {
+ dev_err(te_device.this_device, "%s: couldn't alloc contiguous buffer %d pages", __func__, alloc->nr_pages);
+ goto free_page_struct;
+ }
+ dma_aux = alloc->contig_dma_addr;
+ for (i = 0; i < alloc->nr_pages; i++) {
+ alloc->pages[i] = pfn_to_page(PFN_DOWN(dma_aux));
+ dma_aux += PAGE_SIZE;
+ }
+ } else {
+ for (i = 0; i < alloc->nr_pages; i++) {
+ alloc->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (NULL == alloc->pages[i]) {
+ dev_err(te_device.this_device, "%s: couldn't alloc page", __func__);
+ goto no_page;
+ }
+ }
+ }
+
+ /* alloc ready, let's export it */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+ {
+ struct dma_buf_export_info export_info = {
+ .exp_name = "dma_buf_te",
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
+ .owner = THIS_MODULE,
+#endif
+ .ops = &dma_buf_te_ops,
+ .size = alloc->nr_pages << PAGE_SHIFT,
+ .flags = O_CLOEXEC | O_RDWR,
+ .priv = alloc,
+ };
+
+ dma_buf = dma_buf_export(&export_info);
+ }
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
+ dma_buf = dma_buf_export(alloc, &dma_buf_te_ops,
+ alloc->nr_pages << PAGE_SHIFT, O_CLOEXEC|O_RDWR, NULL);
+#else
+ dma_buf = dma_buf_export(alloc, &dma_buf_te_ops,
+ alloc->nr_pages << PAGE_SHIFT, O_CLOEXEC|O_RDWR);
+#endif
+
+ if (IS_ERR_OR_NULL(dma_buf)) {
+ dev_err(te_device.this_device, "%s: couldn't export dma_buf", __func__);
+ goto no_export;
+ }
+
+ /* get fd for buf */
+ fd = dma_buf_fd(dma_buf, O_CLOEXEC);
+
+ if (fd < 0) {
+ dev_err(te_device.this_device, "%s: couldn't get fd from dma_buf", __func__);
+ goto no_fd;
+ }
+
+ return fd;
+
+no_fd:
+ dma_buf_put(dma_buf);
+no_export:
+ /* i still valid */
+no_page:
+ if (contiguous) {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+ dma_free_attrs(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ alloc->contig_cpu_addr,
+ alloc->contig_dma_addr,
+ DMA_ATTR_WRITE_COMBINE);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ DEFINE_DMA_ATTRS(attrs);
+
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ dma_free_attrs(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ alloc->contig_cpu_addr, alloc->contig_dma_addr, &attrs);
+#else
+ dma_free_writecombine(te_device.this_device,
+ alloc->nr_pages * PAGE_SIZE,
+ alloc->contig_cpu_addr, alloc->contig_dma_addr);
+#endif
+ } else {
+ while (i-- > 0)
+ __free_page(alloc->pages[i]);
+ }
+free_page_struct:
+ kfree(alloc->pages);
+free_alloc_object:
+ kfree(alloc);
+no_alloc_object:
+invalid_size:
+no_input:
+ return -EFAULT;
+}
+
+static int do_dma_buf_te_ioctl_status(struct dma_buf_te_ioctl_status __user *arg)
+{
+ struct dma_buf_te_ioctl_status status;
+ struct dma_buf *dmabuf;
+ struct dma_buf_te_alloc *alloc;
+ int res = -EINVAL;
+
+ if (copy_from_user(&status, arg, sizeof(status)))
+ return -EFAULT;
+
+ dmabuf = dma_buf_get(status.fd);
+ if (IS_ERR_OR_NULL(dmabuf))
+ return -EINVAL;
+
+ /* verify it's one of ours */
+ if (dmabuf->ops != &dma_buf_te_ops)
+ goto err_have_dmabuf;
+
+ /* ours, get the current status */
+ alloc = dmabuf->priv;
+
+ /* lock while reading status to take a snapshot */
+ mutex_lock(&dmabuf->lock);
+ status.attached_devices = alloc->nr_attached_devices;
+ status.device_mappings = alloc->nr_device_mappings;
+ status.cpu_mappings = alloc->nr_cpu_mappings;
+ mutex_unlock(&dmabuf->lock);
+
+ if (copy_to_user(arg, &status, sizeof(status)))
+ goto err_have_dmabuf;
+
+ /* All OK */
+ res = 0;
+
+err_have_dmabuf:
+ dma_buf_put(dmabuf);
+ return res;
+}
+
+static int do_dma_buf_te_ioctl_set_failing(struct dma_buf_te_ioctl_set_failing __user *arg)
+{
+ struct dma_buf *dmabuf;
+ struct dma_buf_te_ioctl_set_failing f;
+ struct dma_buf_te_alloc *alloc;
+ int res = -EINVAL;
+
+ if (copy_from_user(&f, arg, sizeof(f)))
+ return -EFAULT;
+
+ dmabuf = dma_buf_get(f.fd);
+ if (IS_ERR_OR_NULL(dmabuf))
+ return -EINVAL;
+
+ /* verify it's one of ours */
+ if (dmabuf->ops != &dma_buf_te_ops)
+ goto err_have_dmabuf;
+
+ /* ours, set the fail modes */
+ alloc = dmabuf->priv;
+ /* lock to set the fail modes atomically */
+ mutex_lock(&dmabuf->lock);
+ alloc->fail_attach = f.fail_attach;
+ alloc->fail_map = f.fail_map;
+ alloc->fail_mmap = f.fail_mmap;
+ mutex_unlock(&dmabuf->lock);
+
+ /* success */
+ res = 0;
+
+err_have_dmabuf:
+ dma_buf_put(dmabuf);
+ return res;
+}
+
+static u32 dma_te_buf_fill(struct dma_buf *dma_buf, unsigned int value)
+{
+ struct dma_buf_attachment *attachment;
+ struct sg_table *sgt;
+ struct scatterlist *sg;
+ unsigned int count;
+ unsigned int offset = 0;
+ int ret = 0;
+ int i;
+
+ attachment = dma_buf_attach(dma_buf, te_device.this_device);
+ if (IS_ERR_OR_NULL(attachment))
+ return -EBUSY;
+
+ sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
+ if (IS_ERR_OR_NULL(sgt)) {
+ ret = PTR_ERR(sgt);
+ goto no_import;
+ }
+
+ ret = dma_buf_begin_cpu_access(dma_buf,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
+ 0, dma_buf->size,
+#endif
+ DMA_BIDIRECTIONAL);
+ if (ret)
+ goto no_cpu_access;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+ for (i = 0; i < sg_dma_len(sg); i = i + PAGE_SIZE) {
+ void *addr;
+
+ addr = dma_buf_kmap(dma_buf, i >> PAGE_SHIFT);
+ if (!addr) {
+ /* dma_buf_kmap is unimplemented in exynos and returns NULL */
+ ret = -EPERM;
+ goto no_kmap;
+ }
+ memset(addr, value, PAGE_SIZE);
+ dma_buf_kunmap(dma_buf, i >> PAGE_SHIFT, addr);
+ }
+ offset += sg_dma_len(sg);
+ }
+
+no_kmap:
+ dma_buf_end_cpu_access(dma_buf,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
+ 0, dma_buf->size,
+#endif
+ DMA_BIDIRECTIONAL);
+no_cpu_access:
+ dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
+no_import:
+ dma_buf_detach(dma_buf, attachment);
+ return ret;
+}
+
+static int do_dma_buf_te_ioctl_fill(struct dma_buf_te_ioctl_fill __user *arg)
+{
+
+ struct dma_buf *dmabuf;
+ struct dma_buf_te_ioctl_fill f;
+ int ret;
+
+ if (copy_from_user(&f, arg, sizeof(f)))
+ return -EFAULT;
+
+ dmabuf = dma_buf_get(f.fd);
+ if (IS_ERR_OR_NULL(dmabuf))
+ return -EINVAL;
+
+ ret = dma_te_buf_fill(dmabuf, f.value);
+ dma_buf_put(dmabuf);
+
+ return ret;
+}
+
+static long dma_buf_te_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case DMA_BUF_TE_VERSION:
+ return do_dma_buf_te_ioctl_version((struct dma_buf_te_ioctl_version __user *)arg);
+ case DMA_BUF_TE_ALLOC:
+ return do_dma_buf_te_ioctl_alloc((struct dma_buf_te_ioctl_alloc __user *)arg, false);
+ case DMA_BUF_TE_ALLOC_CONT:
+ return do_dma_buf_te_ioctl_alloc((struct dma_buf_te_ioctl_alloc __user *)arg, true);
+ case DMA_BUF_TE_QUERY:
+ return do_dma_buf_te_ioctl_status((struct dma_buf_te_ioctl_status __user *)arg);
+ case DMA_BUF_TE_SET_FAILING:
+ return do_dma_buf_te_ioctl_set_failing((struct dma_buf_te_ioctl_set_failing __user *)arg);
+ case DMA_BUF_TE_FILL:
+ return do_dma_buf_te_ioctl_fill((struct dma_buf_te_ioctl_fill __user *)arg);
+ default:
+ return -ENOTTY;
+ }
+}
+
+static const struct file_operations dma_buf_te_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = dma_buf_te_ioctl,
+ .compat_ioctl = dma_buf_te_ioctl,
+};
+
+static int __init dma_buf_te_init(void)
+{
+ int res;
+ te_device.minor = MISC_DYNAMIC_MINOR;
+ te_device.name = "dma_buf_te";
+ te_device.fops = &dma_buf_te_fops;
+
+ res = misc_register(&te_device);
+ if (res) {
+ printk(KERN_WARNING"Misc device registration failed of 'dma_buf_te'\n");
+ return res;
+ }
+ te_device.this_device->coherent_dma_mask = DMA_BIT_MASK(32);
+
+ dev_info(te_device.this_device, "dma_buf_te ready\n");
+ return 0;
+
+}
+
+static void __exit dma_buf_te_exit(void)
+{
+ misc_deregister(&te_device);
+}
+
+module_init(dma_buf_te_init);
+module_exit(dma_buf_te_exit);
+MODULE_LICENSE("GPL");
+
diff --git a/driver/product/kernel/drivers/base/dma_buf_test_exporter/sconscript b/driver/product/kernel/drivers/base/dma_buf_test_exporter/sconscript
new file mode 100755
index 0000000..5f42141
--- /dev/null
+++ b/driver/product/kernel/drivers/base/dma_buf_test_exporter/sconscript
@@ -0,0 +1,19 @@
+#
+# (C) COPYRIGHT 2010-2013, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+Import('env')
+
+mod = env.BuildKernelModule('$STATIC_LIB_PATH/dma-buf-test-exporter.ko', Glob('*.c'))
+env.KernelObjTarget('dma-buf-test-exporter', mod)
diff --git a/driver/product/kernel/drivers/base/kds/Kbuild b/driver/product/kernel/drivers/base/kds/Kbuild
new file mode 100755
index 0000000..a88acd8
--- /dev/null
+++ b/driver/product/kernel/drivers/base/kds/Kbuild
@@ -0,0 +1,18 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+obj-$(CONFIG_KDS) += kds.o
+obj-$(CONFIG_KDS_TEST) += kds_test.o
diff --git a/driver/product/kernel/drivers/base/kds/Kconfig b/driver/product/kernel/drivers/base/kds/Kconfig
new file mode 100755
index 0000000..5f96165
--- /dev/null
+++ b/driver/product/kernel/drivers/base/kds/Kconfig
@@ -0,0 +1,20 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+config KDS
+ tristate "Kernel dependency system"
+ help
+ This option enables the generic kernel dependency system
diff --git a/driver/product/kernel/drivers/base/kds/Makefile b/driver/product/kernel/drivers/base/kds/Makefile
new file mode 100755
index 0000000..364d151
--- /dev/null
+++ b/driver/product/kernel/drivers/base/kds/Makefile
@@ -0,0 +1,37 @@
+#
+# (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+# linux build system bootstrap for out-of-tree module
+
+# default to building for the host
+ARCH ?= $(shell uname -m)
+CONFIG_KDS_TEST ?= n
+
+ifeq ($(KDIR),)
+$(error Must specify KDIR to point to the kernel to target))
+endif
+
+all: kds
+
+kds:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../include" CONFIG_KDS=m
+
+kds_test:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../include" CONFIG_KDS_TEST=m
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
diff --git a/driver/product/kernel/drivers/base/kds/kds.c b/driver/product/kernel/drivers/base/kds/kds.c
new file mode 100755
index 0000000..62612d4
--- /dev/null
+++ b/driver/product/kernel/drivers/base/kds/kds.c
@@ -0,0 +1,559 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/kds.h>
+#include <linux/kref.h>
+
+#include <asm/atomic.h>
+
+#define KDS_LINK_TRIGGERED (1u << 0)
+#define KDS_LINK_EXCLUSIVE (1u << 1)
+
+#define KDS_INVALID (void *)-2
+#define KDS_RESOURCE (void *)-1
+
+struct kds_resource_set
+{
+ unsigned long num_resources;
+ unsigned long pending;
+ struct kds_callback *cb;
+ void *callback_parameter;
+ void *callback_extra_parameter;
+ struct list_head callback_link;
+ struct work_struct callback_work;
+ atomic_t cb_queued;
+ /* This resource set will be freed when there are no pending
+ * callbacks */
+ struct kref refcount;
+
+ /* This is only initted when kds_waitall() is called. */
+ wait_queue_head_t wake;
+
+ struct kds_link resources[0];
+
+};
+
+static DEFINE_SPINLOCK(kds_lock);
+
+static void __resource_set_release(struct kref *ref)
+{
+ struct kds_resource_set *rset = container_of(ref,
+ struct kds_resource_set, refcount);
+
+ kfree(rset);
+}
+
+int kds_callback_init(struct kds_callback *cb, int direct, kds_callback_fn user_cb)
+{
+ int ret = 0;
+
+ cb->direct = direct;
+ cb->user_cb = user_cb;
+
+ if (!direct)
+ {
+ cb->wq = alloc_workqueue("kds", WQ_UNBOUND | WQ_HIGHPRI, WQ_UNBOUND_MAX_ACTIVE);
+ if (!cb->wq)
+ ret = -ENOMEM;
+ }
+ else
+ {
+ cb->wq = NULL;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(kds_callback_init);
+
+void kds_callback_term(struct kds_callback *cb)
+{
+ if (!cb->direct)
+ {
+ BUG_ON(!cb->wq);
+ destroy_workqueue(cb->wq);
+ }
+ else
+ {
+ BUG_ON(cb->wq);
+ }
+}
+
+EXPORT_SYMBOL(kds_callback_term);
+
+static void kds_do_user_callback(struct kds_resource_set *rset)
+{
+ rset->cb->user_cb(rset->callback_parameter, rset->callback_extra_parameter);
+}
+
+static void kds_queued_callback(struct work_struct *work)
+{
+ struct kds_resource_set *rset;
+ rset = container_of(work, struct kds_resource_set, callback_work);
+
+ atomic_dec(&rset->cb_queued);
+
+ kds_do_user_callback(rset);
+}
+
+static void kds_callback_perform(struct kds_resource_set *rset)
+{
+ if (rset->cb->direct)
+ kds_do_user_callback(rset);
+ else
+ {
+ int result;
+
+ atomic_inc(&rset->cb_queued);
+
+ result = queue_work(rset->cb->wq, &rset->callback_work);
+ /* if we got a 0 return it means we've triggered the same rset twice! */
+ WARN_ON(!result);
+ }
+}
+
+void kds_resource_init(struct kds_resource * const res)
+{
+ BUG_ON(!res);
+ INIT_LIST_HEAD(&res->waiters.link);
+ res->waiters.parent = KDS_RESOURCE;
+}
+EXPORT_SYMBOL(kds_resource_init);
+
+int kds_resource_term(struct kds_resource *res)
+{
+ unsigned long lflags;
+ BUG_ON(!res);
+ spin_lock_irqsave(&kds_lock, lflags);
+ if (!list_empty(&res->waiters.link))
+ {
+ spin_unlock_irqrestore(&kds_lock, lflags);
+ printk(KERN_ERR "ERROR: KDS resource is still in use\n");
+ return -EBUSY;
+ }
+ res->waiters.parent = KDS_INVALID;
+ spin_unlock_irqrestore(&kds_lock, lflags);
+ return 0;
+}
+EXPORT_SYMBOL(kds_resource_term);
+
+int kds_async_waitall(
+ struct kds_resource_set ** const pprset,
+ struct kds_callback *cb,
+ void *callback_parameter,
+ void *callback_extra_parameter,
+ int number_resources,
+ unsigned long *exclusive_access_bitmap,
+ struct kds_resource **resource_list)
+{
+ struct kds_resource_set *rset = NULL;
+ unsigned long lflags;
+ int i;
+ int triggered;
+ int err = -EFAULT;
+
+ BUG_ON(!pprset);
+ BUG_ON(!resource_list);
+ BUG_ON(!cb);
+
+ WARN_ONCE(number_resources > 10, "Waiting on a high numbers of resources may increase latency, see documentation.");
+
+ rset = kmalloc(sizeof(*rset) + number_resources * sizeof(struct kds_link), GFP_KERNEL);
+ if (!rset)
+ {
+ return -ENOMEM;
+ }
+
+ rset->num_resources = number_resources;
+ rset->pending = number_resources;
+ rset->cb = cb;
+ rset->callback_parameter = callback_parameter;
+ rset->callback_extra_parameter = callback_extra_parameter;
+ INIT_LIST_HEAD(&rset->callback_link);
+ INIT_WORK(&rset->callback_work, kds_queued_callback);
+ atomic_set(&rset->cb_queued, 0);
+ kref_init(&rset->refcount);
+
+ for (i = 0; i < number_resources; i++)
+ {
+ INIT_LIST_HEAD(&rset->resources[i].link);
+ rset->resources[i].parent = rset;
+ }
+
+ spin_lock_irqsave(&kds_lock, lflags);
+
+ for (i = 0; i < number_resources; i++)
+ {
+ unsigned long link_state = 0;
+
+ if (test_bit(i, exclusive_access_bitmap))
+ {
+ link_state |= KDS_LINK_EXCLUSIVE;
+ }
+
+ /* no-one else waiting? */
+ if (list_empty(&resource_list[i]->waiters.link))
+ {
+ link_state |= KDS_LINK_TRIGGERED;
+ rset->pending--;
+ }
+ /* Adding a non-exclusive and the current tail is a triggered non-exclusive? */
+ else if (((link_state & KDS_LINK_EXCLUSIVE) == 0) &&
+ (((list_entry(resource_list[i]->waiters.link.prev, struct kds_link, link)->state & (KDS_LINK_EXCLUSIVE | KDS_LINK_TRIGGERED)) == KDS_LINK_TRIGGERED)))
+ {
+ link_state |= KDS_LINK_TRIGGERED;
+ rset->pending--;
+ }
+ rset->resources[i].state = link_state;
+
+ /* avoid double wait (hang) */
+ if (!list_empty(&resource_list[i]->waiters.link))
+ {
+ /* adding same rset again? */
+ if (list_entry(resource_list[i]->waiters.link.prev, struct kds_link, link)->parent == rset)
+ {
+ goto roll_back;
+ }
+ }
+ list_add_tail(&rset->resources[i].link, &resource_list[i]->waiters.link);
+ }
+
+ triggered = (rset->pending == 0);
+
+ /* set the pointer before the callback is called so it sees it */
+ *pprset = rset;
+
+ spin_unlock_irqrestore(&kds_lock, lflags);
+
+ if (triggered)
+ {
+ /* all resources obtained, trigger callback */
+ kds_callback_perform(rset);
+ }
+
+ return 0;
+
+roll_back:
+ /* roll back */
+ while (i-- > 0)
+ {
+ list_del(&rset->resources[i].link);
+ }
+ err = -EINVAL;
+
+ spin_unlock_irqrestore(&kds_lock, lflags);
+ kfree(rset);
+ return err;
+}
+EXPORT_SYMBOL(kds_async_waitall);
+
+static void wake_up_sync_call(void *callback_parameter, void *callback_extra_parameter)
+{
+ wait_queue_head_t *wait = (wait_queue_head_t *)callback_parameter;
+ wake_up(wait);
+}
+
+static struct kds_callback sync_cb =
+{
+ wake_up_sync_call,
+ 1,
+ NULL,
+};
+
+struct kds_resource_set *kds_waitall(
+ int number_resources,
+ unsigned long *exclusive_access_bitmap,
+ struct kds_resource **resource_list,
+ unsigned long jiffies_timeout)
+{
+ struct kds_resource_set *rset;
+ unsigned long lflags;
+ int i;
+ int triggered = 0;
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+
+ rset = kmalloc(sizeof(*rset) + number_resources * sizeof(struct kds_link), GFP_KERNEL);
+ if (!rset)
+ return rset;
+
+ rset->num_resources = number_resources;
+ rset->pending = number_resources;
+ init_waitqueue_head(&rset->wake);
+ INIT_LIST_HEAD(&rset->callback_link);
+ INIT_WORK(&rset->callback_work, kds_queued_callback);
+ atomic_set(&rset->cb_queued, 0);
+ kref_init(&rset->refcount);
+
+ spin_lock_irqsave(&kds_lock, lflags);
+
+ for (i = 0; i < number_resources; i++)
+ {
+ unsigned long link_state = 0;
+
+ if (test_bit(i, exclusive_access_bitmap))
+ {
+ link_state |= KDS_LINK_EXCLUSIVE;
+ }
+
+ if (list_empty(&resource_list[i]->waiters.link))
+ {
+ link_state |= KDS_LINK_TRIGGERED;
+ rset->pending--;
+ }
+ /* Adding a non-exclusive and the current tail is a triggered non-exclusive? */
+ else if (((link_state & KDS_LINK_EXCLUSIVE) == 0) &&
+ (((list_entry(resource_list[i]->waiters.link.prev, struct kds_link, link)->state & (KDS_LINK_EXCLUSIVE | KDS_LINK_TRIGGERED)) == KDS_LINK_TRIGGERED)))
+ {
+ link_state |= KDS_LINK_TRIGGERED;
+ rset->pending--;
+ }
+
+ INIT_LIST_HEAD(&rset->resources[i].link);
+ rset->resources[i].parent = rset;
+ rset->resources[i].state = link_state;
+
+ /* avoid double wait (hang) */
+ if (!list_empty(&resource_list[i]->waiters.link))
+ {
+ /* adding same rset again? */
+ if (list_entry(resource_list[i]->waiters.link.prev, struct kds_link, link)->parent == rset)
+ {
+ goto roll_back;
+ }
+ }
+
+ list_add_tail(&rset->resources[i].link, &resource_list[i]->waiters.link);
+ }
+
+ if (rset->pending == 0)
+ triggered = 1;
+ else
+ {
+ rset->cb = &sync_cb;
+ rset->callback_parameter = &rset->wake;
+ rset->callback_extra_parameter = NULL;
+ }
+
+ spin_unlock_irqrestore(&kds_lock, lflags);
+
+ if (!triggered)
+ {
+ long wait_res = 0;
+ long timeout = (jiffies_timeout == KDS_WAIT_BLOCKING) ?
+ MAX_SCHEDULE_TIMEOUT : jiffies_timeout;
+
+ if (timeout)
+ {
+ wait_res = wait_event_interruptible_timeout(rset->wake,
+ rset->pending == 0, timeout);
+ }
+
+ if ((wait_res == -ERESTARTSYS) || (wait_res == 0))
+ {
+ /* use \a kds_resource_set_release to roll back */
+ kds_resource_set_release(&rset);
+ return ERR_PTR(wait_res);
+ }
+ }
+ return rset;
+
+roll_back:
+ /* roll back */
+ while (i-- > 0)
+ {
+ list_del(&rset->resources[i].link);
+ }
+
+ spin_unlock_irqrestore(&kds_lock, lflags);
+ kfree(rset);
+ return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL(kds_waitall);
+
+static void trigger_new_rset_owner(struct kds_resource_set *rset,
+ struct list_head *triggered)
+{
+ if (0 == --rset->pending) {
+ /* new owner now triggered, track for callback later */
+ kref_get(&rset->refcount);
+ list_add(&rset->callback_link, triggered);
+ }
+}
+
+static void __kds_resource_set_release_common(struct kds_resource_set *rset)
+{
+ struct list_head triggered = LIST_HEAD_INIT(triggered);
+ struct kds_resource_set *it;
+ unsigned long lflags;
+ int i;
+
+ spin_lock_irqsave(&kds_lock, lflags);
+
+ for (i = 0; i < rset->num_resources; i++)
+ {
+ struct kds_resource *resource;
+ struct kds_link *it = NULL;
+
+ /* fetch the previous entry on the linked list */
+ it = list_entry(rset->resources[i].link.prev, struct kds_link, link);
+ /* unlink ourself */
+ list_del(&rset->resources[i].link);
+
+ /* any waiters? */
+ if (list_empty(&it->link))
+ continue;
+
+ /* were we the head of the list? (head if prev is a resource) */
+ if (it->parent != KDS_RESOURCE)
+ {
+ if ((it->state & KDS_LINK_TRIGGERED) && !(it->state & KDS_LINK_EXCLUSIVE))
+ {
+ /*
+ * previous was triggered and not exclusive, so we
+ * trigger non-exclusive until end-of-list or first
+ * exclusive
+ */
+
+ struct kds_link *it_waiting = it;
+
+ list_for_each_entry(it, &it_waiting->link, link)
+ {
+ /* exclusive found, stop triggering */
+ if (it->state & KDS_LINK_EXCLUSIVE)
+ break;
+
+ it->state |= KDS_LINK_TRIGGERED;
+ /* a parent to update? */
+ if (it->parent != KDS_RESOURCE)
+ trigger_new_rset_owner(
+ it->parent,
+ &triggered);
+ }
+ }
+ continue;
+ }
+
+ /* we were the head, find the kds_resource */
+ resource = container_of(it, struct kds_resource, waiters);
+
+ /* we know there is someone waiting from the any-waiters test above */
+
+ /* find the head of the waiting list */
+ it = list_first_entry(&resource->waiters.link, struct kds_link, link);
+
+ /* new exclusive owner? */
+ if (it->state & KDS_LINK_EXCLUSIVE)
+ {
+ /* link now triggered */
+ it->state |= KDS_LINK_TRIGGERED;
+ /* a parent to update? */
+ trigger_new_rset_owner(it->parent, &triggered);
+ }
+ /* exclusive releasing ? */
+ else if (rset->resources[i].state & KDS_LINK_EXCLUSIVE)
+ {
+ /* trigger non-exclusive until end-of-list or first exclusive */
+ list_for_each_entry(it, &resource->waiters.link, link)
+ {
+ /* exclusive found, stop triggering */
+ if (it->state & KDS_LINK_EXCLUSIVE)
+ break;
+
+ it->state |= KDS_LINK_TRIGGERED;
+ /* a parent to update? */
+ trigger_new_rset_owner(it->parent, &triggered);
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&kds_lock, lflags);
+
+ while (!list_empty(&triggered))
+ {
+ it = list_first_entry(&triggered, struct kds_resource_set, callback_link);
+ list_del(&it->callback_link);
+ kds_callback_perform(it);
+
+ /* Free the resource set if no callbacks pending */
+ kref_put(&it->refcount, &__resource_set_release);
+ }
+}
+
+void kds_resource_set_release(struct kds_resource_set **pprset)
+{
+ struct kds_resource_set *rset;
+ int queued;
+
+ rset = cmpxchg(pprset, *pprset, NULL);
+
+ if (!rset)
+ {
+ /* caught a race between a cancelation
+ * and a completion, nothing to do */
+ return;
+ }
+
+ __kds_resource_set_release_common(rset);
+
+ /*
+ * Caller is responsible for guaranteeing that callback work is not
+ * pending (i.e. its running or completed) prior to calling release.
+ */
+ queued = atomic_read(&rset->cb_queued);
+ BUG_ON(queued);
+
+ kref_put(&rset->refcount, &__resource_set_release);
+}
+EXPORT_SYMBOL(kds_resource_set_release);
+
+void kds_resource_set_release_sync(struct kds_resource_set **pprset)
+{
+ struct kds_resource_set *rset;
+
+ rset = cmpxchg(pprset, *pprset, NULL);
+ if (!rset)
+ {
+ /* caught a race between a cancelation
+ * and a completion, nothing to do */
+ return;
+ }
+
+ __kds_resource_set_release_common(rset);
+
+ /*
+ * In the case of a kds async wait cancellation ensure the deferred
+ * call back does not get scheduled if a trigger fired at the same time
+ * to release the wait.
+ */
+ cancel_work_sync(&rset->callback_work);
+
+ kref_put(&rset->refcount, &__resource_set_release);
+}
+EXPORT_SYMBOL(kds_resource_set_release_sync);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("ARM Ltd.");
+MODULE_VERSION("1.0");
diff --git a/driver/product/kernel/drivers/base/kds/sconscript b/driver/product/kernel/drivers/base/kds/sconscript
new file mode 100755
index 0000000..75add37
--- /dev/null
+++ b/driver/product/kernel/drivers/base/kds/sconscript
@@ -0,0 +1,42 @@
+#
+# (C) COPYRIGHT 2010-2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+Import('env')
+
+#Android uses sync_pt to accomplish KDS functionality.
+#Midgard KDS is not used by Android
+if env['os'] == 'android':
+ Return()
+
+if Glob('tests/sconscript'):
+ SConscript('tests/sconscript')
+
+# If KDS is built into the kernel already we skip building the module ourselves
+build_kds = not env.KernelConfigEnabled("CONFIG_KDS")
+
+# Build KDS module
+if build_kds:
+ kds_mod = env.BuildKernelModule('$STATIC_LIB_PATH/kds.ko', ['kds.c'],
+ make_args = ['kds'])
+ env.KernelObjTarget('kds', kds_mod)
+
+# Build KDS test module
+if int(env['unit']) == 1:
+ kds_test_mod = env.BuildKernelModule('$STATIC_LIB_PATH/kds_test.ko',
+ ['kds_test.c'],
+ make_args = ['kds_test'])
+ env.KernelObjTarget('kds', kds_test_mod)
+ if build_kds:
+ env.Depends(kds_test_mod, kds_mod)
diff --git a/driver/product/kernel/drivers/base/sconscript b/driver/product/kernel/drivers/base/sconscript
new file mode 100755
index 0000000..84de8c4
--- /dev/null
+++ b/driver/product/kernel/drivers/base/sconscript
@@ -0,0 +1,36 @@
+#
+# (C) COPYRIGHT 2010-2014, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+Import( 'env' )
+
+if Glob('bus_logger/sconscript'):
+ if env['buslog'] == '1':
+ SConscript('bus_logger/sconscript')
+
+if Glob('mali_fpga_sysctl/sconscript'):
+ SConscript('mali_fpga_sysctl/sconscript')
+
+if Glob('dma_buf_lock/sconscript'):
+ SConscript('dma_buf_lock/sconscript')
+
+if Glob('kds/sconscript'):
+ SConscript('kds/sconscript')
+
+if Glob('ump/sconscript'):
+ SConscript('ump/sconscript')
+
+if Glob('dma_buf_test_exporter/sconscript'):
+ SConscript('dma_buf_test_exporter/sconscript')
+
diff --git a/driver/product/kernel/drivers/base/ump/Kbuild b/driver/product/kernel/drivers/base/ump/Kbuild
new file mode 100755
index 0000000..2bbdba2
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/Kbuild
@@ -0,0 +1,18 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+obj-y += src/
+
diff --git a/driver/product/kernel/drivers/base/ump/Kconfig b/driver/product/kernel/drivers/base/ump/Kconfig
new file mode 100755
index 0000000..f7451e6
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/Kconfig
@@ -0,0 +1,26 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+config UMP
+ tristate "Enable Unified Memory Provider (UMP) support"
+ default n
+ help
+ Enable this option to build support for the ARM UMP module.
+ UMP can be used by the Mali T6xx module to improve performance
+ by reducing the copying of data by sharing memory.
+
+ To compile this driver as a module, choose M here:
+ this will generate one module, called ump.
diff --git a/driver/product/kernel/drivers/base/ump/docs/Doxyfile b/driver/product/kernel/drivers/base/ump/docs/Doxyfile
new file mode 100755
index 0000000..fbec8eb
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/docs/Doxyfile
@@ -0,0 +1,125 @@
+#
+# (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+##############################################################################
+
+# This file contains per-module Doxygen configuration. Please do not add
+# extra settings to this file without consulting all stakeholders, as they
+# may cause override project-wide settings.
+#
+# Additionally, when defining aliases, macros, sections etc, use the module
+# name as a prefix e.g. gles_my_alias.
+
+##############################################################################
+
+@INCLUDE = ../../bldsys/Doxyfile_common
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT += ../../kernel/include/linux/ump-common.h ../../kernel/include/linux/ump.h
+
+##############################################################################
+# Everything below here is optional, and in most cases not required
+##############################################################################
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES +=
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS +=
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS +=
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE +=
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS +=
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS +=
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH += ../../kernel/drivers/base/ump
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH +=
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH +=
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED +=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED +=
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS +=
diff --git a/driver/product/kernel/drivers/base/ump/docs/sconscript b/driver/product/kernel/drivers/base/ump/docs/sconscript
new file mode 100755
index 0000000..521278d
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/docs/sconscript
@@ -0,0 +1,31 @@
+#
+# (C) COPYRIGHT 2010-2011, 2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+Import('env')
+
+doxygen_sources = [
+ 'Doxyfile',
+ Glob('*.png'),
+ Glob('../*.h'),
+ Glob('../src/*.h') ]
+
+if env['doc'] == '1':
+ doxygen_target = env.Command('doxygen/html/index.html', doxygen_sources,
+ ['cd ${SOURCE.dir} && doxygen'])
+ env.Clean(doxygen_target, './doxygen')
+
+ Alias('doxygen', doxygen_target)
+
diff --git a/driver/product/kernel/drivers/base/ump/example_kernel_api.c b/driver/product/kernel/drivers/base/ump/example_kernel_api.c
new file mode 100755
index 0000000..858dd8b
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/example_kernel_api.c
@@ -0,0 +1,73 @@
+/*
+ *
+ * (C) COPYRIGHT 2010-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+#include <linux/ump.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Example routine to display information about an UMP allocation
+ * The routine takes an secure_id which can come from a different kernel module
+ * or from a client application (i.e. an ioctl).
+ * It creates a ump handle from the secure id (which validates the secure id)
+ * and if successful dumps the physical memory information.
+ * It follows the API and pins the memory while "using" the physical memory.
+ * Finally it calls the release function to indicate it's finished with the handle.
+ *
+ * If the function can't look up the handle it fails with return value -1.
+ * If the testy succeeds then it return 0.
+ * */
+
+static int display_ump_memory_information(ump_secure_id secure_id)
+{
+ const ump_dd_physical_block_64 * ump_blocks = NULL;
+ ump_dd_handle ump_mem;
+ uint64_t nr_blocks;
+ int i;
+ ump_alloc_flags flags;
+
+ /* get a handle from the secure id */
+ ump_mem = ump_dd_from_secure_id(secure_id);
+
+ if (UMP_DD_INVALID_MEMORY_HANDLE == ump_mem)
+ {
+ /* invalid ID received */
+ return -1;
+ }
+
+ /* at this point we know we've added a reference to the ump allocation, so we must release it with ump_dd_release */
+
+ ump_dd_phys_blocks_get_64(ump_mem, &nr_blocks, &ump_blocks);
+ flags = ump_dd_allocation_flags_get(ump_mem);
+
+ printf("UMP allocation with secure ID %u consists of %zd physical block(s):\n", secure_id, nr_blocks);
+
+ for(i=0; i<nr_blocks; ++i)
+ {
+ printf("\tBlock %d: 0x%08zX size 0x%08zX\n", i, ump_blocks[i].addr, ump_blocks[i].size);
+ }
+
+ printf("and was allocated using the following bitflag combo: 0x%lX\n", flags);
+
+ ump_dd_release(ump_mem);
+
+ return 0;
+}
+
diff --git a/driver/product/kernel/drivers/base/ump/example_user_api.c b/driver/product/kernel/drivers/base/ump/example_user_api.c
new file mode 100755
index 0000000..d143a64
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/example_user_api.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * (C) COPYRIGHT 2010-2011, 2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 <ump/ump.h>
+#include <memory.h>
+#include <stdio.h>
+
+/*
+ * Example routine to exercise the user space UMP api.
+ * This routine initializes the UMP api and allocates some CPU+device X memory.
+ * No usage hints are given, so the driver will use the default cacheability policy.
+ * With the allocation it creates a duplicate handle and plays with the reference count.
+ * Then it simulates interacting with a device and contains pseudo code for the device.
+ *
+ * If any error is detected correct cleanup will be performed and -1 will be returned.
+ * If successful then 0 will be returned.
+ */
+
+static int test_ump_user_api(void)
+{
+ /* This is the size we try to allocate*/
+ const size_t alloc_size = 4096;
+
+ ump_handle h = UMP_INVALID_MEMORY_HANDLE;
+ ump_handle h_copy = UMP_INVALID_MEMORY_HANDLE;
+ ump_handle h_clone = UMP_INVALID_MEMORY_HANDLE;
+
+ void * mapping = NULL;
+
+ ump_result ump_api_res;
+ int result = -1;
+
+ ump_secure_id id;
+
+ size_t size_returned;
+
+ ump_api_res = ump_open();
+ if (UMP_OK != ump_api_res)
+ {
+ /* failed to open an ump session */
+ /* early out */
+ return -1;
+ }
+
+ h = ump_allocate_64(alloc_size, UMP_PROT_CPU_RD | UMP_PROT_CPU_WR | UMP_PROT_X_RD | UMP_PROT_X_WR);
+ /* the refcount is now 1 */
+ if (UMP_INVALID_MEMORY_HANDLE == h)
+ {
+ /* allocation failure */
+ goto cleanup;
+ }
+
+ /* this is how we could share this allocation with another process */
+
+ /* in process A: */
+ id = ump_secure_id_get(h);
+ /* still ref count 1 */
+ /* send the id to process B */
+
+ /* in process B: */
+ /* receive the id from A */
+ h_clone = ump_from_secure_id(id);
+ /* the ref count of the allocation is now 2 (one from each handle to it) */
+ /* do something ... */
+ /* release our clone */
+ ump_release(h_clone); /* safe to call even if ump_from_secure_id failed */
+ h_clone = UMP_INVALID_MEMORY_HANDLE;
+
+
+ /* a simple save-for-future-use logic inside the driver would just copy the handle (but add a ref manually too!) */
+ /*
+ * void assign_memory_to_job(h)
+ * {
+ */
+ h_copy = h;
+ ump_retain(h_copy); /* manual retain needed as we just assigned the handle, now 2 */
+ /*
+ * }
+ *
+ * void job_completed(void)
+ * {
+ */
+ ump_release(h_copy); /* normal handle release as if we got via an ump_allocate */
+ h_copy = UMP_INVALID_MEMORY_HANDLE;
+ /*
+ * }
+ */
+
+ /* we're now back at ref count 1, and only h is a valid handle */
+ /* enough handle duplication show-off, let's play with the contents instead */
+
+ mapping = ump_map(h, 0, alloc_size);
+ if (NULL == mapping)
+ {
+ /* mapping failure, either out of address space or some other error */
+ goto cleanup;
+ }
+
+ memset(mapping, 0, alloc_size);
+
+ /* let's pretend we're going to start some hw device on this buffer and read the result afterwards */
+ ump_cpu_msync_now(h, UMP_MSYNC_CLEAN, mapping, alloc_size);
+ /*
+ device cache invalidate
+
+ memory barrier
+
+ start device
+
+ memory barrier
+
+ wait for device
+
+ memory barrier
+
+ device cache clean
+
+ memory barrier
+ */
+ ump_cpu_msync_now(h, UMP_MSYNC_CLEAN_AND_INVALIDATE, mapping, alloc_size);
+
+ /* we could now peek at the result produced by the hw device, which is now accessible via our mapping */
+
+ /* unmap the buffer when we're done with it */
+ ump_unmap(h, mapping, alloc_size);
+
+ result = 0;
+
+cleanup:
+ ump_release(h);
+ h = UMP_INVALID_MEMORY_HANDLE;
+
+ ump_close();
+
+ return result;
+}
+
diff --git a/driver/product/kernel/drivers/base/ump/sconscript b/driver/product/kernel/drivers/base/ump/sconscript
new file mode 100755
index 0000000..b4aa8b6
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/sconscript
@@ -0,0 +1,21 @@
+#
+# (C) COPYRIGHT 2010-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+Import('env')
+
+if Glob('src/sconscript') and int(env['ump']) == 1:
+ SConscript( 'src/sconscript' )
+ SConscript( 'docs/sconscript' )
+
diff --git a/driver/product/kernel/drivers/base/ump/src/Kbuild b/driver/product/kernel/drivers/base/ump/src/Kbuild
new file mode 100755
index 0000000..de6d307
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/Kbuild
@@ -0,0 +1,50 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+# Paths required for build
+UMP_PATH = $(src)/../..
+UMP_DEVICEDRV_PATH = $(src)/.
+
+# Set up defaults if not defined by the user
+MALI_UNIT_TEST ?= 0
+
+SRC :=\
+ common/ump_kernel_core.c \
+ common/ump_kernel_descriptor_mapping.c \
+ linux/ump_kernel_linux.c \
+ linux/ump_kernel_linux_mem.c
+
+UNIT_TEST_DEFINES=
+ifeq ($(MALI_UNIT_TEST), 1)
+ MALI_DEBUG ?= 1
+
+ UNIT_TEST_DEFINES = -DMALI_UNIT_TEST=1 \
+ -DMALI_DEBUG=$(MALI_DEBUG)
+endif
+
+# Use our defines when compiling
+ccflags-y += -I$(UMP_PATH) -I$(UMP_DEVICEDRV_PATH) $(UNIT_TEST_DEFINES)
+
+
+# Tell the Linux build system from which .o file to create the kernel module
+obj-$(CONFIG_UMP) += ump.o
+ifeq ($(CONFIG_ION),y)
+ccflags-y += -I$(srctree)/drivers/staging/android/ion -I$(srctree)/include/linux
+obj-$(CONFIG_UMP) += imports/ion/ump_kernel_import_ion.o
+endif
+
+# Tell the Linux build system to enable building of our .c files
+ump-y := $(SRC:.c=.o)
diff --git a/driver/product/kernel/drivers/base/ump/src/Makefile b/driver/product/kernel/drivers/base/ump/src/Makefile
new file mode 100755
index 0000000..45428ad
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/Makefile
@@ -0,0 +1,81 @@
+#
+# (C) COPYRIGHT 2008-2014 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+ifneq ($(KBUILD_EXTMOD),)
+include $(KBUILD_EXTMOD)/Makefile.common
+else
+include ./Makefile.common
+endif
+
+# default to building for the host
+ARCH ?= $(shell uname -m)
+
+# linux build system integration
+RELATIVE_ROOT=../../../../..
+ROOT = $(CURDIR)/$(RELATIVE_ROOT)
+
+EXTRA_CFLAGS=-I$(CURDIR)/../../../../include
+
+ifeq ($(MALI_UNIT_TEST),1)
+ EXTRA_CFLAGS += -DMALI_UNIT_TEST=$(MALI_UNIT_TEST)
+endif
+
+# Get any user defined KDIR-<names> or maybe even a hardcoded KDIR
+-include KDIR_CONFIGURATION
+
+# Define host system directory
+KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
+
+CONFIG ?= $(ARCH)
+
+# default cpu to select
+CPU ?= $(shell uname -m)
+
+# 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
+
+EXTRA_SYMBOLS=
+
+ifeq ($(MALI_UNIT_TEST),1)
+ KBASE_PATH=$(ROOT)/kernel/drivers/gpu/arm/midgard
+ EXTRA_SYMBOLS+=$(KBASE_PATH)/tests/internal/src/kernel_assert_module/linux/Module.symvers
+endif
+KDS_PATH=$(ROOT)/kernel/drivers/base/kds
+EXTRA_SYMBOLS+=$(KDS_PATH)/Module.symvers
+
+all:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="$(EXTRA_CFLAGS) $(SCONS_CFLAGS)" CONFIG_UMP=m KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
+
+kernelrelease:
+ $(MAKE) -C $(KDIR) KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" kernelrelease
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
diff --git a/driver/product/kernel/drivers/base/ump/src/Makefile.common b/driver/product/kernel/drivers/base/ump/src/Makefile.common
new file mode 100755
index 0000000..f29a4c1
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/Makefile.common
@@ -0,0 +1,19 @@
+#
+# (C) COPYRIGHT 2008-2010, 2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+SRC = $(UMP_FILE_PREFIX)/common/ump_kernel_core.c \
+ $(UMP_FILE_PREFIX)/common/ump_kernel_descriptor_mapping.c
+
diff --git a/driver/product/kernel/drivers/base/ump/src/arch-arm/config.h b/driver/product/kernel/drivers/base/ump/src/arch-arm/config.h
new file mode 100755
index 0000000..152d98f
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/arch-arm/config.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2009, 2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 1
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x00000000
+#define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/driver/product/kernel/drivers/base/ump/src/arch-arm64/config.h b/driver/product/kernel/drivers/base/ump/src/arch-arm64/config.h
new file mode 100755
index 0000000..cfb14ca
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/arch-arm64/config.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2009, 2013-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 1
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x00000000
+#define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.c b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.c
new file mode 100755
index 0000000..07aa077
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.c
@@ -0,0 +1,756 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+/* module headers */
+#include <linux/ump.h>
+#include <linux/ump-ioctl.h>
+
+/* local headers */
+#include <common/ump_kernel_core.h>
+#include <common/ump_kernel_descriptor_mapping.h>
+#include <ump_arch.h>
+#include <common/ump_kernel_priv.h>
+
+#define UMP_FLAGS_RANGE ((UMP_PROT_SHAREABLE<<1) - 1u)
+
+static umpp_device device;
+
+ump_result umpp_core_constructor(void)
+{
+ mutex_init(&device.secure_id_map_lock);
+ device.secure_id_map = umpp_descriptor_mapping_create(UMP_EXPECTED_IDS, UMP_MAX_IDS);
+ if (NULL != device.secure_id_map)
+ {
+ if (UMP_OK == umpp_device_initialize())
+ {
+ return UMP_OK;
+ }
+ umpp_descriptor_mapping_destroy(device.secure_id_map);
+ }
+ mutex_destroy(&device.secure_id_map_lock);
+
+ return UMP_ERROR;
+}
+
+void umpp_core_destructor(void)
+{
+ umpp_device_terminate();
+ umpp_descriptor_mapping_destroy(device.secure_id_map);
+ mutex_destroy(&device.secure_id_map_lock);
+}
+
+umpp_session *umpp_core_session_start(void)
+{
+ umpp_session * session;
+
+ session = kzalloc(sizeof(*session), GFP_KERNEL);
+ if (NULL != session)
+ {
+ mutex_init(&session->session_lock);
+
+ INIT_LIST_HEAD(&session->memory_usage);
+
+ /* try to create import client session, not a failure if they fail to initialize */
+ umpp_import_handlers_init(session);
+ }
+
+ return session;
+}
+
+void umpp_core_session_end(umpp_session *session)
+{
+ umpp_session_memory_usage * usage, *_usage;
+ UMP_ASSERT(session);
+
+ list_for_each_entry_safe(usage, _usage, &session->memory_usage, link)
+ {
+ printk(KERN_WARNING "UMP: Memory usage cleanup, releasing secure ID %d\n", ump_dd_secure_id_get(usage->mem));
+ ump_dd_release(usage->mem);
+ kfree(usage);
+
+ }
+
+ /* we should now not hold any imported memory objects,
+ * detatch all import handlers */
+ umpp_import_handlers_term(session);
+
+ mutex_destroy(&session->session_lock);
+ kfree(session);
+}
+
+ump_dd_handle ump_dd_allocate_64(uint64_t size, ump_alloc_flags flags, ump_dd_security_filter filter_func, ump_dd_final_release_callback final_release_func, void* callback_data)
+{
+ umpp_allocation * alloc;
+ int i;
+
+ UMP_ASSERT(size);
+
+ if (flags & (~UMP_FLAGS_RANGE))
+ {
+ printk(KERN_WARNING "UMP: allocation flags out of allowed bits range\n");
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+
+ if( ( flags & (UMP_PROT_CPU_RD | UMP_PROT_W_RD | UMP_PROT_X_RD | UMP_PROT_Y_RD | UMP_PROT_Z_RD ) ) == 0 ||
+ ( flags & (UMP_PROT_CPU_WR | UMP_PROT_W_WR | UMP_PROT_X_WR | UMP_PROT_Y_WR | UMP_PROT_Z_WR )) == 0 )
+ {
+ printk(KERN_WARNING "UMP: allocation flags should have at least one read and one write permission bit set\n");
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+
+ /*check permission flags to be set if hit flags are set too*/
+ for (i = UMP_DEVICE_CPU_SHIFT; i<=UMP_DEVICE_Z_SHIFT; i+=4)
+ {
+ if (flags & (UMP_HINT_DEVICE_RD<<i))
+ {
+ UMP_ASSERT(flags & (UMP_PROT_DEVICE_RD<<i));
+ }
+ if (flags & (UMP_HINT_DEVICE_WR<<i))
+ {
+ UMP_ASSERT(flags & (UMP_PROT_DEVICE_WR<<i));
+ }
+ }
+
+ alloc = kzalloc(sizeof(*alloc), GFP_KERNEL | __GFP_HARDWALL);
+
+ if (NULL == alloc)
+ goto out1;
+
+ alloc->flags = flags;
+ alloc->filter_func = filter_func;
+ alloc->final_release_func = final_release_func;
+ alloc->callback_data = callback_data;
+ alloc->size = size;
+
+ mutex_init(&alloc->map_list_lock);
+ INIT_LIST_HEAD(&alloc->map_list);
+ atomic_set(&alloc->refcount, 1);
+
+#ifdef CONFIG_KDS
+ kds_resource_init(&alloc->kds_res);
+#endif
+
+ if (!(alloc->flags & UMP_PROT_SHAREABLE))
+ {
+ alloc->owner = get_current()->pid;
+ }
+
+ if (0 != umpp_phys_commit(alloc))
+ {
+ goto out2;
+ }
+
+ /* all set up, allocate an ID for it */
+
+ mutex_lock(&device.secure_id_map_lock);
+ alloc->id = umpp_descriptor_mapping_allocate(device.secure_id_map, (void*)alloc);
+ mutex_unlock(&device.secure_id_map_lock);
+
+ if ((int)alloc->id == 0)
+ {
+ /* failed to allocate a secure_id */
+ goto out3;
+ }
+
+ return alloc;
+
+out3:
+ umpp_phys_free(alloc);
+out2:
+ kfree(alloc);
+out1:
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+}
+
+uint64_t ump_dd_size_get_64(const ump_dd_handle mem)
+{
+ umpp_allocation * alloc;
+
+ UMP_ASSERT(mem);
+
+ alloc = (umpp_allocation*)mem;
+
+ return alloc->size;
+}
+
+/*
+ * UMP v1 API
+ */
+unsigned long ump_dd_size_get(ump_dd_handle mem)
+{
+ umpp_allocation * alloc;
+
+ UMP_ASSERT(mem);
+
+ alloc = (umpp_allocation*)mem;
+
+ UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);
+ UMP_ASSERT(alloc->size <= UMP_UINT32_MAX);
+
+ return (unsigned long)alloc->size;
+}
+
+ump_secure_id ump_dd_secure_id_get(const ump_dd_handle mem)
+{
+ umpp_allocation * alloc;
+
+ UMP_ASSERT(mem);
+
+ alloc = (umpp_allocation*)mem;
+
+ return alloc->id;
+}
+
+#ifdef CONFIG_KDS
+struct kds_resource * ump_dd_kds_resource_get(const ump_dd_handle mem)
+{
+ umpp_allocation * alloc;
+
+ UMP_ASSERT(mem);
+
+ alloc = (umpp_allocation*)mem;
+
+ return &alloc->kds_res;
+}
+#endif
+
+ump_alloc_flags ump_dd_allocation_flags_get(const ump_dd_handle mem)
+{
+ const umpp_allocation * alloc;
+
+ UMP_ASSERT(mem);
+ alloc = (const umpp_allocation *)mem;
+
+ return alloc->flags;
+}
+
+ump_dd_handle ump_dd_from_secure_id(ump_secure_id secure_id)
+{
+ umpp_allocation * alloc = UMP_DD_INVALID_MEMORY_HANDLE;
+
+ mutex_lock(&device.secure_id_map_lock);
+
+ if (0 == umpp_descriptor_mapping_lookup(device.secure_id_map, secure_id, (void**)&alloc))
+ {
+ if (NULL != alloc->filter_func)
+ {
+ if (!alloc->filter_func(secure_id, alloc, alloc->callback_data))
+ {
+ alloc = UMP_DD_INVALID_MEMORY_HANDLE; /* the filter denied access */
+ }
+ }
+
+ /* check permission to access it */
+ if ((UMP_DD_INVALID_MEMORY_HANDLE != alloc) && !(alloc->flags & UMP_PROT_SHAREABLE))
+ {
+ if (alloc->owner != get_current()->pid)
+ {
+ alloc = UMP_DD_INVALID_MEMORY_HANDLE; /*no rights for the current process*/
+ }
+ }
+
+ if (UMP_DD_INVALID_MEMORY_HANDLE != alloc)
+ {
+ if( ump_dd_retain(alloc) != UMP_DD_SUCCESS)
+ {
+ alloc = UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+ }
+ }
+ mutex_unlock(&device.secure_id_map_lock);
+
+ return alloc;
+}
+
+/*
+ * UMP v1 API
+ */
+ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id)
+{
+ return ump_dd_from_secure_id(secure_id);
+}
+
+int ump_dd_retain(ump_dd_handle mem)
+{
+ umpp_allocation * alloc;
+
+ UMP_ASSERT(mem);
+
+ alloc = (umpp_allocation*)mem;
+
+ /* check for overflow */
+ while(1)
+ {
+ int refcnt = atomic_read(&alloc->refcount);
+ if (refcnt + 1 > 0)
+ {
+ if(atomic_cmpxchg(&alloc->refcount, refcnt, refcnt + 1) == refcnt)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return -EBUSY;
+ }
+ }
+}
+
+/*
+ * UMP v1 API
+ */
+void ump_dd_reference_add(ump_dd_handle mem)
+{
+ ump_dd_retain(mem);
+}
+
+
+void ump_dd_release(ump_dd_handle mem)
+{
+ umpp_allocation * alloc;
+ uint32_t new_cnt;
+
+ UMP_ASSERT(mem);
+
+ alloc = (umpp_allocation*)mem;
+
+ /* secure the id for lookup while releasing */
+ mutex_lock(&device.secure_id_map_lock);
+
+ /* do the actual release */
+ new_cnt = atomic_sub_return(1, &alloc->refcount);
+ if (0 == new_cnt)
+ {
+ /* remove from the table as this was the last ref */
+ umpp_descriptor_mapping_remove(device.secure_id_map, alloc->id);
+ }
+
+ /* release the lock as early as possible */
+ mutex_unlock(&device.secure_id_map_lock);
+
+ if (0 != new_cnt)
+ {
+ /* exit if still have refs */
+ return;
+ }
+
+ UMP_ASSERT(list_empty(&alloc->map_list));
+
+#ifdef CONFIG_KDS
+ if (kds_resource_term(&alloc->kds_res))
+ {
+ printk(KERN_ERR "ump_dd_release: kds_resource_term failed,"
+ "unable to release UMP allocation\n");
+ return;
+ }
+#endif
+ /* cleanup */
+ if (NULL != alloc->final_release_func)
+ {
+ alloc->final_release_func(alloc, alloc->callback_data);
+ }
+
+ if (0 == (alloc->management_flags & UMP_MGMT_EXTERNAL))
+ {
+ umpp_phys_free(alloc);
+ }
+ else
+ {
+ kfree(alloc->block_array);
+ }
+
+ mutex_destroy(&alloc->map_list_lock);
+
+ kfree(alloc);
+}
+
+/*
+ * UMP v1 API
+ */
+void ump_dd_reference_release(ump_dd_handle mem)
+{
+ ump_dd_release(mem);
+}
+
+void ump_dd_phys_blocks_get_64(const ump_dd_handle mem, uint64_t * const pCount, const ump_dd_physical_block_64 ** const pArray)
+{
+ const umpp_allocation * alloc;
+ UMP_ASSERT(pCount);
+ UMP_ASSERT(pArray);
+ UMP_ASSERT(mem);
+ alloc = (const umpp_allocation *)mem;
+ *pCount = alloc->blocksCount;
+ *pArray = alloc->block_array;
+}
+
+/*
+ * UMP v1 API
+ */
+ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * const blocks, unsigned long num_blocks)
+{
+ const umpp_allocation * alloc;
+ unsigned long i;
+ UMP_ASSERT(mem);
+ UMP_ASSERT(blocks);
+ UMP_ASSERT(num_blocks);
+
+ alloc = (const umpp_allocation *)mem;
+
+ UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);
+
+ if((uint64_t)num_blocks != alloc->blocksCount)
+ {
+ return UMP_DD_INVALID;
+ }
+
+ for( i = 0; i < num_blocks; i++)
+ {
+ UMP_ASSERT(alloc->block_array[i].addr <= UMP_UINT32_MAX);
+ UMP_ASSERT(alloc->block_array[i].size <= UMP_UINT32_MAX);
+
+ blocks[i].addr = (unsigned long)alloc->block_array[i].addr;
+ blocks[i].size = (unsigned long)alloc->block_array[i].size;
+ }
+
+ return UMP_DD_SUCCESS;
+}
+/*
+ * UMP v1 API
+ */
+ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * const block)
+{
+ const umpp_allocation * alloc;
+ UMP_ASSERT(mem);
+ UMP_ASSERT(block);
+ alloc = (const umpp_allocation *)mem;
+
+ UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);
+
+ UMP_ASSERT(alloc->block_array[index].addr <= UMP_UINT32_MAX);
+ UMP_ASSERT(alloc->block_array[index].size <= UMP_UINT32_MAX);
+
+ block->addr = (unsigned long)alloc->block_array[index].addr;
+ block->size = (unsigned long)alloc->block_array[index].size;
+
+ return UMP_DD_SUCCESS;
+}
+
+/*
+ * UMP v1 API
+ */
+unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem)
+{
+ const umpp_allocation * alloc;
+ UMP_ASSERT(mem);
+ alloc = (const umpp_allocation *)mem;
+
+ UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);
+ UMP_ASSERT(alloc->blocksCount <= UMP_UINT32_MAX);
+
+ return (unsigned long)alloc->blocksCount;
+}
+
+umpp_cpu_mapping * umpp_dd_find_enclosing_mapping(umpp_allocation * alloc, void *uaddr, size_t size)
+{
+ umpp_cpu_mapping *map;
+
+ void *target_first = uaddr;
+ void *target_last = (void*)((uintptr_t)uaddr - 1 + size);
+
+ if (target_last < target_first) /* wrapped */
+ {
+ return NULL;
+ }
+
+ mutex_lock(&alloc->map_list_lock);
+ list_for_each_entry(map, &alloc->map_list, link)
+ {
+ if ( map->vaddr_start <= target_first &&
+ (void*)((uintptr_t)map->vaddr_start + (map->nr_pages << PAGE_SHIFT) - 1) >= target_last)
+ {
+ goto out;
+ }
+ }
+ map = NULL;
+out:
+ mutex_unlock(&alloc->map_list_lock);
+
+ return map;
+}
+
+void umpp_dd_add_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * map)
+{
+ UMP_ASSERT(alloc);
+ UMP_ASSERT(map);
+ mutex_lock(&alloc->map_list_lock);
+ list_add(&map->link, &alloc->map_list);
+ mutex_unlock(&alloc->map_list_lock);
+}
+
+void umpp_dd_remove_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * target)
+{
+ umpp_cpu_mapping * map;
+
+ UMP_ASSERT(alloc);
+ UMP_ASSERT(target);
+
+ mutex_lock(&alloc->map_list_lock);
+ list_for_each_entry(map, &alloc->map_list, link)
+ {
+ if (map == target)
+ {
+ list_del(&target->link);
+ kfree(target);
+ mutex_unlock(&alloc->map_list_lock);
+ return;
+ }
+ }
+
+ /* not found, error */
+ UMP_ASSERT(0);
+}
+
+int umpp_dd_find_start_block(const umpp_allocation * alloc, uint64_t offset, uint64_t * const block_index, uint64_t * const block_internal_offset)
+{
+ uint64_t i;
+
+ for (i = 0 ; i < alloc->blocksCount; i++)
+ {
+ if (offset < alloc->block_array[i].size)
+ {
+ /* found the block_array element containing this offset */
+ *block_index = i;
+ *block_internal_offset = offset;
+ return 0;
+ }
+ offset -= alloc->block_array[i].size;
+ }
+
+ return -ENXIO;
+}
+
+void umpp_dd_cpu_msync_now(ump_dd_handle mem, ump_cpu_msync_op op, void * address, size_t size)
+{
+ umpp_allocation * alloc;
+ void *vaddr;
+ umpp_cpu_mapping * mapping;
+ uint64_t virt_page_off; /* offset of given address from beginning of the virtual mapping */
+ uint64_t phys_page_off; /* offset of the virtual mapping from the beginning of the physical buffer */
+ uint64_t page_count; /* number of pages to sync */
+ uint64_t i;
+ uint64_t block_idx;
+ uint64_t block_offset;
+ uint64_t paddr;
+
+ UMP_ASSERT((UMP_MSYNC_CLEAN == op) || (UMP_MSYNC_CLEAN_AND_INVALIDATE == op));
+
+ alloc = (umpp_allocation*)mem;
+ vaddr = (void*)(uintptr_t)address;
+
+ if((alloc->flags & UMP_CONSTRAINT_UNCACHED) != 0)
+ {
+ /* mapping is not cached */
+ return;
+ }
+
+ mapping = umpp_dd_find_enclosing_mapping(alloc, vaddr, size);
+ if (NULL == mapping)
+ {
+ printk(KERN_WARNING "UMP: Illegal cache sync address %lx\n", (uintptr_t)vaddr);
+ return; /* invalid pointer or size causes out-of-bounds */
+ }
+
+ /* we already know that address + size don't wrap around as umpp_dd_find_enclosing_mapping didn't fail */
+ page_count = ((((((uintptr_t)address + size - 1) & PAGE_MASK) - ((uintptr_t)address & PAGE_MASK))) >> PAGE_SHIFT) + 1;
+ virt_page_off = (vaddr - mapping->vaddr_start) >> PAGE_SHIFT;
+ phys_page_off = mapping->page_off;
+
+ if (umpp_dd_find_start_block(alloc, (virt_page_off + phys_page_off) << PAGE_SHIFT, &block_idx, &block_offset))
+ {
+ /* should not fail as a valid mapping was found, so the phys mem must exists */
+ printk(KERN_WARNING "UMP: Unable to find physical start block with offset %llx\n", virt_page_off + phys_page_off);
+ UMP_ASSERT(0);
+ return;
+ }
+
+ paddr = alloc->block_array[block_idx].addr + block_offset + (((uintptr_t)vaddr) & ((1u << PAGE_SHIFT)-1));
+
+ for (i = 0; i < page_count; i++)
+ {
+ size_t offset = ((uintptr_t)vaddr) & ((1u << PAGE_SHIFT)-1);
+ size_t sz = min((size_t)PAGE_SIZE - offset, size);
+
+ /* check if we've overrrun the current block, if so move to the next block */
+ if (paddr >= (alloc->block_array[block_idx].addr + alloc->block_array[block_idx].size))
+ {
+ block_idx++;
+ UMP_ASSERT(block_idx < alloc->blocksCount);
+ paddr = alloc->block_array[block_idx].addr;
+ }
+
+ if (UMP_MSYNC_CLEAN == op)
+ {
+ ump_sync_to_memory(paddr, vaddr, sz);
+ }
+ else /* (UMP_MSYNC_CLEAN_AND_INVALIDATE == op) already validated on entry */
+ {
+ ump_sync_to_cpu(paddr, vaddr, sz);
+ }
+
+ /* advance to next page */
+ vaddr = (void*)((uintptr_t)vaddr + sz);
+ size -= sz;
+ paddr += sz;
+ }
+}
+
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_create_from_phys_blocks_64(const ump_dd_physical_block_64 * blocks, uint64_t num_blocks, ump_alloc_flags flags, ump_dd_security_filter filter_func, ump_dd_final_release_callback final_release_func, void* callback_data)
+{
+ uint64_t size = 0;
+ uint64_t i;
+ umpp_allocation * alloc;
+
+ UMP_ASSERT(blocks);
+ UMP_ASSERT(num_blocks);
+
+ for (i = 0; i < num_blocks; i++)
+ {
+ size += blocks[i].size;
+ }
+ UMP_ASSERT(size);
+
+ if (flags & (~UMP_FLAGS_RANGE))
+ {
+ printk(KERN_WARNING "UMP: allocation flags out of allowed bits range\n");
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+
+ if( ( flags & (UMP_PROT_CPU_RD | UMP_PROT_W_RD | UMP_PROT_X_RD | UMP_PROT_Y_RD | UMP_PROT_Z_RD
+ | UMP_PROT_CPU_WR | UMP_PROT_W_WR | UMP_PROT_X_WR | UMP_PROT_Y_WR | UMP_PROT_Z_WR )) == 0 )
+ {
+ printk(KERN_WARNING "UMP: allocation flags should have at least one read or write permission bit set\n");
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+
+ /*check permission flags to be set if hit flags are set too*/
+ for (i = UMP_DEVICE_CPU_SHIFT; i<=UMP_DEVICE_Z_SHIFT; i+=4)
+ {
+ if (flags & (UMP_HINT_DEVICE_RD<<i))
+ {
+ UMP_ASSERT(flags & (UMP_PROT_DEVICE_RD<<i));
+ }
+ if (flags & (UMP_HINT_DEVICE_WR<<i))
+ {
+ UMP_ASSERT(flags & (UMP_PROT_DEVICE_WR<<i));
+ }
+ }
+
+ alloc = kzalloc(sizeof(*alloc),__GFP_HARDWALL | GFP_KERNEL);
+
+ if (NULL == alloc)
+ {
+ goto out1;
+ }
+
+ alloc->block_array = kzalloc(sizeof(ump_dd_physical_block_64) * num_blocks,__GFP_HARDWALL | GFP_KERNEL);
+ if (NULL == alloc->block_array)
+ {
+ goto out2;
+ }
+
+ memcpy(alloc->block_array, blocks, sizeof(ump_dd_physical_block_64) * num_blocks);
+
+#ifdef CONFIG_KDS
+ kds_resource_init(&alloc->kds_res);
+#endif
+ alloc->size = size;
+ alloc->blocksCount = num_blocks;
+ alloc->flags = flags;
+ alloc->filter_func = filter_func;
+ alloc->final_release_func = final_release_func;
+ alloc->callback_data = callback_data;
+
+ if (!(alloc->flags & UMP_PROT_SHAREABLE))
+ {
+ alloc->owner = get_current()->pid;
+ }
+
+ mutex_init(&alloc->map_list_lock);
+ INIT_LIST_HEAD(&alloc->map_list);
+ atomic_set(&alloc->refcount, 1);
+
+ /* all set up, allocate an ID */
+
+ mutex_lock(&device.secure_id_map_lock);
+ alloc->id = umpp_descriptor_mapping_allocate(device.secure_id_map, (void*)alloc);
+ mutex_unlock(&device.secure_id_map_lock);
+
+ if ((int)alloc->id == 0)
+ {
+ /* failed to allocate a secure_id */
+ goto out3;
+ }
+
+ alloc->management_flags |= UMP_MGMT_EXTERNAL;
+
+ return alloc;
+
+out3:
+ kfree(alloc->block_array);
+out2:
+ kfree(alloc);
+out1:
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+}
+
+
+/*
+ * UMP v1 API
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks)
+{
+ ump_dd_handle mem;
+ ump_dd_physical_block_64 *block_64_array;
+ ump_alloc_flags flags = UMP_V1_API_DEFAULT_ALLOCATION_FLAGS;
+ unsigned long i;
+
+ UMP_ASSERT(blocks);
+ UMP_ASSERT(num_blocks);
+
+ block_64_array = kzalloc(num_blocks * sizeof(*block_64_array), __GFP_HARDWALL | GFP_KERNEL);
+
+ if(block_64_array == NULL)
+ {
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+
+ /* copy physical blocks */
+ for( i = 0; i < num_blocks; i++)
+ {
+ block_64_array[i].addr = blocks[i].addr;
+ block_64_array[i].size = blocks[i].size;
+ }
+
+ mem = ump_dd_create_from_phys_blocks_64(block_64_array, num_blocks, flags, NULL, NULL, NULL);
+
+ kfree(block_64_array);
+
+ return mem;
+
+}
diff --git a/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.h b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.h
new file mode 100755
index 0000000..8cb424d
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_core.h
@@ -0,0 +1,228 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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_CORE_H_
+#define _UMP_KERNEL_CORE_H_
+
+
+#include <linux/mutex.h>
+#include <linux/rwsem.h>
+#include <asm/atomic.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/cred.h>
+#include <asm/mmu_context.h>
+
+#ifdef CONFIG_KDS
+#include <linux/kds.h>
+#endif
+#include <linux/ump-common.h>
+#include <ump/src/common/ump_kernel_descriptor_mapping.h>
+
+/* forward decl */
+struct umpp_session;
+
+/**
+ * UMP handle metadata.
+ * Tracks various data about a handle not of any use to user space
+ */
+typedef enum
+{
+ UMP_MGMT_EXTERNAL = (1ul << 0) /**< Handle created via the ump_dd_create_from_phys_blocks interface */
+ /* (1ul << 31) not to be used */
+} umpp_management_flags;
+
+/**
+ * Structure tracking the single global UMP device.
+ * Holds global data like the ID map
+ */
+typedef struct umpp_device
+{
+ struct mutex secure_id_map_lock; /**< Lock protecting access to the map */
+ umpp_descriptor_mapping * secure_id_map; /**< Map of all known secure IDs on the system */
+} umpp_device;
+
+/**
+ * Structure tracking all memory allocations of a UMP allocation.
+ * Tracks info about an mapping so we can verify cache maintenace
+ * operations and help in the unmap cleanup.
+ */
+typedef struct umpp_cpu_mapping
+{
+ struct list_head link; /**< link to list of mappings for an allocation */
+ void *vaddr_start; /**< CPU VA start of the mapping */
+ size_t nr_pages; /**< Size (in pages) of the mapping */
+ uint64_t page_off; /**< Offset (in pages) from start of the allocation where the mapping starts */
+ ump_dd_handle handle; /**< Which handle this mapping is linked to */
+ struct umpp_session * session; /**< Which session created the mapping */
+} umpp_cpu_mapping;
+
+/**
+ * Structure tracking UMP allocation.
+ * Represent a memory allocation with its ID.
+ * Tracks all needed meta-data about an allocation.
+ * */
+typedef struct umpp_allocation
+{
+ ump_secure_id id; /**< Secure ID of the allocation */
+ atomic_t refcount; /**< Usage count */
+
+ ump_alloc_flags flags; /**< Flags for all supported devices */
+ uint32_t management_flags; /**< Managment flags tracking */
+
+ pid_t owner; /**< The process ID owning the memory if not sharable */
+
+ ump_dd_security_filter filter_func; /**< Hook to verify use, called during retains from new clients */
+ ump_dd_final_release_callback final_release_func; /**< Hook called when the last reference is removed */
+ void* callback_data; /**< Additional data given to release hook */
+
+ uint64_t size; /**< Size (in bytes) of the allocation */
+ uint64_t blocksCount; /**< Number of physsical blocks the allocation is built up of */
+ ump_dd_physical_block_64 * block_array; /**< Array, one entry per block, describing block start and length */
+
+ struct mutex map_list_lock; /**< Lock protecting the map_list */
+ struct list_head map_list; /**< Tracks all CPU VA mappings of this allocation */
+
+#ifdef CONFIG_KDS
+ struct kds_resource kds_res; /**< The KDS resource controlling access to this allocation */
+#endif
+
+ void * backendData; /**< Physical memory backend meta-data */
+} umpp_allocation;
+
+/**
+ * Structure tracking use of UMP memory by a session.
+ * Tracks the use of an allocation by a session so session termination can clean up any outstanding references.
+ * Also protects agains non-matched release calls from user space.
+ */
+typedef struct umpp_session_memory_usage
+{
+ ump_secure_id id; /**< ID being used. For quick look-up */
+ ump_dd_handle mem; /**< Handle being used. */
+
+ /**
+ * Track how many times has the process retained this handle in the kernel.
+ * This should usually just be 1(allocated or resolved) or 2(mapped),
+ * but could be more if someone is playing with the low-level API
+ * */
+ atomic_t process_usage_count;
+
+ struct list_head link; /**< link to other usage trackers for a session */
+} umpp_session_memory_usage;
+
+/**
+ * Structure representing a session/client.
+ * Tracks the UMP allocations being used by this client.
+ */
+typedef struct umpp_session
+{
+ struct mutex session_lock; /**< Lock for memory usage manipulation */
+ struct list_head memory_usage; /**< list of memory currently being used by the this session */
+ void* import_handler_data[UMPP_EXTERNAL_MEM_COUNT]; /**< Import modules per-session data pointer */
+} umpp_session;
+
+/**
+ * UMP core setup.
+ * Called by any OS specific startup function to initialize the common part.
+ * @return UMP_OK if core initialized correctly, any other value for errors
+ */
+ump_result umpp_core_constructor(void);
+
+/**
+ * UMP core teardown.
+ * Called by any OS specific unload function to clean up the common part.
+ */
+void umpp_core_destructor(void);
+
+/**
+ * UMP session start.
+ * Called by any OS specific session handler when a new session is detected
+ * @return Non-NULL if a matching core session could be set up. NULL on failure
+ */
+umpp_session *umpp_core_session_start(void);
+
+/**
+ * UMP session end.
+ * Called by any OS specific session handler when a session is ended/terminated.
+ * @param session The core session object returned by ump_core_session_start
+ */
+void umpp_core_session_end(umpp_session *session);
+
+/**
+ * Find a mapping object (if any) for this allocation.
+ * Called by any function needing to identify a mapping from a user virtual address.
+ * Verifies that the whole range to be within a mapping object.
+ * @param alloc The UMP allocation to find a matching mapping object of
+ * @param uaddr User mapping address to find the mapping object for
+ * @param size Length of the mapping
+ * @return NULL on error (no match found), pointer to mapping object if match found
+ */
+umpp_cpu_mapping * umpp_dd_find_enclosing_mapping(umpp_allocation * alloc, void* uaddr, size_t size);
+
+/**
+ * Register a new mapping of an allocation.
+ * Called by functions creating a new mapping of an allocation, typically OS specific handlers.
+ * @param alloc The allocation object which has been mapped
+ * @param map Info about the mapping
+ */
+void umpp_dd_add_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * map);
+
+/**
+ * Remove and free mapping object from an allocation.
+ * @param alloc The allocation object to remove the mapping info from
+ * @param target The mapping object to remove
+ */
+void umpp_dd_remove_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * target);
+
+/**
+ * Helper to find a block in the blockArray which holds a given byte offset.
+ * @param alloc The allocation object to find the block in
+ * @param offset Offset (in bytes) from allocation start to find the block of
+ * @param[out] block_index Pointer to the index of the block matching
+ * @param[out] block_internal_offset Offset within the returned block of the searched offset
+ * @return 0 if a matching block was found, any other value for error
+ */
+int umpp_dd_find_start_block(const umpp_allocation * alloc, uint64_t offset, uint64_t * const block_index, uint64_t * const block_internal_offset);
+
+/**
+ * Cache maintenance helper.
+ * Performs the requested cache operation on the given handle.
+ * @param mem Allocation handle
+ * @param op Cache maintenance operation to perform
+ * @param address User mapping at which to do the operation
+ * @param size Length (in bytes) of the range to do the operation on
+ */
+void umpp_dd_cpu_msync_now(ump_dd_handle mem, ump_cpu_msync_op op, void * address, size_t size);
+
+/**
+ * Import module session early init.
+ * Calls session_begin on all installed import modules.
+ * @param session The core session object to initialized the import handler for
+ * */
+void umpp_import_handlers_init(umpp_session * session);
+
+/**
+ * Import module session cleanup.
+ * Calls session_end on all import modules bound to the session.
+ * @param session The core session object to initialized the import handler for
+ */
+void umpp_import_handlers_term(umpp_session * session);
+
+#endif /* _UMP_KERNEL_CORE_H_ */
+
diff --git a/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.c b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.c
new file mode 100755
index 0000000..c5b0d74
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.c
@@ -0,0 +1,162 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 <common/ump_kernel_descriptor_mapping.h>
+#include <common/ump_kernel_priv.h>
+
+#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
+
+/**
+ * Allocate a descriptor table capable of holding 'count' mappings
+ * @param count Number of mappings in the table
+ * @return Pointer to a new table, NULL on error
+ */
+static umpp_descriptor_table * descriptor_table_alloc(unsigned int count);
+
+/**
+ * Free a descriptor table
+ * @param table The table to free
+ */
+static void descriptor_table_free(umpp_descriptor_table * table);
+
+umpp_descriptor_mapping * umpp_descriptor_mapping_create(unsigned int init_entries, unsigned int max_entries)
+{
+ umpp_descriptor_mapping * map = kzalloc(sizeof(umpp_descriptor_mapping), GFP_KERNEL);
+
+ init_entries = MALI_PAD_INT(init_entries);
+ max_entries = MALI_PAD_INT(max_entries);
+
+ if (NULL != map)
+ {
+ map->table = descriptor_table_alloc(init_entries);
+ if (NULL != map->table)
+ {
+ init_rwsem( &map->lock);
+ set_bit(0, map->table->usage);
+ map->max_nr_mappings_allowed = max_entries;
+ map->current_nr_mappings = init_entries;
+ return map;
+
+ descriptor_table_free(map->table);
+ }
+ kfree(map);
+ }
+ return NULL;
+}
+
+void umpp_descriptor_mapping_destroy(umpp_descriptor_mapping * map)
+{
+ UMP_ASSERT(NULL != map);
+ descriptor_table_free(map->table);
+ kfree(map);
+}
+
+unsigned int umpp_descriptor_mapping_allocate(umpp_descriptor_mapping * map, void * target)
+{
+ int descriptor = 0;
+ UMP_ASSERT(NULL != map);
+ down_write( &map->lock);
+ descriptor = find_first_zero_bit(map->table->usage, map->current_nr_mappings);
+ if (descriptor == map->current_nr_mappings)
+ {
+ /* no free descriptor, try to expand the table */
+ umpp_descriptor_table * new_table;
+ umpp_descriptor_table * old_table = map->table;
+ int nr_mappings_new = map->current_nr_mappings + BITS_PER_LONG;
+
+ if (map->current_nr_mappings >= map->max_nr_mappings_allowed)
+ {
+ descriptor = 0;
+ goto unlock_and_exit;
+ }
+
+ new_table = descriptor_table_alloc(nr_mappings_new);
+ if (NULL == new_table)
+ {
+ descriptor = 0;
+ goto unlock_and_exit;
+ }
+
+ memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
+ 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);
+ }
+
+ /* we have found a valid descriptor, set the value and usage bit */
+ set_bit(descriptor, map->table->usage);
+ map->table->mappings[descriptor] = target;
+
+unlock_and_exit:
+ up_write(&map->lock);
+ return descriptor;
+}
+
+int umpp_descriptor_mapping_lookup(umpp_descriptor_mapping * map, unsigned int descriptor, void** const target)
+{
+ int result = -EINVAL;
+ UMP_ASSERT(map);
+ UMP_ASSERT(target);
+ down_read(&map->lock);
+ if ( (descriptor > 0) && (descriptor < map->current_nr_mappings) && test_bit(descriptor, map->table->usage) )
+ {
+ *target = map->table->mappings[descriptor];
+ result = 0;
+ }
+ /* keep target untouched if the descriptor was not found */
+ up_read(&map->lock);
+ return result;
+}
+
+void umpp_descriptor_mapping_remove(umpp_descriptor_mapping * map, unsigned int descriptor)
+{
+ UMP_ASSERT(map);
+ down_write(&map->lock);
+ if ( (descriptor > 0) && (descriptor < map->current_nr_mappings) && test_bit(descriptor, map->table->usage) )
+ {
+ map->table->mappings[descriptor] = NULL;
+ clear_bit(descriptor, map->table->usage);
+ }
+ up_write(&map->lock);
+}
+
+static umpp_descriptor_table * descriptor_table_alloc(unsigned int count)
+{
+ umpp_descriptor_table * table;
+
+ table = kzalloc(sizeof(umpp_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count), __GFP_HARDWALL | GFP_KERNEL );
+
+ if (NULL != table)
+ {
+ table->usage = (unsigned long*)((u8*)table + sizeof(umpp_descriptor_table));
+ table->mappings = (void**)((u8*)table + sizeof(umpp_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
+ }
+
+ return table;
+}
+
+static void descriptor_table_free(umpp_descriptor_table * table)
+{
+ UMP_ASSERT(table);
+ kfree(table);
+}
+
diff --git a/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.h b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.h
new file mode 100755
index 0000000..d06c145
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_descriptor_mapping.h
@@ -0,0 +1,94 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+/**
+ * @file ump_kernel_descriptor_mapping.h
+ */
+
+#ifndef _UMP_KERNEL_DESCRIPTOR_MAPPING_H_
+#define _UMP_KERNEL_DESCRIPTOR_MAPPING_H_
+
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+/**
+ * The actual descriptor mapping table, never directly accessed by clients
+ */
+typedef struct umpp_descriptor_table
+{
+ /* keep as a unsigned long to rely on the OS's bitops support */
+ unsigned long * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used(1) or not(0) */
+ void** mappings; /**< Array of the pointers the descriptors map to */
+} umpp_descriptor_table;
+
+/**
+ * The descriptor mapping object
+ * Provides a separate namespace where we can map an integer to a pointer
+ */
+typedef struct umpp_descriptor_mapping
+{
+ struct rw_semaphore lock; /**< Lock protecting access to the mapping object */
+ unsigned int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */
+ unsigned int current_nr_mappings; /**< Current number of possible mappings */
+ umpp_descriptor_table * table; /**< Pointer to the current mapping table */
+} umpp_descriptor_mapping;
+
+/**
+ * Create a descriptor mapping object.
+ * Create a descriptor mapping capable of holding init_entries growable to max_entries.
+ * ID 0 is reserved so the number of available entries will be max - 1.
+ * @param init_entries Number of entries to preallocate memory for
+ * @param max_entries Number of entries to max support
+ * @return Pointer to a descriptor mapping object, NULL on failure
+ */
+umpp_descriptor_mapping * umpp_descriptor_mapping_create(unsigned int init_entries, unsigned int max_entries);
+
+/**
+ * Destroy a descriptor mapping object
+ * @param[in] map The map to free
+ */
+void umpp_descriptor_mapping_destroy(umpp_descriptor_mapping * map);
+
+/**
+ * Allocate a new mapping entry (descriptor ID)
+ * Allocates a new entry in the map.
+ * @param[in] map The map to allocate a new entry in
+ * @param[in] target The value to map to
+ * @return The descriptor allocated, ID 0 on failure.
+ */
+unsigned int umpp_descriptor_mapping_allocate(umpp_descriptor_mapping * map, void * target);
+
+/**
+ * Get the value mapped to by a descriptor ID
+ * @param[in] map The map to lookup the descriptor id in
+ * @param[in] descriptor The descriptor ID to lookup
+ * @param[out] target Pointer to a pointer which will receive the stored value
+ *
+ * @return 0 on success lookup, -EINVAL on lookup failure.
+ */
+int umpp_descriptor_mapping_lookup(umpp_descriptor_mapping * map, unsigned int descriptor, void** const target);
+
+/**
+ * Free the descriptor ID
+ * For the descriptor to be reused it has to be freed
+ * @param[in] map The map to free the descriptor from
+ * @param descriptor The descriptor ID to free
+ */
+void umpp_descriptor_mapping_remove(umpp_descriptor_mapping * map, unsigned int descriptor);
+
+#endif /* _UMP_KERNEL_DESCRIPTOR_MAPPING_H_ */
diff --git a/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_priv.h b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_priv.h
new file mode 100755
index 0000000..38b6f1b
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/common/ump_kernel_priv.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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_PRIV_H_
+#define _UMP_KERNEL_PRIV_H_
+
+#ifdef __KERNEL__
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <asm/cacheflush.h>
+#endif
+
+
+#define UMP_EXPECTED_IDS 64
+#define UMP_MAX_IDS 32768
+
+#ifdef __KERNEL__
+#define UMP_ASSERT(expr) \
+ if (!(expr)) { \
+ printk(KERN_ERR "UMP: Assertion failed! %s,%s,%s,line=%d\n",\
+ #expr,__FILE__,__func__,__LINE__); \
+ BUG(); \
+ }
+
+static inline void ump_sync_to_memory(uint64_t paddr, void* vaddr, size_t sz)
+{
+#ifdef CONFIG_ARM
+ __cpuc_flush_dcache_area(vaddr, sz);
+ outer_flush_range(paddr, paddr+sz);
+#elif defined(CONFIG_ARM64)
+ /*TODO (MID64-46): There's no other suitable cache flush function for ARM64 */
+ flush_cache_all();
+#elif defined(CONFIG_X86)
+ struct scatterlist scl = {0, };
+ sg_set_page(&scl, pfn_to_page(PFN_DOWN(paddr)), sz,
+ paddr & (PAGE_SIZE -1 ));
+ dma_sync_sg_for_cpu(NULL, &scl, 1, DMA_TO_DEVICE);
+ mb(); /* for outer_sync (if needed) */
+#else
+#error Implement cache maintenance for your architecture here
+#endif
+}
+
+static inline void ump_sync_to_cpu(uint64_t paddr, void* vaddr, size_t sz)
+{
+#ifdef CONFIG_ARM
+ __cpuc_flush_dcache_area(vaddr, sz);
+ outer_flush_range(paddr, paddr+sz);
+#elif defined(CONFIG_ARM64)
+ /* TODO (MID64-46): There's no other suitable cache flush function for ARM64 */
+ flush_cache_all();
+#elif defined(CONFIG_X86)
+ struct scatterlist scl = {0, };
+ sg_set_page(&scl, pfn_to_page(PFN_DOWN(paddr)), sz,
+ paddr & (PAGE_SIZE -1 ));
+ dma_sync_sg_for_cpu(NULL, &scl, 1, DMA_FROM_DEVICE);
+#else
+#error Implement cache maintenance for your architecture here
+#endif
+}
+#endif /* __KERNEL__*/
+#endif /* _UMP_KERNEL_PRIV_H_ */
+
diff --git a/driver/product/kernel/drivers/base/ump/src/imports/ion/Makefile b/driver/product/kernel/drivers/base/ump/src/imports/ion/Makefile
new file mode 100755
index 0000000..ef74b27
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/imports/ion/Makefile
@@ -0,0 +1,53 @@
+#
+# (C) COPYRIGHT 2011, 2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+
+# default to building for the host
+ARCH ?= $(shell uname -m)
+
+# linux build system integration
+
+ifneq ($(KERNELRELEASE),)
+# Inside the kernel build system
+
+EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/../../../../..
+KBUILD_EXTRA_SYMBOLS += "$(KBUILD_EXTMOD)/../../Module.symvers"
+
+SRC += ump_kernel_import_ion.c
+
+MODULE:=ump_ion_import.ko
+
+obj-m := $(MODULE:.ko=.o)
+$(MODULE:.ko=-y) := $(SRC:.c=.o)
+$(MODULE:.ko=-objs) := $(SRC:.c=.o)
+
+else
+# Outside the kernel build system
+#
+#
+
+ifeq ($(KDIR),)
+$(error Must specify KDIR to point to the kernel to target))
+endif
+
+all:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR)
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
+endif
+
diff --git a/driver/product/kernel/drivers/base/ump/src/imports/ion/sconscript b/driver/product/kernel/drivers/base/ump/src/imports/ion/sconscript
new file mode 100755
index 0000000..cff24c8
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/imports/ion/sconscript
@@ -0,0 +1,49 @@
+#
+# (C) COPYRIGHT 2010-2013, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+import os
+Import('env')
+
+# Clone the environment so changes don't affect other build files
+env_ion = env.Clone()
+
+if env_ion['ump_ion'] != '1':
+ Return()
+
+# Source files required for UMP.
+ion_src = [Glob('#kernel/drivers/base/ump/src/imports/ion/*.c')]
+
+# Note: cleaning via the Linux kernel build system does not yet work
+if env_ion.GetOption('clean') :
+ makeAction=Action("cd ${SOURCE.dir} && make clean", '$MAKECOMSTR')
+else:
+ makeAction=Action("cd ${SOURCE.dir} && make PLATFORM=${platform} && cp ump_ion_import.ko $STATIC_LIB_PATH/ump_ion_import.ko", '$MAKECOMSTR')
+# The target is ump_import_ion.ko, built from the source in ion_src, via the action makeAction
+# ump_import_ion.ko will be copied to $STATIC_LIB_PATH after being built by the standard Linux
+# kernel build system, after which it can be installed to the directory specified if
+# "libs_install" is set; this is done by LibTarget.
+cmd = env_ion.Command('$STATIC_LIB_PATH/ump_ion_import.ko', ion_src, [makeAction])
+
+# Until we fathom out how the invoke the Linux build system to clean, we can use Clean
+# to remove generated files.
+
+patterns = ['*.mod.c', '*.o', '*.ko', '*.a', '.*.cmd', 'modules.order', '.tmp_versions', 'Module.symvers']
+
+for p in patterns:
+ Clean(cmd, Glob('#kernel/drivers/base/ump/src/imports/ion/%s' % p))
+
+env_ion.Depends('$STATIC_LIB_PATH/ump_ion_import.ko', '$STATIC_LIB_PATH/ump.ko')
+env_ion.KernelObjTarget('ump', cmd)
diff --git a/driver/product/kernel/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c b/driver/product/kernel/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c
new file mode 100755
index 0000000..12b2e32
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/imports/ion/ump_kernel_import_ion.c
@@ -0,0 +1,204 @@
+/*
+ *
+ * (C) COPYRIGHT 2011-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+#include <linux/ump.h>
+#include <linux/dma-mapping.h>
+#include "ion.h"
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+struct ion_wrapping_info
+{
+ struct ion_client * ion_client;
+ struct ion_handle * ion_handle;
+ int num_phys_blocks;
+ struct scatterlist * sglist;
+};
+
+static struct ion_device * ion_device_get(void)
+{
+ /* < Customer to provide implementation >
+ * Return a pointer to the global ion_device on the system
+ */
+ return NULL;
+}
+
+static int import_ion_client_create(void** const custom_session_data)
+{
+ struct ion_client ** ion_client;
+
+ ion_client = (struct ion_client**)custom_session_data;
+
+ *ion_client = ion_client_create(ion_device_get(), "ump");
+
+ return PTR_RET(*ion_client);
+}
+
+
+static void import_ion_client_destroy(void* custom_session_data)
+{
+ struct ion_client * ion_client;
+
+ ion_client = (struct ion_client*)custom_session_data;
+ BUG_ON(!ion_client);
+
+ ion_client_destroy(ion_client);
+}
+
+
+static void import_ion_final_release_callback(const ump_dd_handle handle, void * info)
+{
+ struct ion_wrapping_info * ion_info;
+
+ BUG_ON(!info);
+
+ (void)handle;
+ ion_info = (struct ion_wrapping_info*)info;
+
+ dma_unmap_sg(NULL, ion_info->sglist, ion_info->num_phys_blocks, DMA_BIDIRECTIONAL);
+
+ ion_free(ion_info->ion_client, ion_info->ion_handle);
+ kfree(ion_info);
+ module_put(THIS_MODULE);
+}
+
+static ump_dd_handle import_ion_import(void * custom_session_data, void * pfd, ump_alloc_flags flags)
+{
+ int fd;
+ ump_dd_handle ump_handle;
+ struct scatterlist * sg;
+ int num_dma_blocks;
+ ump_dd_physical_block_64 * phys_blocks;
+ unsigned long i;
+ struct sg_table * sgt;
+
+ struct ion_wrapping_info * ion_info;
+
+ BUG_ON(!custom_session_data);
+ BUG_ON(!pfd);
+
+ ion_info = kzalloc(GFP_KERNEL, sizeof(*ion_info));
+ if (NULL == ion_info)
+ {
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+ }
+
+ ion_info->ion_client = (struct ion_client*)custom_session_data;
+
+ if (get_user(fd, (int*)pfd))
+ {
+ goto out;
+ }
+
+ ion_info->ion_handle = ion_import_dma_buf(ion_info->ion_client, fd);
+
+ if (IS_ERR_OR_NULL(ion_info->ion_handle))
+ {
+ goto out;
+ }
+
+ sgt = ion_sg_table(ion_info->ion_client, ion_info->ion_handle);
+ if (IS_ERR_OR_NULL(sgt))
+ {
+ goto ion_dma_map_failed;
+ }
+
+ ion_info->sglist = sgt->sgl;
+
+ sg = ion_info->sglist;
+ while (sg)
+ {
+ ion_info->num_phys_blocks++;
+ sg = sg_next(sg);
+ }
+
+ num_dma_blocks = dma_map_sg(NULL, ion_info->sglist, ion_info->num_phys_blocks, DMA_BIDIRECTIONAL);
+
+ if (0 == num_dma_blocks)
+ {
+ goto linux_dma_map_failed;
+ }
+
+ phys_blocks = vmalloc(num_dma_blocks * sizeof(*phys_blocks));
+ if (NULL == phys_blocks)
+ {
+ goto vmalloc_failed;
+ }
+
+ for_each_sg(ion_info->sglist, sg, num_dma_blocks, i)
+ {
+ phys_blocks[i].addr = sg_phys(sg);
+ phys_blocks[i].size = sg_dma_len(sg);
+ }
+
+ ump_handle = ump_dd_create_from_phys_blocks_64(phys_blocks, num_dma_blocks, flags, NULL, import_ion_final_release_callback, ion_info);
+
+ vfree(phys_blocks);
+
+ if (ump_handle != UMP_DD_INVALID_MEMORY_HANDLE)
+ {
+ /*
+ * As we have a final release callback installed
+ * we must keep the module locked until
+ * the callback has been triggered
+ * */
+ __module_get(THIS_MODULE);
+ return ump_handle;
+ }
+
+ /* failed*/
+vmalloc_failed:
+ dma_unmap_sg(NULL, ion_info->sglist, ion_info->num_phys_blocks, DMA_BIDIRECTIONAL);
+linux_dma_map_failed:
+ion_dma_map_failed:
+ ion_free(ion_info->ion_client, ion_info->ion_handle);
+out:
+ kfree(ion_info);
+ return UMP_DD_INVALID_MEMORY_HANDLE;
+}
+
+struct ump_import_handler import_handler_ion =
+{
+ .linux_module = THIS_MODULE,
+ .session_begin = import_ion_client_create,
+ .session_end = import_ion_client_destroy,
+ .import = import_ion_import
+};
+
+static int __init import_ion_initialize_module(void)
+{
+ /* register with UMP */
+ return ump_import_module_register(UMP_EXTERNAL_MEM_TYPE_ION, &import_handler_ion);
+}
+
+static void __exit import_ion_cleanup_module(void)
+{
+ /* unregister import handler */
+ ump_import_module_unregister(UMP_EXTERNAL_MEM_TYPE_ION);
+}
+
+/* Setup init and exit functions for this module */
+module_init(import_ion_initialize_module);
+module_exit(import_ion_cleanup_module);
+
+/* And some module information */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("ARM Ltd.");
+MODULE_VERSION("1.0");
diff --git a/driver/product/kernel/drivers/base/ump/src/imports/sconscript b/driver/product/kernel/drivers/base/ump/src/imports/sconscript
new file mode 100755
index 0000000..8f50683
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/imports/sconscript
@@ -0,0 +1,25 @@
+#
+# (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+import os, sys
+Import('env')
+
+import_modules = [ os.path.join( path, 'sconscript' ) for path in sorted(os.listdir( os.getcwd() )) ]
+
+for m in import_modules:
+ if os.path.exists(m):
+ SConscript( m, variant_dir=os.path.join( env['BUILD_DIR_PATH'], os.path.dirname(m) ), duplicate=0 )
+
diff --git a/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux.c b/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux.c
new file mode 100755
index 0000000..d6c3c53
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux.c
@@ -0,0 +1,831 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+#include <linux/ump-ioctl.h>
+#include <linux/ump.h>
+
+#include <asm/uaccess.h> /* copy_*_user */
+#include <linux/compat.h>
+#include <linux/module.h> /* kernel module definitions */
+#include <linux/fs.h> /* file system operations */
+#include <linux/cdev.h> /* character device definitions */
+#include <linux/ioport.h> /* request_mem_region */
+#include <linux/device.h> /* class registration support */
+
+#include <common/ump_kernel_core.h>
+
+#include "ump_kernel_linux_mem.h"
+#include <ump_arch.h>
+
+
+struct ump_linux_device
+{
+ struct cdev cdev;
+ struct class * ump_class;
+};
+
+/* Name of the UMP device driver */
+static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */
+
+/* Module parameter to control log level */
+int ump_debug_level = 2;
+module_param(ump_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(ump_debug_level, "Higher number, more dmesg output");
+
+/* By default the module uses any available major, but it's possible to set it at load time to a specific number */
+int ump_major = 0;
+module_param(ump_major, int, S_IRUGO); /* r--r--r-- */
+MODULE_PARM_DESC(ump_major, "Device major number");
+
+#define UMP_REV_STRING "1.0"
+
+char * ump_revision = UMP_REV_STRING;
+module_param(ump_revision, charp, S_IRUGO); /* r--r--r-- */
+MODULE_PARM_DESC(ump_revision, "Revision info");
+
+static int umpp_linux_open(struct inode *inode, struct file *filp);
+static int umpp_linux_release(struct inode *inode, struct file *filp);
+#ifdef HAVE_UNLOCKED_IOCTL
+static long umpp_linux_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#else
+static int umpp_linux_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+#endif
+
+/* This variable defines the file operations this UMP device driver offers */
+static struct file_operations ump_fops =
+{
+ .owner = THIS_MODULE,
+ .open = umpp_linux_open,
+ .release = umpp_linux_release,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = umpp_linux_ioctl,
+#else
+ .ioctl = umpp_linux_ioctl,
+#endif
+ .compat_ioctl = umpp_linux_ioctl,
+ .mmap = umpp_linux_mmap
+};
+
+/* import module handling */
+DEFINE_MUTEX(import_list_lock);
+struct ump_import_handler * import_handlers[UMPP_EXTERNAL_MEM_COUNT];
+
+/* The global variable containing the global device data */
+static struct ump_linux_device ump_linux_device;
+
+#define DBG_MSG(level, ...) do { \
+if ((level) <= ump_debug_level)\
+{\
+printk(KERN_DEBUG "UMP<" #level ">:\n" __VA_ARGS__);\
+} \
+} while (0)
+
+#define MSG_ERR(...) do{ \
+printk(KERN_ERR "UMP: ERR: %s\n %s()%4d\n", __FILE__, __func__ , __LINE__) ; \
+printk(KERN_ERR __VA_ARGS__); \
+printk(KERN_ERR "\n"); \
+} while(0)
+
+#define MSG(...) do{ \
+printk(KERN_INFO "UMP: " __VA_ARGS__);\
+} while (0)
+
+/*
+ * This function is called by Linux to initialize this module.
+ * All we do is initialize the UMP device driver.
+ */
+static int __init umpp_linux_initialize_module(void)
+{
+ ump_result err;
+
+ err = umpp_core_constructor();
+ if (UMP_OK != err)
+ {
+ MSG_ERR("UMP device driver init failed\n");
+ return -ENOTTY;
+ }
+
+ MSG("UMP device driver %s loaded\n", UMP_REV_STRING);
+ return 0;
+}
+
+
+
+/*
+ * This function is called by Linux to unload/terminate/exit/cleanup this module.
+ * All we do is terminate the UMP device driver.
+ */
+static void __exit umpp_linux_cleanup_module(void)
+{
+ DBG_MSG(2, "Unloading UMP device driver\n");
+ umpp_core_destructor();
+ DBG_MSG(2, "Module unloaded\n");
+}
+
+
+
+/*
+ * Initialize the UMP device driver.
+ */
+ump_result umpp_device_initialize(void)
+{
+ int err;
+ dev_t dev = 0;
+
+ if (0 == ump_major)
+ {
+ /* auto select a major */
+ err = alloc_chrdev_region(&dev, 0, 1, ump_dev_name);
+ ump_major = MAJOR(dev);
+ }
+ else
+ {
+ /* use load time defined major number */
+ dev = MKDEV(ump_major, 0);
+ err = register_chrdev_region(dev, 1, ump_dev_name);
+ }
+
+ if (0 == err)
+ {
+ memset(&ump_linux_device, 0, sizeof(ump_linux_device));
+
+ /* initialize our char dev data */
+ cdev_init(&ump_linux_device.cdev, &ump_fops);
+ ump_linux_device.cdev.owner = THIS_MODULE;
+ ump_linux_device.cdev.ops = &ump_fops;
+
+ /* register char dev with the kernel */
+ err = cdev_add(&ump_linux_device.cdev, dev, 1/*count*/);
+ if (0 == err)
+ {
+
+ ump_linux_device.ump_class = class_create(THIS_MODULE, ump_dev_name);
+ if (IS_ERR(ump_linux_device.ump_class))
+ {
+ err = PTR_ERR(ump_linux_device.ump_class);
+ }
+ else
+ {
+ struct device * mdev;
+ mdev = device_create(ump_linux_device.ump_class, NULL, dev, NULL, ump_dev_name);
+ if (!IS_ERR(mdev))
+ {
+ return UMP_OK;
+ }
+
+ err = PTR_ERR(mdev);
+ class_destroy(ump_linux_device.ump_class);
+ }
+ cdev_del(&ump_linux_device.cdev);
+ }
+
+ unregister_chrdev_region(dev, 1);
+ }
+
+ return UMP_ERROR;
+}
+
+
+
+/*
+ * Terminate the UMP device driver
+ */
+void umpp_device_terminate(void)
+{
+ dev_t dev = MKDEV(ump_major, 0);
+
+ device_destroy(ump_linux_device.ump_class, dev);
+ class_destroy(ump_linux_device.ump_class);
+
+ /* unregister char device */
+ cdev_del(&ump_linux_device.cdev);
+
+ /* free major */
+ unregister_chrdev_region(dev, 1);
+}
+
+
+static int umpp_linux_open(struct inode *inode, struct file *filp)
+{
+ umpp_session *session;
+
+ session = umpp_core_session_start();
+ if (NULL == session)
+ {
+ return -EFAULT;
+ }
+
+ filp->private_data = session;
+
+ return 0;
+}
+
+static int umpp_linux_release(struct inode *inode, struct file *filp)
+{
+ umpp_session *session;
+
+ session = filp->private_data;
+
+ umpp_core_session_end(session);
+
+ filp->private_data = NULL;
+
+ return 0;
+}
+
+/**************************/
+/*ioctl specific functions*/
+/**************************/
+static int do_ump_dd_allocate(umpp_session * session, ump_k_allocate * params)
+{
+ ump_dd_handle new_allocation;
+ new_allocation = ump_dd_allocate_64(params->size, params->alloc_flags, NULL, NULL, NULL);
+
+ if (UMP_DD_INVALID_MEMORY_HANDLE != new_allocation)
+ {
+ umpp_session_memory_usage * tracker;
+
+ tracker = kmalloc(sizeof(*tracker), GFP_KERNEL | __GFP_HARDWALL);
+ if (NULL != tracker)
+ {
+ /* update the return struct with the new ID */
+ params->secure_id = ump_dd_secure_id_get(new_allocation);
+
+ tracker->mem = new_allocation;
+ tracker->id = params->secure_id;
+ atomic_set(&tracker->process_usage_count, 1);
+
+ /* link it into the session in-use list */
+ mutex_lock(&session->session_lock);
+ list_add(&tracker->link, &session->memory_usage);
+ mutex_unlock(&session->session_lock);
+
+ return 0;
+ }
+ ump_dd_release(new_allocation);
+ }
+
+ printk(KERN_WARNING "UMP: Allocation FAILED\n");
+ return -ENOMEM;
+}
+
+static int do_ump_dd_retain(umpp_session * session, ump_k_retain * params)
+{
+ umpp_session_memory_usage * it;
+
+ mutex_lock(&session->session_lock);
+
+ /* try to find it on the session usage list */
+ list_for_each_entry(it, &session->memory_usage, link)
+ {
+ if (it->id == params->secure_id)
+ {
+ /* found to already be in use */
+ /* check for overflow */
+ while(1)
+ {
+ int refcnt = atomic_read(&it->process_usage_count);
+ if (refcnt + 1 > 0)
+ {
+ /* add a process local ref */
+ if(atomic_cmpxchg(&it->process_usage_count, refcnt, refcnt + 1) == refcnt)
+ {
+ mutex_unlock(&session->session_lock);
+ return 0;
+ }
+ }
+ else
+ {
+ /* maximum usage cap reached */
+ mutex_unlock(&session->session_lock);
+ return -EBUSY;
+ }
+ }
+ }
+ }
+ /* try to look it up globally */
+
+ it = kmalloc(sizeof(*it), GFP_KERNEL);
+
+ if (NULL != it)
+ {
+ it->mem = ump_dd_from_secure_id(params->secure_id);
+ if (UMP_DD_INVALID_MEMORY_HANDLE != it->mem)
+ {
+ /* found, add it to the session usage list */
+ it->id = params->secure_id;
+ atomic_set(&it->process_usage_count, 1);
+ list_add(&it->link, &session->memory_usage);
+ }
+ else
+ {
+ /* not found */
+ kfree(it);
+ it = NULL;
+ }
+ }
+
+ mutex_unlock(&session->session_lock);
+
+ return (NULL != it) ? 0 : -ENODEV;
+}
+
+
+static int do_ump_dd_release(umpp_session * session, ump_k_release * params)
+{
+ umpp_session_memory_usage * it;
+ int result = -ENODEV;
+
+ mutex_lock(&session->session_lock);
+
+ /* only do a release if found on the session list */
+ list_for_each_entry(it, &session->memory_usage, link)
+ {
+ if (it->id == params->secure_id)
+ {
+ /* found, a valid call */
+ result = 0;
+
+ if (0 == atomic_sub_return(1, &it->process_usage_count))
+ {
+ /* last ref in this process remove from the usage list and remove the underlying ref */
+ list_del(&it->link);
+ ump_dd_release(it->mem);
+ kfree(it);
+ }
+
+ break;
+ }
+ }
+ mutex_unlock(&session->session_lock);
+
+ return result;
+}
+
+static int do_ump_dd_sizequery(umpp_session * session, ump_k_sizequery * params)
+{
+ umpp_session_memory_usage * it;
+ int result = -ENODEV;
+
+ mutex_lock(&session->session_lock);
+
+ /* only valid if found on the session list */
+ list_for_each_entry(it, &session->memory_usage, link)
+ {
+ if (it->id == params->secure_id)
+ {
+ /* found, a valid call */
+ params->size = ump_dd_size_get_64(it->mem);
+ result = 0;
+ break;
+ }
+
+ }
+ mutex_unlock(&session->session_lock);
+
+ return result;
+}
+
+static int do_ump_dd_allocation_flags_get(umpp_session * session, ump_k_allocation_flags * params)
+{
+ umpp_session_memory_usage * it;
+ int result = -ENODEV;
+
+ mutex_lock(&session->session_lock);
+
+ /* only valid if found on the session list */
+ list_for_each_entry(it, &session->memory_usage, link)
+ {
+ if (it->id == params->secure_id)
+ {
+ /* found, a valid call */
+ params->alloc_flags = ump_dd_allocation_flags_get(it->mem);
+ result = 0;
+ break;
+ }
+
+ }
+ mutex_unlock(&session->session_lock);
+
+ return result;
+}
+
+static int do_ump_dd_msync_now(umpp_session * session, ump_k_msync * params)
+{
+ umpp_session_memory_usage * it;
+ int result = -ENODEV;
+
+ mutex_lock(&session->session_lock);
+
+ /* only valid if found on the session list */
+ list_for_each_entry(it, &session->memory_usage, link)
+ {
+ if (it->id == params->secure_id)
+ {
+ /* found, do the cache op */
+#ifdef CONFIG_COMPAT
+ if (is_compat_task())
+ {
+ umpp_dd_cpu_msync_now(it->mem, params->cache_operation, compat_ptr(params->mapped_ptr.compat_value), params->size);
+ result = 0;
+ }
+ else
+ {
+#endif
+ umpp_dd_cpu_msync_now(it->mem, params->cache_operation, params->mapped_ptr.value, params->size);
+ result = 0;
+#ifdef CONFIG_COMPAT
+ }
+#endif
+ break;
+ }
+ }
+ mutex_unlock(&session->session_lock);
+
+ return result;
+}
+
+
+void umpp_import_handlers_init(umpp_session * session)
+{
+ int i;
+ mutex_lock(&import_list_lock);
+ for ( i = 1; i < UMPP_EXTERNAL_MEM_COUNT; i++ )
+ {
+ if (import_handlers[i])
+ {
+ import_handlers[i]->session_begin(&session->import_handler_data[i]);
+ /* It is OK if session_begin returned an error.
+ * We won't do any import calls if so */
+ }
+ }
+ mutex_unlock(&import_list_lock);
+}
+
+void umpp_import_handlers_term(umpp_session * session)
+{
+ int i;
+ mutex_lock(&import_list_lock);
+ for ( i = 1; i < UMPP_EXTERNAL_MEM_COUNT; i++ )
+ {
+ /* only call if session_begin succeeded */
+ if (session->import_handler_data[i] != NULL)
+ {
+ /* if session_beging succeeded the handler
+ * should not have unregistered with us */
+ BUG_ON(!import_handlers[i]);
+ import_handlers[i]->session_end(session->import_handler_data[i]);
+ session->import_handler_data[i] = NULL;
+ }
+ }
+ mutex_unlock(&import_list_lock);
+}
+
+int ump_import_module_register(enum ump_external_memory_type type, struct ump_import_handler * handler)
+{
+ int res = -EEXIST;
+
+ /* validate input */
+ BUG_ON(type == 0 || type >= UMPP_EXTERNAL_MEM_COUNT);
+ BUG_ON(!handler);
+ BUG_ON(!handler->linux_module);
+ BUG_ON(!handler->session_begin);
+ BUG_ON(!handler->session_end);
+ BUG_ON(!handler->import);
+
+ mutex_lock(&import_list_lock);
+
+ if (!import_handlers[type])
+ {
+ import_handlers[type] = handler;
+ res = 0;
+ }
+
+ mutex_unlock(&import_list_lock);
+
+ return res;
+}
+
+void ump_import_module_unregister(enum ump_external_memory_type type)
+{
+ BUG_ON(type == 0 || type >= UMPP_EXTERNAL_MEM_COUNT);
+
+ mutex_lock(&import_list_lock);
+ /* an error to call this if ump_import_module_register didn't succeed */
+ BUG_ON(!import_handlers[type]);
+ import_handlers[type] = NULL;
+ mutex_unlock(&import_list_lock);
+}
+
+static struct ump_import_handler * import_handler_get(unsigned int type_id)
+{
+ enum ump_external_memory_type type;
+ struct ump_import_handler * handler;
+
+ /* validate and convert input */
+ /* handle bad data here, not just BUG_ON */
+ if (type_id == 0 || type_id >= UMPP_EXTERNAL_MEM_COUNT)
+ return NULL;
+
+ type = (enum ump_external_memory_type)type_id;
+
+ /* find the handler */
+ mutex_lock(&import_list_lock);
+
+ handler = import_handlers[type];
+
+ if (handler)
+ {
+ if (!try_module_get(handler->linux_module))
+ {
+ handler = NULL;
+ }
+ }
+
+ mutex_unlock(&import_list_lock);
+
+ return handler;
+}
+
+static void import_handler_put(struct ump_import_handler * handler)
+{
+ module_put(handler->linux_module);
+}
+
+static int do_ump_dd_import(umpp_session * session, ump_k_import * params)
+{
+ ump_dd_handle new_allocation = UMP_DD_INVALID_MEMORY_HANDLE;
+ struct ump_import_handler * handler;
+
+ handler = import_handler_get(params->type);
+
+ if (handler)
+ {
+ /* try late binding if not already bound */
+ if (!session->import_handler_data[params->type])
+ {
+ handler->session_begin(&session->import_handler_data[params->type]);
+ }
+
+ /* do we have a bound session? */
+ if (session->import_handler_data[params->type])
+ {
+ new_allocation = handler->import( session->import_handler_data[params->type],
+ params->phandle.value,
+ params->alloc_flags);
+ }
+
+ /* done with the handler */
+ import_handler_put(handler);
+ }
+
+ /* did the import succeed? */
+ if (UMP_DD_INVALID_MEMORY_HANDLE != new_allocation)
+ {
+ umpp_session_memory_usage * tracker;
+
+ tracker = kmalloc(sizeof(*tracker), GFP_KERNEL | __GFP_HARDWALL);
+ if (NULL != tracker)
+ {
+ /* update the return struct with the new ID */
+ params->secure_id = ump_dd_secure_id_get(new_allocation);
+
+ tracker->mem = new_allocation;
+ tracker->id = params->secure_id;
+ atomic_set(&tracker->process_usage_count, 1);
+
+ /* link it into the session in-use list */
+ mutex_lock(&session->session_lock);
+ list_add(&tracker->link, &session->memory_usage);
+ mutex_unlock(&session->session_lock);
+
+ return 0;
+ }
+ ump_dd_release(new_allocation);
+ }
+
+ return -ENOMEM;
+
+}
+
+#ifdef HAVE_UNLOCKED_IOCTL
+static long umpp_linux_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+#else
+static int umpp_linux_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+#endif
+{
+ int ret;
+ uint64_t msg[(UMP_CALL_MAX_SIZE+7)>>3]; /* alignment fixup */
+ uint32_t size = _IOC_SIZE(cmd);
+ struct umpp_session *session = filp->private_data;
+
+#ifndef HAVE_UNLOCKED_IOCTL
+ (void)inode; /* unused arg */
+#endif
+
+ /*
+ * extract the type and number bitfields, and don't decode
+ * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
+ */
+ if (_IOC_TYPE(cmd) != UMP_IOC_MAGIC)
+ {
+ return -ENOTTY;
+
+ }
+ if (_IOC_NR(cmd) > UMP_IOC_MAXNR)
+ {
+ return -ENOTTY;
+ }
+
+ switch(cmd)
+ {
+ case UMP_FUNC_ALLOCATE:
+ if (size != sizeof(ump_k_allocate))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_allocate(session, (ump_k_allocate *)&msg);
+ if (ret)
+ {
+ return ret;
+ }
+ if (copy_to_user((void *)arg, &msg, size))
+ {
+ return -EFAULT;
+ }
+ return 0;
+ case UMP_FUNC_SIZEQUERY:
+ if (size != sizeof(ump_k_sizequery))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_sizequery(session,(ump_k_sizequery*) &msg);
+ if (ret)
+ {
+ return ret;
+ }
+ if (copy_to_user((void *)arg, &msg, size))
+ {
+ return -EFAULT;
+ }
+ return 0;
+ case UMP_FUNC_MSYNC:
+ if (size != sizeof(ump_k_msync))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_msync_now(session,(ump_k_msync*) &msg);
+ if (ret)
+ {
+ return ret;
+ }
+ if (copy_to_user((void *)arg, &msg, size))
+ {
+ return -EFAULT;
+ }
+ return 0;
+ case UMP_FUNC_IMPORT:
+ if (size != sizeof(ump_k_import))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user*)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_import(session, (ump_k_import*) &msg);
+ if (ret)
+ {
+ return ret;
+ }
+ if (copy_to_user((void *)arg, &msg, size))
+ {
+ return -EFAULT;
+ }
+ return 0;
+ /* used only by v1 API */
+ case UMP_FUNC_ALLOCATION_FLAGS_GET:
+ if (size != sizeof(ump_k_allocation_flags))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_allocation_flags_get(session,(ump_k_allocation_flags*) &msg);
+ if (ret)
+ {
+ return ret;
+ }
+ if (copy_to_user((void *)arg, &msg, size))
+ {
+ return -EFAULT;
+ }
+ return 0;
+ case UMP_FUNC_RETAIN:
+ if (size != sizeof(ump_k_retain))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_retain(session,(ump_k_retain*) &msg);
+ if (ret)
+ {
+ return ret;
+ }
+ return 0;
+ case UMP_FUNC_RELEASE:
+ if (size != sizeof(ump_k_release))
+ {
+ return -ENOTTY;
+ }
+ if (copy_from_user(&msg, (void __user *)arg, size))
+ {
+ return -EFAULT;
+ }
+ ret = do_ump_dd_release(session,(ump_k_release*) &msg);
+ if (ret)
+ {
+ return ret;
+ }
+ return 0;
+ default:
+ /* not ours */
+ return -ENOTTY;
+ }
+ /*redundant below*/
+ return -ENOTTY;
+}
+
+
+/* Export UMP kernel space API functions */
+EXPORT_SYMBOL(ump_dd_allocate_64);
+EXPORT_SYMBOL(ump_dd_allocation_flags_get);
+EXPORT_SYMBOL(ump_dd_secure_id_get);
+EXPORT_SYMBOL(ump_dd_from_secure_id);
+EXPORT_SYMBOL(ump_dd_phys_blocks_get_64);
+EXPORT_SYMBOL(ump_dd_size_get_64);
+EXPORT_SYMBOL(ump_dd_retain);
+EXPORT_SYMBOL(ump_dd_release);
+EXPORT_SYMBOL(ump_dd_create_from_phys_blocks_64);
+#ifdef CONFIG_KDS
+EXPORT_SYMBOL(ump_dd_kds_resource_get);
+#endif
+
+/* import API */
+EXPORT_SYMBOL(ump_import_module_register);
+EXPORT_SYMBOL(ump_import_module_unregister);
+
+
+
+/* V1 API */
+EXPORT_SYMBOL(ump_dd_handle_create_from_secure_id);
+EXPORT_SYMBOL(ump_dd_phys_block_count_get);
+EXPORT_SYMBOL(ump_dd_phys_block_get);
+EXPORT_SYMBOL(ump_dd_phys_blocks_get);
+EXPORT_SYMBOL(ump_dd_size_get);
+EXPORT_SYMBOL(ump_dd_reference_add);
+EXPORT_SYMBOL(ump_dd_reference_release);
+EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks);
+
+
+/* Setup init and exit functions for this module */
+module_init(umpp_linux_initialize_module);
+module_exit(umpp_linux_cleanup_module);
+
+/* And some module informatio */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("ARM Ltd.");
+MODULE_VERSION(UMP_REV_STRING);
diff --git a/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.c b/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.c
new file mode 100755
index 0000000..9186dd0
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.c
@@ -0,0 +1,250 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013, 2016 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+#include <linux/ump.h>
+#include <linux/ump-ioctl.h>
+
+#include <linux/version.h>
+#include <linux/module.h> /* kernel module definitions */
+#include <linux/fs.h> /* file system operations */
+#include <linux/cdev.h> /* character device definitions */
+#include <linux/ioport.h> /* request_mem_region */
+#include <linux/mm.h> /* memory mananger definitions */
+#include <linux/pfn.h>
+#include <linux/highmem.h> /*kmap*/
+
+#include <linux/compat.h> /* is_compat_task */
+
+#include <common/ump_kernel_core.h>
+#include <ump_arch.h>
+#include <common/ump_kernel_priv.h>
+
+static void umpp_vm_close(struct vm_area_struct *vma)
+{
+ umpp_cpu_mapping * mapping;
+ umpp_session * session;
+ ump_dd_handle handle;
+
+ mapping = (umpp_cpu_mapping*)vma->vm_private_data;
+ UMP_ASSERT(mapping);
+
+ session = mapping->session;
+ handle = mapping->handle;
+
+ umpp_dd_remove_cpu_mapping(mapping->handle, mapping); /* will free the mapping object */
+ ump_dd_release(handle);
+}
+
+
+static const struct vm_operations_struct umpp_vm_ops = {
+ .close = umpp_vm_close
+};
+
+int umpp_phys_commit(umpp_allocation * alloc)
+{
+ uint64_t i;
+
+ /* round up to a page boundary */
+ alloc->size = (alloc->size + PAGE_SIZE - 1) & ~((uint64_t)PAGE_SIZE-1) ;
+ /* calculate number of pages */
+ alloc->blocksCount = alloc->size >> PAGE_SHIFT;
+
+ if( (sizeof(ump_dd_physical_block_64) * alloc->blocksCount) > ((size_t)-1))
+ {
+ printk(KERN_WARNING "UMP: umpp_phys_commit - trying to allocate more than possible\n");
+ return -ENOMEM;
+ }
+
+ alloc->block_array = kmalloc(sizeof(ump_dd_physical_block_64) * alloc->blocksCount, __GFP_HARDWALL | GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
+ if (NULL == alloc->block_array)
+ {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < alloc->blocksCount; i++)
+ {
+ void * mp;
+ struct page * page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD);
+ if (NULL == page)
+ {
+ break;
+ }
+
+ alloc->block_array[i].addr = PFN_PHYS(page_to_pfn(page));
+ alloc->block_array[i].size = PAGE_SIZE;
+
+ mp = kmap(page);
+ if (NULL == mp)
+ {
+ __free_page(page);
+ break;
+ }
+
+ memset(mp, 0x00, PAGE_SIZE); /* instead of __GFP_ZERO, so we can do cache maintenance */
+ ump_sync_to_memory(PFN_PHYS(page_to_pfn(page)), mp, PAGE_SIZE);
+ kunmap(page);
+ }
+
+ if (i == alloc->blocksCount)
+ {
+ return 0;
+ }
+ else
+ {
+ uint64_t j;
+ for (j = 0; j < i; j++)
+ {
+ struct page * page;
+ page = pfn_to_page(alloc->block_array[j].addr >> PAGE_SHIFT);
+ __free_page(page);
+ }
+
+ kfree(alloc->block_array);
+
+ return -ENOMEM;
+ }
+}
+
+void umpp_phys_free(umpp_allocation * alloc)
+{
+ uint64_t i;
+
+ for (i = 0; i < alloc->blocksCount; i++)
+ {
+ __free_page(pfn_to_page(alloc->block_array[i].addr >> PAGE_SHIFT));
+ }
+
+ kfree(alloc->block_array);
+}
+
+int umpp_linux_mmap(struct file * filp, struct vm_area_struct * vma)
+{
+ ump_secure_id id;
+ ump_dd_handle h;
+ size_t offset;
+ int err = -EINVAL;
+ size_t length = vma->vm_end - vma->vm_start;
+
+ umpp_cpu_mapping * map = NULL;
+ umpp_session *session = filp->private_data;
+
+ if ( 0 == length )
+ {
+ return -EINVAL;
+ }
+
+ map = kzalloc(sizeof(*map), GFP_KERNEL);
+ if (NULL == map)
+ {
+ WARN_ON(1);
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* unpack our arg */
+#if defined CONFIG_64BIT && CONFIG_64BIT
+ if (is_compat_task())
+ {
+#endif
+ id = vma->vm_pgoff >> UMP_LINUX_OFFSET_BITS_32;
+ offset = vma->vm_pgoff & UMP_LINUX_OFFSET_MASK_32;
+#if defined CONFIG_64BIT && CONFIG_64BIT
+ }
+ else
+ {
+ id = vma->vm_pgoff >> UMP_LINUX_OFFSET_BITS_64;
+ offset = vma->vm_pgoff & UMP_LINUX_OFFSET_MASK_64;
+ }
+#endif
+
+ h = ump_dd_from_secure_id(id);
+ if (UMP_DD_INVALID_MEMORY_HANDLE != h)
+ {
+ uint64_t i;
+ uint64_t block_idx;
+ uint64_t block_offset;
+ uint64_t paddr;
+ umpp_allocation * alloc;
+ uint64_t last_byte;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
+ vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_IO | VM_MIXEDMAP | VM_DONTDUMP;
+#else
+ vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_IO | VM_MIXEDMAP;
+#endif
+ vma->vm_ops = &umpp_vm_ops;
+ vma->vm_private_data = map;
+
+ alloc = (umpp_allocation*)h;
+
+ if( (alloc->flags & UMP_CONSTRAINT_UNCACHED) != 0)
+ {
+ /* cache disabled flag set, disable caching for cpu mappings */
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ }
+
+ last_byte = length + (offset << PAGE_SHIFT) - 1;
+ if (last_byte >= alloc->size || last_byte < (offset << PAGE_SHIFT))
+ {
+ goto err_out;
+ }
+
+ if (umpp_dd_find_start_block(alloc, offset << PAGE_SHIFT, &block_idx, &block_offset))
+ {
+ goto err_out;
+ }
+
+ paddr = alloc->block_array[block_idx].addr + block_offset;
+
+ for (i = 0; i < (length >> PAGE_SHIFT); i++)
+ {
+ /* check if we've overrrun the current block, if so move to the next block */
+ if (paddr >= (alloc->block_array[block_idx].addr + alloc->block_array[block_idx].size))
+ {
+ block_idx++;
+ UMP_ASSERT(block_idx < alloc->blocksCount);
+ paddr = alloc->block_array[block_idx].addr;
+ }
+
+ err = vm_insert_mixed(vma, vma->vm_start + (i << PAGE_SHIFT), paddr >> PAGE_SHIFT);
+ paddr += PAGE_SIZE;
+ }
+
+ map->vaddr_start = (void*)vma->vm_start;
+ map->nr_pages = length >> PAGE_SHIFT;
+ map->page_off = offset;
+ map->handle = h;
+ map->session = session;
+
+ umpp_dd_add_cpu_mapping(h, map);
+
+ return 0;
+
+ err_out:
+
+ ump_dd_release(h);
+ }
+
+ kfree(map);
+
+out:
+
+ return err;
+}
+
diff --git a/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.h b/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.h
new file mode 100755
index 0000000..4fbf3b2
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/linux/ump_kernel_linux_mem.h
@@ -0,0 +1,26 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2011, 2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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_LINUX_MEM_H_
+#define _UMP_KERNEL_LINUX_MEM_H_
+
+
+int umpp_linux_mmap(struct file * filp, struct vm_area_struct * vma);
+
+#endif /* _UMP_KERNEL_LINUX_MEM_H_ */
diff --git a/driver/product/kernel/drivers/base/ump/src/sconscript b/driver/product/kernel/drivers/base/ump/src/sconscript
new file mode 100755
index 0000000..b34d499
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/sconscript
@@ -0,0 +1,46 @@
+#
+# (C) COPYRIGHT 2010-2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+Import('env')
+
+# Clone the environment so changes don't affect other build files
+env_ump = env.Clone()
+
+# Source files required for UMP.
+ump_src = [
+ Glob('common/*.c'),
+ Glob('imports/*/*.c'),
+ Glob('linux/*.c'),
+]
+
+make_args = env_ump.kernel_get_config_defines(ret_list = True) + [
+ 'PLATFORM=%s' % env_ump['platform'],
+ 'MALI_UNIT_TEST=%s' % env_ump['unit'],
+]
+
+mod = env_ump.BuildKernelModule('$STATIC_LIB_PATH/ump.ko', ump_src,
+ make_args = make_args)
+env_ump.KernelObjTarget('ump', mod)
+
+# Add a dependency on kds.ko only when the build is not Android
+# Android uses sync_pt instead of Midgard KDS to achieve KDS functionality
+# Only necessary when KDS is not built into the kernel.
+#
+if env_ump['os'] != 'android':
+ if not env_ump.KernelConfigEnabled('CONFIG_KDS'):
+ env_ump.Depends(mod, '$STATIC_LIB_PATH/kds.ko')
+
+SConscript( 'imports/sconscript' )
+
diff --git a/driver/product/kernel/drivers/base/ump/src/ump_arch.h b/driver/product/kernel/drivers/base/ump/src/ump_arch.h
new file mode 100755
index 0000000..2303d56
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/src/ump_arch.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * (C) COPYRIGHT 2010-2011, 2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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_ARCH_H_
+#define _UMP_ARCH_H_
+
+#include <common/ump_kernel_core.h>
+
+/**
+ * Device specific setup.
+ * Called by the UMP core code to to host OS/device specific setup.
+ * Typical use case is device node creation for talking to user space.
+ * @return UMP_OK on success, any other value on failure
+ */
+extern ump_result umpp_device_initialize(void);
+
+/**
+ * Device specific teardown.
+ * Undo any things done by ump_device_initialize.
+ */
+extern void umpp_device_terminate(void);
+
+extern int umpp_phys_commit(umpp_allocation * alloc);
+extern void umpp_phys_free(umpp_allocation * alloc);
+
+#endif /* _UMP_ARCH_H_ */
diff --git a/driver/product/kernel/drivers/base/ump/ump_ref_drv.h b/driver/product/kernel/drivers/base/ump/ump_ref_drv.h
new file mode 100755
index 0000000..9a265fe
--- /dev/null
+++ b/driver/product/kernel/drivers/base/ump/ump_ref_drv.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+/**
+ * @file ump_ref_drv.h
+ *
+ * This file contains the link to user space part of the UMP API for usage by MALI 400 gralloc.
+ *
+ */
+
+#ifndef _UMP_REF_DRV_H_
+#define _UMP_REF_DRV_H_
+
+#include <ump/ump.h>
+
+
+#endif /* _UMP_REF_DRV_H_ */
diff --git a/driver/product/kernel/drivers/gpu/arm/Kbuild b/driver/product/kernel/drivers/gpu/arm/Kbuild
new file mode 100755
index 0000000..19c7e9a
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/arm/Kbuild
@@ -0,0 +1,17 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+obj-$(CONFIG_MALI_MIDGARD) += midgard/
diff --git a/driver/product/kernel/drivers/gpu/arm/Kconfig b/driver/product/kernel/drivers/gpu/arm/Kconfig
new file mode 100755
index 0000000..1f30eb5
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/arm/Kconfig
@@ -0,0 +1,19 @@
+#
+# (C) COPYRIGHT 2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+menu "ARM GPU Configuration"
+source "drivers/gpu/arm/midgard/Kconfig"
+endmenu
diff --git a/mali-midgard-16.0/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/Kbuild
index 9496d07..9496d07 100644..100755
--- a/mali-midgard-16.0/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/Kbuild
diff --git a/mali-midgard-16.0/Kconfig b/driver/product/kernel/drivers/gpu/arm/midgard/Kconfig
index c1acaf0..c1acaf0 100644..100755
--- a/mali-midgard-16.0/Kconfig
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/Kconfig
diff --git a/mali-midgard-16.0/Makefile b/driver/product/kernel/drivers/gpu/arm/midgard/Makefile
index e1625e6..e1625e6 100644..100755
--- a/mali-midgard-16.0/Makefile
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/Makefile
diff --git a/mali-midgard-16.0/Makefile.kbase b/driver/product/kernel/drivers/gpu/arm/midgard/Makefile.kbase
index 2bef9c2..2bef9c2 100644..100755
--- a/mali-midgard-16.0/Makefile.kbase
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/Makefile.kbase
diff --git a/mali-midgard-16.0/backend/gpu/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/Kbuild
index df4e796..df4e796 100644..100755
--- a/mali-midgard-16.0/backend/gpu/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/Kbuild
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_backend_config.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_backend_config.h
index c8ae87e..c8ae87e 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_backend_config.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_backend_config.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_cache_policy_backend.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_cache_policy_backend.c
index fef9a2c..fef9a2c 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_cache_policy_backend.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_cache_policy_backend.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_cache_policy_backend.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_cache_policy_backend.h
index fe98691..fe98691 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_cache_policy_backend.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_cache_policy_backend.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_debug_job_fault_backend.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_debug_job_fault_backend.c
index 7851ea6..7851ea6 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_debug_job_fault_backend.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_debug_job_fault_backend.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_devfreq.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c
index 28b4f1d..28b4f1d 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_devfreq.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_devfreq.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.h
index c0bf8b1..c0bf8b1 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_devfreq.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_device_hw.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_device_hw.c
index dcdf15c..dcdf15c 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_device_hw.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_device_hw.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_device_internal.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_device_internal.h
index 5b20445..5b20445 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_device_internal.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_device_internal.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_gpu.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_gpu.c
index d578fd7..d578fd7 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_gpu.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_gpu.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_gpuprops_backend.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_gpuprops_backend.c
index b395325..b395325 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_gpuprops_backend.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_gpuprops_backend.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_instr_backend.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_backend.c
index 7ad309e..7ad309e 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_instr_backend.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_backend.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_instr_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_defs.h
index 4794672..4794672 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_instr_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_defs.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_instr_internal.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_internal.h
index e96aeae..e96aeae 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_instr_internal.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_instr_internal.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_irq_internal.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_internal.h
index 8781561..8781561 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_irq_internal.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_internal.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_irq_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c
index 8416b80..8416b80 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_irq_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_as.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_as.c
index 202dcfa..202dcfa 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_as.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_as.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_defs.h
index 08a7400..08a7400 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_defs.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_hw.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_hw.c
index 7856378..7856378 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_hw.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_hw.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_internal.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_internal.h
index 1f382b3..1f382b3 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_internal.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_internal.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_rb.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_rb.c
index d4ed3d4..d4ed3d4 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_rb.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_rb.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_rb.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_rb.h
index 1e0e05a..1e0e05a 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_jm_rb.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_jm_rb.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_js_affinity.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_affinity.c
index 54d8ddd..54d8ddd 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_js_affinity.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_affinity.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_js_affinity.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_affinity.h
index 35d9781..35d9781 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_js_affinity.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_affinity.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_js_backend.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_backend.c
index a8c1af2..a8c1af2 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_js_backend.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_backend.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_js_internal.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_internal.h
index 3f53779..3f53779 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_js_internal.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_js_internal.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_mmu_hw_direct.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c
index 4e5a74f..4e5a74f 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_mmu_hw_direct.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_mmu_hw_direct.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.h
index c02253c..c02253c 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_mmu_hw_direct.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_always_on.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_always_on.c
index 0614348..0614348 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_always_on.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_always_on.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_always_on.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_always_on.h
index f9d244b..f9d244b 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_always_on.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_always_on.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_backend.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_backend.c
index 146fd48..146fd48 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_backend.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_backend.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca.c
index e8cd8cb..e8cd8cb 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca.h
index ee9e751..ee9e751 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca_fixed.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca_fixed.c
index 864612d..864612d 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca_fixed.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca_fixed.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca_fixed.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca_fixed.h
index a763155..a763155 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_ca_fixed.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_ca_fixed.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_coarse_demand.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_coarse_demand.c
index f891fa2..f891fa2 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_coarse_demand.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_coarse_demand.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_coarse_demand.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_coarse_demand.h
index 749d305..749d305 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_coarse_demand.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_coarse_demand.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_defs.h
index 632ef12..632ef12 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_defs.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_demand.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_demand.c
index 81322fd..81322fd 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_demand.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_demand.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_demand.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_demand.h
index c0c84b6..c0c84b6 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_demand.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_demand.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_driver.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c
index 55763a8..55763a8 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_driver.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_internal.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h
index 58f615d..58f615d 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_internal.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_metrics.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_metrics.c
index 7613e1d..7613e1d 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_metrics.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_metrics.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_policy.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c
index 075f020..075f020 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_policy.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_policy.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.h
index 611a90e..611a90e 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_pm_policy.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.h
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_time.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_time.c
index d992989..d992989 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_time.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_time.c
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_time.h b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_time.h
index 35088ab..35088ab 100644..100755
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_time.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_time.h
diff --git a/mali-midgard-16.0/docs/Doxyfile b/driver/product/kernel/drivers/gpu/arm/midgard/docs/Doxyfile
index 35ff2f1..35ff2f1 100644..100755
--- a/mali-midgard-16.0/docs/Doxyfile
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/docs/Doxyfile
diff --git a/mali-midgard-16.0/docs/policy_operation_diagram.dot b/driver/product/kernel/drivers/gpu/arm/midgard/docs/policy_operation_diagram.dot
index 7ae05c2..7ae05c2 100644..100755
--- a/mali-midgard-16.0/docs/policy_operation_diagram.dot
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/docs/policy_operation_diagram.dot
diff --git a/mali-midgard-16.0/docs/policy_overview.dot b/driver/product/kernel/drivers/gpu/arm/midgard/docs/policy_overview.dot
index 159b993..159b993 100644..100755
--- a/mali-midgard-16.0/docs/policy_overview.dot
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/docs/policy_overview.dot
diff --git a/mali-midgard-16.0/ipa/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/Kbuild
index 7551f9e..7551f9e 100644..100755
--- a/mali-midgard-16.0/ipa/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/Kbuild
diff --git a/mali-midgard-16.0/ipa/mali_kbase_ipa.c b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa.c
index dd0f1d6..dd0f1d6 100644..100755
--- a/mali-midgard-16.0/ipa/mali_kbase_ipa.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa.c
diff --git a/mali-midgard-16.0/ipa/mali_kbase_ipa.h b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa.h
index 67e0270..67e0270 100644..100755
--- a/mali-midgard-16.0/ipa/mali_kbase_ipa.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa.h
diff --git a/mali-midgard-16.0/ipa/mali_kbase_ipa_generic.c b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa_generic.c
index 18fb2b2..18fb2b2 100644..100755
--- a/mali-midgard-16.0/ipa/mali_kbase_ipa_generic.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/ipa/mali_kbase_ipa_generic.c
diff --git a/mali-midgard-16.0/mali_base_hwconfig_features.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_hwconfig_features.h
index 239582e..239582e 100644..100755
--- a/mali-midgard-16.0/mali_base_hwconfig_features.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_hwconfig_features.h
diff --git a/mali-midgard-16.0/mali_base_hwconfig_issues.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_hwconfig_issues.h
index e1e43a1..e1e43a1 100644..100755
--- a/mali-midgard-16.0/mali_base_hwconfig_issues.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_hwconfig_issues.h
diff --git a/mali-midgard-16.0/mali_base_kernel.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_kernel.h
index 0d2ac95..0d2ac95 100644..100755
--- a/mali-midgard-16.0/mali_base_kernel.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_kernel.h
diff --git a/mali-midgard-16.0/mali_base_mem_priv.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_mem_priv.h
index 4a98a72..4a98a72 100644..100755
--- a/mali-midgard-16.0/mali_base_mem_priv.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_mem_priv.h
diff --git a/mali-midgard-16.0/mali_base_vendor_specific_func.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_vendor_specific_func.h
index be454a2..be454a2 100644..100755
--- a/mali-midgard-16.0/mali_base_vendor_specific_func.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_base_vendor_specific_func.h
diff --git a/mali-midgard-16.0/mali_kbase.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h
index b5a771f..b5a771f 100644..100755
--- a/mali-midgard-16.0/mali_kbase.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.h
diff --git a/mali-midgard-16.0/mali_kbase_10969_workaround.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_10969_workaround.c
index 933aa28..933aa28 100644..100755
--- a/mali-midgard-16.0/mali_kbase_10969_workaround.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_10969_workaround.c
diff --git a/mali-midgard-16.0/mali_kbase_10969_workaround.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_10969_workaround.h
index 099a298..099a298 100644..100755
--- a/mali-midgard-16.0/mali_kbase_10969_workaround.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_10969_workaround.h
diff --git a/mali-midgard-16.0/mali_kbase_as_fault_debugfs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_as_fault_debugfs.c
index f910fe9..f910fe9 100644..100755
--- a/mali-midgard-16.0/mali_kbase_as_fault_debugfs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_as_fault_debugfs.c
diff --git a/mali-midgard-16.0/mali_kbase_as_fault_debugfs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_as_fault_debugfs.h
index 3ed2248..3ed2248 100644..100755
--- a/mali-midgard-16.0/mali_kbase_as_fault_debugfs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_as_fault_debugfs.h
diff --git a/mali-midgard-16.0/mali_kbase_cache_policy.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_cache_policy.c
index c67b3e9..c67b3e9 100644..100755
--- a/mali-midgard-16.0/mali_kbase_cache_policy.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_cache_policy.c
diff --git a/mali-midgard-16.0/mali_kbase_cache_policy.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_cache_policy.h
index 0c18bdb..0c18bdb 100644..100755
--- a/mali-midgard-16.0/mali_kbase_cache_policy.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_cache_policy.h
diff --git a/mali-midgard-16.0/mali_kbase_config.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config.c
index fb615ae..fb615ae 100644..100755
--- a/mali-midgard-16.0/mali_kbase_config.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config.c
diff --git a/mali-midgard-16.0/mali_kbase_config.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config.h
index 356d52b..356d52b 100644..100755
--- a/mali-midgard-16.0/mali_kbase_config.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config.h
diff --git a/mali-midgard-16.0/mali_kbase_config_defaults.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h
index f982aa5..f982aa5 100644..100755
--- a/mali-midgard-16.0/mali_kbase_config_defaults.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_config_defaults.h
diff --git a/mali-midgard-16.0/mali_kbase_context.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c
index 1401380..1401380 100644..100755
--- a/mali-midgard-16.0/mali_kbase_context.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.c
diff --git a/mali-midgard-16.0/mali_kbase_context.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.h
index a3f5bb0..a3f5bb0 100644..100755
--- a/mali-midgard-16.0/mali_kbase_context.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_context.h
diff --git a/mali-midgard-16.0/mali_kbase_core_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
index 4e95633..4e95633 100644..100755
--- a/mali-midgard-16.0/mali_kbase_core_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
diff --git a/mali-midgard-16.0/mali_kbase_debug.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug.c
index fb57ac2..fb57ac2 100644..100755
--- a/mali-midgard-16.0/mali_kbase_debug.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug.c
diff --git a/mali-midgard-16.0/mali_kbase_debug.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug.h
index 5fff289..5fff289 100644..100755
--- a/mali-midgard-16.0/mali_kbase_debug.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug.h
diff --git a/mali-midgard-16.0/mali_kbase_debug_job_fault.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_job_fault.c
index f29430d..f29430d 100644..100755
--- a/mali-midgard-16.0/mali_kbase_debug_job_fault.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_job_fault.c
diff --git a/mali-midgard-16.0/mali_kbase_debug_job_fault.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_job_fault.h
index a2bf898..a2bf898 100644..100755
--- a/mali-midgard-16.0/mali_kbase_debug_job_fault.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_job_fault.h
diff --git a/mali-midgard-16.0/mali_kbase_debug_mem_view.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c
index dc75c86..dc75c86 100644..100755
--- a/mali-midgard-16.0/mali_kbase_debug_mem_view.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c
diff --git a/mali-midgard-16.0/mali_kbase_debug_mem_view.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.h
index 20ab51a..20ab51a 100644..100755
--- a/mali-midgard-16.0/mali_kbase_debug_mem_view.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.h
diff --git a/mali-midgard-16.0/mali_kbase_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
index 290d460..290d460 100644..100755
--- a/mali-midgard-16.0/mali_kbase_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
diff --git a/mali-midgard-16.0/mali_kbase_device.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c
index 7484eec..7484eec 100644..100755
--- a/mali-midgard-16.0/mali_kbase_device.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c
diff --git a/mali-midgard-16.0/mali_kbase_disjoint_events.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_disjoint_events.c
index f70bccc..f70bccc 100644..100755
--- a/mali-midgard-16.0/mali_kbase_disjoint_events.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_disjoint_events.c
diff --git a/mali-midgard-16.0/mali_kbase_dma_fence.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_dma_fence.c
index 97bb6c5..97bb6c5 100644..100755
--- a/mali-midgard-16.0/mali_kbase_dma_fence.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_dma_fence.c
diff --git a/mali-midgard-16.0/mali_kbase_dma_fence.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_dma_fence.h
index 3b0a69b..3b0a69b 100644..100755
--- a/mali-midgard-16.0/mali_kbase_dma_fence.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_dma_fence.h
diff --git a/mali-midgard-16.0/mali_kbase_event.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_event.c
index 1881486..1881486 100644..100755
--- a/mali-midgard-16.0/mali_kbase_event.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_event.c
diff --git a/mali-midgard-16.0/mali_kbase_gator.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator.h
index ce65b55..ce65b55 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator.h
diff --git a/mali-midgard-16.0/mali_kbase_gator_api.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_api.c
index 7c3c5f3..7c3c5f3 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator_api.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_api.c
diff --git a/mali-midgard-16.0/mali_kbase_gator_api.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_api.h
index ef9ac0f..ef9ac0f 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator_api.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_api.h
diff --git a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names.h
index ce8e424..ce8e424 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names.h
diff --git a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names_thex.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_thex.h
index bcceef4..bcceef4 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names_thex.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_thex.h
diff --git a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names_tmix.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_tmix.h
index 5ea0677..5ea0677 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names_tmix.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_tmix.h
diff --git a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names_tsix.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_tsix.h
index 7ff7009..7ff7009 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gator_hwcnt_names_tsix.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gator_hwcnt_names_tsix.h
diff --git a/mali-midgard-16.0/mali_kbase_gpu_id.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_id.h
index 5c2367f..5c2367f 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gpu_id.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_id.h
diff --git a/mali-midgard-16.0/mali_kbase_gpu_memory_debugfs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_memory_debugfs.c
index 6df0a1c..6df0a1c 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gpu_memory_debugfs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_memory_debugfs.c
diff --git a/mali-midgard-16.0/mali_kbase_gpu_memory_debugfs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_memory_debugfs.h
index 7045693..7045693 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gpu_memory_debugfs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpu_memory_debugfs.h
diff --git a/mali-midgard-16.0/mali_kbase_gpuprops.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c
index ceba27c..ceba27c 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gpuprops.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.c
diff --git a/mali-midgard-16.0/mali_kbase_gpuprops.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.h
index f3c95cc..f3c95cc 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gpuprops.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops.h
diff --git a/mali-midgard-16.0/mali_kbase_gpuprops_types.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops_types.h
index 920cf77..920cf77 100644..100755
--- a/mali-midgard-16.0/mali_kbase_gpuprops_types.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_gpuprops_types.h
diff --git a/mali-midgard-16.0/mali_kbase_hw.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hw.c
index 51a31fb..51a31fb 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hw.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hw.c
diff --git a/mali-midgard-16.0/mali_kbase_hw.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hw.h
index fce7d29..fce7d29 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hw.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hw.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_backend.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_backend.h
index b09be99..b09be99 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_backend.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_backend.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_defs.h
index 0acf297..0acf297 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_defs.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_gpuprops.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_gpuprops.h
index cf8a813..cf8a813 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_gpuprops.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_gpuprops.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_instr.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_instr.h
index 5de2b75..5de2b75 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_instr.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_instr.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_jm.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_jm.h
index 821b68a..821b68a 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_jm.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_jm.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_pm.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h
index 71c7d49..71c7d49 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_pm.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h
diff --git a/mali-midgard-16.0/mali_kbase_hwaccess_time.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_time.h
index 89d26ea..89d26ea 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwaccess_time.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_time.h
diff --git a/mali-midgard-16.0/mali_kbase_hwcnt_reader.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwcnt_reader.h
index cf7bf1b..cf7bf1b 100644..100755
--- a/mali-midgard-16.0/mali_kbase_hwcnt_reader.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_hwcnt_reader.h
diff --git a/mali-midgard-16.0/mali_kbase_jd.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd.c
index 596b047..596b047 100644..100755
--- a/mali-midgard-16.0/mali_kbase_jd.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd.c
diff --git a/mali-midgard-16.0/mali_kbase_jd_debugfs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd_debugfs.c
index 47ea426..47ea426 100644..100755
--- a/mali-midgard-16.0/mali_kbase_jd_debugfs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd_debugfs.c
diff --git a/mali-midgard-16.0/mali_kbase_jd_debugfs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd_debugfs.h
index 0935f1d..0935f1d 100644..100755
--- a/mali-midgard-16.0/mali_kbase_jd_debugfs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jd_debugfs.h
diff --git a/mali-midgard-16.0/mali_kbase_jm.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jm.c
index 0c5c6a6..0c5c6a6 100644..100755
--- a/mali-midgard-16.0/mali_kbase_jm.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jm.c
diff --git a/mali-midgard-16.0/mali_kbase_jm.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jm.h
index a74ee24..a74ee24 100644..100755
--- a/mali-midgard-16.0/mali_kbase_jm.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_jm.h
diff --git a/mali-midgard-16.0/mali_kbase_js.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js.c
index 3a675a1..3a675a1 100644..100755
--- a/mali-midgard-16.0/mali_kbase_js.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js.c
diff --git a/mali-midgard-16.0/mali_kbase_js.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js.h
index 76172f7..76172f7 100644..100755
--- a/mali-midgard-16.0/mali_kbase_js.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js.h
diff --git a/mali-midgard-16.0/mali_kbase_js_ctx_attr.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_ctx_attr.c
index 321506a..321506a 100644..100755
--- a/mali-midgard-16.0/mali_kbase_js_ctx_attr.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_ctx_attr.c
diff --git a/mali-midgard-16.0/mali_kbase_js_ctx_attr.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_ctx_attr.h
index ce91833..ce91833 100644..100755
--- a/mali-midgard-16.0/mali_kbase_js_ctx_attr.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_ctx_attr.h
diff --git a/mali-midgard-16.0/mali_kbase_js_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_defs.h
index 119344c..119344c 100644..100755
--- a/mali-midgard-16.0/mali_kbase_js_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_js_defs.h
diff --git a/mali-midgard-16.0/mali_kbase_linux.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_linux.h
index 6d1e61f..6d1e61f 100644..100755
--- a/mali-midgard-16.0/mali_kbase_linux.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_linux.h
diff --git a/mali-midgard-16.0/mali_kbase_mem.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
index 20a18a9..20a18a9 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
diff --git a/mali-midgard-16.0/mali_kbase_mem.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
index fb4ca4d..fb4ca4d 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
diff --git a/mali-midgard-16.0/mali_kbase_mem_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
index 503a5ec..503a5ec 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
diff --git a/mali-midgard-16.0/mali_kbase_mem_linux.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.h
index 2053a47..2053a47 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_linux.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.h
diff --git a/mali-midgard-16.0/mali_kbase_mem_lowlevel.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_lowlevel.h
index 441180b..441180b 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_lowlevel.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_lowlevel.h
diff --git a/mali-midgard-16.0/mali_kbase_mem_pool.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
index b5a7b8c..b5a7b8c 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_pool.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
diff --git a/mali-midgard-16.0/mali_kbase_mem_pool_debugfs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool_debugfs.c
index 585fba0..585fba0 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_pool_debugfs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool_debugfs.c
diff --git a/mali-midgard-16.0/mali_kbase_mem_pool_debugfs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool_debugfs.h
index 1442854..1442854 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_pool_debugfs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool_debugfs.h
diff --git a/mali-midgard-16.0/mali_kbase_mem_profile_debugfs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs.c
index 092da9a..092da9a 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_profile_debugfs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs.c
diff --git a/mali-midgard-16.0/mali_kbase_mem_profile_debugfs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs.h
index a1dc2e0..a1dc2e0 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_profile_debugfs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs.h
diff --git a/mali-midgard-16.0/mali_kbase_mem_profile_debugfs_buf_size.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs_buf_size.h
index 82f0702..82f0702 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mem_profile_debugfs_buf_size.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_profile_debugfs_buf_size.h
diff --git a/mali-midgard-16.0/mali_kbase_mmu.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu.c
index 0329dfd..0329dfd 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mmu.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu.c
diff --git a/mali-midgard-16.0/mali_kbase_mmu_hw.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_hw.h
index 986e959..986e959 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mmu_hw.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_hw.h
diff --git a/mali-midgard-16.0/mali_kbase_mmu_mode.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode.h
index 2449c60..2449c60 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mmu_mode.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode.h
diff --git a/mali-midgard-16.0/mali_kbase_mmu_mode_aarch64.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode_aarch64.c
index 791f3ed..791f3ed 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mmu_mode_aarch64.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode_aarch64.c
diff --git a/mali-midgard-16.0/mali_kbase_mmu_mode_lpae.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode_lpae.c
index 683cabb..683cabb 100644..100755
--- a/mali-midgard-16.0/mali_kbase_mmu_mode_lpae.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mmu_mode_lpae.c
diff --git a/mali-midgard-16.0/mali_kbase_platform_fake.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_platform_fake.c
index 1a44957..1a44957 100644..100755
--- a/mali-midgard-16.0/mali_kbase_platform_fake.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_platform_fake.c
diff --git a/mali-midgard-16.0/mali_kbase_pm.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_pm.c
index 97d5434..97d5434 100644..100755
--- a/mali-midgard-16.0/mali_kbase_pm.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_pm.c
diff --git a/mali-midgard-16.0/mali_kbase_pm.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_pm.h
index 37fa247..37fa247 100644..100755
--- a/mali-midgard-16.0/mali_kbase_pm.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_pm.h
diff --git a/mali-midgard-16.0/mali_kbase_profiling_gator_api.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_profiling_gator_api.h
index 7fb674e..7fb674e 100644..100755
--- a/mali-midgard-16.0/mali_kbase_profiling_gator_api.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_profiling_gator_api.h
diff --git a/mali-midgard-16.0/mali_kbase_regs_history_debugfs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_regs_history_debugfs.c
index c970650..c970650 100644..100755
--- a/mali-midgard-16.0/mali_kbase_regs_history_debugfs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_regs_history_debugfs.c
diff --git a/mali-midgard-16.0/mali_kbase_regs_history_debugfs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_regs_history_debugfs.h
index f108370..f108370 100644..100755
--- a/mali-midgard-16.0/mali_kbase_regs_history_debugfs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_regs_history_debugfs.h
diff --git a/mali-midgard-16.0/mali_kbase_replay.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_replay.c
index 84aa331..84aa331 100644..100755
--- a/mali-midgard-16.0/mali_kbase_replay.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_replay.c
diff --git a/mali-midgard-16.0/mali_kbase_smc.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c
index 43175c8..43175c8 100644..100755
--- a/mali-midgard-16.0/mali_kbase_smc.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.c
diff --git a/mali-midgard-16.0/mali_kbase_smc.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.h
index 9bff3d2..9bff3d2 100644..100755
--- a/mali-midgard-16.0/mali_kbase_smc.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_smc.h
diff --git a/mali-midgard-16.0/mali_kbase_softjobs.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c
index 2997e6f..2997e6f 100644..100755
--- a/mali-midgard-16.0/mali_kbase_softjobs.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_softjobs.c
diff --git a/mali-midgard-16.0/mali_kbase_strings.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_strings.c
index c98762c..c98762c 100644..100755
--- a/mali-midgard-16.0/mali_kbase_strings.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_strings.c
diff --git a/mali-midgard-16.0/mali_kbase_strings.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_strings.h
index 41b8fdb..41b8fdb 100644..100755
--- a/mali-midgard-16.0/mali_kbase_strings.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_strings.h
diff --git a/mali-midgard-16.0/mali_kbase_sync.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.c
index 97e301d..97e301d 100644..100755
--- a/mali-midgard-16.0/mali_kbase_sync.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.c
diff --git a/mali-midgard-16.0/mali_kbase_sync.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.h
index 07e5158..07e5158 100644..100755
--- a/mali-midgard-16.0/mali_kbase_sync.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync.h
diff --git a/mali-midgard-16.0/mali_kbase_sync_user.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync_user.c
index b9baa91..b9baa91 100644..100755
--- a/mali-midgard-16.0/mali_kbase_sync_user.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_sync_user.c
diff --git a/mali-midgard-16.0/mali_kbase_tlstream.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
index 408b9d9..408b9d9 100644..100755
--- a/mali-midgard-16.0/mali_kbase_tlstream.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
diff --git a/mali-midgard-16.0/mali_kbase_tlstream.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.h
index 7349ab2..7349ab2 100644..100755
--- a/mali-midgard-16.0/mali_kbase_tlstream.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.h
diff --git a/mali-midgard-16.0/mali_kbase_trace_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_defs.h
index e2e0544..e2e0544 100644..100755
--- a/mali-midgard-16.0/mali_kbase_trace_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_defs.h
diff --git a/mali-midgard-16.0/mali_kbase_trace_timeline.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline.c
index 5830e87..5830e87 100644..100755
--- a/mali-midgard-16.0/mali_kbase_trace_timeline.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline.c
diff --git a/mali-midgard-16.0/mali_kbase_trace_timeline.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline.h
index 619072f..619072f 100644..100755
--- a/mali-midgard-16.0/mali_kbase_trace_timeline.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline.h
diff --git a/mali-midgard-16.0/mali_kbase_trace_timeline_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline_defs.h
index 156a95a..156a95a 100644..100755
--- a/mali-midgard-16.0/mali_kbase_trace_timeline_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_trace_timeline_defs.h
diff --git a/mali-midgard-16.0/mali_kbase_uku.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_uku.h
index baa9296..baa9296 100644..100755
--- a/mali-midgard-16.0/mali_kbase_uku.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_uku.h
diff --git a/mali-midgard-16.0/mali_kbase_utility.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_utility.c
index be474ff..be474ff 100644..100755
--- a/mali-midgard-16.0/mali_kbase_utility.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_utility.c
diff --git a/mali-midgard-16.0/mali_kbase_utility.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_utility.h
index fd7252d..fd7252d 100644..100755
--- a/mali-midgard-16.0/mali_kbase_utility.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_utility.h
diff --git a/mali-midgard-16.0/mali_kbase_vinstr.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_vinstr.c
index 7f7efc8..7f7efc8 100644..100755
--- a/mali-midgard-16.0/mali_kbase_vinstr.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_vinstr.c
diff --git a/mali-midgard-16.0/mali_kbase_vinstr.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_vinstr.h
index 6207d25..6207d25 100644..100755
--- a/mali-midgard-16.0/mali_kbase_vinstr.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_vinstr.h
diff --git a/mali-midgard-16.0/mali_linux_kbase_trace.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_linux_kbase_trace.h
index 5d6b402..5d6b402 100644..100755
--- a/mali-midgard-16.0/mali_linux_kbase_trace.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_linux_kbase_trace.h
diff --git a/mali-midgard-16.0/mali_linux_trace.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_linux_trace.h
index 2be06a5..2be06a5 100644..100755
--- a/mali-midgard-16.0/mali_linux_trace.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_linux_trace.h
diff --git a/mali-midgard-16.0/mali_malisw.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_malisw.h
index 9945293..9945293 100644..100755
--- a/mali-midgard-16.0/mali_malisw.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_malisw.h
diff --git a/mali-midgard-16.0/mali_midg_coherency.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_midg_coherency.h
index a509cbd..a509cbd 100644..100755
--- a/mali-midgard-16.0/mali_midg_coherency.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_midg_coherency.h
diff --git a/mali-midgard-16.0/mali_midg_regmap.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_midg_regmap.h
index 2d8231d..2d8231d 100644..100755
--- a/mali-midgard-16.0/mali_midg_regmap.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_midg_regmap.h
diff --git a/mali-midgard-16.0/mali_timeline.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_timeline.h
index bd5f661..bd5f661 100644..100755
--- a/mali-midgard-16.0/mali_timeline.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_timeline.h
diff --git a/mali-midgard-16.0/mali_uk.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_uk.h
index 841d03f..841d03f 100644..100755
--- a/mali-midgard-16.0/mali_uk.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_uk.h
diff --git a/mali-midgard-16.0/platform/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/platform/Kbuild
index 558657b..558657b 100644..100755
--- a/mali-midgard-16.0/platform/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/Kbuild
diff --git a/mali-midgard-16.0/platform/Kconfig b/driver/product/kernel/drivers/gpu/arm/midgard/platform/Kconfig
index 8fb4e91..8fb4e91 100644..100755
--- a/mali-midgard-16.0/platform/Kconfig
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/Kconfig
diff --git a/mali-midgard-16.0/platform/devicetree/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/Kbuild
index b5a49f3..b5a49f3 100644..100755
--- a/mali-midgard-16.0/platform/devicetree/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/Kbuild
diff --git a/mali-midgard-16.0/platform/devicetree/mali_kbase_config_devicetree.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_devicetree.c
index b2a7c93..b2a7c93 100644..100755
--- a/mali-midgard-16.0/platform/devicetree/mali_kbase_config_devicetree.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_devicetree.c
diff --git a/mali-midgard-16.0/platform/devicetree/mali_kbase_config_platform.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h
index 34f6d57..34f6d57 100644..100755
--- a/mali-midgard-16.0/platform/devicetree/mali_kbase_config_platform.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_config_platform.h
diff --git a/mali-midgard-16.0/platform/devicetree/mali_kbase_runtime_pm.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c
index aa4376a..aa4376a 100644..100755
--- a/mali-midgard-16.0/platform/devicetree/mali_kbase_runtime_pm.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c
diff --git a/mali-midgard-16.0/platform/juno_soc/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/Kbuild
index 0449442..0449442 100644..100755
--- a/mali-midgard-16.0/platform/juno_soc/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/Kbuild
diff --git a/mali-midgard-16.0/platform/juno_soc/juno_mali_opp.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/juno_mali_opp.c
index ccfd8cc..ccfd8cc 100644..100755
--- a/mali-midgard-16.0/platform/juno_soc/juno_mali_opp.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/juno_mali_opp.c
diff --git a/mali-midgard-16.0/platform/juno_soc/mali_kbase_config_juno_soc.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_juno_soc.c
index d237a38..d237a38 100644..100755
--- a/mali-midgard-16.0/platform/juno_soc/mali_kbase_config_juno_soc.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_juno_soc.c
diff --git a/mali-midgard-16.0/platform/juno_soc/mali_kbase_config_platform.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_platform.h
index ab29e9d..ab29e9d 100644..100755
--- a/mali-midgard-16.0/platform/juno_soc/mali_kbase_config_platform.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/juno_soc/mali_kbase_config_platform.h
diff --git a/mali-midgard-16.0/platform/mali_kbase_platform_common.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/mali_kbase_platform_common.h
index 7cb3be7..7cb3be7 100644..100755
--- a/mali-midgard-16.0/platform/mali_kbase_platform_common.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/mali_kbase_platform_common.h
diff --git a/mali-midgard-16.0/platform/mali_kbase_platform_fake.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/mali_kbase_platform_fake.h
index 01f9dfc..01f9dfc 100644..100755
--- a/mali-midgard-16.0/platform/mali_kbase_platform_fake.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/mali_kbase_platform_fake.h
diff --git a/mali-midgard-16.0/platform/vexpress/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/Kbuild
index 084a156..084a156 100644..100755
--- a/mali-midgard-16.0/platform/vexpress/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/Kbuild
diff --git a/mali-midgard-16.0/platform/vexpress/mali_kbase_config_platform.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_config_platform.h
index dc4471b..dc4471b 100644..100755
--- a/mali-midgard-16.0/platform/vexpress/mali_kbase_config_platform.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_config_platform.h
diff --git a/mali-midgard-16.0/platform/vexpress/mali_kbase_config_vexpress.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_config_vexpress.c
index 15ce2bc..15ce2bc 100644..100755
--- a/mali-midgard-16.0/platform/vexpress/mali_kbase_config_vexpress.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_config_vexpress.c
diff --git a/mali-midgard-16.0/platform/vexpress/mali_kbase_cpu_vexpress.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_cpu_vexpress.c
index 4665f98..4665f98 100644..100755
--- a/mali-midgard-16.0/platform/vexpress/mali_kbase_cpu_vexpress.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_cpu_vexpress.c
diff --git a/mali-midgard-16.0/platform/vexpress/mali_kbase_cpu_vexpress.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_cpu_vexpress.h
index da86569..da86569 100644..100755
--- a/mali-midgard-16.0/platform/vexpress/mali_kbase_cpu_vexpress.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress/mali_kbase_cpu_vexpress.h
diff --git a/mali-midgard-16.0/platform/vexpress_1xv7_a57/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/Kbuild
index d9bfabc..d9bfabc 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_1xv7_a57/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/Kbuild
diff --git a/mali-midgard-16.0/platform/vexpress_1xv7_a57/mali_kbase_config_platform.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/mali_kbase_config_platform.h
index b0490ca..b0490ca 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_1xv7_a57/mali_kbase_config_platform.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/mali_kbase_config_platform.h
diff --git a/mali-midgard-16.0/platform/vexpress_1xv7_a57/mali_kbase_config_vexpress.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/mali_kbase_config_vexpress.c
index 3ff0930..3ff0930 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_1xv7_a57/mali_kbase_config_vexpress.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_1xv7_a57/mali_kbase_config_vexpress.c
diff --git a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/Kbuild b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/Kbuild
index 0cb41ce..0cb41ce 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/Kbuild
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/Kbuild
diff --git a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_platform.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_platform.h
index 22ffccb..22ffccb 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_platform.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_platform.h
diff --git a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_vexpress.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_vexpress.c
index 76ffe4a..76ffe4a 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_vexpress.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_config_vexpress.c
diff --git a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.c b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.c
index 816dff4..816dff4 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.c
diff --git a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.h
index 23647cc..23647cc 100644..100755
--- a/mali-midgard-16.0/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform/vexpress_6xvirtex7_10mhz/mali_kbase_cpu_vexpress.h
diff --git a/mali-midgard-16.0/platform_dummy/mali_ukk_os.h b/driver/product/kernel/drivers/gpu/arm/midgard/platform_dummy/mali_ukk_os.h
index 5fa9b39..5fa9b39 100644..100755
--- a/mali-midgard-16.0/platform_dummy/mali_ukk_os.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/platform_dummy/mali_ukk_os.h
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/sconscript b/driver/product/kernel/drivers/gpu/arm/midgard/sconscript
new file mode 100755
index 0000000..137d532
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/sconscript
@@ -0,0 +1,86 @@
+#
+# (C) COPYRIGHT 2010-2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+import sys
+Import('env')
+
+if Glob('tests/sconscript'):
+ SConscript( 'tests/sconscript' )
+
+mock_test = 0
+
+# Fake platform is a transient solution for GPL drivers running in kernel that does not provide configuration via platform data.
+# For such kernels fake_platform_device should be set to 1. For kernels providing platform data fake_platform_device should be set to 0.
+if env['platform_config']=='devicetree':
+ fake_platform_device = 0
+else:
+ fake_platform_device = 1
+
+# Source files required for kbase.
+kbase_src = [
+ Glob('*.c'),
+ Glob('backend/*/*.c'),
+ Glob('internal/*/*.c'),
+ Glob('ipa/*.c'),
+ Glob('platform/%s/*.c' % env['platform_config']),
+]
+
+if Glob('#kernel/drivers/gpu/arm/midgard/tests/internal/src/mock') and env['unit'] == '1':
+ kbase_src += [Glob('#kernel/drivers/gpu/arm/midgard/tests/internal/src/mock/*.c')]
+ mock_test = 1
+
+# we need platform config for GPL version using fake platform
+if fake_platform_device==1:
+ # Check if we are compiling for PBX
+ if env.KernelConfigEnabled("CONFIG_MACH_REALVIEW_PBX") and \
+ env["platform_config"] in {"vexpress", "vexpress_6xvirtex7_10mhz"}:
+ sys.stderr.write("WARNING: Building for a PBX kernel but with platform_config=vexpress*\n")
+ # if the file platform config file is in the tpip directory then use that, otherwise use the default config directory
+ if Glob('#kernel/drivers/gpu/arm/midgard/config/tpip/*%s.c' % (env['platform_config'])):
+ kbase_src += Glob('#kernel/drivers/gpu/arm/midgard/config/tpip/*%s.c' % (env['platform_config']))
+ else:
+ kbase_src += Glob('#kernel/drivers/gpu/arm/midgard/config/*%s.c' % (env['platform_config']))
+
+make_args = env.kernel_get_config_defines(ret_list = True,
+ fake = fake_platform_device) + [
+ 'PLATFORM=%s' % env['platform'],
+ 'MALI_ERROR_INJECT_ON=%s' % env['error_inject'],
+ 'MALI_KERNEL_TEST_API=%s' % env['unit'],
+ 'MALI_UNIT_TEST=%s' % env['unit'],
+ 'MALI_RELEASE_NAME=%s' % env['mali_release_name'],
+ 'MALI_MOCK_TEST=%s' % mock_test,
+ 'MALI_CUSTOMER_RELEASE=%s' % env['release'],
+ 'MALI_INSTRUMENTATION_LEVEL=%s' % env['instr'],
+ 'MALI_COVERAGE=%s' % env['coverage'],
+ 'MALI_BUS_LOG=%s' % env['buslog'],
+]
+
+kbase = env.BuildKernelModule('$STATIC_LIB_PATH/mali_kbase.ko', kbase_src,
+ make_args = make_args)
+
+# Add a dependency on kds.ko.
+# Only necessary when KDS is not built into the kernel.
+#
+if env['os'] != 'android':
+ if not env.KernelConfigEnabled("CONFIG_KDS"):
+ env.Depends(kbase, '$STATIC_LIB_PATH/kds.ko')
+
+# need Module.symvers from ump.ko build
+if int(env['ump']) == 1:
+ env.Depends(kbase, '$STATIC_LIB_PATH/ump.ko')
+
+env.KernelObjTarget('kbase', kbase)
+
+env.AppendUnique(BASE=['cutils_linked_list'])
diff --git a/driver/product/kernel/drivers/gpu/arm/sconscript b/driver/product/kernel/drivers/gpu/arm/sconscript
new file mode 100755
index 0000000..924511b
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/arm/sconscript
@@ -0,0 +1,20 @@
+#
+# (C) COPYRIGHT 2015-2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+import glob
+
+
+SConscript('midgard/sconscript')
+
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/Kbuild b/driver/product/kernel/drivers/gpu/drm/pl111/Kbuild
new file mode 100755
index 0000000..f10d58c
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/Kbuild
@@ -0,0 +1,28 @@
+#
+# (C) COPYRIGHT ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+pl111_drm-y += pl111_drm_device.o \
+ pl111_drm_connector.o \
+ pl111_drm_crtc.o \
+ pl111_drm_cursor.o \
+ pl111_drm_dma_buf.o \
+ pl111_drm_encoder.o \
+ pl111_drm_fb.o \
+ pl111_drm_gem.o \
+ pl111_drm_pl111.o \
+ pl111_drm_platform.o \
+ pl111_drm_suspend.o \
+ pl111_drm_vma.o
+
+obj-$(CONFIG_DRM_PL111) += pl111_drm.o
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/Kconfig b/driver/product/kernel/drivers/gpu/drm/pl111/Kconfig
new file mode 100755
index 0000000..60b465c
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/Kconfig
@@ -0,0 +1,23 @@
+#
+# (C) COPYRIGHT ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+config DRM_PL111
+ tristate "DRM Support for PL111 CLCD Controller"
+ depends on DRM
+ select DRM_KMS_HELPER
+ select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
+ help
+ Choose this option for DRM support for the PL111 CLCD controller.
+ If M is selected the module will be called pl111_drm.
+
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/Makefile b/driver/product/kernel/drivers/gpu/drm/pl111/Makefile
new file mode 100755
index 0000000..2869f58
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/Makefile
@@ -0,0 +1,32 @@
+#
+# (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+# linux build system bootstrap for out-of-tree module
+
+# default to building for the host
+ARCH ?= $(shell uname -m)
+
+ifeq ($(KDIR),)
+$(error Must specify KDIR to point to the kernel to target))
+endif
+
+all: pl111_drm
+
+pl111_drm:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../include" CONFIG_DMA_SHARED_BUFFER_USES_KDS=y CONFIG_DRM_PL111=m
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_clcd_ext.h b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_clcd_ext.h
new file mode 100755
index 0000000..d3e0086
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_clcd_ext.h
@@ -0,0 +1,95 @@
+/*
+ *
+ * (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+/**
+ * pl111_clcd_ext.h
+ * Extended CLCD register definitions
+ */
+
+#ifndef PL111_CLCD_EXT_H_
+#define PL111_CLCD_EXT_H_
+
+/*
+ * PL111 cursor register definitions not defined in the kernel's clcd header.
+ *
+ * TODO MIDEGL-1718: move to include/linux/amba/clcd.h
+ */
+
+#define CLCD_CRSR_IMAGE 0x00000800
+#define CLCD_CRSR_IMAGE_MAX_WORDS 256
+#define CLCD_CRSR_IMAGE_WORDS_PER_LINE 4
+#define CLCD_CRSR_IMAGE_PIXELS_PER_WORD 16
+
+#define CLCD_CRSR_LBBP_COLOR_MASK 0x00000003
+#define CLCD_CRSR_LBBP_BACKGROUND 0x0
+#define CLCD_CRSR_LBBP_FOREGROUND 0x1
+#define CLCD_CRSR_LBBP_TRANSPARENT 0x2
+#define CLCD_CRSR_LBBP_INVERSE 0x3
+
+
+#define CLCD_CRSR_CTRL 0x00000c00
+#define CLCD_CRSR_CONFIG 0x00000c04
+#define CLCD_CRSR_PALETTE_0 0x00000c08
+#define CLCD_CRSR_PALETTE_1 0x00000c0c
+#define CLCD_CRSR_XY 0x00000c10
+#define CLCD_CRSR_CLIP 0x00000c14
+#define CLCD_CRSR_IMSC 0x00000c20
+#define CLCD_CRSR_ICR 0x00000c24
+#define CLCD_CRSR_RIS 0x00000c28
+#define CLCD_MIS 0x00000c2c
+
+#define CRSR_CTRL_CRSR_ON (1 << 0)
+#define CRSR_CTRL_CRSR_MAX 3
+#define CRSR_CTRL_CRSR_NUM_SHIFT 4
+#define CRSR_CTRL_CRSR_NUM_MASK \
+ (CRSR_CTRL_CRSR_MAX << CRSR_CTRL_CRSR_NUM_SHIFT)
+#define CRSR_CTRL_CURSOR_0 0
+#define CRSR_CTRL_CURSOR_1 1
+#define CRSR_CTRL_CURSOR_2 2
+#define CRSR_CTRL_CURSOR_3 3
+
+#define CRSR_CONFIG_CRSR_SIZE (1 << 0)
+#define CRSR_CONFIG_CRSR_FRAME_SYNC (1 << 1)
+
+#define CRSR_PALETTE_RED_SHIFT 0
+#define CRSR_PALETTE_GREEN_SHIFT 8
+#define CRSR_PALETTE_BLUE_SHIFT 16
+
+#define CRSR_PALETTE_RED_MASK 0x000000ff
+#define CRSR_PALETTE_GREEN_MASK 0x0000ff00
+#define CRSR_PALETTE_BLUE_MASK 0x00ff0000
+#define CRSR_PALETTE_MASK (~0xff000000)
+
+#define CRSR_XY_MASK 0x000003ff
+#define CRSR_XY_X_SHIFT 0
+#define CRSR_XY_Y_SHIFT 16
+
+#define CRSR_XY_X_MASK CRSR_XY_MASK
+#define CRSR_XY_Y_MASK (CRSR_XY_MASK << CRSR_XY_Y_SHIFT)
+
+#define CRSR_CLIP_MASK 0x3f
+#define CRSR_CLIP_X_SHIFT 0
+#define CRSR_CLIP_Y_SHIFT 8
+
+#define CRSR_CLIP_X_MASK CRSR_CLIP_MASK
+#define CRSR_CLIP_Y_MASK (CRSR_CLIP_MASK << CRSR_CLIP_Y_SHIFT)
+
+#define CRSR_IMSC_CRSR_IM (1<<0)
+#define CRSR_ICR_CRSR_IC (1<<0)
+#define CRSR_RIS_CRSR_RIS (1<<0)
+#define CRSR_MIS_CRSR_MIS (1<<0)
+
+#endif /* PL111_CLCD_EXT_H_ */
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm.h b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm.h
new file mode 100755
index 0000000..64d87b6
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm.h
@@ -0,0 +1,270 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 _PL111_DRM_H_
+#define _PL111_DRM_H_
+
+#define DRIVER_AUTHOR "ARM Ltd."
+#define DRIVER_NAME "pl111_drm"
+#define DRIVER_DESC "DRM module for PL111"
+#define DRIVER_LICENCE "GPL"
+#define DRIVER_ALIAS "platform:pl111_drm"
+#define DRIVER_DATE "20101111"
+#define DRIVER_VERSION "0.2"
+#define DRIVER_MAJOR 2
+#define DRIVER_MINOR 1
+#define DRIVER_PATCHLEVEL 1
+
+/*
+ * Number of flips allowed in flight at any one time. Any more flips requested
+ * beyond this value will cause the caller to block until earlier flips have
+ * completed.
+ *
+ * For performance reasons, this must be greater than the number of buffers
+ * used in the rendering pipeline. Note that the rendering pipeline can contain
+ * different types of buffer, e.g.:
+ * - 2 final framebuffers
+ * - >2 geometry buffers for GPU use-cases
+ * - >2 vertex buffers for GPU use-cases
+ *
+ * For example, a system using 5 geometry buffers could have 5 flips in flight,
+ * and so NR_FLIPS_IN_FLIGHT_THRESHOLD must be 5 or greater.
+ *
+ * Whilst there may be more intermediate buffers (such as vertex/geometry) than
+ * final framebuffers, KDS is used to ensure that GPU rendering waits for the
+ * next off-screen buffer, so it doesn't overwrite an on-screen buffer and
+ * produce tearing.
+ */
+
+/*
+ * Here, we choose a conservative value. A lower value is most likely
+ * suitable for GPU use-cases.
+ */
+#define NR_FLIPS_IN_FLIGHT_THRESHOLD 16
+
+#define CLCD_IRQ_NEXTBASE_UPDATE (1u<<2)
+
+struct pl111_drm_flip_resource;
+
+struct pl111_gem_bo_dma {
+ dma_addr_t fb_dev_addr;
+ void *fb_cpu_addr;
+};
+
+struct pl111_gem_bo_shm {
+ struct page **pages;
+ dma_addr_t *dma_addrs;
+};
+
+struct pl111_gem_bo {
+ struct drm_gem_object gem_object;
+ u32 type;
+ union {
+ struct pl111_gem_bo_dma dma;
+ struct pl111_gem_bo_shm shm;
+ } backing_data;
+ struct sg_table *sgt;
+};
+
+extern struct pl111_drm_dev_private priv;
+
+struct pl111_drm_framebuffer {
+ struct drm_framebuffer fb;
+ struct pl111_gem_bo *bo;
+};
+
+struct pl111_drm_flip_resource {
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ /* This is the kds set associated to the dma_buf we want to flip */
+ struct kds_resource_set *kds_res_set;
+#endif
+ struct drm_framebuffer *fb;
+ struct drm_crtc *crtc;
+ struct list_head link;
+ bool page_flip;
+ struct drm_pending_vblank_event *event;
+};
+
+struct pl111_drm_crtc {
+ struct drm_crtc crtc;
+ int crtc_index;
+
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ /* This protects "old_kds_res_set" and "displaying_fb" */
+ spinlock_t current_displaying_lock;
+ /*
+ * When a buffer is displayed its associated kds resource
+ * will be obtained and stored here. Every time a buffer
+ * flip is completed this old kds set is released and assigned
+ * the kds set of the new buffer.
+ */
+ struct kds_resource_set *old_kds_res_set;
+ /*
+ * Stores which frame buffer is currently being displayed by
+ * this CRTC or NULL if nothing is being displayed. It is used
+ * to tell whether we need to obtain a set of kds resources for
+ * exported buffer objects.
+ */
+ struct drm_framebuffer *displaying_fb;
+#endif
+ struct drm_display_mode *new_mode;
+ struct drm_display_mode *current_mode;
+ int last_bpp;
+
+ /*
+ * This spinlock protects "update_queue", "current_update_res"
+ * and calls to do_flip_to_res() which updates the CLCD base
+ * registers.
+ */
+ spinlock_t base_update_lock;
+ /*
+ * The resource that caused a base address update. Only one can be
+ * pending, hence it's != NULL if there's a pending update
+ */
+ struct pl111_drm_flip_resource *current_update_res;
+ /* Queue of things waiting to update the base address */
+ struct list_head update_queue;
+
+ void (*show_framebuffer_cb)(struct pl111_drm_flip_resource *flip_res,
+ struct drm_framebuffer *fb);
+};
+
+struct pl111_drm_connector {
+ struct drm_connector connector;
+};
+
+struct pl111_drm_encoder {
+ struct drm_encoder encoder;
+};
+
+struct pl111_drm_dev_private {
+ struct pl111_drm_crtc *pl111_crtc;
+
+ struct amba_device *amba_dev;
+ unsigned long mmio_start;
+ __u32 mmio_len;
+ void *regs;
+ struct clk *clk;
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ struct kds_callback kds_cb;
+ struct kds_callback kds_obtain_current_cb;
+#endif
+ /*
+ * Number of flips that were started in show_framebuffer_on_crtc(),
+ * but haven't completed yet - because we do deferred flipping
+ */
+ atomic_t nr_flips_in_flight;
+ wait_queue_head_t wait_for_flips;
+
+ /*
+ * Used to prevent race between pl111_dma_buf_release and
+ * drm_gem_prime_handle_to_fd
+ */
+ struct mutex export_dma_buf_lock;
+
+ uint32_t number_crtcs;
+
+ /* Cache for flip resources used to avoid kmalloc on each page flip */
+ struct kmem_cache *page_flip_slab;
+};
+
+enum pl111_cursor_size {
+ CURSOR_32X32,
+ CURSOR_64X64
+};
+
+enum pl111_cursor_sync {
+ CURSOR_SYNC_NONE,
+ CURSOR_SYNC_VSYNC
+};
+
+
+/**
+ * Buffer allocation function which is more flexible than dumb_create(),
+ * it allows passing driver specific flags to control the kind of buffer
+ * to be allocated.
+ */
+int pl111_drm_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/****** TODO MIDEGL-1718: this should be moved to uapi/include/drm/pl111_drm.h ********/
+
+/*
+ * Parameters for different buffer objects:
+ * bit [0]: backing storage
+ * (0 -> SHM)
+ * (1 -> DMA)
+ * bit [2:1]: kind of mapping
+ * (0x0 -> uncached)
+ * (0x1 -> write combine)
+ * (0x2 -> cached)
+ */
+#define PL111_BOT_MASK (0x7)
+#define PL111_BOT_SHM (0x0 << 0)
+#define PL111_BOT_DMA (0x1 << 0)
+#define PL111_BOT_UNCACHED (0x0 << 1)
+#define PL111_BOT_WC (0x1 << 1)
+#define PL111_BOT_CACHED (0x2 << 1)
+
+/**
+ * User-desired buffer creation information structure.
+ *
+ * @size: user-desired memory allocation size.
+ * - this size value would be page-aligned internally.
+ * @flags: user request for setting memory type or cache attributes as a bit op
+ * - PL111_BOT_DMA / PL111_BOT_SHM
+ * - PL111_BOT_UNCACHED / PL111_BOT_WC / PL111_BOT_CACHED
+ * @handle: returned a handle to created gem object.
+ * - this handle will be set by gem module of kernel side.
+ */
+struct drm_pl111_gem_create {
+ uint32_t height;
+ uint32_t width;
+ uint32_t bpp;
+ uint32_t flags;
+ /* handle, pitch, size will be returned */
+ uint32_t handle;
+ uint32_t pitch;
+ uint64_t size;
+};
+
+#define DRM_PL111_GEM_CREATE 0x00
+
+#define DRM_IOCTL_PL111_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_PL111_GEM_CREATE, struct drm_pl111_gem_create)
+/****************************************************************************/
+
+#define PL111_FB_FROM_FRAMEBUFFER(drm_fb) \
+ (container_of(drm_fb, struct pl111_drm_framebuffer, fb))
+
+#define PL111_BO_FROM_FRAMEBUFFER(drm_fb) \
+ (container_of(drm_fb, struct pl111_drm_framebuffer, fb)->bo)
+
+#define PL111_BO_FROM_GEM(gem_obj) \
+ container_of(gem_obj, struct pl111_gem_bo, gem_object)
+
+#define to_pl111_crtc(x) container_of(x, struct pl111_drm_crtc, crtc)
+
+#define PL111_ENCODER_FROM_ENCODER(x) \
+ container_of(x, struct pl111_drm_encoder, encoder)
+
+#define PL111_CONNECTOR_FROM_CONNECTOR(x) \
+ container_of(x, struct pl111_drm_connector, connector)
+
+#include "pl111_drm_funcs.h"
+
+#endif /* _PL111_DRM_H_ */
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_connector.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_connector.c
new file mode 100755
index 0000000..c7c3a22
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_connector.c
@@ -0,0 +1,170 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_connector.c
+ * Implementation of the connector functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "pl111_drm.h"
+
+
+static struct {
+ int w, h, type;
+} pl111_drm_modes[] = {
+ { 640, 480, DRM_MODE_TYPE_PREFERRED},
+ { 800, 600, 0},
+ {1024, 768, 0},
+ { -1, -1, -1}
+};
+
+void pl111_connector_destroy(struct drm_connector *connector)
+{
+ struct pl111_drm_connector *pl111_connector =
+ PL111_CONNECTOR_FROM_CONNECTOR(connector);
+
+ DRM_DEBUG_KMS("DRM %s on connector=%p\n", __func__, connector);
+
+ drm_sysfs_connector_remove(connector);
+ drm_connector_cleanup(connector);
+ kfree(pl111_connector);
+}
+
+enum drm_connector_status pl111_connector_detect(struct drm_connector
+ *connector, bool force)
+{
+ DRM_DEBUG_KMS("DRM %s on connector=%p\n", __func__, connector);
+ return connector_status_connected;
+}
+
+void pl111_connector_dpms(struct drm_connector *connector, int mode)
+{
+ DRM_DEBUG_KMS("DRM %s on connector=%p\n", __func__, connector);
+}
+
+struct drm_encoder *
+pl111_connector_helper_best_encoder(struct drm_connector *connector)
+{
+ DRM_DEBUG_KMS("DRM %s on connector=%p\n", __func__, connector);
+
+ if (connector->encoder != NULL) {
+ return connector->encoder; /* Return attached encoder */
+ } else {
+ /*
+ * If there is no attached encoder we choose the best candidate
+ * from the list.
+ * For PL111 there is only one encoder so we return the first
+ * one we find.
+ * Other h/w would require a suitable criterion below.
+ */
+ struct drm_encoder *encoder = NULL;
+ struct drm_device *dev = connector->dev;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ head) {
+ if (1) { /* criterion ? */
+ break;
+ }
+ }
+ return encoder; /* return best candidate encoder */
+ }
+}
+
+int pl111_connector_helper_get_modes(struct drm_connector *connector)
+{
+ int i = 0;
+ int count = 0;
+
+ DRM_DEBUG_KMS("DRM %s on connector=%p\n", __func__, connector);
+
+ while (pl111_drm_modes[i].w != -1) {
+ struct drm_display_mode *mode =
+ drm_mode_find_dmt(connector->dev,
+ pl111_drm_modes[i].w,
+ pl111_drm_modes[i].h,
+ 60
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ , false
+#endif
+ );
+
+ if (mode != NULL) {
+ mode->type |= pl111_drm_modes[i].type;
+ drm_mode_probed_add(connector, mode);
+ count++;
+ }
+
+ i++;
+ }
+
+ DRM_DEBUG_KMS("found %d modes\n", count);
+
+ return count;
+}
+
+int pl111_connector_helper_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ DRM_DEBUG_KMS("DRM %s on connector=%p\n", __func__, connector);
+ return MODE_OK;
+}
+
+const struct drm_connector_funcs connector_funcs = {
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = pl111_connector_destroy,
+ .detect = pl111_connector_detect,
+ .dpms = pl111_connector_dpms,
+};
+
+const struct drm_connector_helper_funcs connector_helper_funcs = {
+ .get_modes = pl111_connector_helper_get_modes,
+ .mode_valid = pl111_connector_helper_mode_valid,
+ .best_encoder = pl111_connector_helper_best_encoder,
+};
+
+struct pl111_drm_connector *pl111_connector_create(struct drm_device *dev)
+{
+ struct pl111_drm_connector *pl111_connector;
+
+ pl111_connector = kzalloc(sizeof(struct pl111_drm_connector),
+ GFP_KERNEL);
+
+ if (pl111_connector == NULL) {
+ pr_err("Failed to allocated pl111_drm_connector\n");
+ return NULL;
+ }
+
+ drm_connector_init(dev, &pl111_connector->connector, &connector_funcs,
+ DRM_MODE_CONNECTOR_DVII);
+
+ drm_connector_helper_add(&pl111_connector->connector,
+ &connector_helper_funcs);
+
+ drm_sysfs_connector_add(&pl111_connector->connector);
+
+ return pl111_connector;
+}
+
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_crtc.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_crtc.c
new file mode 100755
index 0000000..ede07ff
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_crtc.c
@@ -0,0 +1,449 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_crtc.c
+ * Implementation of the CRTC functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "pl111_drm.h"
+
+static int pl111_crtc_num;
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+#define export_dma_buf export_dma_buf
+#else
+#define export_dma_buf dma_buf
+#endif
+
+void pl111_common_irq(struct pl111_drm_crtc *pl111_crtc)
+{
+ struct drm_device *dev = pl111_crtc->crtc.dev;
+ struct pl111_drm_flip_resource *old_flip_res;
+ struct pl111_gem_bo *bo;
+ unsigned long irq_flags;
+ int flips_in_flight;
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ unsigned long flags;
+#endif
+
+ spin_lock_irqsave(&pl111_crtc->base_update_lock, irq_flags);
+
+ /*
+ * Cache the flip resource that caused the IRQ since it will be
+ * dispatched later. Early return if the IRQ isn't associated to
+ * a base register update.
+ *
+ * TODO MIDBASE-2790: disable IRQs when a flip is not pending.
+ */
+ old_flip_res = pl111_crtc->current_update_res;
+ if (!old_flip_res) {
+ spin_unlock_irqrestore(&pl111_crtc->base_update_lock, irq_flags);
+ return;
+ }
+ pl111_crtc->current_update_res = NULL;
+
+ /* Prepare the next flip (if any) of the queue as soon as possible. */
+ if (!list_empty(&pl111_crtc->update_queue)) {
+ struct pl111_drm_flip_resource *flip_res;
+ /* Remove the head of the list */
+ flip_res = list_first_entry(&pl111_crtc->update_queue,
+ struct pl111_drm_flip_resource, link);
+ list_del(&flip_res->link);
+ do_flip_to_res(flip_res);
+ /*
+ * current_update_res will be set, so guarentees that
+ * another flip_res coming in gets queued instead of
+ * handled immediately
+ */
+ }
+ spin_unlock_irqrestore(&pl111_crtc->base_update_lock, irq_flags);
+
+ /* Finalize properly the flip that caused the IRQ */
+ DRM_DEBUG_KMS("DRM Finalizing old_flip_res=%p\n", old_flip_res);
+
+ bo = PL111_BO_FROM_FRAMEBUFFER(old_flip_res->fb);
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ spin_lock_irqsave(&pl111_crtc->current_displaying_lock, flags);
+ release_kds_resource_and_display(old_flip_res);
+ spin_unlock_irqrestore(&pl111_crtc->current_displaying_lock, flags);
+#endif
+ /* Release DMA buffer on this flip */
+
+ if (bo->gem_object.export_dma_buf != NULL)
+ dma_buf_put(bo->gem_object.export_dma_buf);
+
+ drm_handle_vblank(dev, pl111_crtc->crtc_index);
+
+ /* Wake up any processes waiting for page flip event */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
+ if (old_flip_res->event) {
+ spin_lock_bh(&dev->event_lock);
+ drm_send_vblank_event(dev, pl111_crtc->crtc_index,
+ old_flip_res->event);
+ spin_unlock_bh(&dev->event_lock);
+ }
+#else
+ if (old_flip_res->event) {
+ struct drm_pending_vblank_event *e = old_flip_res->event;
+ struct timeval now;
+ unsigned int seq;
+
+ DRM_DEBUG_KMS("%s: wake up page flip event (%p)\n", __func__,
+ old_flip_res->event);
+
+ spin_lock_bh(&dev->event_lock);
+ seq = drm_vblank_count_and_time(dev, pl111_crtc->crtc_index,
+ &now);
+ e->pipe = pl111_crtc->crtc_index;
+ e->event.sequence = seq;
+ e->event.tv_sec = now.tv_sec;
+ e->event.tv_usec = now.tv_usec;
+
+ list_add_tail(&e->base.link,
+ &e->base.file_priv->event_list);
+
+ wake_up_interruptible(&e->base.file_priv->event_wait);
+ spin_unlock_bh(&dev->event_lock);
+ }
+#endif
+
+ drm_vblank_put(dev, pl111_crtc->crtc_index);
+
+ /*
+ * workqueue.c:process_one_work():
+ * "It is permissible to free the struct work_struct from
+ * inside the function that is called from it"
+ */
+ kmem_cache_free(priv.page_flip_slab, old_flip_res);
+
+ flips_in_flight = atomic_dec_return(&priv.nr_flips_in_flight);
+ if (flips_in_flight == 0 ||
+ flips_in_flight == (NR_FLIPS_IN_FLIGHT_THRESHOLD - 1))
+ wake_up(&priv.wait_for_flips);
+
+ DRM_DEBUG_KMS("DRM release flip_res=%p\n", old_flip_res);
+}
+
+void show_framebuffer_on_crtc_cb(void *cb1, void *cb2)
+{
+ struct pl111_drm_flip_resource *flip_res = cb1;
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(flip_res->crtc);
+
+ pl111_crtc->show_framebuffer_cb(cb1, cb2);
+}
+
+int show_framebuffer_on_crtc(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, bool page_flip,
+ struct drm_pending_vblank_event *event)
+{
+ struct pl111_gem_bo *bo;
+ struct pl111_drm_flip_resource *flip_res;
+ int flips_in_flight;
+ int old_flips_in_flight;
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 14, 0))
+ crtc->fb = fb;
+#else
+ crtc->primary->fb = fb;
+#endif
+
+ bo = PL111_BO_FROM_FRAMEBUFFER(fb);
+ if (bo == NULL) {
+ DRM_DEBUG_KMS("Failed to get pl111_gem_bo object\n");
+ return -EINVAL;
+ }
+
+ /* If this is a full modeset, wait for all outstanding flips to complete
+ * before continuing. This avoids unnecessary complication from being
+ * able to queue up multiple modesets and queues of mixed modesets and
+ * page flips.
+ *
+ * Modesets should be uncommon and will not be performant anyway, so
+ * making them synchronous should have negligible performance impact.
+ */
+ if (!page_flip) {
+ int ret = wait_event_killable(priv.wait_for_flips,
+ atomic_read(&priv.nr_flips_in_flight) == 0);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * There can be more 'early display' flips in flight than there are
+ * buffers, and there is (currently) no explicit bound on the number of
+ * flips. Hence, we need a new allocation for each one.
+ *
+ * Note: this could be optimized down if we knew a bound on the flips,
+ * since an application can only have so many buffers in flight to be
+ * useful/not hog all the memory
+ */
+ flip_res = kmem_cache_alloc(priv.page_flip_slab, GFP_KERNEL);
+ if (flip_res == NULL) {
+ pr_err("kmem_cache_alloc failed to alloc - flip ignored\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * increment flips in flight, whilst blocking when we reach
+ * NR_FLIPS_IN_FLIGHT_THRESHOLD
+ */
+ do {
+ /*
+ * Note: use of assign-and-then-compare in the condition to set
+ * flips_in_flight
+ */
+ int ret = wait_event_killable(priv.wait_for_flips,
+ (flips_in_flight =
+ atomic_read(&priv.nr_flips_in_flight))
+ < NR_FLIPS_IN_FLIGHT_THRESHOLD);
+ if (ret != 0) {
+ kmem_cache_free(priv.page_flip_slab, flip_res);
+ return ret;
+ }
+
+ old_flips_in_flight = atomic_cmpxchg(&priv.nr_flips_in_flight,
+ flips_in_flight, flips_in_flight + 1);
+ } while (old_flips_in_flight != flips_in_flight);
+
+ flip_res->fb = fb;
+ flip_res->crtc = crtc;
+ flip_res->page_flip = page_flip;
+ flip_res->event = event;
+ INIT_LIST_HEAD(&flip_res->link);
+ DRM_DEBUG_KMS("DRM alloc flip_res=%p\n", flip_res);
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ if (bo->gem_object.export_dma_buf != NULL) {
+ struct dma_buf *buf = bo->gem_object.export_dma_buf;
+ unsigned long shared[1] = { 0 };
+ struct kds_resource *resource_list[1] = {
+ get_dma_buf_kds_resource(buf) };
+ int err;
+
+ get_dma_buf(buf);
+ DRM_DEBUG_KMS("Got dma_buf %p\n", buf);
+
+ /* Wait for the KDS resource associated with this buffer */
+ err = kds_async_waitall(&flip_res->kds_res_set,
+ &priv.kds_cb, flip_res, fb, 1, shared,
+ resource_list);
+ BUG_ON(err);
+ } else {
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+
+ DRM_DEBUG_KMS("No dma_buf for this flip\n");
+
+ /* No dma-buf attached so just call the callback directly */
+ flip_res->kds_res_set = NULL;
+ pl111_crtc->show_framebuffer_cb(flip_res, fb);
+ }
+#else
+ if (bo->gem_object.export_dma_buf != NULL) {
+ struct dma_buf *buf = bo->gem_object.export_dma_buf;
+
+ get_dma_buf(buf);
+ DRM_DEBUG_KMS("Got dma_buf %p\n", buf);
+ } else {
+ DRM_DEBUG_KMS("No dma_buf for this flip\n");
+ }
+
+ /* No dma-buf attached to this so just call the callback directly */
+ {
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+ pl111_crtc->show_framebuffer_cb(flip_res, fb);
+ }
+#endif
+
+ /* For the same reasons as the wait at the start of this function,
+ * wait for the modeset to complete before continuing.
+ */
+ if (!page_flip) {
+ int ret = wait_event_killable(priv.wait_for_flips,
+ flips_in_flight == 0);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int pl111_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+ struct drm_pending_vblank_event *event)
+#else
+ struct drm_pending_vblank_event *event,
+ uint32_t flags)
+#endif
+{
+ DRM_DEBUG_KMS("%s: crtc=%p, fb=%p, event=%p\n",
+ __func__, crtc, fb, event);
+ return show_framebuffer_on_crtc(crtc, fb, true, event);
+}
+
+int pl111_crtc_helper_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y, struct drm_framebuffer *old_fb)
+{
+ int ret;
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+ struct drm_display_mode *duplicated_mode;
+
+ DRM_DEBUG_KMS("DRM crtc_helper_mode_set, x=%d y=%d bpp=%d\n",
+ adjusted_mode->hdisplay, adjusted_mode->vdisplay,
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 14, 0))
+ crtc->fb->bits_per_pixel);
+#else
+ crtc->primary->fb->bits_per_pixel);
+#endif
+
+ duplicated_mode = drm_mode_duplicate(crtc->dev, adjusted_mode);
+ if (!duplicated_mode)
+ return -ENOMEM;
+
+ pl111_crtc->new_mode = duplicated_mode;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 14, 0))
+ ret = show_framebuffer_on_crtc(crtc, crtc->fb, false, NULL);
+#else
+ ret = show_framebuffer_on_crtc(crtc, crtc->primary->fb, false, NULL);
+#endif
+ if (ret != 0) {
+ pl111_crtc->new_mode = pl111_crtc->current_mode;
+ drm_mode_destroy(crtc->dev, duplicated_mode);
+ }
+
+ return ret;
+}
+
+void pl111_crtc_helper_prepare(struct drm_crtc *crtc)
+{
+ DRM_DEBUG_KMS("DRM %s on crtc=%p\n", __func__, crtc);
+}
+
+void pl111_crtc_helper_commit(struct drm_crtc *crtc)
+{
+ DRM_DEBUG_KMS("DRM %s on crtc=%p\n", __func__, crtc);
+}
+
+bool pl111_crtc_helper_mode_fixup(struct drm_crtc *crtc,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+ const struct drm_display_mode *mode,
+#else
+ struct drm_display_mode *mode,
+#endif
+ struct drm_display_mode *adjusted_mode)
+{
+ DRM_DEBUG_KMS("DRM %s on crtc=%p\n", __func__, crtc);
+
+#ifdef CONFIG_ARCH_VEXPRESS
+ /*
+ * 1024x768 with more than 16 bits per pixel may not work
+ * correctly on Versatile Express due to bandwidth issues
+ */
+ if (mode->hdisplay == 1024 && mode->vdisplay == 768 &&
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 14, 0))
+ crtc->fb->bits_per_pixel > 16) {
+#else
+ crtc->primary->fb->bits_per_pixel > 16) {
+#endif
+ DRM_INFO("*WARNING* 1024x768 at > 16 bpp may suffer corruption\n");
+ }
+#endif
+
+ return true;
+}
+
+void pl111_crtc_helper_disable(struct drm_crtc *crtc)
+{
+ int ret;
+
+ DRM_DEBUG_KMS("DRM %s on crtc=%p\n", __func__, crtc);
+
+ /* don't disable crtc until no flips in flight as irq will be disabled */
+ ret = wait_event_killable(priv.wait_for_flips, atomic_read(&priv.nr_flips_in_flight) == 0);
+ if(ret) {
+ pr_err("pl111_crtc_helper_disable failed\n");
+ return;
+ }
+ clcd_disable(crtc);
+}
+
+void pl111_crtc_destroy(struct drm_crtc *crtc)
+{
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+
+ DRM_DEBUG_KMS("DRM %s on crtc=%p\n", __func__, crtc);
+
+ drm_crtc_cleanup(crtc);
+ kfree(pl111_crtc);
+}
+
+const struct drm_crtc_funcs crtc_funcs = {
+ .cursor_set = pl111_crtc_cursor_set,
+ .cursor_move = pl111_crtc_cursor_move,
+ .set_config = drm_crtc_helper_set_config,
+ .page_flip = pl111_crtc_page_flip,
+ .destroy = pl111_crtc_destroy
+};
+
+const struct drm_crtc_helper_funcs crtc_helper_funcs = {
+ .mode_set = pl111_crtc_helper_mode_set,
+ .prepare = pl111_crtc_helper_prepare,
+ .commit = pl111_crtc_helper_commit,
+ .mode_fixup = pl111_crtc_helper_mode_fixup,
+ .disable = pl111_crtc_helper_disable,
+};
+
+struct pl111_drm_crtc *pl111_crtc_create(struct drm_device *dev)
+{
+ struct pl111_drm_crtc *pl111_crtc;
+
+ pl111_crtc = kzalloc(sizeof(struct pl111_drm_crtc), GFP_KERNEL);
+ if (pl111_crtc == NULL) {
+ pr_err("Failed to allocated pl111_drm_crtc\n");
+ return NULL;
+ }
+
+ drm_crtc_init(dev, &pl111_crtc->crtc, &crtc_funcs);
+ drm_crtc_helper_add(&pl111_crtc->crtc, &crtc_helper_funcs);
+
+ pl111_crtc->crtc_index = pl111_crtc_num;
+ pl111_crtc_num++;
+ pl111_crtc->crtc.enabled = 0;
+ pl111_crtc->last_bpp = 0;
+ pl111_crtc->current_update_res = NULL;
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ pl111_crtc->displaying_fb = NULL;
+ pl111_crtc->old_kds_res_set = NULL;
+ spin_lock_init(&pl111_crtc->current_displaying_lock);
+#endif
+ pl111_crtc->show_framebuffer_cb = show_framebuffer_on_crtc_cb_internal;
+ INIT_LIST_HEAD(&pl111_crtc->update_queue);
+ spin_lock_init(&pl111_crtc->base_update_lock);
+
+ return pl111_crtc;
+}
+
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_cursor.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_cursor.c
new file mode 100755
index 0000000..4bf20fe
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_cursor.c
@@ -0,0 +1,331 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_cursor.c
+ * Implementation of cursor functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "pl111_clcd_ext.h"
+#include "pl111_drm.h"
+
+#define PL111_MAX_CURSOR_WIDTH (64)
+#define PL111_MAX_CURSOR_HEIGHT (64)
+
+#define ARGB_2_LBBP_BINARY_THRESHOLD (1 << 7)
+#define ARGB_ALPHA_SHIFT 24
+#define ARGB_ALPHA_MASK (0xff << ARGB_ALPHA_SHIFT)
+#define ARGB_RED_SHIFT 16
+#define ARGB_RED_MASK (0xff << ARGB_RED_SHIFT)
+#define ARGB_GREEN_SHIFT 8
+#define ARGB_GREEN_MASK (0xff << ARGB_GREEN_SHIFT)
+#define ARGB_BLUE_SHIFT 0
+#define ARGB_BLUE_MASK (0xff << ARGB_BLUE_SHIFT)
+
+
+void pl111_set_cursor_size(enum pl111_cursor_size size)
+{
+ u32 reg_data = readl(priv.regs + CLCD_CRSR_CONFIG);
+
+ if (size == CURSOR_64X64)
+ reg_data |= CRSR_CONFIG_CRSR_SIZE;
+ else
+ reg_data &= ~CRSR_CONFIG_CRSR_SIZE;
+
+ writel(reg_data, priv.regs + CLCD_CRSR_CONFIG);
+}
+
+void pl111_set_cursor_sync(enum pl111_cursor_sync sync)
+{
+ u32 reg_data = readl(priv.regs + CLCD_CRSR_CONFIG);
+
+ if (sync == CURSOR_SYNC_VSYNC)
+ reg_data |= CRSR_CONFIG_CRSR_FRAME_SYNC;
+ else
+ reg_data &= ~CRSR_CONFIG_CRSR_FRAME_SYNC;
+
+ writel(reg_data, priv.regs + CLCD_CRSR_CONFIG);
+}
+
+void pl111_set_cursor(u32 cursor)
+{
+ u32 reg_data = readl(priv.regs + CLCD_CRSR_CTRL);
+
+ reg_data &= ~(CRSR_CTRL_CRSR_MAX << CRSR_CTRL_CRSR_NUM_SHIFT);
+ reg_data |= (cursor & CRSR_CTRL_CRSR_MAX) << CRSR_CTRL_CRSR_NUM_SHIFT;
+
+ writel(reg_data, priv.regs + CLCD_CRSR_CTRL);
+}
+
+void pl111_set_cursor_enable(bool enable)
+{
+ u32 reg_data = readl(priv.regs + CLCD_CRSR_CTRL);
+
+ if (enable)
+ reg_data |= CRSR_CTRL_CRSR_ON;
+ else
+ reg_data &= ~CRSR_CTRL_CRSR_ON;
+
+ writel(reg_data, priv.regs + CLCD_CRSR_CTRL);
+}
+
+void pl111_set_cursor_position(u32 x, u32 y)
+{
+ u32 reg_data = (x & CRSR_XY_MASK) |
+ ((y & CRSR_XY_MASK) << CRSR_XY_Y_SHIFT);
+
+ writel(reg_data, priv.regs + CLCD_CRSR_XY);
+}
+
+void pl111_set_cursor_clipping(u32 x, u32 y)
+{
+ u32 reg_data;
+
+ /*
+ * Do not allow setting clipping values larger than
+ * the cursor size since the cursor is already fully hidden
+ * when x,y = PL111_MAX_CURSOR_WIDTH.
+ */
+ if (x > PL111_MAX_CURSOR_WIDTH)
+ x = PL111_MAX_CURSOR_WIDTH;
+ if (y > PL111_MAX_CURSOR_WIDTH)
+ y = PL111_MAX_CURSOR_WIDTH;
+
+ reg_data = (x & CRSR_CLIP_MASK) |
+ ((y & CRSR_CLIP_MASK) << CRSR_CLIP_Y_SHIFT);
+
+ writel(reg_data, priv.regs + CLCD_CRSR_CLIP);
+}
+
+void pl111_set_cursor_palette(u32 color0, u32 color1)
+{
+ writel(color0 & CRSR_PALETTE_MASK, priv.regs + CLCD_CRSR_PALETTE_0);
+ writel(color1 & CRSR_PALETTE_MASK, priv.regs + CLCD_CRSR_PALETTE_1);
+}
+
+void pl111_cursor_enable(void)
+{
+ pl111_set_cursor_sync(CURSOR_SYNC_VSYNC);
+ pl111_set_cursor_size(CURSOR_64X64);
+ pl111_set_cursor_palette(0x0, 0x00ffffff);
+ pl111_set_cursor_enable(true);
+}
+
+void pl111_cursor_disable(void)
+{
+ pl111_set_cursor_enable(false);
+}
+
+/* shift required to locate pixel into the correct position in
+ * a cursor LBBP word, indexed by x mod 16.
+ */
+static const unsigned char
+x_mod_16_to_value_shift[CLCD_CRSR_IMAGE_PIXELS_PER_WORD] = {
+ 6, 4, 2, 0, 14, 12, 10, 8, 22, 20, 18, 16, 30, 28, 26, 24
+};
+
+/* Pack the pixel value into its correct position in the buffer as specified
+ * for LBBP */
+static inline void
+set_lbbp_pixel(uint32_t *buffer, unsigned int x, unsigned int y,
+ uint32_t value)
+{
+ u32 *cursor_ram = priv.regs + CLCD_CRSR_IMAGE;
+ uint32_t shift;
+ uint32_t data;
+
+ shift = x_mod_16_to_value_shift[x % CLCD_CRSR_IMAGE_PIXELS_PER_WORD];
+
+ /* Get the word containing this pixel */
+ cursor_ram = cursor_ram + (x >> CLCD_CRSR_IMAGE_WORDS_PER_LINE) + (y << 2);
+
+ /* Update pixel in cursor RAM */
+ data = readl(cursor_ram);
+ data &= ~(CLCD_CRSR_LBBP_COLOR_MASK << shift);
+ data |= value << shift;
+ writel(data, cursor_ram);
+}
+
+static u32 pl111_argb_to_lbbp(u32 argb_pix)
+{
+ u32 lbbp_pix = CLCD_CRSR_LBBP_TRANSPARENT;
+ u32 alpha = (argb_pix & ARGB_ALPHA_MASK) >> ARGB_ALPHA_SHIFT;
+ u32 red = (argb_pix & ARGB_RED_MASK) >> ARGB_RED_SHIFT;
+ u32 green = (argb_pix & ARGB_GREEN_MASK) >> ARGB_GREEN_SHIFT;
+ u32 blue = (argb_pix & ARGB_BLUE_MASK) >> ARGB_BLUE_SHIFT;
+
+ /*
+ * Converting from 8 pixel transparency to binary transparency
+ * it's the best we can achieve.
+ */
+ if (alpha & ARGB_2_LBBP_BINARY_THRESHOLD) {
+ u32 gray, max, min;
+
+ /*
+ * Convert to gray using the lightness method:
+ * gray = [max(R,G,B) + min(R,G,B)]/2
+ */
+ min = min(red, green);
+ min = min(min, blue);
+ max = max(red, green);
+ max = max(max, blue);
+ gray = (min + max) >> 1; /* divide by 2 */
+ /* Apply binary threshold to the gray value calculated */
+ if (gray & ARGB_2_LBBP_BINARY_THRESHOLD)
+ lbbp_pix = CLCD_CRSR_LBBP_FOREGROUND;
+ else
+ lbbp_pix = CLCD_CRSR_LBBP_BACKGROUND;
+ }
+
+ return lbbp_pix;
+}
+
+/*
+ * The PL111 hardware cursor supports only LBBP which is a 2bpp format but
+ * the cursor format from userspace is ARGB8888 so we need to convert
+ * to LBBP here.
+ */
+static void pl111_set_cursor_image(u32 *data)
+{
+#ifdef ARGB_LBBP_CONVERSION_DEBUG
+ /* Add 1 on width to insert trailing NULL */
+ char string_cursor[PL111_MAX_CURSOR_WIDTH + 1];
+#endif /* ARGB_LBBP_CONVERSION_DEBUG */
+ unsigned int x;
+ unsigned int y;
+
+ for (y = 0; y < PL111_MAX_CURSOR_HEIGHT; y++) {
+ for (x = 0; x < PL111_MAX_CURSOR_WIDTH; x++) {
+ u32 value = pl111_argb_to_lbbp(*data);
+
+#ifdef ARGB_LBBP_CONVERSION_DEBUG
+ if (value == CLCD_CRSR_LBBP_TRANSPARENT)
+ string_cursor[x] = 'T';
+ else if (value == CLCD_CRSR_LBBP_FOREGROUND)
+ string_cursor[x] = 'F';
+ else if (value == CLCD_CRSR_LBBP_INVERSE)
+ string_cursor[x] = 'I';
+ else
+ string_cursor[x] = 'B';
+
+#endif /* ARGB_LBBP_CONVERSION_DEBUG */
+ set_lbbp_pixel(data, x, y, value);
+ ++data;
+ }
+#ifdef ARGB_LBBP_CONVERSION_DEBUG
+ string_cursor[PL111_MAX_CURSOR_WIDTH] = '\0';
+ DRM_INFO("%s\n", string_cursor);
+#endif /* ARGB_LBBP_CONVERSION_DEBUG */
+ }
+}
+
+int pl111_crtc_cursor_set(struct drm_crtc *crtc,
+ struct drm_file *file_priv,
+ uint32_t handle,
+ uint32_t width,
+ uint32_t height)
+{
+ struct drm_gem_object *obj;
+ struct pl111_gem_bo *bo;
+
+ DRM_DEBUG_KMS("handle = %u, width = %u, height = %u\n",
+ handle, width, height);
+
+ if (!handle) {
+ pl111_cursor_disable();
+ return 0;
+ }
+
+ if ((width != PL111_MAX_CURSOR_WIDTH) ||
+ (height != PL111_MAX_CURSOR_HEIGHT))
+ return -EINVAL;
+
+ obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
+ if (!obj) {
+ DRM_ERROR("Cannot find cursor object for handle = %d\n",
+ handle);
+ return -ENOENT;
+ }
+
+ /*
+ * We expect a PL111_MAX_CURSOR_WIDTH x PL111_MAX_CURSOR_HEIGHT
+ * ARGB888 buffer object in the input.
+ *
+ */
+ if (obj->size < (PL111_MAX_CURSOR_WIDTH * PL111_MAX_CURSOR_HEIGHT * 4)) {
+ DRM_ERROR("Cannot set cursor with an obj size = %d\n",
+ obj->size);
+ drm_gem_object_unreference_unlocked(obj);
+ return -EINVAL;
+ }
+
+ bo = PL111_BO_FROM_GEM(obj);
+ if (!(bo->type & PL111_BOT_DMA)) {
+ DRM_ERROR("Tried to set cursor with non DMA backed obj = %p\n",
+ obj);
+ drm_gem_object_unreference_unlocked(obj);
+ return -EINVAL;
+ }
+
+ pl111_set_cursor_image(bo->backing_data.dma.fb_cpu_addr);
+
+ /*
+ * Since we copy the contents of the buffer to the HW cursor internal
+ * memory this GEM object is not needed anymore.
+ */
+ drm_gem_object_unreference_unlocked(obj);
+
+ pl111_cursor_enable();
+
+ return 0;
+}
+
+int pl111_crtc_cursor_move(struct drm_crtc *crtc,
+ int x, int y)
+{
+ int x_clip = 0;
+ int y_clip = 0;
+
+ DRM_DEBUG("x %d y %d\n", x, y);
+
+ /*
+ * The cursor image is clipped automatically at the screen limits when
+ * it extends beyond the screen image to the right or bottom but
+ * we must clip it using pl111 HW features for negative values.
+ */
+ if (x < 0) {
+ x_clip = -x;
+ x = 0;
+ }
+ if (y < 0) {
+ y_clip = -y;
+ y = 0;
+ }
+
+ pl111_set_cursor_clipping(x_clip, y_clip);
+ pl111_set_cursor_position(x, y);
+
+ return 0;
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_device.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_device.c
new file mode 100755
index 0000000..6619c07
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_device.c
@@ -0,0 +1,338 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_device.c
+ * Implementation of the Linux device driver entrypoints for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "pl111_drm.h"
+
+struct pl111_drm_dev_private priv;
+
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+static void initial_kds_obtained(void *cb1, void *cb2)
+{
+ wait_queue_head_t *wait = (wait_queue_head_t *) cb1;
+ bool *cb_has_called = (bool *) cb2;
+
+ *cb_has_called = true;
+ wake_up(wait);
+}
+
+/* Must be called from within current_displaying_lock spinlock */
+void release_kds_resource_and_display(struct pl111_drm_flip_resource *flip_res)
+{
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(flip_res->crtc);
+ pl111_crtc->displaying_fb = flip_res->fb;
+
+ /* Release the previous buffer */
+ if (pl111_crtc->old_kds_res_set != NULL) {
+ /*
+ * Can flip to the same buffer, but must not release the current
+ * resource set
+ */
+ BUG_ON(pl111_crtc->old_kds_res_set == flip_res->kds_res_set);
+ kds_resource_set_release(&pl111_crtc->old_kds_res_set);
+ }
+ /* Record the current buffer, to release on the next buffer flip */
+ pl111_crtc->old_kds_res_set = flip_res->kds_res_set;
+}
+#endif
+
+void pl111_drm_preclose(struct drm_device *dev, struct drm_file *file_priv)
+{
+ DRM_DEBUG_KMS("DRM %s on dev=%p\n", __func__, dev);
+}
+
+void pl111_drm_lastclose(struct drm_device *dev)
+{
+ DRM_DEBUG_KMS("DRM %s on dev=%p\n", __func__, dev);
+}
+
+/*
+ * pl111 does not have a proper HW counter for vblank IRQs so enable_vblank
+ * and disable_vblank are just no op callbacks.
+ */
+static int pl111_enable_vblank(struct drm_device *dev, int crtc)
+{
+ DRM_DEBUG_KMS("%s: dev=%p, crtc=%d", __func__, dev, crtc);
+ return 0;
+}
+
+static void pl111_disable_vblank(struct drm_device *dev, int crtc)
+{
+ DRM_DEBUG_KMS("%s: dev=%p, crtc=%d", __func__, dev, crtc);
+}
+
+struct drm_mode_config_funcs mode_config_funcs = {
+ .fb_create = pl111_fb_create,
+};
+
+static int pl111_modeset_init(struct drm_device *dev)
+{
+ struct drm_mode_config *mode_config;
+ struct pl111_drm_dev_private *priv = dev->dev_private;
+ struct pl111_drm_connector *pl111_connector;
+ struct pl111_drm_encoder *pl111_encoder;
+ int ret = 0;
+
+ if (priv == NULL)
+ return -EINVAL;
+
+ drm_mode_config_init(dev);
+ mode_config = &dev->mode_config;
+ mode_config->funcs = &mode_config_funcs;
+ mode_config->min_width = 1;
+ mode_config->max_width = 1024;
+ mode_config->min_height = 1;
+ mode_config->max_height = 768;
+
+ priv->pl111_crtc = pl111_crtc_create(dev);
+ if (priv->pl111_crtc == NULL) {
+ pr_err("Failed to create pl111_drm_crtc\n");
+ ret = -ENOMEM;
+ goto out_config;
+ }
+
+ priv->number_crtcs = 1;
+
+ pl111_connector = pl111_connector_create(dev);
+ if (pl111_connector == NULL) {
+ pr_err("Failed to create pl111_drm_connector\n");
+ ret = -ENOMEM;
+ goto out_config;
+ }
+
+ pl111_encoder = pl111_encoder_create(dev, 1);
+ if (pl111_encoder == NULL) {
+ pr_err("Failed to create pl111_drm_encoder\n");
+ ret = -ENOMEM;
+ goto out_config;
+ }
+
+ ret = drm_mode_connector_attach_encoder(&pl111_connector->connector,
+ &pl111_encoder->encoder);
+ if (ret != 0) {
+ DRM_ERROR("Failed to attach encoder\n");
+ goto out_config;
+ }
+
+ pl111_connector->connector.encoder = &pl111_encoder->encoder;
+
+ pl111_encoder->encoder.crtc = &priv->pl111_crtc->crtc;
+
+ goto finish;
+
+out_config:
+ drm_mode_config_cleanup(dev);
+finish:
+ DRM_DEBUG("%s returned %d\n", __func__, ret);
+ return ret;
+}
+
+static void pl111_modeset_fini(struct drm_device *dev)
+{
+ drm_mode_config_cleanup(dev);
+}
+
+static int pl111_drm_load(struct drm_device *dev, unsigned long chipset)
+{
+ int ret = 0;
+
+ pr_info("DRM %s\n", __func__);
+
+ mutex_init(&priv.export_dma_buf_lock);
+ atomic_set(&priv.nr_flips_in_flight, 0);
+ init_waitqueue_head(&priv.wait_for_flips);
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ ret = kds_callback_init(&priv.kds_cb, 1, show_framebuffer_on_crtc_cb);
+ if (ret != 0) {
+ pr_err("Failed to initialise KDS callback\n");
+ goto finish;
+ }
+
+ ret = kds_callback_init(&priv.kds_obtain_current_cb, 1,
+ initial_kds_obtained);
+ if (ret != 0) {
+ pr_err("Failed to init KDS obtain callback\n");
+ kds_callback_term(&priv.kds_cb);
+ goto finish;
+ }
+#endif
+
+ /* Create a cache for page flips */
+ priv.page_flip_slab = kmem_cache_create("page flip slab",
+ sizeof(struct pl111_drm_flip_resource), 0, 0, NULL);
+ if (priv.page_flip_slab == NULL) {
+ DRM_ERROR("Failed to create slab\n");
+ ret = -ENOMEM;
+ goto out_kds_callbacks;
+ }
+
+ dev->dev_private = &priv;
+
+ ret = pl111_modeset_init(dev);
+ if (ret != 0) {
+ pr_err("Failed to init modeset\n");
+ goto out_slab;
+ }
+
+ ret = pl111_device_init(dev);
+ if (ret != 0) {
+ DRM_ERROR("Failed to init MMIO and IRQ\n");
+ goto out_modeset;
+ }
+
+ ret = drm_vblank_init(dev, 1);
+ if (ret != 0) {
+ DRM_ERROR("Failed to init vblank\n");
+ goto out_vblank;
+ }
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0))
+ platform_set_drvdata(dev->platformdev, dev);
+#endif
+
+ goto finish;
+
+out_vblank:
+ pl111_device_fini(dev);
+out_modeset:
+ pl111_modeset_fini(dev);
+out_slab:
+ kmem_cache_destroy(priv.page_flip_slab);
+out_kds_callbacks:
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ kds_callback_term(&priv.kds_obtain_current_cb);
+ kds_callback_term(&priv.kds_cb);
+#endif
+finish:
+ DRM_DEBUG_KMS("pl111_drm_load returned %d\n", ret);
+ return ret;
+}
+
+static int pl111_drm_unload(struct drm_device *dev)
+{
+ pr_info("DRM %s\n", __func__);
+
+ kmem_cache_destroy(priv.page_flip_slab);
+
+ drm_vblank_cleanup(dev);
+ pl111_modeset_fini(dev);
+ pl111_device_fini(dev);
+
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ kds_callback_term(&priv.kds_obtain_current_cb);
+ kds_callback_term(&priv.kds_cb);
+#endif
+ return 0;
+}
+
+static struct vm_operations_struct pl111_gem_vm_ops = {
+ .fault = pl111_gem_fault,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+#else
+ .open = pl111_gem_vm_open,
+ .close = pl111_gem_vm_close,
+#endif
+};
+
+static const struct file_operations drm_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = pl111_gem_mmap,
+ .poll = drm_poll,
+ .read = drm_read,
+};
+
+static struct drm_ioctl_desc pl111_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(PL111_GEM_CREATE, pl111_drm_gem_create_ioctl,
+ DRM_CONTROL_ALLOW | DRM_UNLOCKED),
+};
+
+static struct drm_driver driver = {
+ .driver_features =
+ DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+ .load = pl111_drm_load,
+ .unload = pl111_drm_unload,
+ .context_dtor = NULL,
+ .preclose = pl111_drm_preclose,
+ .lastclose = pl111_drm_lastclose,
+ .suspend = pl111_drm_suspend,
+ .resume = pl111_drm_resume,
+ .get_vblank_counter = drm_vblank_count,
+ .enable_vblank = pl111_enable_vblank,
+ .disable_vblank = pl111_disable_vblank,
+ .ioctls = pl111_ioctls,
+ .fops = &drm_fops,
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+ .dumb_create = pl111_dumb_create,
+ .dumb_destroy = pl111_dumb_destroy,
+ .dumb_map_offset = pl111_dumb_map_offset,
+ .gem_free_object = pl111_gem_free_object,
+ .gem_vm_ops = &pl111_gem_vm_ops,
+ .prime_handle_to_fd = &pl111_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = &pl111_gem_prime_export,
+ .gem_prime_import = &pl111_gem_prime_import,
+};
+
+int pl111_drm_init(struct platform_device *dev)
+{
+ int ret;
+ pr_info("DRM %s\n", __func__);
+ pr_info("PL111 DRM initialize, driver name: %s, version %d.%d\n",
+ DRIVER_NAME, DRIVER_MAJOR, DRIVER_MINOR);
+ driver.num_ioctls = ARRAY_SIZE(pl111_ioctls);
+ ret = 0;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 15, 0))
+ driver.kdriver.platform_device = dev;
+#endif
+ return drm_platform_init(&driver, dev);
+
+}
+
+void pl111_drm_exit(struct platform_device *dev)
+{
+ pr_info("DRM %s\n", __func__);
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 13, 0))
+ drm_platform_exit(&driver, dev);
+#else
+ drm_put_dev(platform_get_drvdata(dev));
+#endif
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_dma_buf.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_dma_buf.c
new file mode 100755
index 0000000..1131f46
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_dma_buf.c
@@ -0,0 +1,625 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_dma_buf.c
+ * Implementation of the dma_buf functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "pl111_drm.h"
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+#define export_dma_buf export_dma_buf
+#else
+#define export_dma_buf dma_buf
+#endif
+
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+static void obtain_kds_if_currently_displayed(struct drm_device *dev,
+ struct pl111_gem_bo *bo,
+ struct dma_buf *dma_buf)
+{
+ unsigned long shared[1] = { 0 };
+ struct kds_resource *resource_list[1];
+ struct kds_resource_set *kds_res_set;
+ struct drm_crtc *crtc;
+ bool cb_has_called = false;
+ unsigned long flags;
+ int err;
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+
+ DRM_DEBUG_KMS("Obtaining initial KDS res for bo:%p dma_buf:%p\n",
+ bo, dma_buf);
+
+ resource_list[0] = get_dma_buf_kds_resource(dma_buf);
+ get_dma_buf(dma_buf);
+
+ /*
+ * Can't use kds_waitall(), because kbase will be let through due to
+ * locked ignore'
+ */
+ err = kds_async_waitall(&kds_res_set,
+ &priv.kds_obtain_current_cb, &wake,
+ &cb_has_called, 1, shared, resource_list);
+ BUG_ON(err);
+ wait_event(wake, cb_has_called == true);
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+ spin_lock_irqsave(&pl111_crtc->current_displaying_lock, flags);
+ if (pl111_crtc->displaying_fb) {
+ struct pl111_drm_framebuffer *pl111_fb;
+ struct drm_framebuffer *fb = pl111_crtc->displaying_fb;
+
+ pl111_fb = PL111_FB_FROM_FRAMEBUFFER(fb);
+
+ if (pl111_fb->bo == bo) {
+ DRM_DEBUG_KMS("Initial KDS resource for bo %p", bo);
+ DRM_DEBUG_KMS(" is being displayed, keeping\n");
+ /* There shouldn't be a previous buffer to release */
+ BUG_ON(pl111_crtc->old_kds_res_set);
+
+ if (kds_res_set == NULL) {
+ err = kds_async_waitall(&kds_res_set,
+ &priv.kds_obtain_current_cb,
+ &wake, &cb_has_called,
+ 1, shared, resource_list);
+ BUG_ON(err);
+ wait_event(wake, cb_has_called == true);
+ }
+
+ /* Current buffer will need releasing on next flip */
+ pl111_crtc->old_kds_res_set = kds_res_set;
+
+ /*
+ * Clear kds_res_set, so a new kds_res_set is allocated
+ * for additional CRTCs
+ */
+ kds_res_set = NULL;
+ }
+ }
+ spin_unlock_irqrestore(&pl111_crtc->current_displaying_lock, flags);
+ }
+
+ /* kds_res_set will be NULL here if any CRTCs are displaying fb */
+ if (kds_res_set != NULL) {
+ DRM_DEBUG_KMS("Initial KDS resource for bo %p", bo);
+ DRM_DEBUG_KMS(" not being displayed, discarding\n");
+ /* They're not being displayed, release them */
+ kds_resource_set_release(&kds_res_set);
+ }
+
+ dma_buf_put(dma_buf);
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+
+static int pl111_dma_buf_mmap(struct dma_buf *buffer,
+ struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = buffer->priv;
+ struct pl111_gem_bo *bo = PL111_BO_FROM_GEM(obj);
+ struct drm_device *dev = obj->dev;
+ int ret;
+
+ DRM_DEBUG_KMS("DRM %s on dma_buf=%p\n", __func__, buffer);
+
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_gem_mmap_obj(obj, obj->size, vma);
+ mutex_unlock(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ return pl111_bo_mmap(obj, bo, vma, buffer->size);
+}
+
+#else
+
+static int pl111_dma_buf_mmap(struct dma_buf *buffer,
+ struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = buffer->priv;
+ struct pl111_gem_bo *bo = PL111_BO_FROM_GEM(obj);
+ struct drm_device *dev = obj->dev;
+
+ DRM_DEBUG_KMS("DRM %s on dma_buf=%p\n", __func__, buffer);
+
+ mutex_lock(&dev->struct_mutex);
+
+ /* Check for valid size. */
+ if (obj->size < vma->vm_end - vma->vm_start)
+ return -EINVAL;
+
+ BUG_ON(!dev->driver->gem_vm_ops);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
+#else
+ vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
+#endif
+
+ vma->vm_ops = dev->driver->gem_vm_ops;
+ vma->vm_private_data = obj;
+
+ /* Take a ref for this mapping of the object, so that the fault
+ * handler can dereference the mmap offset's pointer to the object.
+ * This reference is cleaned up by the corresponding vm_close
+ * (which should happen whether the vma was created by this call, or
+ * by a vm_open due to mremap or partial unmap or whatever).
+ */
+ drm_gem_object_reference(obj);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
+ pl111_drm_vm_open_locked(dev, vma);
+#else
+ drm_vm_open_locked(dev, vma);
+#endif
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return pl111_bo_mmap(obj, bo, vma, buffer->size);
+}
+
+#endif /* KERNEL_VERSION */
+
+static void pl111_dma_buf_release(struct dma_buf *buf)
+{
+ /*
+ * Need to release the dma_buf's reference on the gem object it was
+ * exported from, and also clear the gem object's export_dma_buf
+ * pointer to this dma_buf as it no longer exists
+ */
+ struct drm_gem_object *obj = (struct drm_gem_object *)buf->priv;
+ struct pl111_gem_bo *bo;
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ struct drm_crtc *crtc;
+ unsigned long flags;
+#endif
+ bo = PL111_BO_FROM_GEM(obj);
+
+ DRM_DEBUG_KMS("Releasing dma_buf %p, drm_gem_obj=%p\n", buf, obj);
+
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ list_for_each_entry(crtc, &bo->gem_object.dev->mode_config.crtc_list,
+ head) {
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+ spin_lock_irqsave(&pl111_crtc->current_displaying_lock, flags);
+ if (pl111_crtc->displaying_fb) {
+ struct pl111_drm_framebuffer *pl111_fb;
+ struct drm_framebuffer *fb = pl111_crtc->displaying_fb;
+
+ pl111_fb = PL111_FB_FROM_FRAMEBUFFER(fb);
+ if (pl111_fb->bo == bo) {
+ kds_resource_set_release(&pl111_crtc->old_kds_res_set);
+ pl111_crtc->old_kds_res_set = NULL;
+ }
+ }
+ spin_unlock_irqrestore(&pl111_crtc->current_displaying_lock, flags);
+ }
+#endif
+ mutex_lock(&priv.export_dma_buf_lock);
+
+ obj->export_dma_buf = NULL;
+ drm_gem_object_unreference_unlocked(obj);
+
+ mutex_unlock(&priv.export_dma_buf_lock);
+}
+
+static int pl111_dma_buf_attach(struct dma_buf *buf, struct device *dev,
+ struct dma_buf_attachment *attach)
+{
+ DRM_DEBUG_KMS("Attaching dma_buf %p to device %p attach=%p\n", buf,
+ dev, attach);
+
+ attach->priv = dev;
+
+ return 0;
+}
+
+static void pl111_dma_buf_detach(struct dma_buf *buf,
+ struct dma_buf_attachment *attach)
+{
+ DRM_DEBUG_KMS("Detaching dma_buf %p attach=%p\n", attach->dmabuf,
+ attach);
+}
+
+/* Heavily from exynos_drm_dmabuf.c */
+static struct sg_table *pl111_dma_buf_map_dma_buf(struct dma_buf_attachment
+ *attach,
+ enum dma_data_direction
+ direction)
+{
+ struct drm_gem_object *obj = attach->dmabuf->priv;
+ struct pl111_gem_bo *bo = PL111_BO_FROM_GEM(obj);
+ struct drm_device *dev = obj->dev;
+ int size, n_pages, nents;
+ struct scatterlist *s, *sg;
+ struct sg_table *sgt;
+ int ret, i;
+
+ DRM_DEBUG_KMS("Mapping dma_buf %p from attach=%p (bo=%p)\n", attach->dmabuf,
+ attach, bo);
+
+ /*
+ * Nothing to do, if we are trying to map a dmabuf that has been imported.
+ * Just return the existing sgt.
+ */
+ if (obj->import_attach) {
+ BUG_ON(!bo->sgt);
+ return bo->sgt;
+ }
+
+ size = obj->size;
+ n_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+ if (bo->type & PL111_BOT_DMA) {
+ sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt) {
+ DRM_ERROR("Failed to allocate sg_table\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+ if (ret < 0) {
+ DRM_ERROR("Failed to allocate page table\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ sg_dma_len(sgt->sgl) = size;
+ /* We use DMA coherent mappings for PL111_BOT_DMA so we must
+ * use the virtual address returned at buffer allocation */
+ sg_set_buf(sgt->sgl, bo->backing_data.dma.fb_cpu_addr, size);
+ sg_dma_address(sgt->sgl) = bo->backing_data.dma.fb_dev_addr;
+ } else { /* PL111_BOT_SHM */
+ struct page **pages;
+ int pg = 0;
+
+ mutex_lock(&dev->struct_mutex);
+ pages = get_pages(obj);
+ if (IS_ERR(pages)) {
+ dev_err(obj->dev->dev, "could not get pages: %ld\n",
+ PTR_ERR(pages));
+ return ERR_CAST(pages);
+ }
+ sgt = drm_prime_pages_to_sg(pages, n_pages);
+ if (sgt == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ pl111_gem_sync_to_dma(bo);
+
+ /*
+ * At this point the pages have been dma-mapped by either
+ * get_pages() for non cached maps or pl111_gem_sync_to_dma()
+ * for cached. So the physical addresses can be assigned
+ * to the sg entries.
+ * drm_prime_pages_to_sg() may have combined contiguous pages
+ * into chunks so we assign the physical address of the first
+ * page of a chunk to the chunk and check that the physical
+ * addresses of the rest of the pages in that chunk are also
+ * contiguous.
+ */
+ sg = sgt->sgl;
+ nents = sgt->nents;
+
+ for_each_sg(sg, s, nents, i) {
+ int j, n_pages_in_chunk = sg_dma_len(s) >> PAGE_SHIFT;
+
+ sg_dma_address(s) = bo->backing_data.shm.dma_addrs[pg];
+
+ for (j = pg+1; j < pg+n_pages_in_chunk; j++) {
+ BUG_ON(bo->backing_data.shm.dma_addrs[j] !=
+ bo->backing_data.shm.dma_addrs[j-1]+PAGE_SIZE);
+ }
+
+ pg += n_pages_in_chunk;
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+ }
+ bo->sgt = sgt;
+ return sgt;
+}
+
+static void pl111_dma_buf_unmap_dma_buf(struct dma_buf_attachment *attach,
+ struct sg_table *sgt,
+ enum dma_data_direction direction)
+{
+ struct drm_gem_object *obj = attach->dmabuf->priv;
+ struct pl111_gem_bo *bo = PL111_BO_FROM_GEM(obj);
+
+ DRM_DEBUG_KMS("Unmapping dma_buf %p from attach=%p (bo=%p)\n", attach->dmabuf,
+ attach, bo);
+
+ sg_free_table(sgt);
+ kfree(sgt);
+ bo->sgt = NULL;
+}
+
+/*
+ * There isn't any operation here that can sleep or fail so this callback can
+ * be used for both kmap and kmap_atomic implementations.
+ */
+static void *pl111_dma_buf_kmap(struct dma_buf *dma_buf, unsigned long pageno)
+{
+ struct pl111_gem_bo *bo = dma_buf->priv;
+ void *vaddr = NULL;
+
+ /* Make sure we cannot access outside the memory range */
+ if (((pageno + 1) << PAGE_SHIFT) > bo->gem_object.size)
+ return NULL;
+
+ if (bo->type & PL111_BOT_DMA) {
+ vaddr = (bo->backing_data.dma.fb_cpu_addr +
+ (pageno << PAGE_SHIFT));
+ } else {
+ vaddr = page_address(bo->backing_data.shm.pages[pageno]);
+ }
+
+ return vaddr;
+}
+
+/*
+ * Find a scatterlist that starts in "start" and has "len"
+ * or return a NULL dma_handle.
+ */
+static dma_addr_t pl111_find_matching_sg(struct sg_table *sgt, size_t start,
+ size_t len)
+{
+ struct scatterlist *sg;
+ unsigned int count;
+ size_t size = 0;
+ dma_addr_t dma_handle = 0;
+
+ /* Find a scatterlist that starts in "start" and has "len"
+ * or return error */
+ for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+ if ((size == start) && (len == sg_dma_len(sg))) {
+ dma_handle = sg_dma_address(sg);
+ break;
+ }
+ size += sg_dma_len(sg);
+ }
+ return dma_handle;
+}
+
+static int pl111_dma_buf_begin_cpu(struct dma_buf *dma_buf,
+ size_t start, size_t len,
+ enum dma_data_direction dir)
+{
+ struct pl111_gem_bo *bo = dma_buf->priv;
+ struct sg_table *sgt = bo->sgt;
+ dma_addr_t dma_handle;
+
+ if ((start + len) > bo->gem_object.size)
+ return -EINVAL;
+
+ if (!(bo->type & PL111_BOT_SHM)) {
+ struct device *dev = bo->gem_object.dev->dev;
+
+ dma_handle = pl111_find_matching_sg(sgt, start, len);
+ if (!dma_handle)
+ return -EINVAL;
+
+ dma_sync_single_range_for_cpu(dev, dma_handle, 0, len, dir);
+ }
+ /* PL111_BOT_DMA uses coherents mappings, no need to sync */
+ return 0;
+}
+
+static void pl111_dma_buf_end_cpu(struct dma_buf *dma_buf,
+ size_t start, size_t len,
+ enum dma_data_direction dir)
+{
+ struct pl111_gem_bo *bo = dma_buf->priv;
+ struct sg_table *sgt = bo->sgt;
+ dma_addr_t dma_handle;
+
+ if ((start + len) > bo->gem_object.size)
+ return;
+
+ if (!(bo->type & PL111_BOT_DMA)) {
+ struct device *dev = bo->gem_object.dev->dev;
+
+ dma_handle = pl111_find_matching_sg(sgt, start, len);
+ if (!dma_handle)
+ return;
+
+ dma_sync_single_range_for_device(dev, dma_handle, 0, len, dir);
+ }
+ /* PL111_BOT_DMA uses coherents mappings, no need to sync */
+}
+
+static struct dma_buf_ops pl111_dma_buf_ops = {
+ .release = &pl111_dma_buf_release,
+ .attach = &pl111_dma_buf_attach,
+ .detach = &pl111_dma_buf_detach,
+ .map_dma_buf = &pl111_dma_buf_map_dma_buf,
+ .unmap_dma_buf = &pl111_dma_buf_unmap_dma_buf,
+ .kmap_atomic = &pl111_dma_buf_kmap,
+ .kmap = &pl111_dma_buf_kmap,
+ .begin_cpu_access = &pl111_dma_buf_begin_cpu,
+ .end_cpu_access = &pl111_dma_buf_end_cpu,
+ .mmap = &pl111_dma_buf_mmap,
+};
+
+struct drm_gem_object *pl111_gem_prime_import(struct drm_device *dev,
+ struct dma_buf *dma_buf)
+{
+ struct dma_buf_attachment *attachment;
+ struct drm_gem_object *obj;
+ struct pl111_gem_bo *bo;
+ struct scatterlist *sgl;
+ struct sg_table *sgt;
+ dma_addr_t cont_phys;
+ int ret = 0;
+ int i;
+
+ DRM_DEBUG_KMS("DRM %s on dev=%p dma_buf=%p\n", __func__, dev, dma_buf);
+
+ /* is this one of own objects? */
+ if (dma_buf->ops == &pl111_dma_buf_ops) {
+ obj = dma_buf->priv;
+ /* is it from our device? */
+ if (obj->dev == dev) {
+ /*
+ * Importing dmabuf exported from our own gem increases
+ * refcount on gem itself instead of f_count of dmabuf.
+ */
+ drm_gem_object_reference(obj);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
+ /* before v3.10.0 we assume the caller has taken a ref on the dma_buf
+ * we don't want it for self-imported buffers so drop it here */
+ dma_buf_put(dma_buf);
+#endif
+
+ return obj;
+ }
+ }
+
+ attachment = dma_buf_attach(dma_buf, dev->dev);
+ if (IS_ERR(attachment))
+ return ERR_CAST(attachment);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+ /* from 3.10.0 we assume the caller has not taken a ref so we take one here */
+ get_dma_buf(dma_buf);
+#endif
+
+ sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
+ if (IS_ERR_OR_NULL(sgt)) {
+ ret = PTR_ERR(sgt);
+ goto err_buf_detach;
+ }
+
+ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo) {
+ DRM_ERROR("%s: failed to allocate buffer object.\n", __func__);
+ ret = -ENOMEM;
+ goto err_unmap_attach;
+ }
+
+ /* Find out whether the buffer is contiguous or not */
+ sgl = sgt->sgl;
+ cont_phys = sg_phys(sgl);
+ bo->type |= PL111_BOT_DMA;
+ for_each_sg(sgt->sgl, sgl, sgt->nents, i) {
+ dma_addr_t real_phys = sg_phys(sgl);
+ if (real_phys != cont_phys) {
+ bo->type &= ~PL111_BOT_DMA;
+ break;
+ }
+ cont_phys += (PAGE_SIZE - sgl->offset);
+ }
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+ ret = drm_gem_private_object_init(dev, &bo->gem_object,
+ dma_buf->size);
+ if (ret != 0) {
+ DRM_ERROR("DRM could not import DMA GEM obj\n");
+ goto err_free_buffer;
+ }
+#else
+ drm_gem_private_object_init(dev, &bo->gem_object, dma_buf->size);
+#endif
+
+ if (bo->type & PL111_BOT_DMA) {
+ bo->backing_data.dma.fb_cpu_addr = sg_virt(sgt->sgl);
+ bo->backing_data.dma.fb_dev_addr = sg_phys(sgt->sgl);
+ DRM_DEBUG_KMS("DRM %s pl111_gem_bo=%p, contiguous import\n", __func__, bo);
+ } else { /* PL111_BOT_SHM */
+ DRM_DEBUG_KMS("DRM %s pl111_gem_bo=%p, non contiguous import\n", __func__, bo);
+ }
+
+ bo->gem_object.import_attach = attachment;
+ bo->sgt = sgt;
+
+ return &bo->gem_object;
+
+err_free_buffer:
+ kfree(bo);
+ bo = NULL;
+err_unmap_attach:
+ dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
+err_buf_detach:
+ dma_buf_detach(dma_buf, attachment);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+ /* from 3.10.0 we will have taken a ref so drop it here */
+ dma_buf_put(dma_buf);
+#endif
+ return ERR_PTR(ret);
+}
+
+struct dma_buf *pl111_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj, int flags)
+{
+ struct dma_buf *new_buf;
+ struct pl111_gem_bo *bo;
+ size_t size;
+
+ DRM_DEBUG("DRM %s on dev=%p drm_gem_obj=%p\n", __func__, dev, obj);
+ size = obj->size;
+
+ new_buf = dma_buf_export(obj /*priv */ , &pl111_dma_buf_ops, size,
+ flags | O_RDWR);
+ bo = PL111_BO_FROM_GEM(new_buf->priv);
+
+ /*
+ * bo->gem_object.export_dma_buf not setup until after gem_prime_export
+ * finishes
+ */
+
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ /*
+ * Ensure that we hold the kds resource if it's the currently
+ * displayed buffer.
+ */
+ obtain_kds_if_currently_displayed(dev, bo, new_buf);
+#endif
+
+ DRM_DEBUG("Created dma_buf %p\n", new_buf);
+
+ return new_buf;
+}
+
+int pl111_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv,
+ uint32_t handle, uint32_t flags, int *prime_fd)
+{
+ int result;
+ /*
+ * This will re-use any existing exports, and calls
+ * driver->gem_prime_export to do the first export when needed
+ */
+ DRM_DEBUG_KMS("DRM %s on file_priv=%p, handle=0x%.8x\n", __func__,
+ file_priv, handle);
+
+ mutex_lock(&priv.export_dma_buf_lock);
+ result = drm_gem_prime_handle_to_fd(dev, file_priv, handle, flags,
+ prime_fd);
+ mutex_unlock(&priv.export_dma_buf_lock);
+
+ return result;
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_encoder.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_encoder.c
new file mode 100755
index 0000000..78c91c0
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_encoder.c
@@ -0,0 +1,107 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_encoder.c
+ * Implementation of the encoder functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "pl111_drm.h"
+
+bool pl111_encoder_helper_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ DRM_DEBUG_KMS("DRM %s on encoder=%p\n", __func__, encoder);
+ return true;
+}
+
+void pl111_encoder_helper_prepare(struct drm_encoder *encoder)
+{
+ DRM_DEBUG_KMS("DRM %s on encoder=%p\n", __func__, encoder);
+}
+
+void pl111_encoder_helper_commit(struct drm_encoder *encoder)
+{
+ DRM_DEBUG_KMS("DRM %s on encoder=%p\n", __func__, encoder);
+}
+
+void pl111_encoder_helper_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ DRM_DEBUG_KMS("DRM %s on encoder=%p\n", __func__, encoder);
+}
+
+void pl111_encoder_helper_disable(struct drm_encoder *encoder)
+{
+ DRM_DEBUG_KMS("DRM %s on encoder=%p\n", __func__, encoder);
+}
+
+void pl111_encoder_destroy(struct drm_encoder *encoder)
+{
+ struct pl111_drm_encoder *pl111_encoder =
+ PL111_ENCODER_FROM_ENCODER(encoder);
+
+ DRM_DEBUG_KMS("DRM %s on encoder=%p\n", __func__, encoder);
+
+ drm_encoder_cleanup(encoder);
+ kfree(pl111_encoder);
+}
+
+const struct drm_encoder_funcs encoder_funcs = {
+ .destroy = pl111_encoder_destroy,
+};
+
+const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+ .mode_fixup = pl111_encoder_helper_mode_fixup,
+ .prepare = pl111_encoder_helper_prepare,
+ .commit = pl111_encoder_helper_commit,
+ .mode_set = pl111_encoder_helper_mode_set,
+ .disable = pl111_encoder_helper_disable,
+};
+
+struct pl111_drm_encoder *pl111_encoder_create(struct drm_device *dev,
+ int possible_crtcs)
+{
+ struct pl111_drm_encoder *pl111_encoder;
+
+ pl111_encoder = kzalloc(sizeof(struct pl111_drm_encoder), GFP_KERNEL);
+ if (pl111_encoder == NULL) {
+ pr_err("Failed to allocated pl111_drm_encoder\n");
+ return NULL;
+ }
+
+ drm_encoder_init(dev, &pl111_encoder->encoder, &encoder_funcs,
+ DRM_MODE_ENCODER_DAC);
+
+ drm_encoder_helper_add(&pl111_encoder->encoder, &encoder_helper_funcs);
+
+ pl111_encoder->encoder.possible_crtcs = possible_crtcs;
+
+ return pl111_encoder;
+}
+
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_fb.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_fb.c
new file mode 100755
index 0000000..f575c9e
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_fb.c
@@ -0,0 +1,202 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_fb.c
+ * Implementation of the framebuffer functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_crtc.h>
+#include "pl111_drm.h"
+
+static void pl111_fb_destroy(struct drm_framebuffer *framebuffer)
+{
+ struct pl111_drm_framebuffer *pl111_fb;
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ struct drm_crtc *crtc;
+ unsigned long flags;
+#endif
+ DRM_DEBUG_KMS("Destroying framebuffer 0x%p...\n", framebuffer);
+
+ pl111_fb = PL111_FB_FROM_FRAMEBUFFER(framebuffer);
+
+ /*
+ * Because flips are deferred, wait for all previous flips to complete
+ */
+ wait_event(priv.wait_for_flips,
+ atomic_read(&priv.nr_flips_in_flight) == 0);
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ /*
+ * Release KDS resources if it's currently being displayed. Only occurs
+ * when the last framebuffer is destroyed.
+ */
+ list_for_each_entry(crtc, &framebuffer->dev->mode_config.crtc_list,
+ head) {
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+ spin_lock_irqsave(&pl111_crtc->current_displaying_lock, flags);
+ if (pl111_crtc->displaying_fb == framebuffer) {
+ /* Release the current buffers */
+ if (pl111_crtc->old_kds_res_set != NULL) {
+ DRM_DEBUG_KMS("Releasing KDS resources for ");
+ DRM_DEBUG_KMS("displayed 0x%p\n", framebuffer);
+ kds_resource_set_release(
+ &pl111_crtc->old_kds_res_set);
+ }
+ pl111_crtc->old_kds_res_set = NULL;
+ }
+ spin_unlock_irqrestore(&pl111_crtc->current_displaying_lock,
+ flags);
+ }
+#endif
+ drm_framebuffer_cleanup(framebuffer);
+
+ if ((pl111_fb->bo != NULL) && (&pl111_fb->bo->gem_object != NULL))
+ drm_gem_object_unreference_unlocked(&pl111_fb->bo->gem_object);
+
+ kfree(pl111_fb);
+
+ DRM_DEBUG_KMS("Destroyed framebuffer 0x%p\n", framebuffer);
+}
+
+static int pl111_fb_create_handle(struct drm_framebuffer *fb,
+ struct drm_file *file_priv,
+ unsigned int *handle)
+{
+ struct pl111_gem_bo *bo = PL111_BO_FROM_FRAMEBUFFER(fb);
+ DRM_DEBUG_KMS("DRM %s on fb=%p\n", __func__, fb);
+
+ if (bo == NULL)
+ return -EINVAL;
+
+ return drm_gem_handle_create(file_priv, &bo->gem_object, handle);
+}
+
+const struct drm_framebuffer_funcs fb_funcs = {
+ .destroy = pl111_fb_destroy,
+ .create_handle = pl111_fb_create_handle,
+};
+
+struct drm_framebuffer *pl111_fb_create(struct drm_device *dev,
+ struct drm_file *file_priv,
+ struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ struct pl111_drm_framebuffer *pl111_fb = NULL;
+ struct drm_framebuffer *fb = NULL;
+ struct drm_gem_object *gem_obj;
+ struct pl111_gem_bo *bo;
+ int err = 0;
+ size_t min_size;
+ int bpp;
+ int depth;
+
+ pr_info("DRM %s\n", __func__);
+ gem_obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
+ if (gem_obj == NULL) {
+ DRM_ERROR("Could not get gem obj from handle to create fb\n");
+ err = -ENOENT;
+ goto error;
+ }
+
+ bo = PL111_BO_FROM_GEM(gem_obj);
+ drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
+
+ if (mode_cmd->pitches[0] < mode_cmd->width * (bpp >> 3)) {
+ DRM_ERROR("bad pitch %u for plane 0\n", mode_cmd->pitches[0]);
+ err = -EINVAL;
+ goto error;
+ }
+
+ min_size = (mode_cmd->height - 1) * mode_cmd->pitches[0]
+ + mode_cmd->width * (bpp >> 3);
+
+ if (bo->gem_object.size < min_size) {
+ DRM_ERROR("gem obj size < min size\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ /* We can't scan out SHM so we can't create an fb for it */
+ if (!(bo->type & PL111_BOT_DMA)) {
+ DRM_ERROR("Can't create FB for non-scanout buffer\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ switch ((char)(mode_cmd->pixel_format & 0xFF)) {
+ case 'Y':
+ case 'U':
+ case 'V':
+ case 'N':
+ case 'T':
+ DRM_ERROR("YUV formats not supported\n");
+ err = -EINVAL;
+ goto error;
+ }
+
+ pl111_fb = kzalloc(sizeof(struct pl111_drm_framebuffer), GFP_KERNEL);
+ if (pl111_fb == NULL) {
+ DRM_ERROR("Could not allocate pl111_drm_framebuffer\n");
+ err = -ENOMEM;
+ goto error;
+ }
+ fb = &pl111_fb->fb;
+
+ err = drm_framebuffer_init(dev, fb, &fb_funcs);
+ if (err) {
+ DRM_ERROR("drm_framebuffer_init failed\n");
+ kfree(fb);
+ fb = NULL;
+ goto error;
+ }
+
+ drm_helper_mode_fill_fb_struct(fb, mode_cmd);
+
+ /* The only framebuffer formats supported by pl111
+ * are 16 bpp or 32 bpp with 24 bit depth.
+ * See clcd_enable()
+ */
+ if (!((fb->bits_per_pixel == 16) ||
+ (fb->bits_per_pixel == 32 && fb->depth == 24))) {
+ DRM_DEBUG_KMS("unsupported pixel format bpp=%d, depth=%d\n", fb->bits_per_pixel, fb->depth);
+ drm_framebuffer_cleanup(fb);
+ kfree(fb);
+ fb = NULL;
+ err = -EINVAL;
+ goto error;
+ }
+
+ pl111_fb->bo = bo;
+
+ DRM_DEBUG_KMS("Created fb 0x%p with gem_obj 0x%p physaddr=0x%.8x\n",
+ fb, gem_obj, bo->backing_data.dma.fb_dev_addr);
+
+ return fb;
+
+error:
+ if (gem_obj != NULL)
+ drm_gem_object_unreference_unlocked(gem_obj);
+
+ return ERR_PTR(err);
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_funcs.h b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_funcs.h
new file mode 100755
index 0000000..494baa0
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_funcs.h
@@ -0,0 +1,130 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_funcs.h
+ * Function prototypes for PL111 DRM
+ */
+
+#ifndef PL111_DRM_FUNCS_H_
+#define PL111_DRM_FUNCS_H_
+
+/* Platform Initialisation */
+int pl111_drm_init(struct platform_device *dev);
+void pl111_drm_exit(struct platform_device *dev);
+
+/* KDS Callbacks */
+void show_framebuffer_on_crtc_cb(void *cb1, void *cb2);
+void release_kds_resource_and_display(struct pl111_drm_flip_resource *flip_res);
+
+/* CRTC Functions */
+struct pl111_drm_crtc *pl111_crtc_create(struct drm_device *dev);
+struct pl111_drm_crtc *pl111_crtc_dummy_create(struct drm_device *dev);
+void pl111_crtc_destroy(struct drm_crtc *crtc);
+
+bool pl111_crtc_is_fb_currently_displayed(struct drm_device *dev,
+ struct drm_framebuffer *fb);
+
+int show_framebuffer_on_crtc(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, bool page_flip,
+ struct drm_pending_vblank_event *event);
+
+/* Common IRQ handler */
+void pl111_common_irq(struct pl111_drm_crtc *pl111_crtc);
+
+int pl111_crtc_cursor_set(struct drm_crtc *crtc,
+ struct drm_file *file_priv,
+ uint32_t handle,
+ uint32_t width,
+ uint32_t height);
+int pl111_crtc_cursor_move(struct drm_crtc *crtc,
+ int x, int y);
+
+/* Connector Functions */
+struct pl111_drm_connector *pl111_connector_create(struct drm_device *dev);
+void pl111_connector_destroy(struct drm_connector *connector);
+struct pl111_drm_connector *pl111_connector_dummy_create(struct drm_device
+ *dev);
+
+/* Encoder Functions */
+struct pl111_drm_encoder *pl111_encoder_create(struct drm_device *dev,
+ int possible_crtcs);
+struct pl111_drm_encoder *pl111_encoder_dummy_create(struct drm_device *dev,
+ int possible_crtcs);
+void pl111_encoder_destroy(struct drm_encoder *encoder);
+
+/* Frame Buffer Functions */
+struct drm_framebuffer *pl111_fb_create(struct drm_device *dev,
+ struct drm_file *file_priv,
+ struct drm_mode_fb_cmd2 *mode_cmd);
+
+/* VMA Functions */
+int pl111_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+int pl111_gem_mmap(struct file *file_priv, struct vm_area_struct *vma);
+struct page **get_pages(struct drm_gem_object *obj);
+void put_pages(struct drm_gem_object *obj, struct page **pages);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
+void pl111_drm_vm_open_locked(struct drm_device *dev,
+ struct vm_area_struct *vma);
+void pl111_gem_vm_open(struct vm_area_struct *vma);
+void pl111_gem_vm_close(struct vm_area_struct *vma);
+#endif
+
+/* Suspend Functions */
+int pl111_drm_resume(struct drm_device *dev);
+int pl111_drm_suspend(struct drm_device *dev, pm_message_t state);
+
+/* GEM Functions */
+int pl111_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args);
+int pl111_dumb_destroy(struct drm_file *file_priv,
+ struct drm_device *dev, uint32_t handle);
+int pl111_dumb_map_offset(struct drm_file *file_priv,
+ struct drm_device *dev, uint32_t handle,
+ uint64_t *offset);
+void pl111_gem_free_object(struct drm_gem_object *obj);
+
+int pl111_bo_mmap(struct drm_gem_object *obj, struct pl111_gem_bo *bo,
+ struct vm_area_struct *vma, size_t size);
+void pl111_gem_sync_to_cpu(struct pl111_gem_bo *bo, int pgoff);
+void pl111_gem_sync_to_dma(struct pl111_gem_bo *bo);
+
+/* DMA BUF Functions */
+struct drm_gem_object *pl111_gem_prime_import(struct drm_device *dev,
+ struct dma_buf *dma_buf);
+int pl111_prime_handle_to_fd(struct drm_device *dev, struct drm_file *file_priv,
+ uint32_t handle, uint32_t flags, int *prime_fd);
+struct dma_buf *pl111_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj, int flags);
+
+/* Pl111 Functions */
+void show_framebuffer_on_crtc_cb_internal(struct pl111_drm_flip_resource
+ *flip_res, struct drm_framebuffer *fb);
+int clcd_disable(struct drm_crtc *crtc);
+void do_flip_to_res(struct pl111_drm_flip_resource *flip_res);
+int pl111_amba_probe(struct amba_device *dev, const struct amba_id *id);
+int pl111_amba_remove(struct amba_device *dev);
+
+int pl111_device_init(struct drm_device *dev);
+void pl111_device_fini(struct drm_device *dev);
+
+void pl111_convert_drm_mode_to_timing(struct drm_display_mode *mode,
+ struct clcd_regs *timing);
+void pl111_convert_timing_to_drm_mode(struct clcd_regs *timing,
+ struct drm_display_mode *mode);
+#endif /* PL111_DRM_FUNCS_H_ */
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_gem.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_gem.c
new file mode 100755
index 0000000..13fb256
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_gem.c
@@ -0,0 +1,476 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_gem.c
+ * Implementation of the GEM functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <asm/cacheflush.h>
+#include <asm/outercache.h>
+#include "pl111_drm.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+#include <linux/dma-attrs.h>
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+#include <drm/drm_vma_manager.h>
+#endif
+
+void pl111_gem_free_object(struct drm_gem_object *obj)
+{
+ struct pl111_gem_bo *bo;
+ struct drm_device *dev = obj->dev;
+ DRM_DEBUG_KMS("DRM %s on drm_gem_object=%p\n", __func__, obj);
+
+ bo = PL111_BO_FROM_GEM(obj);
+
+ if (obj->import_attach)
+ drm_prime_gem_destroy(obj, bo->sgt);
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+ if (obj->map_list.map != NULL)
+ drm_gem_free_mmap_offset(obj);
+#else
+ drm_gem_free_mmap_offset(obj);
+#endif
+ /*
+ * Only free the backing memory if the object has not been imported.
+ * If it has been imported, the exporter is in charge to free that
+ * once dmabuf's refcount becomes 0.
+ */
+ if (obj->import_attach)
+ goto imported_out;
+
+ if (bo->type & PL111_BOT_DMA) {
+ dma_free_writecombine(dev->dev, obj->size,
+ bo->backing_data.dma.fb_cpu_addr,
+ bo->backing_data.dma.fb_dev_addr);
+ } else if (bo->backing_data.shm.pages != NULL) {
+ put_pages(obj, bo->backing_data.shm.pages);
+ }
+
+imported_out:
+ drm_gem_object_release(obj);
+
+ kfree(bo);
+
+ DRM_DEBUG_KMS("Destroyed dumb_bo handle 0x%p\n", bo);
+}
+
+static int pl111_gem_object_create(struct drm_device *dev, u64 size,
+ u32 flags, struct drm_file *file_priv,
+ u32 *handle)
+{
+ int ret = 0;
+ struct pl111_gem_bo *bo = NULL;
+
+ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+ if (bo == NULL) {
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ bo->type = flags;
+
+#ifndef ARCH_HAS_SG_CHAIN
+ /*
+ * If the ARCH can't chain we can't have non-contiguous allocs larger
+ * than a single sg can hold.
+ * In this case we fall back to using contiguous memory
+ */
+ if (!(bo->type & PL111_BOT_DMA)) {
+ long unsigned int n_pages =
+ PAGE_ALIGN(size) >> PAGE_SHIFT;
+ if (n_pages > SG_MAX_SINGLE_ALLOC) {
+ bo->type |= PL111_BOT_DMA;
+ /*
+ * Non-contiguous allocation request changed to
+ * contigous
+ */
+ DRM_INFO("non-contig alloc to contig %lu > %lu pages.",
+ n_pages, SG_MAX_SINGLE_ALLOC);
+ }
+ }
+#endif
+ if (bo->type & PL111_BOT_DMA) {
+ /* scanout compatible - use physically contiguous buffer */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ DEFINE_DMA_ATTRS(attrs);
+
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ bo->backing_data.dma.fb_cpu_addr =
+ dma_alloc_attrs(dev->dev, size,
+ &bo->backing_data.dma.fb_dev_addr,
+ GFP_KERNEL,
+ &attrs);
+ if (bo->backing_data.dma.fb_cpu_addr == NULL) {
+ DRM_ERROR("dma_alloc_attrs failed\n");
+ ret = -ENOMEM;
+ goto free_bo;
+ }
+#else
+ bo->backing_data.dma.fb_cpu_addr =
+ dma_alloc_writecombine(dev->dev, size,
+ &bo->backing_data.dma.fb_dev_addr,
+ GFP_KERNEL);
+ if (bo->backing_data.dma.fb_cpu_addr == NULL) {
+ DRM_ERROR("dma_alloc_writecombine failed\n");
+ ret = -ENOMEM;
+ goto free_bo;
+ }
+#endif
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+ ret = drm_gem_private_object_init(dev, &bo->gem_object,
+ size);
+ if (ret != 0) {
+ DRM_ERROR("DRM could not initialise GEM object\n");
+ goto free_dma;
+ }
+#else
+ drm_gem_private_object_init(dev, &bo->gem_object, size);
+#endif
+
+ } else { /* PL111_BOT_SHM */
+ /* not scanout compatible - use SHM backed object */
+ ret = drm_gem_object_init(dev, &bo->gem_object, size);
+ if (ret != 0) {
+ DRM_ERROR("DRM could not init SHM backed GEM obj\n");
+ ret = -ENOMEM;
+ goto free_bo;
+ }
+ DRM_DEBUG_KMS("Num bytes: %d\n", bo->gem_object.size);
+ }
+
+ DRM_DEBUG("s=%llu, flags=0x%x, %s 0x%.8lx, type=%d\n",
+ size, flags,
+ (bo->type & PL111_BOT_DMA) ? "physaddr" : "shared page array",
+ (bo->type & PL111_BOT_DMA) ?
+ (unsigned long)bo->backing_data.dma.fb_dev_addr:
+ (unsigned long)bo->backing_data.shm.pages,
+ bo->type);
+
+ ret = drm_gem_handle_create(file_priv, &bo->gem_object, handle);
+ if (ret != 0) {
+ DRM_ERROR("DRM failed to create GEM handle\n");
+ goto obj_release;
+ }
+
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(&bo->gem_object);
+
+ return 0;
+
+obj_release:
+ drm_gem_object_release(&bo->gem_object);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+free_dma:
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+ if (bo->type & PL111_BOT_DMA) {
+ DEFINE_DMA_ATTRS(attrs);
+
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ dma_free_attrs(dev->dev, size,
+ bo->backing_data.dma.fb_cpu_addr,
+ bo->backing_data.dma.fb_dev_addr,
+ &attrs);
+ }
+#else
+ if (bo->type & PL111_BOT_DMA)
+ dma_free_writecombine(dev->dev, size,
+ bo->backing_data.dma.fb_cpu_addr,
+ bo->backing_data.dma.fb_dev_addr);
+#endif
+free_bo:
+ kfree(bo);
+finish:
+ return ret;
+}
+
+int pl111_drm_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_pl111_gem_create *args = data;
+ uint32_t bytes_pp;
+
+ /* Round bpp up, to allow for case where bpp<8 */
+ bytes_pp = args->bpp >> 3;
+ if (args->bpp & ((1 << 3) - 1))
+ bytes_pp++;
+
+ if (args->flags & ~PL111_BOT_MASK) {
+ DRM_ERROR("wrong flags: 0x%x\n", args->flags);
+ return -EINVAL;
+ }
+
+ args->pitch = ALIGN(args->width * bytes_pp, 64);
+ args->size = PAGE_ALIGN(args->pitch * args->height);
+
+ DRM_DEBUG_KMS("gem_create w=%d h=%d p=%d bpp=%d b=%d s=%llu f=0x%x\n",
+ args->width, args->height, args->pitch, args->bpp,
+ bytes_pp, args->size, args->flags);
+
+ return pl111_gem_object_create(dev, args->size, args->flags, file_priv,
+ &args->handle);
+}
+
+int pl111_dumb_create(struct drm_file *file_priv,
+ struct drm_device *dev, struct drm_mode_create_dumb *args)
+{
+ uint32_t bytes_pp;
+
+ /* Round bpp up, to allow for case where bpp<8 */
+ bytes_pp = args->bpp >> 3;
+ if (args->bpp & ((1 << 3) - 1))
+ bytes_pp++;
+
+ if (args->flags) {
+ DRM_ERROR("flags must be zero: 0x%x\n", args->flags);
+ return -EINVAL;
+ }
+
+ args->pitch = ALIGN(args->width * bytes_pp, 64);
+ args->size = PAGE_ALIGN(args->pitch * args->height);
+
+ DRM_DEBUG_KMS("dumb_create w=%d h=%d p=%d bpp=%d b=%d s=%llu f=0x%x\n",
+ args->width, args->height, args->pitch, args->bpp,
+ bytes_pp, args->size, args->flags);
+
+ return pl111_gem_object_create(dev, args->size,
+ PL111_BOT_DMA | PL111_BOT_UNCACHED,
+ file_priv, &args->handle);
+}
+
+int pl111_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev,
+ uint32_t handle)
+{
+ DRM_DEBUG_KMS("DRM %s on file_priv=%p handle=0x%.8x\n", __func__,
+ file_priv, handle);
+ return drm_gem_handle_delete(file_priv, handle);
+}
+
+int pl111_dumb_map_offset(struct drm_file *file_priv,
+ struct drm_device *dev, uint32_t handle,
+ uint64_t *offset)
+{
+ struct drm_gem_object *obj;
+ int ret = 0;
+ DRM_DEBUG_KMS("DRM %s on file_priv=%p handle=0x%.8x\n", __func__,
+ file_priv, handle);
+
+ /* GEM does all our handle to object mapping */
+ obj = drm_gem_object_lookup(dev, file_priv, handle);
+ if (obj == NULL) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+ if (obj->map_list.map == NULL) {
+ ret = drm_gem_create_mmap_offset(obj);
+ if (ret != 0) {
+ drm_gem_object_unreference_unlocked(obj);
+ goto fail;
+ }
+ }
+#else
+ ret = drm_gem_create_mmap_offset(obj);
+ if (ret != 0) {
+ drm_gem_object_unreference_unlocked(obj);
+ goto fail;
+ }
+#endif
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 0))
+ *offset = (uint64_t) obj->map_list.hash.key << PAGE_SHIFT;
+#else
+ *offset = drm_vma_node_offset_addr(&obj->vma_node);
+ DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
+#endif
+
+ drm_gem_object_unreference_unlocked(obj);
+fail:
+ return ret;
+}
+
+/* sync the buffer for DMA access */
+void pl111_gem_sync_to_dma(struct pl111_gem_bo *bo)
+{
+ struct drm_device *dev = bo->gem_object.dev;
+
+ if (!(bo->type & PL111_BOT_DMA) && (bo->type & PL111_BOT_CACHED)) {
+ int i, npages = bo->gem_object.size >> PAGE_SHIFT;
+ struct page **pages = bo->backing_data.shm.pages;
+ bool dirty = false;
+
+ for (i = 0; i < npages; i++) {
+ if (!bo->backing_data.shm.dma_addrs[i]) {
+ DRM_DEBUG("%s: dma map page=%d bo=%p\n", __func__, i, bo);
+ bo->backing_data.shm.dma_addrs[i] =
+ dma_map_page(dev->dev, pages[i], 0,
+ PAGE_SIZE, DMA_BIDIRECTIONAL);
+ dirty = true;
+ }
+ }
+
+ if (dirty) {
+ DRM_DEBUG("%s: zap ptes (and flush cache) bo=%p\n", __func__, bo);
+ /*
+ * TODO MIDEGL-1813
+ *
+ * Use flush_cache_page() and outer_flush_range() to
+ * flush only the user space mappings of the dirty pages
+ */
+ flush_cache_all();
+ outer_flush_all();
+ unmap_mapping_range(bo->gem_object.filp->f_mapping, 0,
+ bo->gem_object.size, 1);
+ }
+ }
+}
+
+void pl111_gem_sync_to_cpu(struct pl111_gem_bo *bo, int pgoff)
+{
+ struct drm_device *dev = bo->gem_object.dev;
+
+ /*
+ * TODO MIDEGL-1808
+ *
+ * The following check was meant to detect if the CPU is trying to access
+ * a buffer that is currently mapped for DMA accesses, which is illegal
+ * as described by the DMA-API.
+ *
+ * However, some of our tests are trying to do that, which triggers the message
+ * below and avoids dma-unmapping the pages not to annoy the DMA device but that
+ * leads to the test failing because of caches not being properly flushed.
+ */
+
+ /*
+ if (bo->sgt) {
+ DRM_ERROR("%s: the CPU is trying to access a dma-mapped buffer\n", __func__);
+ return;
+ }
+ */
+
+ if (!(bo->type & PL111_BOT_DMA) && (bo->type & PL111_BOT_CACHED) &&
+ bo->backing_data.shm.dma_addrs[pgoff]) {
+ DRM_DEBUG("%s: unmap bo=%p (s=%d), paddr=%08x\n",
+ __func__, bo, bo->gem_object.size,
+ bo->backing_data.shm.dma_addrs[pgoff]);
+ dma_unmap_page(dev->dev, bo->backing_data.shm.dma_addrs[pgoff],
+ PAGE_SIZE, DMA_BIDIRECTIONAL);
+ bo->backing_data.shm.dma_addrs[pgoff] = 0;
+ }
+}
+
+/* Based on omapdrm driver */
+int pl111_bo_mmap(struct drm_gem_object *obj, struct pl111_gem_bo *bo,
+ struct vm_area_struct *vma, size_t size)
+{
+ DRM_DEBUG("DRM %s on drm_gem_object=%p, pl111_gem_bo=%p type=%08x\n",
+ __func__, obj, bo, bo->type);
+
+ vma->vm_flags &= ~VM_PFNMAP;
+ vma->vm_flags |= VM_MIXEDMAP;
+
+ if (bo->type & PL111_BOT_WC) {
+ vma->vm_page_prot =
+ pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+ } else if (bo->type & PL111_BOT_CACHED) {
+ /*
+ * Objects that do not have a filp (DMA backed) can't be
+ * mapped as cached now. Write-combine should be enough.
+ */
+ if (WARN_ON(!obj->filp))
+ return -EINVAL;
+
+ /*
+ * As explained in Documentation/dma-buf-sharing.txt
+ * we need this trick so that we can manually zap ptes
+ * in order to fake coherency.
+ */
+ fput(vma->vm_file);
+ get_file(obj->filp);
+ vma->vm_file = obj->filp;
+
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ } else { /* PL111_BOT_UNCACHED */
+ vma->vm_page_prot =
+ pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+ }
+ return 0;
+}
+
+int pl111_gem_mmap(struct file *file_priv, struct vm_area_struct *vma)
+{
+ int ret;
+ struct drm_file *priv = file_priv->private_data;
+ struct drm_device *dev = priv->minor->dev;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 13, 0))
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_hash_item *hash;
+ struct drm_local_map *map = NULL;
+#else
+ struct drm_vma_offset_node *node;
+#endif
+ struct drm_gem_object *obj;
+ struct pl111_gem_bo *bo;
+
+ DRM_DEBUG_KMS("DRM %s\n", __func__);
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 13, 0))
+ drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash);
+ map = drm_hash_entry(hash, struct drm_map_list, hash)->map;
+ obj = map->handle;
+#else
+ node = drm_vma_offset_exact_lookup(dev->vma_offset_manager,
+ vma->vm_pgoff,
+ vma_pages(vma));
+ obj = container_of(node, struct drm_gem_object, vma_node);
+#endif
+ bo = PL111_BO_FROM_GEM(obj);
+
+ DRM_DEBUG_KMS("DRM %s on pl111_gem_bo %p bo->type 0x%08x\n", __func__, bo, bo->type);
+
+ /* for an imported buffer we let the exporter handle the mmap */
+ if (obj->import_attach)
+ return dma_buf_mmap(obj->import_attach->dmabuf, vma, 0);
+
+ ret = drm_gem_mmap(file_priv, vma);
+ if (ret < 0) {
+ DRM_ERROR("failed to mmap\n");
+ return ret;
+ }
+
+ /* Our page fault handler uses the page offset calculated from the vma,
+ * so we need to remove the gem cookie offset specified in the call.
+ */
+ vma->vm_pgoff = 0;
+
+ return pl111_bo_mmap(obj, bo, vma, vma->vm_end - vma->vm_start);
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_pl111.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_pl111.c
new file mode 100755
index 0000000..1d613d0
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_pl111.c
@@ -0,0 +1,417 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2014 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_pl111.c
+ * PL111 specific functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "pl111_drm.h"
+
+/* This can't be called from IRQ context, due to clk_get() and board->enable */
+static int clcd_enable(struct drm_framebuffer *fb)
+{
+ __u32 cntl;
+ struct clcd_board *board;
+
+ pr_info("DRM %s\n", __func__);
+
+ clk_prepare_enable(priv.clk);
+
+ /* Enable and Power Up */
+ cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDPWR | CNTL_LCDVCOMP(1);
+ DRM_DEBUG_KMS("fb->bits_per_pixel = %d\n", fb->bits_per_pixel);
+ if (fb->bits_per_pixel == 16)
+ cntl |= CNTL_LCDBPP16_565;
+ else if (fb->bits_per_pixel == 32 && fb->depth == 24)
+ cntl |= CNTL_LCDBPP24;
+ else
+ BUG_ON(1);
+
+ cntl |= CNTL_BGR;
+
+ writel(cntl, priv.regs + CLCD_PL111_CNTL);
+
+ if (priv.amba_dev->dev.platform_data) {
+ board = priv.amba_dev->dev.platform_data;
+
+ if (board->enable)
+ board->enable(NULL);
+ }
+
+ /* Enable Interrupts */
+ writel(CLCD_IRQ_NEXTBASE_UPDATE, priv.regs + CLCD_PL111_IENB);
+
+ return 0;
+}
+
+int clcd_disable(struct drm_crtc *crtc)
+{
+ struct clcd_board *board;
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ unsigned long flags;
+#endif
+
+ pr_info("DRM %s\n", __func__);
+
+ /* Disable Interrupts */
+ writel(0x00000000, priv.regs + CLCD_PL111_IENB);
+
+ if (priv.amba_dev->dev.platform_data) {
+ board = priv.amba_dev->dev.platform_data;
+
+ if (board->disable)
+ board->disable(NULL);
+ }
+
+ /* Disable and Power Down */
+ writel(0, priv.regs + CLCD_PL111_CNTL);
+
+ /* Disable clock */
+ clk_disable_unprepare(priv.clk);
+
+ pl111_crtc->last_bpp = 0;
+#ifdef CONFIG_DMA_SHARED_BUFFER_USES_KDS
+ spin_lock_irqsave(&pl111_crtc->current_displaying_lock, flags);
+ /* Release the previous buffers */
+ if (pl111_crtc->old_kds_res_set != NULL)
+ kds_resource_set_release(&pl111_crtc->old_kds_res_set);
+
+ pl111_crtc->old_kds_res_set = NULL;
+ spin_unlock_irqrestore(&pl111_crtc->current_displaying_lock, flags);
+#endif
+ return 0;
+}
+
+/*
+ * To avoid a possible race where "pl111_crtc->current_update_res" has
+ * been updated (non NULL) but the corresponding scanout buffer has not been
+ * written to the base registers we must always call this function holding
+ * the "base_update_lock" spinlock with IRQs disabled (spin_lock_irqsave()).
+ */
+void do_flip_to_res(struct pl111_drm_flip_resource *flip_res)
+{
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(flip_res->crtc);
+ struct drm_framebuffer *fb;
+ struct pl111_gem_bo *bo;
+ size_t min_size;
+ fb = flip_res->fb;
+ bo = PL111_BO_FROM_FRAMEBUFFER(fb);
+
+
+
+ min_size = (fb->height - 1) * fb->pitches[0]
+ + fb->width * (fb->bits_per_pixel >> 3);
+
+ BUG_ON(bo->gem_object.size < min_size);
+
+ /* Don't even attempt PL111_BOT_SHM, it's not contiguous */
+ BUG_ON(bo->type != PL111_BOT_DMA);
+
+ /*
+ * Note the buffer for releasing after IRQ, and don't allow any more
+ * updates until then.
+ *
+ * This clcd controller latches the new address on next vsync. Address
+ * latching is indicated by CLCD_IRQ_NEXTBASE_UPDATE, and so we must
+ * wait for that before releasing the previous buffer's kds
+ * resources. Otherwise, we'll allow writers to write to the old buffer
+ * whilst it is still being displayed
+ */
+ pl111_crtc->current_update_res = flip_res;
+
+ DRM_DEBUG_KMS("Displaying fb 0x%p, dumb_bo 0x%p, physaddr %.8x\n",
+ fb, bo, bo->backing_data.dma.fb_dev_addr);
+
+ if (drm_vblank_get(pl111_crtc->crtc.dev, pl111_crtc->crtc_index) < 0)
+ DRM_ERROR("Could not get vblank reference for crtc %d\n",
+ pl111_crtc->crtc_index);
+
+ /* Set the scanout buffer */
+ writel(bo->backing_data.dma.fb_dev_addr, priv.regs + CLCD_UBAS);
+ writel(bo->backing_data.dma.fb_dev_addr +
+ ((fb->height - 1) * fb->pitches[0]), priv.regs + CLCD_LBAS);
+}
+
+void
+show_framebuffer_on_crtc_cb_internal(struct pl111_drm_flip_resource *flip_res,
+ struct drm_framebuffer *fb)
+{
+ unsigned long irq_flags;
+ struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(flip_res->crtc);
+
+ spin_lock_irqsave(&pl111_crtc->base_update_lock, irq_flags);
+ if (list_empty(&pl111_crtc->update_queue) &&
+ !pl111_crtc->current_update_res) {
+ do_flip_to_res(flip_res);
+ } else {
+ /*
+ * Enqueue the update to occur on a future IRQ
+ * This only happens on triple-or-greater buffering
+ */
+ DRM_DEBUG_KMS("Deferring 3+ buffered flip to fb %p to IRQ\n",
+ fb);
+ list_add_tail(&flip_res->link, &pl111_crtc->update_queue);
+ }
+ spin_unlock_irqrestore(&pl111_crtc->base_update_lock, irq_flags);
+
+ if (!flip_res->page_flip && (pl111_crtc->last_bpp == 0 ||
+ pl111_crtc->last_bpp != fb->bits_per_pixel ||
+ !drm_mode_equal(pl111_crtc->new_mode,
+ pl111_crtc->current_mode))) {
+ struct clcd_regs timing;
+
+ pl111_convert_drm_mode_to_timing(pl111_crtc->new_mode, &timing);
+
+ DRM_DEBUG_KMS("Set timing: %08X:%08X:%08X:%08X clk=%ldHz\n",
+ timing.tim0, timing.tim1, timing.tim2,
+ timing.tim3, timing.pixclock);
+
+ /* This is the actual mode setting part */
+ clk_set_rate(priv.clk, timing.pixclock);
+
+ writel(timing.tim0, priv.regs + CLCD_TIM0);
+ writel(timing.tim1, priv.regs + CLCD_TIM1);
+ writel(timing.tim2, priv.regs + CLCD_TIM2);
+ writel(timing.tim3, priv.regs + CLCD_TIM3);
+
+ clcd_enable(fb);
+ pl111_crtc->last_bpp = fb->bits_per_pixel;
+ }
+
+ if (!flip_res->page_flip) {
+ drm_mode_destroy(flip_res->crtc->dev, pl111_crtc->current_mode);
+ pl111_crtc->current_mode = pl111_crtc->new_mode;
+ pl111_crtc->new_mode = NULL;
+ }
+
+ BUG_ON(!pl111_crtc->current_mode);
+
+ /*
+ * If IRQs weren't enabled before, they are now. This will eventually
+ * cause flip_res to be released via pl111_common_irq, which updates
+ * every time the Base Address is latched (i.e. every frame, regardless
+ * of whether we update the base address or not)
+ */
+}
+
+irqreturn_t pl111_irq(int irq, void *data)
+{
+ u32 irq_stat;
+ struct pl111_drm_crtc *pl111_crtc = priv.pl111_crtc;
+
+ irq_stat = readl(priv.regs + CLCD_PL111_MIS);
+
+ if (!irq_stat)
+ return IRQ_NONE;
+
+ if (irq_stat & CLCD_IRQ_NEXTBASE_UPDATE)
+ pl111_common_irq(pl111_crtc);
+
+ /* Clear the interrupt once done */
+ writel(irq_stat, priv.regs + CLCD_PL111_ICR);
+
+ return IRQ_HANDLED;
+}
+
+int pl111_device_init(struct drm_device *dev)
+{
+ struct pl111_drm_dev_private *priv = dev->dev_private;
+ int ret;
+
+ if (priv == NULL) {
+ pr_err("%s no private data\n", __func__);
+ return -EINVAL;
+ }
+
+ if (priv->amba_dev == NULL) {
+ pr_err("%s no amba device found\n", __func__);
+ return -EINVAL;
+ }
+
+ /* set up MMIO for register access */
+ priv->mmio_start = priv->amba_dev->res.start;
+ priv->mmio_len = resource_size(&priv->amba_dev->res);
+
+ DRM_DEBUG_KMS("mmio_start=%lu, mmio_len=%u\n", priv->mmio_start,
+ priv->mmio_len);
+
+ priv->regs = ioremap(priv->mmio_start, priv->mmio_len);
+ if (priv->regs == NULL) {
+ pr_err("%s failed mmio\n", __func__);
+ return -EINVAL;
+ }
+
+ /* turn off interrupts */
+ writel(0, priv->regs + CLCD_PL111_IENB);
+
+ ret = request_irq(priv->amba_dev->irq[0], pl111_irq, 0,
+ "pl111_irq_handler", NULL);
+ if (ret != 0) {
+ pr_err("%s failed %d\n", __func__, ret);
+ goto out_mmio;
+ }
+
+ goto finish;
+
+out_mmio:
+ iounmap(priv->regs);
+finish:
+ DRM_DEBUG_KMS("pl111_device_init returned %d\n", ret);
+ return ret;
+}
+
+void pl111_device_fini(struct drm_device *dev)
+{
+ struct pl111_drm_dev_private *priv = dev->dev_private;
+ u32 cntl;
+
+ if (priv == NULL || priv->regs == NULL)
+ return;
+
+ free_irq(priv->amba_dev->irq[0], NULL);
+
+ cntl = readl(priv->regs + CLCD_PL111_CNTL);
+
+ cntl &= ~CNTL_LCDEN;
+ writel(cntl, priv->regs + CLCD_PL111_CNTL);
+
+ cntl &= ~CNTL_LCDPWR;
+ writel(cntl, priv->regs + CLCD_PL111_CNTL);
+
+ iounmap(priv->regs);
+}
+
+int pl111_amba_probe(struct amba_device *dev, const struct amba_id *id)
+{
+ struct clcd_board *board = dev->dev.platform_data;
+ int ret;
+ pr_info("DRM %s\n", __func__);
+
+ if (!board)
+ dev_warn(&dev->dev, "board data not available\n");
+
+ ret = amba_request_regions(dev, NULL);
+ if (ret != 0) {
+ DRM_ERROR("CLCD: unable to reserve regs region\n");
+ goto out;
+ }
+
+ priv.amba_dev = dev;
+
+ priv.clk = clk_get(&priv.amba_dev->dev, NULL);
+ if (IS_ERR(priv.clk)) {
+ DRM_ERROR("CLCD: unable to get clk.\n");
+ ret = PTR_ERR(priv.clk);
+ goto clk_err;
+ }
+
+ return 0;
+
+clk_err:
+ amba_release_regions(dev);
+out:
+ return ret;
+}
+
+int pl111_amba_remove(struct amba_device *dev)
+{
+ DRM_DEBUG_KMS("DRM %s\n", __func__);
+
+ clk_put(priv.clk);
+
+ amba_release_regions(dev);
+
+ priv.amba_dev = NULL;
+
+ return 0;
+}
+
+void pl111_convert_drm_mode_to_timing(struct drm_display_mode *mode,
+ struct clcd_regs *timing)
+{
+ unsigned int ppl, hsw, hfp, hbp;
+ unsigned int lpp, vsw, vfp, vbp;
+ unsigned int cpl;
+
+ memset(timing, 0, sizeof(struct clcd_regs));
+
+ ppl = (mode->hdisplay / 16) - 1;
+ hsw = mode->hsync_end - mode->hsync_start - 1;
+ hfp = mode->hsync_start - mode->hdisplay - 1;
+ hbp = mode->htotal - mode->hsync_end - 1;
+
+ lpp = mode->vdisplay - 1;
+ vsw = mode->vsync_end - mode->vsync_start - 1;
+ vfp = mode->vsync_start - mode->vdisplay;
+ vbp = mode->vtotal - mode->vsync_end;
+
+ cpl = mode->hdisplay - 1;
+
+ timing->tim0 = (ppl << 2) | (hsw << 8) | (hfp << 16) | (hbp << 24);
+ timing->tim1 = lpp | (vsw << 10) | (vfp << 16) | (vbp << 24);
+ timing->tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC | TIM2_BCD | (cpl << 16);
+ timing->tim3 = 0;
+
+ timing->pixclock = mode->clock * 1000;
+}
+
+void pl111_convert_timing_to_drm_mode(struct clcd_regs *timing,
+ struct drm_display_mode *mode)
+{
+ unsigned int ppl, hsw, hfp, hbp;
+ unsigned int lpp, vsw, vfp, vbp;
+
+ ppl = (timing->tim0 >> 2) & 0x3f;
+ hsw = (timing->tim0 >> 8) & 0xff;
+ hfp = (timing->tim0 >> 16) & 0xff;
+ hbp = (timing->tim0 >> 24) & 0xff;
+
+ lpp = timing->tim1 & 0x3ff;
+ vsw = (timing->tim1 >> 10) & 0x3f;
+ vfp = (timing->tim1 >> 16) & 0xff;
+ vbp = (timing->tim1 >> 24) & 0xff;
+
+ mode->hdisplay = (ppl + 1) * 16;
+ mode->hsync_start = ((ppl + 1) * 16) + hfp + 1;
+ mode->hsync_end = ((ppl + 1) * 16) + hfp + hsw + 2;
+ mode->htotal = ((ppl + 1) * 16) + hfp + hsw + hbp + 3;
+ mode->hskew = 0;
+
+ mode->vdisplay = lpp + 1;
+ mode->vsync_start = lpp + vfp + 1;
+ mode->vsync_end = lpp + vfp + vsw + 2;
+ mode->vtotal = lpp + vfp + vsw + vbp + 2;
+
+ mode->flags = 0;
+
+ mode->width_mm = 0;
+ mode->height_mm = 0;
+
+ mode->clock = timing->pixclock / 1000;
+ mode->hsync = timing->pixclock / mode->htotal;
+ mode->vrefresh = mode->hsync / mode->vtotal;
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_platform.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_platform.c
new file mode 100755
index 0000000..9d5ec0c
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_platform.c
@@ -0,0 +1,151 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_platform.c
+ * Implementation of the Linux platform device entrypoints for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "pl111_drm.h"
+
+static int pl111_platform_drm_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ pr_info("DRM %s\n", __func__);
+ return 0;
+}
+
+static int pl111_platform_drm_resume(struct platform_device *dev)
+{
+ pr_info("DRM %s\n", __func__);
+ return 0;
+}
+
+int pl111_platform_drm_probe(struct platform_device *dev)
+{
+ pr_info("DRM %s\n", __func__);
+ return pl111_drm_init(dev);
+}
+
+static int pl111_platform_drm_remove(struct platform_device *dev)
+{
+ pr_info("DRM %s\n", __func__);
+ pl111_drm_exit(dev);
+
+ return 0;
+}
+
+static struct amba_id pl111_id_table[] = {
+ {
+ .id = 0x00041110,
+ .mask = 0x000ffffe,
+ },
+ {0, 0},
+};
+
+static struct amba_driver pl111_amba_driver = {
+ .drv = {
+ .name = "clcd-pl11x",
+ },
+ .probe = pl111_amba_probe,
+ .remove = pl111_amba_remove,
+ .id_table = pl111_id_table,
+};
+
+static struct platform_driver platform_drm_driver = {
+ .probe = pl111_platform_drm_probe,
+ .remove = pl111_platform_drm_remove,
+ .suspend = pl111_platform_drm_suspend,
+ .resume = pl111_platform_drm_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ },
+};
+
+static const struct platform_device_info pl111_drm_pdevinfo = {
+ .name = DRIVER_NAME,
+ .id = -1,
+ .dma_mask = ~0UL
+};
+
+static struct platform_device *pl111_drm_device;
+
+static int __init pl111_platform_drm_init(void)
+{
+ int ret;
+
+ pr_info("DRM %s\n", __func__);
+
+ pl111_drm_device = platform_device_register_full(&pl111_drm_pdevinfo);
+ if (pl111_drm_device == NULL) {
+ pr_err("DRM platform_device_register_full() failed\n");
+ return -ENOMEM;
+ }
+
+ ret = amba_driver_register(&pl111_amba_driver);
+ if (ret != 0) {
+ pr_err("DRM amba_driver_register() failed %d\n", ret);
+ goto err_amba_reg;
+ }
+
+ ret = platform_driver_register(&platform_drm_driver);
+ if (ret != 0) {
+ pr_err("DRM platform_driver_register() failed %d\n", ret);
+ goto err_pdrv_reg;
+ }
+
+ return 0;
+
+err_pdrv_reg:
+ amba_driver_unregister(&pl111_amba_driver);
+err_amba_reg:
+ platform_device_unregister(pl111_drm_device);
+
+ return ret;
+}
+
+static void __exit pl111_platform_drm_exit(void)
+{
+ pr_info("DRM %s\n", __func__);
+
+ platform_device_unregister(pl111_drm_device);
+ amba_driver_unregister(&pl111_amba_driver);
+ platform_driver_unregister(&platform_drm_driver);
+}
+
+#ifdef MODULE
+module_init(pl111_platform_drm_init);
+#else
+late_initcall(pl111_platform_drm_init);
+#endif
+module_exit(pl111_platform_drm_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE(DRIVER_LICENCE);
+MODULE_ALIAS(DRIVER_ALIAS);
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_suspend.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_suspend.c
new file mode 100755
index 0000000..d033566
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_suspend.c
@@ -0,0 +1,43 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_suspend.c
+ * Implementation of the suspend/resume functions for PL111 DRM
+ */
+
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "pl111_drm.h"
+
+int pl111_drm_suspend(struct drm_device *dev, pm_message_t state)
+{
+ pr_info("DRM %s\n", __func__);
+ return 0;
+}
+
+int pl111_drm_resume(struct drm_device *dev)
+{
+ pr_info("DRM %s\n", __func__);
+ return 0;
+}
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_vma.c b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_vma.c
new file mode 100755
index 0000000..ff602ef
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/pl111_drm_vma.c
@@ -0,0 +1,308 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+/**
+ * pl111_drm_vma.c
+ * Implementation of the VM functions for PL111 DRM
+ */
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/version.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/module.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "pl111_drm.h"
+
+/* BEGIN drivers/staging/omapdrm/omap_gem_helpers.c */
+/**
+ * drm_gem_put_pages - helper to free backing pages for a GEM object
+ * @obj: obj in question
+ * @pages: pages to free
+ */
+static void _drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
+ bool dirty, bool accessed)
+{
+ int i, npages;
+ struct pl111_gem_bo *bo;
+ npages = obj->size >> PAGE_SHIFT;
+ bo = PL111_BO_FROM_GEM(obj);
+ for (i = 0; i < npages; i++) {
+ if (dirty)
+ set_page_dirty(pages[i]);
+ if (accessed)
+ mark_page_accessed(pages[i]);
+ /* Undo the reference we took when populating the table */
+ page_cache_release(pages[i]);
+ }
+ drm_free_large(pages);
+}
+
+void put_pages(struct drm_gem_object *obj, struct page **pages)
+{
+ int i, npages;
+ struct pl111_gem_bo *bo;
+ npages = obj->size >> PAGE_SHIFT;
+ bo = PL111_BO_FROM_GEM(obj);
+ _drm_gem_put_pages(obj, pages, true, true);
+ if (bo->backing_data.shm.dma_addrs) {
+ for (i = 0; i < npages; i++) {
+ /* Filter pages unmapped because of CPU accesses */
+ if (!bo->backing_data.shm.dma_addrs[i])
+ continue;
+ if (!dma_mapping_error(obj->dev->dev,
+ bo->backing_data.shm.dma_addrs[i])) {
+ dma_unmap_page(obj->dev->dev,
+ bo->backing_data.shm.dma_addrs[i],
+ PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ }
+ }
+ kfree(bo->backing_data.shm.dma_addrs);
+ bo->backing_data.shm.dma_addrs = NULL;
+ }
+}
+
+/**
+ * drm_gem_get_pages - helper to allocate backing pages for a GEM object
+ * @obj: obj in question
+ * @gfpmask: gfp mask of requested pages
+ */
+static struct page **_drm_gem_get_pages(struct drm_gem_object *obj,
+ gfp_t gfpmask)
+{
+ struct inode *inode;
+ struct address_space *mapping;
+ struct page *p, **pages;
+ int i, npages;
+
+ /* This is the shared memory object that backs the GEM resource */
+ inode = obj->filp->f_path.dentry->d_inode;
+ mapping = inode->i_mapping;
+
+ npages = obj->size >> PAGE_SHIFT;
+
+ pages = drm_malloc_ab(npages, sizeof(struct page *));
+ if (pages == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ gfpmask |= mapping_gfp_mask(mapping);
+
+ for (i = 0; i < npages; i++) {
+ p = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
+ if (IS_ERR(p))
+ goto fail;
+ pages[i] = p;
+
+ /*
+ * There is a hypothetical issue w/ drivers that require
+ * buffer memory in the low 4GB.. if the pages are un-
+ * pinned, and swapped out, they can end up swapped back
+ * in above 4GB. If pages are already in memory, then
+ * shmem_read_mapping_page_gfp will ignore the gfpmask,
+ * even if the already in-memory page disobeys the mask.
+ *
+ * It is only a theoretical issue today, because none of
+ * the devices with this limitation can be populated with
+ * enough memory to trigger the issue. But this BUG_ON()
+ * is here as a reminder in case the problem with
+ * shmem_read_mapping_page_gfp() isn't solved by the time
+ * it does become a real issue.
+ *
+ * See this thread: http://lkml.org/lkml/2011/7/11/238
+ */
+ BUG_ON((gfpmask & __GFP_DMA32) &&
+ (page_to_pfn(p) >= 0x00100000UL));
+ }
+
+ return pages;
+
+fail:
+ while (i--)
+ page_cache_release(pages[i]);
+
+ drm_free_large(pages);
+ return ERR_PTR(PTR_ERR(p));
+}
+
+struct page **get_pages(struct drm_gem_object *obj)
+{
+ struct pl111_gem_bo *bo;
+ bo = PL111_BO_FROM_GEM(obj);
+
+ if (bo->backing_data.shm.pages == NULL) {
+ struct page **p;
+ int npages = obj->size >> PAGE_SHIFT;
+ int i;
+
+ p = _drm_gem_get_pages(obj, GFP_KERNEL);
+ if (IS_ERR(p))
+ return ERR_PTR(-ENOMEM);
+
+ bo->backing_data.shm.pages = p;
+
+ if (bo->backing_data.shm.dma_addrs == NULL) {
+ bo->backing_data.shm.dma_addrs =
+ kzalloc(npages * sizeof(dma_addr_t),
+ GFP_KERNEL);
+ if (bo->backing_data.shm.dma_addrs == NULL)
+ goto error_out;
+ }
+
+ if (!(bo->type & PL111_BOT_CACHED)) {
+ for (i = 0; i < npages; ++i) {
+ bo->backing_data.shm.dma_addrs[i] =
+ dma_map_page(obj->dev->dev, p[i], 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(obj->dev->dev,
+ bo->backing_data.shm.dma_addrs[i]))
+ goto error_out;
+ }
+ }
+ }
+
+ return bo->backing_data.shm.pages;
+
+error_out:
+ put_pages(obj, bo->backing_data.shm.pages);
+ bo->backing_data.shm.pages = NULL;
+ return ERR_PTR(-ENOMEM);
+}
+
+/* END drivers/staging/omapdrm/omap_gem_helpers.c */
+int pl111_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct page **pages;
+ unsigned long pfn;
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct pl111_gem_bo *bo = PL111_BO_FROM_GEM(obj);
+ struct drm_device *dev = obj->dev;
+ int ret;
+
+ mutex_lock(&dev->struct_mutex);
+
+ /*
+ * Our mmap calls setup a valid vma->vm_pgoff
+ * so we can use vmf->pgoff
+ */
+
+ if (bo->type & PL111_BOT_DMA) {
+ pfn = (bo->backing_data.dma.fb_dev_addr >> PAGE_SHIFT) +
+ vmf->pgoff;
+ } else { /* PL111_BOT_SHM */
+ pages = get_pages(obj);
+ if (IS_ERR(pages)) {
+ dev_err(obj->dev->dev,
+ "could not get pages: %ld\n", PTR_ERR(pages));
+ ret = PTR_ERR(pages);
+ goto error;
+ }
+ pfn = page_to_pfn(pages[vmf->pgoff]);
+ pl111_gem_sync_to_cpu(bo, vmf->pgoff);
+ }
+
+ DRM_DEBUG("bo=%p physaddr=0x%.8x for offset 0x%x\n",
+ bo, PFN_PHYS(pfn), PFN_PHYS(vmf->pgoff));
+
+ ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
+
+error:
+ mutex_unlock(&dev->struct_mutex);
+
+ switch (ret) {
+ case 0:
+ case -ERESTARTSYS:
+ case -EINTR:
+ case -EBUSY:
+ return VM_FAULT_NOPAGE;
+ case -ENOMEM:
+ return VM_FAULT_OOM;
+ default:
+ return VM_FAULT_SIGBUS;
+ }
+}
+
+/*
+ * The core drm_vm_ functions in kernel 3.4 are not ready
+ * to handle dma_buf cases where vma->vm_file->private_data
+ * cannot be accessed to get the device.
+ *
+ * We use these functions from 3.5 instead where the device
+ * pointer is passed explicitly.
+ *
+ * However they aren't exported from the kernel until 3.10
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
+void pl111_drm_vm_open_locked(struct drm_device *dev,
+ struct vm_area_struct *vma)
+{
+ struct drm_vma_entry *vma_entry;
+
+ DRM_DEBUG("0x%08lx,0x%08lx\n",
+ vma->vm_start, vma->vm_end - vma->vm_start);
+ atomic_inc(&dev->vma_count);
+
+ vma_entry = kmalloc(sizeof(*vma_entry), GFP_KERNEL);
+ if (vma_entry) {
+ vma_entry->vma = vma;
+ vma_entry->pid = current->pid;
+ list_add(&vma_entry->head, &dev->vmalist);
+ }
+}
+
+void pl111_drm_vm_close_locked(struct drm_device *dev,
+ struct vm_area_struct *vma)
+{
+ struct drm_vma_entry *pt, *temp;
+
+ DRM_DEBUG("0x%08lx,0x%08lx\n",
+ vma->vm_start, vma->vm_end - vma->vm_start);
+ atomic_dec(&dev->vma_count);
+
+ list_for_each_entry_safe(pt, temp, &dev->vmalist, head) {
+ if (pt->vma == vma) {
+ list_del(&pt->head);
+ kfree(pt);
+ break;
+ }
+ }
+}
+
+void pl111_gem_vm_open(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+
+ drm_gem_object_reference(obj);
+
+ mutex_lock(&obj->dev->struct_mutex);
+ pl111_drm_vm_open_locked(obj->dev, vma);
+ mutex_unlock(&obj->dev->struct_mutex);
+}
+
+void pl111_gem_vm_close(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ pl111_drm_vm_close_locked(obj->dev, vma);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+}
+#endif
diff --git a/driver/product/kernel/drivers/gpu/drm/pl111/sconscript b/driver/product/kernel/drivers/gpu/drm/pl111/sconscript
new file mode 100755
index 0000000..5c47de7
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/pl111/sconscript
@@ -0,0 +1,52 @@
+#
+# (C) COPYRIGHT 2010-2013, 2015-2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+import os
+import shutil
+Import('env')
+
+# Generate a build environment for the integration tests, taking a copy of the top-level build environment
+# (env) as a start.
+drm_env = env.Clone()
+
+# Xorg uses C++ style comments and 'inline' keyword
+if '-std=c89' in drm_env['CFLAGS']:
+ drm_env['CFLAGS'].remove('-std=c89')
+
+# X11 generates a lot of warnings
+if '-Werror' in drm_env['CCFLAGS']:
+ drm_env['CCFLAGS'].remove('-Werror')
+
+#remove the 'lib'prefix
+drm_env['LIBPREFIX'] = ''
+
+src = Glob('*.c')
+
+if drm_env.GetOption('clean') :
+ drm_env.Execute(Action("make clean", 'clean [pl111]'))
+ cmd = drm_env.Command('$STATIC_LIB_PATH/mali_drm.ko', src, [])
+else:
+ # The target is mali_drm.ko, built from the source in pl111_drm/pl111, via the action makeAction
+ # mali_drm.ko will be copied to $STATIC_LIB_PATH after being built by the standard Linux
+ # kernel build system, after which it can be installed to the directory specified if
+ # "libs_install" is set; this is done by LibTarget.
+ makeAction=Action("cd ${SOURCE.dir} && make MALI_DEBUG=${debug} && cp pl111_drm.ko $STATIC_LIB_PATH/mali_drm.ko", '$MAKECOMSTR')
+ cmd = drm_env.Command('$STATIC_LIB_PATH/mali_drm.ko', src, [makeAction])
+
+# need Module.symvers from drm.ko
+#drm_env.Depends('$STATIC_LIB_PATH/pl111_drm.ko', '$STATIC_LIB_PATH/drm.ko')
+
+drm_env.KernelObjTarget('x11', cmd)
+
diff --git a/driver/product/kernel/drivers/gpu/drm/sconscript b/driver/product/kernel/drivers/gpu/drm/sconscript
new file mode 100755
index 0000000..a90fa89
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/drm/sconscript
@@ -0,0 +1,23 @@
+#
+# (C) COPYRIGHT 2010-2015 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+Import('env')
+
+if 'x11' in env['winsys'] or 'gbm' in env['winsys']:
+ # pl111_drm isn't released so only try to build it if it's there
+ if Glob('pl111/sconscript') and (env['platform_config'] == 'vexpress' or env['platform_config'] == 'vexpress_6xvirtex7_10mhz'):
+ SConscript('pl111/sconscript')
+
+#SConscript('dummy_drm/sconscript')
diff --git a/driver/product/kernel/drivers/gpu/sconscript b/driver/product/kernel/drivers/gpu/sconscript
new file mode 100755
index 0000000..729dbda
--- /dev/null
+++ b/driver/product/kernel/drivers/gpu/sconscript
@@ -0,0 +1,21 @@
+#
+# (C) COPYRIGHT 2010-2013 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+
+SConscript('arm/sconscript')
+
+if Glob('drm/sconscript'):
+ SConscript('drm/sconscript')
diff --git a/driver/product/kernel/drivers/sconscript b/driver/product/kernel/drivers/sconscript
new file mode 100755
index 0000000..71b194e
--- /dev/null
+++ b/driver/product/kernel/drivers/sconscript
@@ -0,0 +1,116 @@
+#
+# (C) COPYRIGHT 2010-2013, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+import glob
+import os
+import shutil
+import subprocess
+
+from SCons.Script import SCons
+
+Import("env")
+
+# -----------------------------------------------------------------------------
+g_kernel_config = dict()
+
+def kernel_config_enabled(sEnv, option):
+ """Return true if a given kernel config option is enabled"""
+ global g_kernel_config
+ if not g_kernel_config:
+ config_file = os.path.join(sEnv["ENV"]["KDIR"], "include/config/auto.conf")
+ print "Parsing kernel config '%s'." % config_file
+ with open(config_file, "rt") as fp:
+ for line in fp.readlines():
+ try:
+ (key, val) = line.split("=")
+ g_kernel_config[key.strip()] = val.strip()
+ except ValueError:
+ pass
+ if option not in g_kernel_config:
+ return False
+ val = g_kernel_config[option]
+ if val == "y":
+ return True
+ return False
+
+env.AddMethod(kernel_config_enabled, "KernelConfigEnabled")
+
+def kernel_module_builder(env = None, target = None, source = None):
+ assert (len(target) == 1 and 'M' in env and 'make_args' in env and
+ 'built_module' in env)
+
+ module_dir = str(env['M'])
+ cmd = ['make', '-j%d' % GetOption('num_jobs')] + env['make_args']
+ status = subprocess.call(cmd, cwd = module_dir, env = env['ENV'])
+ if status:
+ return status
+
+ shutil.copy2(env['built_module'], target[0].abspath)
+ return 0 # Success (SCons will catch any exceptions thrown by copy2).
+
+action = SCons.Action.Action(kernel_module_builder, "[KBUILD] $TARGET")
+builder = env.Builder(action = action)
+env.Append(BUILDERS = {'KernelModuleBuilder': builder})
+
+def build_kernel_module(env, target, sources, M = None, make_args = [],
+ built_module = None):
+ if not M:
+ M = Dir('.').srcnode().abspath
+ if not built_module:
+ built_module = os.path.basename(str(target))
+ built_module = os.path.join(M, built_module)
+
+ env_kern = env.Clone()
+ kdir = env_kern['ENV']['KDIR']
+ env_kern.Append(CPPPATH = [M, '#kernel/include', os.path.join(kdir, 'include')])
+ mod = env_kern.KernelModuleBuilder(target, sources, M = M,
+ make_args = make_args,
+ built_module = built_module)
+
+ # Kbuild implicitly #includes kconfig.h (which includes autoconf.h) when
+ # building kernel module source files.
+ env_kern.Depends(mod, os.path.join(kdir, 'include/generated/autoconf.h'))
+ # Built files may change depending on CONFIG_* values in auto.conf.
+ env_kern.Depends(mod, os.path.join(kdir, 'include/config/auto.conf'))
+
+ for f in ['Kconfig', 'Kbuild', 'Makefile*']:
+ env_kern.Depends(mod, glob.glob(os.path.join(M, f)))
+
+ scanner = SCons.Scanner.C.CScanner()
+ all_headers = set()
+ for src in Flatten(sources):
+ src = env_kern.File(src)
+ (base, ext) = os.path.splitext(src.abspath)
+ if ext == '.c':
+ env_kern.Clean(mod, base + '.o')
+ # Scan for header dependencies explicitly.
+ headers = scanner(src, env_kern, scanner.path_function(env_kern))
+ env_kern.Depends(mod, headers)
+ all_headers.update(headers)
+
+ env_kern.Clean(mod, os.path.join(M, 'Module.symvers'))
+ env_kern.Clean(mod, os.path.join(M, 'module.order'))
+
+ return mod
+
+env.AddMethod(build_kernel_module, 'BuildKernelModule')
+
+if Glob('base/sconscript'):
+ SConscript('base/sconscript')
+
+if Glob('video/sconscript'):
+ SConscript('video/sconscript')
+
+SConscript('gpu/sconscript')
diff --git a/driver/product/kernel/include/linux/dma-buf-test-exporter.h b/driver/product/kernel/include/linux/dma-buf-test-exporter.h
new file mode 100755
index 0000000..98984ba
--- /dev/null
+++ b/driver/product/kernel/include/linux/dma-buf-test-exporter.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 _LINUX_DMA_BUF_TEST_EXPORTER_H_
+#define _LINUX_DMA_BUF_TEST_EXPORTER_H_
+
+#include <linux/types.h>
+#include <asm/ioctl.h>
+
+#define DMA_BUF_TE_VER_MAJOR 1
+#define DMA_BUF_TE_VER_MINOR 0
+#define DMA_BUF_TE_ENQ 0x642d7465
+#define DMA_BUF_TE_ACK 0x68692100
+
+struct dma_buf_te_ioctl_version
+{
+ int op; /**< Must be set to DMA_BUF_TE_ENQ by client, driver will set it to DMA_BUF_TE_ACK */
+ int major; /**< Major version */
+ int minor; /**< Minor version */
+};
+
+struct dma_buf_te_ioctl_alloc
+{
+ __u64 size; /* size of buffer to allocate, in pages */
+};
+
+struct dma_buf_te_ioctl_status
+{
+ /* in */
+ int fd; /* the dma_buf to query, only dma_buf objects exported by this driver is supported */
+ /* out */
+ int attached_devices; /* number of devices attached (active 'dma_buf_attach's) */
+ int device_mappings; /* number of device mappings (active 'dma_buf_map_attachment's) */
+ int cpu_mappings; /* number of cpu mappings (active 'mmap's) */
+};
+
+struct dma_buf_te_ioctl_set_failing
+{
+ /* in */
+ int fd; /* the dma_buf to set failure mode for, only dma_buf objects exported by this driver is supported */
+
+ /* zero = no fail injection, non-zero = inject failure */
+ int fail_attach;
+ int fail_map;
+ int fail_mmap;
+};
+
+struct dma_buf_te_ioctl_fill
+{
+ int fd;
+ unsigned int value;
+};
+
+#define DMA_BUF_TE_IOCTL_BASE 'E'
+/* Below all returning 0 if successful or -errcode except DMA_BUF_TE_ALLOC which will return fd or -errcode */
+#define DMA_BUF_TE_VERSION _IOR(DMA_BUF_TE_IOCTL_BASE, 0x00, struct dma_buf_te_ioctl_version)
+#define DMA_BUF_TE_ALLOC _IOR(DMA_BUF_TE_IOCTL_BASE, 0x01, struct dma_buf_te_ioctl_alloc)
+#define DMA_BUF_TE_QUERY _IOR(DMA_BUF_TE_IOCTL_BASE, 0x02, struct dma_buf_te_ioctl_status)
+#define DMA_BUF_TE_SET_FAILING _IOW(DMA_BUF_TE_IOCTL_BASE, 0x03, struct dma_buf_te_ioctl_set_failing)
+#define DMA_BUF_TE_ALLOC_CONT _IOR(DMA_BUF_TE_IOCTL_BASE, 0x04, struct dma_buf_te_ioctl_alloc)
+#define DMA_BUF_TE_FILL _IOR(DMA_BUF_TE_IOCTL_BASE, 0x05, struct dma_buf_te_ioctl_fill)
+
+#endif /* _LINUX_DMA_BUF_TEST_EXPORTER_H_ */
diff --git a/driver/product/kernel/include/linux/kds.h b/driver/product/kernel/include/linux/kds.h
new file mode 100755
index 0000000..1346eda
--- /dev/null
+++ b/driver/product/kernel/include/linux/kds.h
@@ -0,0 +1,173 @@
+/*
+ *
+ * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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 _KDS_H_
+#define _KDS_H_
+
+#include <linux/list.h>
+#include <linux/workqueue.h>
+
+#define KDS_WAIT_BLOCKING (ULONG_MAX)
+
+struct kds_resource_set;
+
+typedef void (*kds_callback_fn) (void *callback_parameter, void *callback_extra_parameter);
+
+struct kds_callback
+{
+ kds_callback_fn user_cb; /* real cb */
+ int direct; /* do direct or queued call? */
+ struct workqueue_struct *wq;
+};
+
+struct kds_link
+{
+ struct kds_resource_set *parent;
+ struct list_head link;
+ unsigned long state;
+};
+
+struct kds_resource
+{
+ struct kds_link waiters;
+};
+
+/* callback API */
+
+/* Initialize a callback object.
+ *
+ * Typically created per context or per hw resource.
+ *
+ * Callbacks can be performed directly if no nested locking can
+ * happen in the client.
+ *
+ * Nested locking can occur when a lock is held during the kds_async_waitall or
+ * kds_resource_set_release call. If the callback needs to take the same lock
+ * nested locking will happen.
+ *
+ * If nested locking could happen non-direct callbacks can be requested.
+ * Callbacks will then be called asynchronous to the triggering call.
+ */
+int kds_callback_init(struct kds_callback *cb, int direct, kds_callback_fn user_cb);
+
+/* Terminate the use of a callback object.
+ *
+ * If the callback object was set up as non-direct
+ * any pending callbacks will be flushed first.
+ * Note that to avoid a deadlock the lock callbacks needs
+ * can't be held when a callback object is terminated.
+ */
+void kds_callback_term(struct kds_callback *cb);
+
+
+/* resource object API */
+
+/* initialize a resource handle for a shared resource */
+void kds_resource_init(struct kds_resource * const resource);
+
+/*
+ * Will return 0 on success.
+ * If the resource is being used or waited -EBUSY is returned.
+ * The caller should NOT try to terminate a resource that could still have clients.
+ * After the function returns the resource is no longer known by kds.
+ */
+int kds_resource_term(struct kds_resource *resource);
+
+/* Asynchronous wait for a set of resources.
+ * Callback will be called when all resources are available.
+ * If all the resources was available the callback will be called before kds_async_waitall returns.
+ * So one must not hold any locks the callback code-flow can take when calling kds_async_waitall.
+ * Caller considered to own/use the resources until \a kds_rset_release is called.
+ * exclusive_access_bitmap is a bitmap where a high bit means exclusive access while a low bit means shared access.
+ * Use the Linux __set_bit API, where the index of the buffer to control is used as the bit index.
+ *
+ * Standard Linux error return value.
+ */
+int kds_async_waitall(
+ struct kds_resource_set ** const pprset,
+ struct kds_callback *cb,
+ void *callback_parameter,
+ void *callback_extra_parameter,
+ int number_resources,
+ unsigned long *exclusive_access_bitmap,
+ struct kds_resource **resource_list);
+
+/* Synchronous wait for a set of resources.
+ * Function will return when one of these have happened:
+ * - all resources have been obtained
+ * - timeout lapsed while waiting
+ * - a signal was received while waiting
+ *
+ * To wait without a timeout, specify KDS_WAIT_BLOCKING for \a jifies_timeout, otherwise
+ * the timeout in jiffies. A zero timeout attempts to obtain all resources and returns
+ * immediately with a timeout if all resources could not be obtained.
+ *
+ * Caller considered to own/use the resources when the function returns.
+ * Caller must release the resources using \a kds_rset_release.
+ *
+ * Calling this function while holding already locked resources or other locking primitives is dangerous.
+ * One must if this is needed decide on a lock order of the resources and/or the other locking primitives
+ * and always take the resources/locking primitives in the specific order.
+ *
+ * Use the ERR_PTR framework to decode the return value.
+ * NULL = time out
+ * If IS_ERR then PTR_ERR gives:
+ * ERESTARTSYS = signal received, retry call after signal
+ * all other values = internal error, lock failed
+ * Other values = successful wait, now the owner, must call kds_resource_set_release
+ */
+struct kds_resource_set *kds_waitall(
+ int number_resources,
+ unsigned long *exclusive_access_bitmap,
+ struct kds_resource **resource_list,
+ unsigned long jifies_timeout);
+
+/* Release resources after use.
+ * Caller must handle that other async callbacks will trigger,
+ * so must avoid holding any locks a callback will take.
+ *
+ * The function takes a pointer to your poiner to handle a race
+ * between a cancelation and a completion.
+ *
+ * If the caller can't guarantee that a race can't occur then
+ * the passed in pointer must be the same in both call paths
+ * to allow kds to manage the potential race.
+ */
+void kds_resource_set_release(struct kds_resource_set **pprset);
+
+/* Release resources after use and wait callbacks to complete.
+ * Caller must handle that other async callbacks will trigger,
+ * so must avoid holding any locks a callback will take.
+ *
+ * The function takes a pointer to your poiner to handle a race
+ * between a cancelation and a completion.
+ *
+ * If the caller can't guarantee that a race can't occur then
+ * the passed in pointer must be the same in both call paths
+ * to allow kds to manage the potential race.
+ *
+ * This should be used to cancel waits which are pending on a kds
+ * resource.
+ *
+ * It is a bug to call this from atomic contexts and from within
+ * a kds callback that now owns the kds_rseource.
+ */
+
+void kds_resource_set_release_sync(struct kds_resource_set **pprset);
+#endif /* _KDS_H_ */
diff --git a/driver/product/kernel/include/linux/ump-common.h b/driver/product/kernel/include/linux/ump-common.h
new file mode 100755
index 0000000..0015bda
--- /dev/null
+++ b/driver/product/kernel/include/linux/ump-common.h
@@ -0,0 +1,252 @@
+/*
+ *
+ * (C) COPYRIGHT 2010-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained
+ * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+
+
+/**
+ * @file ump-common.h
+ *
+ * This file contains some common enum values used both in both the user and kernel space side of UMP.
+ */
+
+#ifndef _UMP_COMMON_H_
+#define _UMP_COMMON_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#define UMP_UINT32_MAX (4294967295U)
+#define UMP_UINT64_MAX (18446744073709551615ULL)
+
+#ifdef __GNUC__
+ #define CHECK_RESULT __attribute__((__warn_unused_result__))
+ #define INLINE __inline__
+#else
+ #define CHECK_RESULT
+ #define INLINE __inline
+#endif
+
+#ifndef STATIC
+ #define STATIC static
+#endif
+
+/**
+ * Values to identify major and minor version of UMP
+ */
+#define UMP_VERSION_MAJOR 2
+#define UMP_VERSION_MINOR 0
+
+/**
+ * Typedef for a secure ID, a system wide identifier for UMP memory buffers.
+ */
+typedef int32_t ump_secure_id;
+
+/**
+ * Value to indicate an invalid secure Id.
+ */
+#define UMP_INVALID_SECURE_ID ((ump_secure_id)0)
+
+/**
+ * UMP error codes.
+ */
+typedef enum
+{
+ UMP_OK = 0, /**< indicates success */
+ UMP_ERROR = 1 /**< indicates failure */
+} ump_result;
+
+/**
+ * Allocation flag bits.
+ *
+ * ump_allocate accepts zero or more flags to specify the type of memory to allocate and how to expose it to devices.
+ *
+ * For each supported device there are 4 flags to control access permissions and give usage characteristic hints to optimize the allocation/mapping.
+ * They are;
+ * @li @a UMP_PROT_<device>_RD read permission
+ * @li @a UMP_PROT_<device>_WR write permission
+ * @li @a UMP_HINT_<device>_RD read often
+ * @li @a UMP_HINT_<device>_WR written often
+ *
+ * 5 devices are currently supported, with a device being the CPU itself.
+ * The other 4 devices will be mapped to real devices per SoC design.
+ * They are just named W,X,Y,Z by UMP as it has no knowledge of their real names/identifiers.
+ * As an example device W could be a camera device while device Z could be an ARM GPU device, leaving X and Y unused.
+ *
+ * 2 additional flags control the allocation;
+ * @li @a UMP_CONSTRAINT_PHYSICALLY_LINEAR the allocation must be physical linear. Typical for devices without an MMU and no IOMMU to help it.
+ * @li @a UMP_PROT_SHAREABLE the allocation can be shared with other processes on the system. Without this flag the returned allocation won't be resolvable in other processes.
+ *
+ * All UMP allocation are growable unless they're @a UMP_PROT_SHAREABLE.
+ * The hint bits should be used to indicate the access pattern so the driver can select the most optimal memory type and cache settings based on the what the system supports.
+ */
+typedef enum
+{
+ /* Generic helpers */
+ UMP_PROT_DEVICE_RD = (1u << 0),
+ UMP_PROT_DEVICE_WR = (1u << 1),
+ UMP_HINT_DEVICE_RD = (1u << 2),
+ UMP_HINT_DEVICE_WR = (1u << 3),
+ UMP_DEVICE_MASK = 0xF,
+ UMP_DEVICE_CPU_SHIFT = 0,
+ UMP_DEVICE_W_SHIFT = 4,
+ UMP_DEVICE_X_SHIFT = 8,
+ UMP_DEVICE_Y_SHIFT = 12,
+ UMP_DEVICE_Z_SHIFT = 16,
+
+ /* CPU protection and hints. */
+ UMP_PROT_CPU_RD = (1u << 0),
+ UMP_PROT_CPU_WR = (1u << 1),
+ UMP_HINT_CPU_RD = (1u << 2),
+ UMP_HINT_CPU_WR = (1u << 3),
+
+ /* device W */
+ UMP_PROT_W_RD = (1u << 4),
+ UMP_PROT_W_WR = (1u << 5),
+ UMP_HINT_W_RD = (1u << 6),
+ UMP_HINT_W_WR = (1u << 7),
+
+ /* device X */
+ UMP_PROT_X_RD = (1u << 8),
+ UMP_PROT_X_WR = (1u << 9),
+ UMP_HINT_X_RD = (1u << 10),
+ UMP_HINT_X_WR = (1u << 11),
+
+ /* device Y */
+ UMP_PROT_Y_RD = (1u << 12),
+ UMP_PROT_Y_WR = (1u << 13),
+ UMP_HINT_Y_RD = (1u << 14),
+ UMP_HINT_Y_WR = (1u << 15),
+
+ /* device Z */
+ UMP_PROT_Z_RD = (1u << 16),
+ UMP_PROT_Z_WR = (1u << 17),
+ UMP_HINT_Z_RD = (1u << 18),
+ UMP_HINT_Z_WR = (1u << 19),
+
+ /* 20-26 reserved for future use */
+ UMPP_ALLOCBITS_UNUSED = (0x7Fu << 20),
+ /** Allocations marked as @ UMP_CONSTRAINT_UNCACHED won't be mapped as cached by the cpu */
+ UMP_CONSTRAINT_UNCACHED = (1u << 27),
+ /** Require 32-bit physically addressable memory */
+ UMP_CONSTRAINT_32BIT_ADDRESSABLE = (1u << 28),
+ /** For devices without an MMU and with no IOMMU assistance. */
+ UMP_CONSTRAINT_PHYSICALLY_LINEAR = (1u << 29),
+ /** Shareable must be set to allow the allocation to be used by other processes, the default is non-shared */
+ UMP_PROT_SHAREABLE = (1u << 30)
+ /* (1u << 31) should not be used to ensure compiler portability */
+} ump_allocation_bits;
+
+/**
+ * ump_allocation_bits combination argument type.
+ *
+ * Type used to pass zero or more bits from the @ref ump_allocation_bits enum
+ */
+typedef uint32_t ump_alloc_flags;
+
+
+/**
+ * Default allocation flags for UMP v1 compatible allocations.
+ */
+#define UMP_V1_API_DEFAULT_ALLOCATION_FLAGS UMP_PROT_CPU_RD | UMP_PROT_CPU_WR | \
+ UMP_PROT_W_RD | UMP_PROT_W_WR | \
+ UMP_PROT_X_RD | UMP_PROT_X_WR | \
+ UMP_PROT_Y_RD | UMP_PROT_Y_WR | \
+ UMP_PROT_Z_RD | UMP_PROT_Z_WR | \
+ UMP_PROT_SHAREABLE | \
+ UMP_CONSTRAINT_32BIT_ADDRESSABLE
+
+/**
+ * CPU cache sync operations.
+ *
+ * Cache synchronization operations to pass to @ref ump_cpu_msync_now
+ */
+enum
+{
+ /**
+ * Cleans any dirty cache lines to main memory, but the data will still be available in the cache.
+ * After a clean the contents of memory is considered to be "owned" by the device.
+ * */
+ UMP_MSYNC_CLEAN = 1,
+
+ /** Cleans any dirty cache lines to main memory and Ejects all lines from the cache.
+ * After an clean&invalidate the contents of memory is considered to be "owned" by the CPU.
+ * Any subsequent access will fetch data from main memory.
+ *
+ * @note Due to CPUs doing speculative prefetching a UMP_MSYNC_CLEAN_AND_INVALIDATE must be done before and after interacting with hardware.
+ * */
+ UMP_MSYNC_CLEAN_AND_INVALIDATE
+
+};
+
+typedef uint32_t ump_cpu_msync_op;
+
+/**
+ * Memory import types supported.
+ * If new import types are added they will appear here.
+ * They must be added before UMPP_EXTERNAL_MEM_COUNT and
+ * must be assigned an explicit sequantial number.
+ *
+ * @li UMP_EXTERNAL_MEM_TYPE_ION - Import an ION allocation
+ * Takes a int* (pointer to a file descriptor)
+ * Another ION reference is taken which is released on the final ump_release
+ */
+enum ump_external_memory_type
+{
+ UMPP_EXTERNAL_MEM_TYPE_UNUSED = 0, /* reserve type 0 */
+ UMP_EXTERNAL_MEM_TYPE_ION = 1,
+ UMPP_EXTERNAL_MEM_COUNT
+};
+
+/** @name UMP v1 API
+ *
+ *@{
+ */
+
+/**
+ * Allocation constraints.
+ *
+ * Allocation flags to pass @ref ump_ref_drv_allocate
+ *
+ * UMP v1 API only.
+ */
+typedef enum
+{
+ /** the allocation is mapped as noncached. */
+ UMP_REF_DRV_CONSTRAINT_NONE = 0,
+ /** not supported. */
+ UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR = 1,
+ /** the allocation is mapped as cached by the cpu. */
+ UMP_REF_DRV_CONSTRAINT_USE_CACHE = 4
+} ump_alloc_constraints;
+
+/* @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _UMP_COMMON_H_ */
diff --git a/driver/product/kernel/include/linux/ump-import.h b/driver/product/kernel/include/linux/ump-import.h
new file mode 100755
index 0000000..89ce727
--- /dev/null
+++ b/driver/product/kernel/include/linux/ump-import.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * (C) COPYRIGHT 2011-2013 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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_IMPORT_H_
+#define _UMP_IMPORT_H_
+
+#include <linux/ump.h>
+#include <linux/module.h>
+
+/**
+ * UMP import module info.
+ * Contains information about the Linux module providing the import module,
+ * used to block unloading of the Linux module while imported memory exists.
+ * Lists the functions implementing the UMP import functions.
+ */
+struct ump_import_handler
+{
+ /**
+ * Linux module of the import handler
+ */
+ struct module * linux_module;
+
+ /**
+ * UMP session usage begin.
+ *
+ * Called when a UMP session first is bound to the handler.
+ * Typically used to set up any import module specific per-session data.
+ * The function returns a pointer to this data in the output pointer custom_session_data
+ * which will be passed to \a session_end and \a import.
+ *
+ * Note: custom_session_data must be set to non-NULL if successful.
+ * If no pointer is needed set it a magic value to validate instead.
+ *
+ * @param[out] custom_session_data Pointer to a generic pointer where any data can be stored
+ * @return 0 on success, error code if the session could not be initiated.
+ */
+ int (*session_begin)(void ** custom_session_data);
+
+ /**
+ * UMP session usage end.
+ *
+ * Called when a UMP session is no longer using the handler.
+ * Only called if @a session_begin returned OK.
+ *
+ * @param[in] custom_session_data The value set by the session_begin handler
+ */
+ void (*session_end)(void * custom_session_data);
+
+ /**
+ * Import request.
+ *
+ * Called when a client has asked to import a resource of the type the import module was installed for.
+ * Only called if @a session_begin returned OK.
+ *
+ * The requested flags must be verified to be valid to apply to the imported memory.
+ * If not valid return UMP_DD_INVALID_MEMORY_HANDLE.
+ * If the flags are found to be valid call \a ump_dd_create_from_phys_blocks_64 to create a handle.
+ *
+ * @param[in] custom_session_data The value set by the session_begin handler
+ * @param[in] phandle Pointer to the handle to import
+ * @param flags The requested UMPv2 flags to assign to the imported handle
+ * @return UMP_DD_INVALID_MEMORY_HANDLE if the import failed, a valid ump handle on success
+ */
+ ump_dd_handle (*import)(void * custom_session_data, void * phandle, ump_alloc_flags flags);
+};
+
+/**
+ * Import module registration.
+ * Registers a ump_import_handler structure for a memory type.
+ * @param type Type of the memory to register a handler for
+ * @param[in] handler Handler strcture to install
+ * @return 0 on success, a Linux error code on failure
+ */
+int ump_import_module_register(enum ump_external_memory_type type, struct ump_import_handler * handler);
+
+/**
+ * Import module deregistration.
+ * Uninstalls the handler for the given memory type.
+ * @param type Type of the memory to unregister the handler for
+ */
+void ump_import_module_unregister(enum ump_external_memory_type type);
+
+#endif /* _UMP_IMPORT_H_ */
diff --git a/driver/product/kernel/include/linux/ump-ioctl.h b/driver/product/kernel/include/linux/ump-ioctl.h
new file mode 100755
index 0000000..caf4c0b
--- /dev/null
+++ b/driver/product/kernel/include/linux/ump-ioctl.h
@@ -0,0 +1,152 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013, 2016 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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_IOCTL_H_
+#define _UMP_IOCTL_H_
+
+#include <linux/ump-common.h>
+
+/*
+ * The order and size of the members of these have been chosen so the structures look the same in 32-bit and 64-bit builds.
+ * If any changes are done build the ump_struct_size_checker test for 32-bit and 64-bit targets. Both must compile successfully to commit.
+ */
+
+/** 32/64-bit neutral way to represent pointers */
+typedef union ump_pointer
+{
+ void * value; /**< client should store their pointers here */
+ uint32_t compat_value; /**< 64-bit kernels should fetch value here when handling 32-bit clients */
+ uint64_t sizer; /**< Force 64-bit storage for all clients regardless */
+} ump_pointer;
+
+/**
+ * UMP allocation request.
+ * Used when performing ump_allocate
+ */
+typedef struct ump_k_allocate
+{
+ uint64_t size; /**< [in] Size in bytes to allocate */
+ ump_secure_id secure_id; /**< [out] Secure ID of allocation on success */
+ ump_alloc_flags alloc_flags; /**< [in] Flags to use when allocating */
+} ump_k_allocate;
+
+/**
+ * UMP size query request.
+ * Used when performing ump_size_get
+ */
+typedef struct ump_k_sizequery
+{
+ uint64_t size; /**< [out] Size of allocation */
+ ump_secure_id secure_id; /**< [in] ID of allocation to query the size of */
+ uint32_t padding; /* don't remove */
+} ump_k_sizequery;
+
+/**
+ * UMP cache synchronization request.
+ * Used when performing ump_cpu_msync_now
+ */
+typedef struct ump_k_msync
+{
+ ump_pointer mapped_ptr; /**< [in] CPU VA to perform cache operation on */
+ ump_secure_id secure_id; /**< [in] ID of allocation to perform cache operation on */
+ ump_cpu_msync_op cache_operation; /**< [in] Cache operation to perform */
+ uint64_t size; /**< [in] Size in bytes of the range to synchronize */
+} ump_k_msync;
+
+/**
+ * UMP memory retain request.
+ * Used when performing ump_retain
+ */
+typedef struct ump_k_retain
+{
+ ump_secure_id secure_id; /**< [in] ID of allocation to retain a reference to */
+ uint32_t padding; /* don't remove */
+} ump_k_retain;
+
+/**
+ * UMP memory release request.
+ * Used when performing ump_release
+ */
+typedef struct ump_k_release
+{
+ ump_secure_id secure_id; /**< [in] ID of allocation to release a reference to */
+ uint32_t padding; /* don't remove */
+} ump_k_release;
+
+typedef struct ump_k_import
+{
+ ump_pointer phandle; /**< [in] Pointer to handle to import */
+ uint32_t type; /**< [in] Type of handle to import */
+ ump_alloc_flags alloc_flags; /**< [in] Flags to assign to the imported memory */
+ ump_secure_id secure_id; /**< [out] UMP ID representing the imported memory */
+ uint32_t padding; /* don't remove */
+} ump_k_import;
+
+/**
+ * UMP allocation flags request.
+ * Used when performing umpp_get_allocation_flags
+ *
+ * used only by v1 API
+ */
+typedef struct ump_k_allocation_flags
+{
+ ump_secure_id secure_id; /**< [in] Secure ID of allocation on success */
+ ump_alloc_flags alloc_flags; /**< [out] Flags to use when allocating */
+} ump_k_allocation_flags;
+
+#define UMP_CALL_MAX_SIZE 512
+/*
+ * Ioctl definitions
+ */
+
+/* Use '~' as magic number */
+
+#define UMP_IOC_MAGIC '~'
+
+#define UMP_FUNC_ALLOCATE _IOWR(UMP_IOC_MAGIC, 1, ump_k_allocate)
+#define UMP_FUNC_SIZEQUERY _IOWR(UMP_IOC_MAGIC, 2, ump_k_sizequery)
+#define UMP_FUNC_MSYNC _IOWR(UMP_IOC_MAGIC, 3, ump_k_msync)
+#define UMP_FUNC_RETAIN _IOW(UMP_IOC_MAGIC, 4, ump_k_retain)
+#define UMP_FUNC_RELEASE _IOW(UMP_IOC_MAGIC, 5, ump_k_release)
+#define UMP_FUNC_ALLOCATION_FLAGS_GET _IOWR(UMP_IOC_MAGIC, 6, ump_k_allocation_flags)
+#define UMP_FUNC_IMPORT _IOWR(UMP_IOC_MAGIC, 7, ump_k_import)
+
+/*max ioctl sequential number*/
+#define UMP_IOC_MAXNR 7
+
+/* 15 bits for the UMP ID (allowing 32768 IDs) */
+#define UMP_LINUX_ID_BITS 15
+#define UMP_LINUX_ID_MASK ((1ULL << UMP_LINUX_ID_BITS) - 1ULL)
+
+/* 64-bit (really 52 bits) encoding: 15 bits for the ID, 37 bits for the offset */
+#define UMP_LINUX_OFFSET_BITS_64 37
+#define UMP_LINUX_OFFSET_MASK_64 ((1ULL << UMP_LINUX_OFFSET_BITS_64)-1)
+/* 32-bit encoding: 15 bits for the ID, 17 bits for the offset */
+#define UMP_LINUX_OFFSET_BITS_32 17
+#define UMP_LINUX_OFFSET_MASK_32 ((1ULL << UMP_LINUX_OFFSET_BITS_32)-1)
+
+#if __SIZEOF_LONG__ == 8
+#define UMP_LINUX_OFFSET_BITS UMP_LINUX_OFFSET_BITS_64
+#define UMP_LINUX_OFFSET_MASK UMP_LINUX_OFFSET_MASK_64
+#else
+#define UMP_LINUX_OFFSET_BITS UMP_LINUX_OFFSET_BITS_32
+#define UMP_LINUX_OFFSET_MASK UMP_LINUX_OFFSET_MASK_32
+#endif
+
+#endif /* _UMP_IOCTL_H_ */
diff --git a/driver/product/kernel/include/linux/ump.h b/driver/product/kernel/include/linux/ump.h
new file mode 100755
index 0000000..16f9c39
--- /dev/null
+++ b/driver/product/kernel/include/linux/ump.h
@@ -0,0 +1,481 @@
+/*
+ *
+ * (C) COPYRIGHT 2008-2013, 2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU licence.
+ *
+ * A copy of the licence is 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
+ *
+ * This file contains the kernel space part of the UMP API.
+ *
+ */
+
+#ifndef _UMP_KERNEL_INTERFACE_H_
+#define _UMP_KERNEL_INTERFACE_H_
+
+/**
+ * @addtogroup ump_api
+ * @{
+ */
+
+/** @defgroup ump_kernel_space_api UMP Kernel Space API
+ * @{ */
+
+/**
+ * External representation of a UMP handle in kernel space.
+ */
+typedef void * ump_dd_handle;
+
+#ifdef CONFIG_KDS
+#include <linux/kds.h>
+#endif
+
+#include <linux/ump-common.h>
+
+#define UMP_KERNEL_API_EXPORT
+
+#if defined(__KERNEL__)
+#include <linux/ump-import.h>
+#else
+#include <ump/src/library/common/ump_user.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Value to indicate an invalid UMP memory handle.
+ */
+#define UMP_DD_INVALID_MEMORY_HANDLE ((ump_dd_handle)0)
+
+/**
+ * Struct used to describe a physical block used by UMP memory
+ */
+typedef struct ump_dd_physical_block_64
+{
+ uint64_t addr; /**< The physical address of the block */
+ uint64_t size; /**< The length of the block, in bytes, typically page aligned */
+} ump_dd_physical_block_64;
+
+/**
+ * Security filter hook.
+ *
+ * Each allocation can have a security filter attached to it.@n
+ * The hook receives
+ * @li the secure ID
+ * @li a handle to the allocation
+ * @li the callback_data argument provided to @ref ump_dd_allocate_64 or @ref ump_dd_create_from_phys_blocks_64
+ *
+ * The hook must return @a true to indicate that access to the handle is allowed or @n
+ * @a false to state that no access is permitted.@n
+ * This hook is guaranteed to be called in the context of the requesting process/address space.
+ *
+ * The arguments provided to the hook are;
+ * @li the secure ID
+ * @li handle to the allocation
+ * @li the callback_data set when registering the hook
+ *
+ * Return value;
+ * @li @a true to permit access
+ * @li @a false to deny access
+ */
+typedef bool (*ump_dd_security_filter)(ump_secure_id, ump_dd_handle, void *);
+
+/**
+ * Final release notify hook.
+ *
+ * Allocations can have a hook attached to them which is called when the last reference to the allocation is released.
+ * No reference count manipulation is allowed on the provided handle, just property querying (ID get, size get, phys block get).
+ * This is similar to finalizers in OO languages.
+ *
+ * The arguments provided to the hook are;
+ * * handle to the allocation
+ * * the callback_data set when registering the hook
+ */
+typedef void (*ump_dd_final_release_callback)(const ump_dd_handle, void *);
+
+/**
+ * Allocate a buffer.
+ * The lifetime of the allocation is controlled by a reference count.
+ * The reference count of the returned buffer is set to 1.
+ * The memory will be freed once the reference count reaches 0.
+ * Use @ref ump_dd_retain and @ref ump_dd_release to control the reference count.
+ * @param size Number of bytes to allocate. Will be padded up to a multiple of the page size.
+ * @param flags Bit-wise OR of zero or more of the allocation flag bits.
+ * @param[in] filter_func Pointer to a function which will be called when an allocation is required from a
+ * secure id before the allocation itself is returned to user-space.
+ * NULL permitted if no need for a callback.
+ * @param[in] final_release_func Pointer to a function which will be called when the last reference is removed,
+ * just before the allocation is freed. NULL permitted if no need for a callback.
+ * @param[in] callback_data An opaque pointer which will be provided to @a filter_func and @a final_release_func
+ * @return Handle to the new allocation, or @a UMP_DD_INVALID_MEMORY_HANDLE on allocation failure.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_allocate_64(uint64_t size, ump_alloc_flags flags, ump_dd_security_filter filter_func, ump_dd_final_release_callback final_release_func, void* callback_data);
+
+
+/**
+ * Allocation bits getter.
+ * Retrieves the allocation flags used when instantiating the given handle.
+ * Just a copy of the flag given to @ref ump_dd_allocate_64 and @ref ump_dd_create_from_phys_blocks_64
+ * @param mem The handle retrieve the bits for
+ * @return The allocation bits used to instantiate the allocation
+ */
+UMP_KERNEL_API_EXPORT ump_alloc_flags ump_dd_allocation_flags_get(const ump_dd_handle mem);
+
+
+/**
+ * Retrieves the secure ID for the specified UMP memory.
+ *
+ * This identifier is unique across the entire system, and uniquely identifies
+ * the specified UMP memory allocation. This identifier can later be used through the
+ * @ref ump_dd_from_secure_id or
+ * @ref ump_from_secure_id
+ * functions in order to access this UMP memory, for instance from another process (if shared of course).
+ * Unless the allocation was marked as shared the returned ID will only be resolvable in the same process as did the allocation.
+ *
+ * Calling on an @a UMP_DD_INVALID_MEMORY_HANDLE will result in undefined behavior.
+ * Debug builds will assert on this.
+ *
+ * @note There is a user space equivalent function called @ref ump_secure_id_get
+ *
+ * @see ump_dd_from_secure_id
+ * @see ump_from_secure_id
+ * @see ump_secure_id_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return Returns the secure ID for the specified UMP memory.
+ */
+UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(const ump_dd_handle mem);
+
+#ifdef CONFIG_KDS
+/**
+ * Retrieve the KDS resource for the specified UMP memory.
+ *
+ * The KDS resource should be used to synchronize access to the UMP allocation.
+ * See the KDS API for how to do that.
+ *
+ * @param mem Handle to the UMP memory to query.
+ * @return Pointer to the KDS resource controlling access to the UMP memory.
+ */
+UMP_KERNEL_API_EXPORT struct kds_resource * ump_dd_kds_resource_get(const ump_dd_handle mem);
+#endif
+
+/**
+ * Retrieves a handle to allocated UMP memory.
+ *
+ * The usage of UMP memory is reference counted, so this will increment the reference
+ * count by one for the specified UMP memory.
+ * Use @ref ump_dd_release when there is no longer any
+ * use for the retrieved handle.
+ *
+ * If called on an non-shared allocation and this is a different process @a UMP_DD_INVALID_MEMORY_HANDLE will be returned.
+ *
+ * Calling on an @a UMP_INVALID_SECURE_ID will return @a UMP_DD_INVALID_MEMORY_HANDLE
+ *
+ * @note There is a user space equivalent function called @ref ump_from_secure_id
+ *
+ * @see ump_dd_release
+ * @see ump_from_secure_id
+ *
+ * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get function.
+ *
+ * @return @a UMP_DD_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_from_secure_id(ump_secure_id secure_id);
+
+
+/**
+ * Retrieves all physical memory block information for specified UMP memory.
+ *
+ * This function can be used by other device drivers in order to create MMU tables.
+ * This function will return a pointer to an array of @ref ump_dd_physical_block_64 in @a pArray and the number of array elements in @a pCount
+ *
+ * Calling on an @a UMP_DD_INVALID_MEMORY_HANDLE results in undefined behavior.
+ * Debug builds will assert on this.
+ *
+ * @param mem Handle to UMP memory.
+ * @param[out] pCount Pointer to where to store the number of items in the returned array
+ * @param[out] pArray Pointer to where to store a pointer to the physical blocks array
+ */
+UMP_KERNEL_API_EXPORT void ump_dd_phys_blocks_get_64(const ump_dd_handle mem, uint64_t * const pCount, const ump_dd_physical_block_64 ** const pArray);
+
+/**
+ * Retrieves the actual size of the specified UMP memory.
+ *
+ * The size is reported in bytes, and is typically page aligned.
+ *
+ * Calling on an @a UMP_DD_INVALID_MEMORY_HANDLE results in undefined behavior.
+ * Debug builds will assert on this.
+ *
+ * @note There is a user space equivalent function called @ref ump_size_get
+ *
+ * @see ump_size_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return Returns the allocated size of the specified UMP memory, in bytes.
+ */
+UMP_KERNEL_API_EXPORT uint64_t ump_dd_size_get_64(const ump_dd_handle mem);
+
+
+/**
+ * Adds an extra reference to the specified UMP memory allocation.
+ *
+ * The function @ref ump_dd_release must then be used
+ * to release each copy of the UMP memory handle.
+ *
+ * Calling on an @a UMP_DD_INVALID_MEMORY_HANDLE results in undefined behavior.
+ * Debug builds will assert on this.
+ *
+ * @note You are not required to call @ref ump_dd_retain
+ * for UMP handles returned from
+ * @ref ump_dd_from_secure_id,
+ * because these handles are already reference counted by this function.
+ *
+ * @note There is a user space equivalent function called @ref ump_retain
+ *
+ * @see ump_retain
+ *
+ * @param mem Handle to UMP memory.
+ * @return 0 indicates success, any other value indicates failure.
+ */
+UMP_KERNEL_API_EXPORT int ump_dd_retain(ump_dd_handle mem);
+
+
+/**
+ * Releases a reference from the specified UMP memory.
+ *
+ * This function must be called once for every reference to the UMP memory handle.
+ * When the last reference is released, all resources associated with this UMP memory
+ * handle are freed.
+ *
+ * One can only call ump_release when matched with a successful ump_dd_retain, ump_dd_allocate_64 or ump_dd_from_secure_id
+ * If called on an @a UMP_DD_INVALID_MEMORY_HANDLE the function will early out.
+ *
+ * @note There is a user space equivalent function called @ref ump_release
+ *
+ * @see ump_release
+ *
+ * @param mem Handle to UMP memory.
+ */
+UMP_KERNEL_API_EXPORT void ump_dd_release(ump_dd_handle mem);
+
+/**
+ * Create an ump allocation handle based on externally managed memory.
+ * Used to wrap an existing allocation as an UMP memory handle.
+ * Once wrapped the memory acts just like a normal allocation coming from @ref ump_dd_allocate_64.
+ * The only exception is that the freed physical memory is not put into the pool of free memory, but instead considered returned to the caller once @a final_release_func returns.
+ * The blocks array will be copied, so no need to hold on to it after this function returns.
+ * @param[in] blocks Array of @ref ump_dd_physical_block_64
+ * @param num_blocks Number of elements in the array pointed to by @a blocks
+ * @param flags Allocation flags to mark the handle with
+ * @param[in] filter_func Pointer to a function which will be called when an allocation is required from a secure id before the allocation itself is returned to user-space.
+ * NULL permitted if no need for a callback.
+ * @param[in] final_release_func Pointer to a function which will be called when the last reference is removed, just before the allocation is freed. NULL permitted if no need for a callback.
+ * @param[in] callback_data An opaque pointer which will be provided to @a filter_func and @a final_release_func
+ * @return Handle to the UMP allocation handle created, or @a UMP_DD_INVALID_MEMORY_HANDLE if no such handle could be created.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_create_from_phys_blocks_64(const ump_dd_physical_block_64 * blocks, uint64_t num_blocks, ump_alloc_flags flags, ump_dd_security_filter filter_func, ump_dd_final_release_callback final_release_func, void* callback_data);
+
+
+/** @name UMP v1 API
+ * Functions provided to support compatibility with UMP v1 API
+ *
+ *@{
+ */
+
+/**
+ * Value to indicate an invalid UMP memory handle.
+ */
+#define UMP_DD_HANDLE_INVALID UMP_DD_INVALID_MEMORY_HANDLE
+
+/**
+ * UMP error codes for kernel space.
+ */
+typedef enum
+{
+ UMP_DD_SUCCESS, /**< indicates success */
+ UMP_DD_INVALID /**< indicates failure */
+} ump_dd_status_code;
+
+
+/**
+ * Struct used to describe a physical block used by UMP memory
+ */
+typedef struct ump_dd_physical_block
+{
+ unsigned long addr; /**< The physical address of the block */
+ unsigned long size; /**< The length of the block, typically page aligned */
+} ump_dd_physical_block;
+
+
+/**
+ * Retrieves a handle to allocated UMP memory.
+ *
+ * The usage of UMP memory is reference counted, so this will increment the reference
+ * count by one for the specified UMP memory.
+ * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any
+ * use for the retrieved handle.
+ *
+ * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id"
+ *
+ * @see ump_dd_reference_release
+ * @see ump_handle_create_from_secure_id
+ *
+ * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function.
+ *
+ * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id);
+
+
+
+/**
+ * Create an ump allocation handle based on externally managed memory.
+ * Used to wrap an existing allocation as an UMP memory handle.
+ *
+ * @param[in] blocks Array of @ref ump_dd_physical_block
+ * @param num_blocks Number of elements in the array pointed to by @a blocks
+ *
+ * @return Handle to the UMP allocation handle created, or @a UMP_DD_INVALID_MEMORY_HANDLE if no such handle could be created.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks);
+
+
+/**
+ * Retrieves the number of physical blocks used by the specified UMP memory.
+ *
+ * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed
+ * to describe the physical memory layout of the given UMP memory. This can later be used when calling
+ * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and
+ * @ref ump_dd_phys_block_get "ump_dd_phys_block_get".
+ *
+ * @see ump_dd_phys_blocks_get
+ * @see ump_dd_phys_block_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory.
+ */
+UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem);
+
+
+/**
+ * Retrieves all physical memory block information for specified UMP memory.
+ *
+ * This function can be used by other device drivers in order to create MMU tables.
+ *
+ * @note This function will fail if the num_blocks parameter is either to large or to small.
+ *
+ * @see ump_dd_phys_block_get
+ *
+ * @param mem Handle to UMP memory.
+ * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description.
+ * @param num_blocks The number of blocks to return in the blocks array. Use the function
+ * @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required.
+ *
+ * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * const blocks, unsigned long num_blocks);
+
+
+/**
+ * Retrieves the physical memory block information for specified block for the specified UMP memory.
+ *
+ * This function can be used by other device drivers in order to create MMU tables.
+ *
+ * @note This function will return UMP_DD_INVALID if the specified index is out of range.
+ *
+ * @see ump_dd_phys_blocks_get
+ *
+ * @param mem Handle to UMP memory.
+ * @param index Which physical info block to retrieve.
+ * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information.
+ *
+ * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * const block);
+
+
+/**
+ * Retrieves the actual size of the specified UMP memory.
+ *
+ * The size is reported in bytes, and is typically page aligned.
+ *
+ * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get"
+ *
+ * @see ump_size_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return Returns the allocated size of the specified UMP memory, in bytes.
+ */
+UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem);
+
+
+/**
+ * Adds an extra reference to the specified UMP memory.
+ *
+ * This function adds an extra reference to the specified UMP memory. This function should
+ * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle
+ * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used
+ * to release each copy of the UMP memory handle.
+ *
+ * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add"
+ * for UMP handles returned from
+ * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id",
+ * because these handles are already reference counted by this function.
+ *
+ * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add"
+ *
+ * @see ump_reference_add
+ *
+ * @param mem Handle to UMP memory.
+ */
+UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem);
+
+
+/**
+ * Releases a reference from the specified UMP memory.
+ *
+ * This function should be called once for every reference to the UMP memory handle.
+ * When the last reference is released, all resources associated with this UMP memory
+ * handle are freed.
+ *
+ * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release"
+ *
+ * @see ump_reference_release
+ *
+ * @param mem Handle to UMP memory.
+ */
+UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem);
+
+/* @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** @} */ /* end group ump_kernel_space_api */
+
+/** @} */ /* end group ump_api */
+
+#endif /* _UMP_KERNEL_INTERFACE_H_ */
diff --git a/driver/product/kernel/license.txt b/driver/product/kernel/license.txt
new file mode 100755
index 0000000..77c14bd
--- /dev/null
+++ b/driver/product/kernel/license.txt
@@ -0,0 +1,198 @@
+GPLV2 LICENCE AGREEMENT FOR MALI GPUS LINUX KERNEL DEVICE DRIVERS SOURCE CODE
+
+THE USE OF THE SOFTWARE ACCOMPANYING THIS DOCUMENT IS EXPRESSLY SUBJECT TO THE TERMS OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION AND SET OUT BELOW FOR REFERENCE (?GPL LICENCE?). ARM IS ONLY WILLING TO DISTRIBUTE THE SOFTWARE TO YOU ON CONDITION THAT YOU ACCEPT ALL OF THE TERMS IN THE GPL LICENCE PRIOR TO MODIFYING OR DISTRIBUTING THE SOFTWARE.
+
+
+
+Further for the period of three (3) years, ARM hereby offers to make available the source code of any part of the software program that is supplied as object code or in executable form.
+
+
+
+GPL Licence
+
+
+
+GNU GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+
+
+Preamble
+
+
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.
+
+
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
+
+
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
+
+
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
+
+
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
+
+
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
+
+
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+
+
+GNU GENERAL PUBLIC LICENSE
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
+
+
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program).
+
+Whether that is true depends on what the Program does.
+
+
+
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty;
+
+and give any other recipients of the Program a copy of this License along with the Program.
+
+
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+
+
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+
+
+a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+
+
+
+b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
+
+
+
+c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
+
+
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
+
+
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+
+
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
+
+
+
+a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+
+
+b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+
+
+c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
+
+
+
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
+
+
+
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+
+
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the
+
+Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
+
+
+
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein.
+
+You are not responsible for enforcing compliance by third parties to this License.
+
+
+
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
+
+
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+
+
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+
+
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
+
+
+
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+
+
+NO WARRANTY
+
+
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+/end
+
diff --git a/driver/product/kernel/patches/integrate_kds_with_dma_buf.patch b/driver/product/kernel/patches/integrate_kds_with_dma_buf.patch
new file mode 100755
index 0000000..37458cf
--- /dev/null
+++ b/driver/product/kernel/patches/integrate_kds_with_dma_buf.patch
@@ -0,0 +1,188 @@
+diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
+index 9aa618a..30e07ea 100644
+--- a/drivers/base/Kconfig
++++ b/drivers/base/Kconfig
+@@ -192,4 +192,12 @@ config DMA_SHARED_BUFFER
+ APIs extension; the file's descriptor can then be passed on to other
+ driver.
+
++config DMA_SHARED_BUFFER_USES_KDS
++ bool "Synchronize access to dma_buf with KDS"
++ default n
++ select KDS
++ depends on DMA_SHARED_BUFFER
++ help
++ This option adds a KDS resource within every dma_buf allocation.
++
+ endmenu
+diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
+index 20258e1..e4083fd 100644
+--- a/drivers/base/dma-buf.c
++++ b/drivers/base/dma-buf.c
+@@ -27,6 +27,8 @@
+ #include <linux/dma-buf.h>
+ #include <linux/anon_inodes.h>
+ #include <linux/export.h>
++#include <linux/poll.h>
++#include <linux/sched.h>
+
+ static inline int is_dma_buf_file(struct file *);
+
+@@ -40,6 +42,8 @@ static int dma_buf_release(struct inode *inode, struct file *file)
+ dmabuf = file->private_data;
+
+ dmabuf->ops->release(dmabuf);
++ kds_callback_term(&dmabuf->kds_cb);
++ kds_resource_term(&dmabuf->kds);
+ kfree(dmabuf);
+ return 0;
+ }
+@@ -61,9 +65,90 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
+ return dmabuf->ops->mmap(dmabuf, vma);
+ }
+
++
++static void dma_buf_kds_cb_fn (void *param1, void *param2)
++{
++ struct kds_resource_set **rset_ptr = param1;
++ struct kds_resource_set *rset = *rset_ptr;
++ wait_queue_head_t *wait_queue = param2;
++
++ kfree(rset_ptr);
++ kds_resource_set_release(&rset);
++ wake_up(wait_queue);
++}
++
++static int dma_buf_kds_check(struct kds_resource *kds,
++ long unsigned int exclusive, int *poll_ret)
++{
++ /* Synchronous wait with 0 timeout - poll availability */
++ struct kds_resource_set *rset = kds_waitall(1,&exclusive,&kds,0);
++
++ if (IS_ERR(rset))
++ return POLLERR;
++
++ if (rset){
++ kds_resource_set_release(&rset);
++ *poll_ret = POLLIN | POLLRDNORM;
++ if (exclusive)
++ *poll_ret |= POLLOUT | POLLWRNORM;
++ return 1;
++ }else{
++ return 0;
++ }
++}
++
++static unsigned int dma_buf_poll(struct file *file,
++ struct poll_table_struct *wait)
++{
++ struct dma_buf *dmabuf;
++ struct kds_resource *kds;
++ unsigned int ret = 0;
++
++ if (!is_dma_buf_file(file))
++ return POLLERR;
++
++ dmabuf = file->private_data;
++ kds = &dmabuf->kds;
++
++ if (poll_does_not_wait(wait)){
++ /* Check for exclusive access (superset of shared) first */
++ if(!dma_buf_kds_check(kds, 1ul, &ret))
++ dma_buf_kds_check(kds, 0ul, &ret);
++ }else{
++ int events = poll_requested_events(wait);
++ unsigned long exclusive;
++ wait_queue_head_t *wq;
++ struct kds_resource_set **rset_ptr = kmalloc(sizeof(*rset_ptr), GFP_KERNEL);
++
++ if (!rset_ptr)
++ return POLL_ERR;
++
++ if (events & POLLOUT){
++ wq = &dmabuf->wq_exclusive;
++ exclusive = 1;
++ }else{
++ wq = &dmabuf->wq_shared;
++ exclusive = 0;
++ }
++ poll_wait(file, wq, wait);
++ ret = kds_async_waitall(rset_ptr, KDS_FLAG_LOCKED_WAIT, &dmabuf->kds_cb,
++ rset_ptr, wq, 1, &exclusive, &kds);
++
++ if (IS_ERR_VALUE(ret)){
++ ret = POLL_ERR;
++ kfree(rset_ptr);
++ }else{
++ /* Can't allow access until callback */
++ ret = 0;
++ }
++ }
++ return ret;
++}
++
+ static const struct file_operations dma_buf_fops = {
+ .release = dma_buf_release,
+ .mmap = dma_buf_mmap_internal,
++ .poll = dma_buf_poll,
+ };
+
+ /*
+@@ -120,6 +205,11 @@ struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops,
+ mutex_init(&dmabuf->lock);
+ INIT_LIST_HEAD(&dmabuf->attachments);
+
++ init_waitqueue_head(&dmabuf->wq_exclusive);
++ init_waitqueue_head(&dmabuf->wq_shared);
++ kds_resource_init(&dmabuf->kds);
++ kds_callback_init(&dmabuf->kds_cb, 1, dma_buf_kds_cb_fn);
++
+ return dmabuf;
+ }
+ EXPORT_SYMBOL_GPL(dma_buf_export);
+diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
+index eb48f38..6e824d2 100644
+--- a/include/linux/dma-buf.h
++++ b/include/linux/dma-buf.h
+@@ -30,6 +30,8 @@
+ #include <linux/list.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/fs.h>
++#include <linux/kds.h>
++#include <linux/wait.h>
+
+ struct device;
+ struct dma_buf;
+@@ -121,6 +123,10 @@ struct dma_buf {
+ const struct dma_buf_ops *ops;
+ /* mutex to serialize list manipulation and attach/detach */
+ struct mutex lock;
++ struct kds_resource kds;
++ wait_queue_head_t wq_exclusive;
++ wait_queue_head_t wq_shared;
++ struct kds_callback kds_cb;
+ void *priv;
+ };
+
+@@ -156,6 +162,21 @@ static inline void get_dma_buf(struct dma_buf *dmabuf)
+ get_file(dmabuf->file);
+ }
+
++/**
++ * get_dma_buf_kds_resource - get a KDS resource for this dma-buf
++ * @dmabuf: [in] pointer to dma_buf
++ *
++ * Returns a KDS resource that represents the dma-buf. This should be used by
++ * drivers to synchronize access to the buffer. Note that the caller should
++ * ensure that a reference to the dma-buf exists from the call to
++ * kds_async_wait until kds_resource_set_release is called.
++ */
++static inline struct kds_resource *
++ get_dma_buf_kds_resource(struct dma_buf *dmabuf)
++{
++ return &dmabuf->kds;
++}
++
+ #ifdef CONFIG_DMA_SHARED_BUFFER
+ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
+ struct device *dev);
diff --git a/driver/product/kernel/sconscript b/driver/product/kernel/sconscript
new file mode 100755
index 0000000..9cbccb0
--- /dev/null
+++ b/driver/product/kernel/sconscript
@@ -0,0 +1,23 @@
+#
+# (C) COPYRIGHT 2010-2014, 2016 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the
+# GNU General Public License version 2 as published by the Free Software
+# Foundation, and any use by you of this program is subject to the terms
+# of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained
+# from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+#
+
+
+
+Import('env')
+
+if env['backend'] == 'kernel' and int(env['kernel_modules']) == 1:
+ SConscript('drivers/sconscript')
+
+ if Glob('tests/sconscript'):
+ SConscript('tests/sconscript')
diff --git a/mali-midgard-16.0/README b/mali-midgard-16.0/README
deleted file mode 100644
index b49412f..0000000
--- a/mali-midgard-16.0/README
+++ /dev/null
@@ -1,21 +0,0 @@
-This repository contains the out-of-tree Linux kernel driver for the ARM Mali
-Midgard GPU. It is based on the r16p0 release, called 16.0 in the Debian DKMS
-packages. It also contains some patches to make it work with mainline device
-tree bindings backported to v4.9 kernel. Newer kernel versions are not
-supported in this driver version.
-
-To use it with dkms, first clone this repository in /usr/src:
-
- sudo clone https://git.collabora.com/git/user/gtucker/mali-midgard.git /usr/src/mali-midgard-16.0
-
-Then add it to dkms (will end up in /var/lib/dkms)
-
- sudo dkms add -m mali-midgard -v 16.0
-
-Now you can decide to just build it to use it straight away:
-
- sudo dkms build -m mali-midgard -v 16.0
-
-Or, make a Debian dkms source package:
-
- sudo dkms mkdeb -m mali-midgard -v 16.0 --source-only
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.c b/mali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.c
deleted file mode 100755
index d965033..0000000
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- *
- * (C) COPYRIGHT 2011-2016 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained
- * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-
-
-#include <linux/devfreq_cooling.h>
-#include <linux/thermal.h>
-#include <linux/of.h>
-#include <mali_kbase.h>
-#include <mali_kbase_defs.h>
-#include <backend/gpu/mali_kbase_power_model_simple.h>
-
-/*
- * This model is primarily designed for the Juno platform. It may not be
- * suitable for other platforms.
- */
-
-#define FALLBACK_STATIC_TEMPERATURE 55000
-
-static u32 dynamic_coefficient;
-static u32 static_coefficient;
-static s32 ts[4];
-static struct thermal_zone_device *gpu_tz;
-
-static unsigned long model_static_power(unsigned long voltage)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
- unsigned long temperature;
-#else
- int temperature;
-#endif
- unsigned long temp;
- unsigned long temp_squared, temp_cubed, temp_scaling_factor;
- const unsigned long voltage_cubed = (voltage * voltage * voltage) >> 10;
-
- if (gpu_tz) {
- int ret;
-
- ret = gpu_tz->ops->get_temp(gpu_tz, &temperature);
- if (ret) {
- pr_warn_ratelimited("Error reading temperature for gpu thermal zone: %d\n",
- ret);
- temperature = FALLBACK_STATIC_TEMPERATURE;
- }
- } else {
- temperature = FALLBACK_STATIC_TEMPERATURE;
- }
-
- /* Calculate the temperature scaling factor. To be applied to the
- * voltage scaled power.
- */
- temp = temperature / 1000;
- temp_squared = temp * temp;
- temp_cubed = temp_squared * temp;
- temp_scaling_factor =
- (ts[3] * temp_cubed)
- + (ts[2] * temp_squared)
- + (ts[1] * temp)
- + ts[0];
-
- return (((static_coefficient * voltage_cubed) >> 20)
- * temp_scaling_factor)
- / 1000000;
-}
-
-static unsigned long model_dynamic_power(unsigned long freq,
- unsigned long voltage)
-{
- /* The inputs: freq (f) is in Hz, and voltage (v) in mV.
- * The coefficient (c) is in mW/(MHz mV mV).
- *
- * This function calculates the dynamic power after this formula:
- * Pdyn (mW) = c (mW/(MHz*mV*mV)) * v (mV) * v (mV) * f (MHz)
- */
- const unsigned long v2 = (voltage * voltage) / 1000; /* m*(V*V) */
- const unsigned long f_mhz = freq / 1000000; /* MHz */
-
- return (dynamic_coefficient * v2 * f_mhz) / 1000000; /* mW */
-}
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
-struct devfreq_cooling_ops power_model_simple_ops = {
-#else
-struct devfreq_cooling_power power_model_simple_ops = {
-#endif
- .get_static_power = model_static_power,
- .get_dynamic_power = model_dynamic_power,
-};
-
-int kbase_power_model_simple_init(struct kbase_device *kbdev)
-{
- struct device_node *power_model_node;
- const char *tz_name;
- u32 static_power, dynamic_power;
- u32 voltage, voltage_squared, voltage_cubed, frequency;
-
- power_model_node = of_get_child_by_name(kbdev->dev->of_node,
- "power_model");
- if (!power_model_node) {
- dev_err(kbdev->dev, "could not find power_model node\n");
- return -ENODEV;
- }
- if (!of_device_is_compatible(power_model_node,
- "arm,mali-simple-power-model")) {
- dev_err(kbdev->dev, "power_model incompatible with simple power model\n");
- return -ENODEV;
- }
-
- if (of_property_read_string(power_model_node, "thermal-zone",
- &tz_name)) {
- dev_err(kbdev->dev, "ts in power_model not available\n");
- return -EINVAL;
- }
-
- gpu_tz = thermal_zone_get_zone_by_name(tz_name);
- if (IS_ERR(gpu_tz)) {
- pr_warn_ratelimited("Error getting gpu thermal zone (%ld), not yet ready?\n",
- PTR_ERR(gpu_tz));
- gpu_tz = NULL;
-
- return -EPROBE_DEFER;
- }
-
- if (of_property_read_u32(power_model_node, "static-power",
- &static_power)) {
- dev_err(kbdev->dev, "static-power in power_model not available\n");
- return -EINVAL;
- }
- if (of_property_read_u32(power_model_node, "dynamic-power",
- &dynamic_power)) {
- dev_err(kbdev->dev, "dynamic-power in power_model not available\n");
- return -EINVAL;
- }
- if (of_property_read_u32(power_model_node, "voltage",
- &voltage)) {
- dev_err(kbdev->dev, "voltage in power_model not available\n");
- return -EINVAL;
- }
- if (of_property_read_u32(power_model_node, "frequency",
- &frequency)) {
- dev_err(kbdev->dev, "frequency in power_model not available\n");
- return -EINVAL;
- }
- voltage_squared = (voltage * voltage) / 1000;
- voltage_cubed = voltage * voltage * voltage;
- static_coefficient = (static_power << 20) / (voltage_cubed >> 10);
- dynamic_coefficient = (((dynamic_power * 1000) / voltage_squared)
- * 1000) / frequency;
-
- if (of_property_read_u32_array(power_model_node, "ts", (u32 *)ts, 4)) {
- dev_err(kbdev->dev, "ts in power_model not available\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
diff --git a/mali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.h b/mali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.h
deleted file mode 100755
index 9b5e69a..0000000
--- a/mali-midgard-16.0/backend/gpu/mali_kbase_power_model_simple.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *
- * (C) COPYRIGHT 2014-2016 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
- *
- * A copy of the licence is 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 _BASE_POWER_MODEL_SIMPLE_H_
-#define _BASE_POWER_MODEL_SIMPLE_H_
-
-/**
- * kbase_power_model_simple_init - Initialise the simple power model
- * @kbdev: Device pointer
- *
- * The simple power model estimates power based on current voltage, temperature,
- * and coefficients read from device tree. It does not take utilization into
- * account.
- *
- * The power model requires coefficients from the power_model node in device
- * tree. The absence of this node will prevent the model from functioning, but
- * should not prevent the rest of the driver from running.
- *
- * Return: 0 on success
- * -ENOSYS if the power_model node is not present in device tree
- * -EPROBE_DEFER if the thermal zone specified in device tree is not
- * currently available
- * Any other negative value on failure
- */
-int kbase_power_model_simple_init(struct kbase_device *kbdev);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
-extern struct devfreq_cooling_ops power_model_simple_ops;
-#else
-extern struct devfreq_cooling_power power_model_simple_ops;
-#endif
-
-#endif /* _BASE_POWER_MODEL_SIMPLE_H_ */
diff --git a/mali-midgard-16.0/patches/0001-gpu-midgard-replace-device-tree-compatible-strings.patch b/mali-midgard-16.0/patches/0001-gpu-midgard-replace-device-tree-compatible-strings.patch
deleted file mode 100644
index 4e8bbcd..0000000
--- a/mali-midgard-16.0/patches/0001-gpu-midgard-replace-device-tree-compatible-strings.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From cb4a8e9b23464953ddf3898095e08670e8a8f6ea Mon Sep 17 00:00:00 2001
-From: Guillaume Tucker <guillaume.tucker@collabora.com>
-Date: Wed, 12 Apr 2017 17:27:29 +0100
-Subject: [PATCH 1/4] gpu: midgard: replace device tree compatible strings
-
-Replace the list of device tree compatible strings with all the Mali
-Midgard GPU types to match the device tree bindings documentation.
-
-Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
----
- drivers/gpu/arm/midgard/mali_kbase_core_linux.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/mali_kbase_core_linux.c b/mali_kbase_core_linux.c
-index 4e95633c307f..6cba3e2318ed 100644
---- a/mali_kbase_core_linux.c
-+++ b/mali_kbase_core_linux.c
-@@ -4161,7 +4161,14 @@ static const struct dev_pm_ops kbase_pm_ops = {
-
- #ifdef CONFIG_OF
- static const struct of_device_id kbase_dt_ids[] = {
-- { .compatible = "arm,malit6xx" },
-+ { .compatible = "arm,mali-t604" },
-+ { .compatible = "arm,mali-t624" },
-+ { .compatible = "arm,mali-t628" },
-+ { .compatible = "arm,mali-t720" },
-+ { .compatible = "arm,mali-t760" },
-+ { .compatible = "arm,mali-t820" },
-+ { .compatible = "arm,mali-t860" },
-+ { .compatible = "arm,mali-t880" },
- { .compatible = "arm,mali-midgard" },
- { /* sentinel */ }
- };
---
-2.11.0
diff --git a/mali-midgard-16.0/patches/0002-gpu-midgard-drop-clk_mali-name.patch b/mali-midgard-16.0/patches/0002-gpu-midgard-drop-clk_mali-name.patch
deleted file mode 100644
index e329c47..0000000
--- a/mali-midgard-16.0/patches/0002-gpu-midgard-drop-clk_mali-name.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 92f20fec63bdbb7341135875f6579b148ac07574 Mon Sep 17 00:00:00 2001
-From: Guillaume Tucker <guillaume.tucker@collabora.com>
-Date: Tue, 11 Apr 2017 18:45:01 +0100
-Subject: [PATCH 2/4] gpu: midgard: drop "clk_mali" name
-
-As the "clock-names" entry has been removed from the device tree, also
-remove the clock name "clk_mali" in the driver to get the only clock
-without any name.
-
-Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
----
- drivers/gpu/arm/midgard/mali_kbase_core_linux.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mali_kbase_core_linux.c b/mali_kbase_core_linux.c
-index 6cba3e2318ed..d35ca2bb446c 100644
---- a/mali_kbase_core_linux.c
-+++ b/mali_kbase_core_linux.c
-@@ -3269,7 +3269,7 @@ static int power_control_init(struct platform_device *pdev)
- }
- #endif /* LINUX_VERSION_CODE >= 3, 12, 0 */
-
-- kbdev->clock = clk_get(kbdev->dev, "clk_mali");
-+ kbdev->clock = clk_get(kbdev->dev, NULL);
- if (IS_ERR_OR_NULL(kbdev->clock)) {
- err = PTR_ERR(kbdev->clock);
- kbdev->clock = NULL;
---
-2.11.0
diff --git a/mali-midgard-16.0/patches/0003-gpu-midgard-look-for-lower-case-IRQ-names.patch b/mali-midgard-16.0/patches/0003-gpu-midgard-look-for-lower-case-IRQ-names.patch
deleted file mode 100644
index e122de6..0000000
--- a/mali-midgard-16.0/patches/0003-gpu-midgard-look-for-lower-case-IRQ-names.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 3fd3833a2f2862bcb4e464a4298ec8e061e83e0f Mon Sep 17 00:00:00 2001
-From: Guillaume Tucker <guillaume.tucker@collabora.com>
-Date: Tue, 11 Apr 2017 19:18:02 +0100
-Subject: [PATCH 3/4] gpu: midgard: look for lower-case IRQ names
-
-As the interrupt-names have been changed to lower-case, adjust the
-driver accordingly.
-
-Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
----
- drivers/gpu/arm/midgard/mali_kbase_core_linux.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/mali_kbase_core_linux.c b/mali_kbase_core_linux.c
-index d35ca2bb446c..945f222e6d9e 100644
---- a/mali_kbase_core_linux.c
-+++ b/mali_kbase_core_linux.c
-@@ -1057,11 +1057,11 @@ static int assign_irqs(struct platform_device *pdev)
- }
-
- #ifdef CONFIG_OF
-- if (!strncmp(irq_res->name, "JOB", 4)) {
-+ if (!strncmp(irq_res->name, "job", 4)) {
- irqtag = JOB_IRQ_TAG;
-- } else if (!strncmp(irq_res->name, "MMU", 4)) {
-+ } else if (!strncmp(irq_res->name, "mmu", 4)) {
- irqtag = MMU_IRQ_TAG;
-- } else if (!strncmp(irq_res->name, "GPU", 4)) {
-+ } else if (!strncmp(irq_res->name, "gpu", 4)) {
- irqtag = GPU_IRQ_TAG;
- } else {
- dev_err(&pdev->dev, "Invalid irq res name: '%s'\n",
---
-2.11.0
diff --git a/mali-midgard-16.0/patches/0004-gpu-midgard-add-deferring-in-log-when-clock-or-regul.patch b/mali-midgard-16.0/patches/0004-gpu-midgard-add-deferring-in-log-when-clock-or-regul.patch
deleted file mode 100644
index 4d28635..0000000
--- a/mali-midgard-16.0/patches/0004-gpu-midgard-add-deferring-in-log-when-clock-or-regul.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From bbbffd7ddf71fbfbea2437a9111a338e0cf26a5d Mon Sep 17 00:00:00 2001
-From: Guillaume Tucker <guillaume.tucker@collabora.com>
-Date: Mon, 27 Mar 2017 15:33:43 +0100
-Subject: [PATCH 4/4] gpu: midgard: add "deferring" in log when clock or
- regulator not found
-
-Update log messages to show that a failure to find the Mali GPU clock
-or regulator results in a later retry (-EPROBE_DEFER).
-
-Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
----
- drivers/gpu/arm/midgard/mali_kbase_core_linux.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/mali_kbase_core_linux.c b/mali_kbase_core_linux.c
-index 945f222e6d9e..abc931794275 100644
---- a/mali_kbase_core_linux.c
-+++ b/mali_kbase_core_linux.c
-@@ -3260,7 +3260,8 @@ static int power_control_init(struct platform_device *pdev)
- err = PTR_ERR(kbdev->regulator);
- kbdev->regulator = NULL;
- if (err == -EPROBE_DEFER) {
-- dev_err(&pdev->dev, "Failed to get regulator\n");
-+ dev_err(&pdev->dev,
-+ "Failed to get regulator, deferring.\n");
- return err;
- }
- dev_info(kbdev->dev,
-@@ -3274,7 +3275,8 @@ static int power_control_init(struct platform_device *pdev)
- err = PTR_ERR(kbdev->clock);
- kbdev->clock = NULL;
- if (err == -EPROBE_DEFER) {
-- dev_err(&pdev->dev, "Failed to get clock\n");
-+ dev_err(&pdev->dev,
-+ "Failed to get clock, deferring.\n");
- goto fail;
- }
- dev_info(kbdev->dev, "Continuing without Mali clock control\n");
---
-2.11.0
diff --git a/mali-midgard-16.0/patches/arm64-standalone-headers.patch b/mali-midgard-16.0/patches/arm64-standalone-headers.patch
deleted file mode 100644
index 969e387..0000000
--- a/mali-midgard-16.0/patches/arm64-standalone-headers.patch
+++ /dev/null
@@ -1,532 +0,0 @@
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/opcodes.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/opcodes.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/opcodes.h 2016-12-15 15:29:37.330706881 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/opcodes.h 1970-01-01 00:00:00.000000000 +0000
-@@ -1,5 +0,0 @@
--#ifdef CONFIG_CPU_BIG_ENDIAN
--#define CONFIG_CPU_ENDIAN_BE8 CONFIG_CPU_BIG_ENDIAN
--#endif
--
--#include <../../arm/include/asm/opcodes.h>
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/sysreg.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/sysreg.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/sysreg.h 2016-12-15 15:29:37.334706963 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/sysreg.h 2016-12-29 17:53:10.380735552 +0000
-@@ -22,8 +22,6 @@
-
- #include <linux/stringify.h>
-
--#include <asm/opcodes.h>
--
- /*
- * ARMv8 ARM reserves the following encoding for system registers:
- * (Ref: ARMv8 ARM, Section: "System instruction class encoding overview",
-@@ -37,6 +35,14 @@
- #define sys_reg(op0, op1, crn, crm, op2) \
- ((((op0)&3)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
-
-+#ifdef __ASSEMBLY__
-+#define ___emit_inst(x) .inst x
-+#else
-+#define ___emit_inst(x) ".inst " __stringify(x) "\n\t"
-+#endif
-+
-+#define __emit_inst(x) ___emit_inst((x))
-+
- #define SYS_MIDR_EL1 sys_reg(3, 0, 0, 0, 0)
- #define SYS_MPIDR_EL1 sys_reg(3, 0, 0, 0, 5)
- #define SYS_REVIDR_EL1 sys_reg(3, 0, 0, 0, 6)
-@@ -81,10 +87,10 @@
- #define REG_PSTATE_PAN_IMM sys_reg(0, 0, 4, 0, 4)
- #define REG_PSTATE_UAO_IMM sys_reg(0, 0, 4, 0, 3)
-
--#define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
-- (!!x)<<8 | 0x1f)
--#define SET_PSTATE_UAO(x) __inst_arm(0xd5000000 | REG_PSTATE_UAO_IMM |\
-- (!!x)<<8 | 0x1f)
-+#define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM | \
-+ (!!x)<<8 | 0x1f)
-+#define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM | \
-+ (!!x)<<8 | 0x1f)
-
- /* Common SCTLR_ELx flags. */
- #define SCTLR_ELx_EE (1 << 25)
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/hypercall.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/hypercall.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/hypercall.h 2016-12-15 15:29:37.334706963 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/hypercall.h 2016-12-29 18:50:39.875430462 +0000
-@@ -1 +1 @@
--#include <../../arm/include/asm/xen/hypercall.h>
-+#include <xen/arm/hypercall.h>
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/hypervisor.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/hypervisor.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/hypervisor.h 2016-12-15 15:29:37.334706963 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/hypervisor.h 2016-12-29 18:50:56.119697557 +0000
-@@ -1 +1 @@
--#include <../../arm/include/asm/xen/hypervisor.h>
-+#include <xen/arm/hypervisor.h>
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/interface.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/interface.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/interface.h 2016-12-15 15:29:37.334706963 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/interface.h 2016-12-29 18:50:33.559326677 +0000
-@@ -1 +1 @@
--#include <../../arm/include/asm/xen/interface.h>
-+#include <xen/arm/interface.h>
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/page-coherent.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/page-coherent.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/page-coherent.h 2016-12-15 15:29:37.334706963 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/page-coherent.h 2016-12-29 18:50:48.011564209 +0000
-@@ -1 +1 @@
--#include <../../arm/include/asm/xen/page-coherent.h>
-+#include <xen/arm/page-coherent.h>
-diff -urN linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/page.h linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/page.h
---- linux-headers-4.8.0-2-common-unpatched/arch/arm64/include/asm/xen/page.h 2016-12-15 15:29:37.334706963 +0000
-+++ linux-headers-4.8.0-2-common/arch/arm64/include/asm/xen/page.h 2016-12-29 18:50:28.155237909 +0000
-@@ -1 +1 @@
--#include <../../arm/include/asm/xen/page.h>
-+#include <xen/arm/page.h>
-diff -urN linux-headers-4.8.0-2-common-unpatched/include/xen/arm/hypercall.h linux-headers-4.8.0-2-common/include/xen/arm/hypercall.h
---- linux-headers-4.8.0-2-common-unpatched/include/xen/arm/hypercall.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-headers-4.8.0-2-common/include/xen/arm/hypercall.h 2016-12-29 18:32:54.781934916 +0000
-@@ -0,0 +1,87 @@
-+/******************************************************************************
-+ * hypercall.h
-+ *
-+ * Linux-specific hypervisor handling.
-+ *
-+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
-+ *
-+ * 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; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef _ASM_ARM_XEN_HYPERCALL_H
-+#define _ASM_ARM_XEN_HYPERCALL_H
-+
-+#include <linux/bug.h>
-+
-+#include <xen/interface/xen.h>
-+#include <xen/interface/sched.h>
-+#include <xen/interface/platform.h>
-+
-+long privcmd_call(unsigned call, unsigned long a1,
-+ unsigned long a2, unsigned long a3,
-+ unsigned long a4, unsigned long a5);
-+int HYPERVISOR_xen_version(int cmd, void *arg);
-+int HYPERVISOR_console_io(int cmd, int count, char *str);
-+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-+int HYPERVISOR_sched_op(int cmd, void *arg);
-+int HYPERVISOR_event_channel_op(int cmd, void *arg);
-+unsigned long HYPERVISOR_hvm_op(int op, void *arg);
-+int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
-+int HYPERVISOR_physdev_op(int cmd, void *arg);
-+int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
-+int HYPERVISOR_tmem_op(void *arg);
-+int HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type);
-+int HYPERVISOR_platform_op_raw(void *arg);
-+static inline int HYPERVISOR_platform_op(struct xen_platform_op *op)
-+{
-+ op->interface_version = XENPF_INTERFACE_VERSION;
-+ return HYPERVISOR_platform_op_raw(op);
-+}
-+int HYPERVISOR_multicall(struct multicall_entry *calls, uint32_t nr);
-+
-+static inline int
-+HYPERVISOR_suspend(unsigned long start_info_mfn)
-+{
-+ struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
-+
-+ /* start_info_mfn is unused on ARM */
-+ return HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
-+}
-+
-+static inline void
-+MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
-+ unsigned int new_val, unsigned long flags)
-+{
-+ BUG();
-+}
-+
-+static inline void
-+MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
-+ int count, int *success_count, domid_t domid)
-+{
-+ BUG();
-+}
-+
-+#endif /* _ASM_ARM_XEN_HYPERCALL_H */
-diff -urN linux-headers-4.8.0-2-common-unpatched/include/xen/arm/hypervisor.h linux-headers-4.8.0-2-common/include/xen/arm/hypervisor.h
---- linux-headers-4.8.0-2-common-unpatched/include/xen/arm/hypervisor.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-headers-4.8.0-2-common/include/xen/arm/hypervisor.h 2016-12-29 18:38:24.175590765 +0000
-@@ -0,0 +1,39 @@
-+#ifndef _ASM_ARM_XEN_HYPERVISOR_H
-+#define _ASM_ARM_XEN_HYPERVISOR_H
-+
-+#include <linux/init.h>
-+
-+extern struct shared_info *HYPERVISOR_shared_info;
-+extern struct start_info *xen_start_info;
-+
-+/* Lazy mode for batching updates / context switch */
-+enum paravirt_lazy_mode {
-+ PARAVIRT_LAZY_NONE,
-+ PARAVIRT_LAZY_MMU,
-+ PARAVIRT_LAZY_CPU,
-+};
-+
-+static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
-+{
-+ return PARAVIRT_LAZY_NONE;
-+}
-+
-+extern struct dma_map_ops *xen_dma_ops;
-+
-+#ifdef CONFIG_XEN
-+void __init xen_early_init(void);
-+#else
-+static inline void xen_early_init(void) { return; }
-+#endif
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static inline void xen_arch_register_cpu(int num)
-+{
-+}
-+
-+static inline void xen_arch_unregister_cpu(int num)
-+{
-+}
-+#endif
-+
-+#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
-diff -urN linux-headers-4.8.0-2-common-unpatched/include/xen/arm/interface.h linux-headers-4.8.0-2-common/include/xen/arm/interface.h
---- linux-headers-4.8.0-2-common-unpatched/include/xen/arm/interface.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-headers-4.8.0-2-common/include/xen/arm/interface.h 2016-12-29 18:45:12.422113087 +0000
-@@ -0,0 +1,85 @@
-+/******************************************************************************
-+ * Guest OS interface to ARM Xen.
-+ *
-+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
-+ */
-+
-+#ifndef _ASM_ARM_XEN_INTERFACE_H
-+#define _ASM_ARM_XEN_INTERFACE_H
-+
-+#include <linux/types.h>
-+
-+#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-+
-+#define __DEFINE_GUEST_HANDLE(name, type) \
-+ typedef struct { union { type *p; uint64_aligned_t q; }; } \
-+ __guest_handle_ ## name
-+
-+#define DEFINE_GUEST_HANDLE_STRUCT(name) \
-+ __DEFINE_GUEST_HANDLE(name, struct name)
-+#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
-+#define GUEST_HANDLE(name) __guest_handle_ ## name
-+
-+#define set_xen_guest_handle(hnd, val) \
-+ do { \
-+ if (sizeof(hnd) == 8) \
-+ *(uint64_t *)&(hnd) = 0; \
-+ (hnd).p = val; \
-+ } while (0)
-+
-+#define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op
-+
-+#ifndef __ASSEMBLY__
-+/* Explicitly size integers that represent pfns in the interface with
-+ * Xen so that we can have one ABI that works for 32 and 64 bit guests.
-+ * Note that this means that the xen_pfn_t type may be capable of
-+ * representing pfn's which the guest cannot represent in its own pfn
-+ * type. However since pfn space is controlled by the guest this is
-+ * fine since it simply wouldn't be able to create any sure pfns in
-+ * the first place.
-+ */
-+typedef uint64_t xen_pfn_t;
-+#define PRI_xen_pfn "llx"
-+typedef uint64_t xen_ulong_t;
-+#define PRI_xen_ulong "llx"
-+typedef int64_t xen_long_t;
-+#define PRI_xen_long "llx"
-+/* Guest handles for primitive C types. */
-+__DEFINE_GUEST_HANDLE(uchar, unsigned char);
-+__DEFINE_GUEST_HANDLE(uint, unsigned int);
-+DEFINE_GUEST_HANDLE(char);
-+DEFINE_GUEST_HANDLE(int);
-+DEFINE_GUEST_HANDLE(void);
-+DEFINE_GUEST_HANDLE(uint64_t);
-+DEFINE_GUEST_HANDLE(uint32_t);
-+DEFINE_GUEST_HANDLE(xen_pfn_t);
-+DEFINE_GUEST_HANDLE(xen_ulong_t);
-+
-+/* Maximum number of virtual CPUs in multi-processor guests. */
-+#define MAX_VIRT_CPUS 1
-+
-+struct arch_vcpu_info { };
-+struct arch_shared_info { };
-+
-+/* TODO: Move pvclock definitions some place arch independent */
-+struct pvclock_vcpu_time_info {
-+ u32 version;
-+ u32 pad0;
-+ u64 tsc_timestamp;
-+ u64 system_time;
-+ u32 tsc_to_system_mul;
-+ s8 tsc_shift;
-+ u8 flags;
-+ u8 pad[2];
-+} __attribute__((__packed__)); /* 32 bytes */
-+
-+/* It is OK to have a 12 bytes struct with no padding because it is packed */
-+struct pvclock_wall_clock {
-+ u32 version;
-+ u32 sec;
-+ u32 nsec;
-+ u32 sec_hi;
-+} __attribute__((__packed__));
-+#endif
-+
-+#endif /* _ASM_ARM_XEN_INTERFACE_H */
-diff -urN linux-headers-4.8.0-2-common-unpatched/include/xen/arm/page-coherent.h linux-headers-4.8.0-2-common/include/xen/arm/page-coherent.h
---- linux-headers-4.8.0-2-common-unpatched/include/xen/arm/page-coherent.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-headers-4.8.0-2-common/include/xen/arm/page-coherent.h 2016-12-29 18:45:54.666790395 +0000
-@@ -0,0 +1,98 @@
-+#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
-+#define _ASM_ARM_XEN_PAGE_COHERENT_H
-+
-+#include <asm/page.h>
-+#include <linux/dma-mapping.h>
-+
-+void __xen_dma_map_page(struct device *hwdev, struct page *page,
-+ dma_addr_t dev_addr, unsigned long offset, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs);
-+void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-+ size_t size, enum dma_data_direction dir,
-+ unsigned long attrs);
-+void __xen_dma_sync_single_for_cpu(struct device *hwdev,
-+ dma_addr_t handle, size_t size, enum dma_data_direction dir);
-+
-+void __xen_dma_sync_single_for_device(struct device *hwdev,
-+ dma_addr_t handle, size_t size, enum dma_data_direction dir);
-+
-+static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-+ dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
-+{
-+ return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
-+}
-+
-+static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-+ void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
-+{
-+ __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
-+}
-+
-+static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
-+ dma_addr_t dev_addr, unsigned long offset, size_t size,
-+ enum dma_data_direction dir, unsigned long attrs)
-+{
-+ unsigned long page_pfn = page_to_xen_pfn(page);
-+ unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
-+ unsigned long compound_pages =
-+ (1<<compound_order(page)) * XEN_PFN_PER_PAGE;
-+ bool local = (page_pfn <= dev_pfn) &&
-+ (dev_pfn - page_pfn < compound_pages);
-+
-+ /*
-+ * Dom0 is mapped 1:1, while the Linux page can span across
-+ * multiple Xen pages, it's not possible for it to contain a
-+ * mix of local and foreign Xen pages. So if the first xen_pfn
-+ * == mfn the page is local otherwise it's a foreign page
-+ * grant-mapped in dom0. If the page is local we can safely
-+ * call the native dma_ops function, otherwise we call the xen
-+ * specific function.
-+ */
-+ if (local)
-+ __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
-+ else
-+ __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
-+}
-+
-+static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-+ size_t size, enum dma_data_direction dir, unsigned long attrs)
-+{
-+ unsigned long pfn = PFN_DOWN(handle);
-+ /*
-+ * Dom0 is mapped 1:1, while the Linux page can be spanned accross
-+ * multiple Xen page, it's not possible to have a mix of local and
-+ * foreign Xen page. Dom0 is mapped 1:1, so calling pfn_valid on a
-+ * foreign mfn will always return false. If the page is local we can
-+ * safely call the native dma_ops function, otherwise we call the xen
-+ * specific function.
-+ */
-+ if (pfn_valid(pfn)) {
-+ if (__generic_dma_ops(hwdev)->unmap_page)
-+ __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
-+ } else
-+ __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
-+}
-+
-+static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
-+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
-+{
-+ unsigned long pfn = PFN_DOWN(handle);
-+ if (pfn_valid(pfn)) {
-+ if (__generic_dma_ops(hwdev)->sync_single_for_cpu)
-+ __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
-+ } else
-+ __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
-+}
-+
-+static inline void xen_dma_sync_single_for_device(struct device *hwdev,
-+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
-+{
-+ unsigned long pfn = PFN_DOWN(handle);
-+ if (pfn_valid(pfn)) {
-+ if (__generic_dma_ops(hwdev)->sync_single_for_device)
-+ __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir;
-+ } else
-+ __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
-+}
-+
-+#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
-diff -urN linux-headers-4.8.0-2-common-unpatched/include/xen/arm/page.h linux-headers-4.8.0-2-common/include/xen/arm/page.h
---- linux-headers-4.8.0-2-common-unpatched/include/xen/arm/page.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-headers-4.8.0-2-common/include/xen/arm/page.h 2016-12-29 18:46:47.371639580 +0000
-@@ -0,0 +1,122 @@
-+#ifndef _ASM_ARM_XEN_PAGE_H
-+#define _ASM_ARM_XEN_PAGE_H
-+
-+#include <asm/page.h>
-+#include <asm/pgtable.h>
-+
-+#include <linux/pfn.h>
-+#include <linux/types.h>
-+#include <linux/dma-mapping.h>
-+
-+#include <xen/xen.h>
-+#include <xen/interface/grant_table.h>
-+
-+#define phys_to_machine_mapping_valid(pfn) (1)
-+
-+/* Xen machine address */
-+typedef struct xmaddr {
-+ phys_addr_t maddr;
-+} xmaddr_t;
-+
-+/* Xen pseudo-physical address */
-+typedef struct xpaddr {
-+ phys_addr_t paddr;
-+} xpaddr_t;
-+
-+#define XMADDR(x) ((xmaddr_t) { .maddr = (x) })
-+#define XPADDR(x) ((xpaddr_t) { .paddr = (x) })
-+
-+#define INVALID_P2M_ENTRY (~0UL)
-+
-+/*
-+ * The pseudo-physical frame (pfn) used in all the helpers is always based
-+ * on Xen page granularity (i.e 4KB).
-+ *
-+ * A Linux page may be split across multiple non-contiguous Xen page so we
-+ * have to keep track with frame based on 4KB page granularity.
-+ *
-+ * PV drivers should never make a direct usage of those helpers (particularly
-+ * pfn_to_gfn and gfn_to_pfn).
-+ */
-+
-+unsigned long __pfn_to_mfn(unsigned long pfn);
-+extern struct rb_root phys_to_mach;
-+
-+/* Pseudo-physical <-> Guest conversion */
-+static inline unsigned long pfn_to_gfn(unsigned long pfn)
-+{
-+ return pfn;
-+}
-+
-+static inline unsigned long gfn_to_pfn(unsigned long gfn)
-+{
-+ return gfn;
-+}
-+
-+/* Pseudo-physical <-> BUS conversion */
-+static inline unsigned long pfn_to_bfn(unsigned long pfn)
-+{
-+ unsigned long mfn;
-+
-+ if (phys_to_mach.rb_node != NULL) {
-+ mfn = __pfn_to_mfn(pfn);
-+ if (mfn != INVALID_P2M_ENTRY)
-+ return mfn;
-+ }
-+
-+ return pfn;
-+}
-+
-+static inline unsigned long bfn_to_pfn(unsigned long bfn)
-+{
-+ return bfn;
-+}
-+
-+#define bfn_to_local_pfn(bfn) bfn_to_pfn(bfn)
-+
-+/* VIRT <-> GUEST conversion */
-+#define virt_to_gfn(v) (pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT))
-+#define gfn_to_virt(m) (__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT))
-+
-+/* Only used in PV code. But ARM guests are always HVM. */
-+static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
-+{
-+ BUG();
-+}
-+
-+/* TODO: this shouldn't be here but it is because the frontend drivers
-+ * are using it (its rolled in headers) even though we won't hit the code path.
-+ * So for right now just punt with this.
-+ */
-+static inline pte_t *lookup_address(unsigned long address, unsigned int *level)
-+{
-+ BUG();
-+ return NULL;
-+}
-+
-+extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
-+ struct gnttab_map_grant_ref *kmap_ops,
-+ struct page **pages, unsigned int count);
-+
-+extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
-+ struct gnttab_unmap_grant_ref *kunmap_ops,
-+ struct page **pages, unsigned int count);
-+
-+bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
-+bool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn,
-+ unsigned long nr_pages);
-+
-+static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-+{
-+ return __set_phys_to_machine(pfn, mfn);
-+}
-+
-+#define xen_remap(cookie, size) ioremap_cache((cookie), (size))
-+#define xen_unmap(cookie) iounmap((cookie))
-+
-+bool xen_arch_need_swiotlb(struct device *dev,
-+ phys_addr_t phys,
-+ dma_addr_t dev_addr);
-+unsigned long xen_get_swiotlb_free_pages(unsigned int order);
-+
-+#endif /* _ASM_ARM_XEN_PAGE_H */